You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
An outage longer than ~45 minutes permanently discards queued agent work, and nothing says so
Found 2026-08-18 while diagnosing a fleet-wide quota outage. @sprint-review noticed the word unacked in its own failure lines and counted the gap; the code confirms it.
What happens
agentEventService requeues delivered-but-unacked events, capped at AGENT_EVENT_REQUEUE_MAX_ATTEMPTS (default 3). Events that hit the cap are retired to a terminal failed status. From the code comment:
Events that hit the requeue cap and were retired to the terminal 'failed' state. Without this pass they would sit in 'delivered' — invisible to list(), ineligible for requeue — until the 168h retention delete.
The spacing is longer than the 10-minute default suggests, and the code says so:
Effective redelivery latency is NOT 10 minutes: schedulerService runs this job on */10, so an event delivered just after a pass waits for the one after next. Period P and threshold T give [T, T+P) — uniform over 10-20 min here, mean ~15.
3 attempts × ~15 min mean ≈ 45 minutes. After that the event is gone: not retried, not surfaced, deleted at 168h.
Observed
During the 4am quota exhaustion, sprint-review lost three events — 6a842b0d…, 6a842f2a…, 6a842fd6… — with a measured 46-minute gap between its last failed spawn and its next activity. pod-architect was in the same state with four consecutive failures.
The seat was not at fault and this is worth stating because it is the natural first suspicion: it kept polling throughout and processed a human mention at 04:10. It asked; the kernel had stopped serving.
Why this is worth fixing
The requeue exists precisely to prevent silent loss. Its own comment cites the incident that motivated it:
Saw this 2026-05-18: Cody's old pod marked 2 chat.mentions delivered then died on a stale config; the new pod never re-fetched them.
The attempt cap reintroduces that exact failure on a 45-minute timer. And the triggering condition is not exotic — BYO seats share the operator's Claude subscription, so quota exhaustion is routine and hits every seat at once. Tonight it hit the operator's own session in the same minutes. Any such outage reliably exceeds 45 minutes.
What I am NOT proposing
Do not simply raise the cap. It is a reasonable poison-event guard — an event that crashes its handler should not retry forever. The defect is not the cap, it is that hitting it is invisible.
Suggested direction (for whoever picks this up to challenge)
Surface the terminal state.failed events are currently invisible to list(). At minimum they should be countable and queryable per (agentName, instanceId).
Distinguish poison from outage. Repeated failure of one event with different errors is a poison event. All events for a seat failing with the same error is an outage — and an outage should not consume the poison budget. This distinction is probably the real fix.
Related
spawnRetryPolicy has an explicit QUOTA failure class that opens the circuit at the 15-minute ceiling, but classifySpawnFailure did not match "You've hit your session limit" — the failures logged as runtime. Worth fixing separately; note it does not change this outcome, since at either delay the event still dies on the requeue cap.
ADR-023 (hosted runtime): the shared-subscription ceiling is what makes the triggering outage routine.
An outage longer than ~45 minutes permanently discards queued agent work, and nothing says so
Found 2026-08-18 while diagnosing a fleet-wide quota outage.
@sprint-reviewnoticed the wordunackedin its own failure lines and counted the gap; the code confirms it.What happens
agentEventServicerequeues delivered-but-unacked events, capped atAGENT_EVENT_REQUEUE_MAX_ATTEMPTS(default 3). Events that hit the cap are retired to a terminalfailedstatus. From the code comment:The spacing is longer than the 10-minute default suggests, and the code says so:
3 attempts × ~15 min mean ≈ 45 minutes. After that the event is gone: not retried, not surfaced, deleted at 168h.
Observed
During the 4am quota exhaustion,
sprint-reviewlost three events —6a842b0d…,6a842f2a…,6a842fd6…— with a measured 46-minute gap between its last failed spawn and its next activity.pod-architectwas in the same state with four consecutive failures.The seat was not at fault and this is worth stating because it is the natural first suspicion: it kept polling throughout and processed a human mention at 04:10. It asked; the kernel had stopped serving.
Why this is worth fixing
The requeue exists precisely to prevent silent loss. Its own comment cites the incident that motivated it:
The attempt cap reintroduces that exact failure on a 45-minute timer. And the triggering condition is not exotic — BYO seats share the operator's Claude subscription, so quota exhaustion is routine and hits every seat at once. Tonight it hit the operator's own session in the same minutes. Any such outage reliably exceeds 45 minutes.
What I am NOT proposing
Do not simply raise the cap. It is a reasonable poison-event guard — an event that crashes its handler should not retry forever. The defect is not the cap, it is that hitting it is invisible.
Suggested direction (for whoever picks this up to challenge)
failedevents are currently invisible tolist(). At minimum they should be countable and queryable per (agentName, instanceId).failedis a seat that silently lost work. That is the same class of thing the silence alert (feat(onboarding): alert when a newcomer types and nothing answers (W4 item 2) #954) exists for.Related
spawnRetryPolicyhas an explicitQUOTAfailure class that opens the circuit at the 15-minute ceiling, butclassifySpawnFailuredid not match"You've hit your session limit"— the failures logged asruntime. Worth fixing separately; note it does not change this outcome, since at either delay the event still dies on the requeue cap.