Lane quota detection uses a total-turn timeout, so it kills healthy long turns #525
No reviewers
Labels
No labels
Compat/Breaking
Kind/Bug
Kind/Documentation
Kind/Enhancement
Kind/Feature
Kind/Security
Kind/Testing
Priority
Critical
Priority
High
Priority
Low
Priority
Medium
Reviewed
Confirmed
Reviewed
Duplicate
Reviewed
Invalid
Reviewed
Won't Fix
Status
Abandoned
Status
Blocked
Status
Need More Info
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
toasterson/Anima!525
Loading…
Reference in a new issue
No description provided.
Delete branch "claude/wi-019fdd2a-lane-quota-detection-uses-a-total-turn-t"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Anima work item
019fdd2a-7101-7380-a71c-348e260884a1.Symptom
ANIMA_RUNNER_MAX_SESSION_SECSis a cap on the whole turn. On the opencode lane it was set to 300s as a quota probe, and it silently amputated every healthy implementation turn at exactly five minutes. The turn is then reported ascancelledwith "the agent produced no durable output", which the server charges to the work item as a turn failure — so productive work reads as failure and the item eventually parks.Evidence
Sessions on the opencode lane, from
activity_events:019fdb77: 42acp.tool_call, 99acp.tool_call_update, 12acp.agent_message, spanning 09:04:50 → 09:09:47. Killed at 300s mid-work.019fd8ea: 41 tool calls over 21:11:48 → 21:16:11. Same.019fdb8a: 38 tool calls over 09:25:26 → 09:30:09. Same.Thirteen work items were parked by this: WI-371, 378, 382, 385, 389, 392, 396, 403, 406, 407, 408, 409, 419. Several had been re-dispatched repeatedly, each attempt dying at the same five-minute wall.
Why the original setting was wrong
The rationale in
docker-compose.runner.yml(2026-08-03) is sound about the failure it targets: opencode's AI-SDK client swallows a 429 and retries with a growing backoff without surfacing it to ACP, sorun_turnnever seesErrand just waits outmax_secs. The mistake is the instrument. The comment justifies 300s against first-token latency ("well above the longest healthy first-turn latency (~5s)") but the value is applied to the entire turn, and a real implementation turn legitimately runs far longer than five minutes.The distinguishing signal
A quota-stuck turn and a healthy long turn are trivially separable, just not by total duration:
acp.tool_call/tool_call_update, 40+ within five minutes.Expected
Replace the total-turn cap with an idle timeout: if no ACP event of any kind arrives for N seconds (30-60s is far below the ~33s smallest escaping backoff tier and far above any healthy inter-event gap), fail the turn as
provider lane blockedand mark the laneNoQuotaexactly as today. Keep a total-turn cap only as a very high backstop.Both timeouts should be configurable, and the failure text must name which one fired — "no ACP event for 60s (provider lane blocked)" and "turn exceeded the 3600s backstop" are different diagnoses and must not share a message.
Interim state (already applied by the operator, 2026-08-07)
ANIMA_RUNNER_MAX_SESSION_SECSon the opencode lane raised 300 → 1800 in/home/toasty/ws/anima/docker-compose.runner.yml, runner recreated. This unblocks real work at the cost of a quota-stuck turn burning 30 minutes instead of 5. Revert to a smaller backstop once the idle timeout exists.Acceptance criteria
NoQuotalane-health path.bcc8b2d94ftoafb65b23ceafb65b23cetoc225d37004c225d37004toc718cbb849WIP: Lane quota detection uses a total-turn timeout, so it kills healthy long turns: 13 work items parked as "produced no durable output" while their transcripts show 40+ tool callsto Lane quota detection uses a total-turn timeout, so it kills healthy long turnsc718cbb849tod73b284874ac53711ed29ddfb9b9e7