Skip to content

fix(scheduler): idle fill leaves a supersession backoff alone — the owning PR does not close because a slot is free (AGT-4036) - #653

Merged
unohee merged 1 commit into
mainfrom
fix/agt-4036-idle-fill-supersession
Sep 17, 2026
Merged

unohee merged 1 commit into
mainfrom
fix/agt-4036-idle-fill-supersession

Conversation

@unohee

@unohee unohee commented Sep 17, 2026

Copy link
Copy Markdown
Collaborator

Why

AGT-4036 asked for a deferred claim to stop wearing superseded; that landed in #493 (deferred status). Its DoD — grep 'Task superseded' returns only genuine supersessions — is still violated, from a different direction: the current daemon log has 256 Task superseded lines, 84 of them AX-1481, and the ledger shows AX-1481 at attempt #415, ~25 s apart:

22:36:54 claimed READY→CLAIMED  (attempt 413)
22:36:56 EXECUTING→RETRY_AT {"finalStatus":"superseded"}   ← draft grooming: an open PR owns the planned files
22:37:15 RETRY_AT→READY                                      ← idle fill lifts the backoff
22:37:18 claimed READY→CLAIMED  (attempt 414)

The supersession is genuine and the exponential backoff (retryAtFor, 5 min × 2ⁿ up to 6 h) is set correctly — then filterAlreadyProcessed's durable idle-fill branch (idleLiftable) lifts any future RETRY_AT while a slot is free. A free slot does not close the PR that owns the files, so each lift re-runs the drafter against the same PR: 8 draft + 17 decompose calls, $0.37, for one task that could not start.

What

idleLiftable excludes lastErrorCode === 'superseded' — the same shape as the AGT-4305 infra_error gate, one condition. Everything else (ordinary rejection backoffs, NEEDS_SPEC/NEEDS_ENV, elapsed RETRY_AT) is lifted as before.

Verified

  • autonomousRunner.infraError.test.ts: new case seeds a durable RETRY_AT with errorCode: 'superseded' → not lifted, stays RETRY_AT; control case with errorCode: 'rejected' → lifted to READY. Mutant (drop the condition) fails the first. 15 passed (one 30 s hook timeout in an unrelated case at load 90, green on rerun).
  • tsc + oxlint clean.

After deploy

grep -c 'Task superseded' stdout.log per hour should fall from ~40 to the number of genuinely blocked issues × their backoff rechecks.

…wning PR does not close because a slot is free (AGT-4036)

A run refused because an open PR still owns its planned files is parked
in RETRY_AT with an exponential backoff (retryAtFor). Idle fill lifted
that row every heartbeat, so the drafter re-ran against the same PR
25 s apart: AX-1481 reached attempt #415 on 2026-09-17, 256 'Task
superseded' lines in one log file, $0.37 of draft/decompose calls for
a task that could not start. The backoff is the recheck cadence.
@unohee
unohee merged commit 2826b56 into main Sep 17, 2026
13 of 14 checks passed
@unohee
unohee deleted the fix/agt-4036-idle-fill-supersession branch September 17, 2026 23:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant