Skip to content

fix(scheduler): keep idle fill off a run that is on the retry ramp (AGT-4675) - #815

Merged
unohee merged 1 commit into
mainfrom
fix/agt-4675-idle-fill-ramp
Oct 3, 2026
Merged

unohee merged 1 commit into
mainfrom
fix/agt-4675-idle-fill-ramp

Conversation

@unohee

@unohee unohee commented Oct 3, 2026

Copy link
Copy Markdown
Collaborator

TL;DR

The retry backoff from AGT-4673 is bypassed by idle fill. filterAlreadyProcessed gives each heartbeat an idleFillBudget equal to the free slots and spends it, in priority order, on RETRY_AT rows whose backoff has not elapsed (markReady). A freed slot goes to the highest-priority failing run, ahead of the READY tasks that are waiting.

Evidence (ledger events, 2026-10-03)

  • AX-1844, attempt 8, failed: 20:33:01 PUBLISHING > RETRY_AT (backoff applied), 20:33:08 missing_worktree_reconciled clear, 20:33:19 RETRY_AT > READY, 20:33:19 claimed; attempt 9 was running 7 minutes later.
  • The same ramp held where idle fill did not run: AX-1633 attempt 9 stayed at RETRY_AT with 336 minutes left.
  • Queue at the time: READY 36, RETRY_AT 53, so the slot was not going to waste.
  • Idle fill's own comments record the same loop twice (attempt 20 in AGT-4155, attempt 415 in AGT-4036, the latter fixed only for superseded).

Change

  • durableRunCoordinator.ts: RETRY_RAMP_FROM_ATTEMPT = 4, used by retryAtFor (same delays as before).
  • autonomousRunner.ts: idleLiftable also requires durableRun.attemptNo < RETRY_RAMP_FROM_ATTEMPT, so a run that has reached the ramp is left to its retry_at. Operator answers and reopens still readmit it through their own paths.

Tests

  • A run at attempt 4 with a future retry_at stays RETRY_AT when a slot is free; a run at attempt 3 is still lifted to READY (control). Removing the guard fails the first.
  • vitest runner, coordinator and ledger suites: 20 files, 310 tests pass.

Risk

When nothing else is runnable, a slot stays empty instead of re-running a run that has failed three times. READY work is not scarce today.

After deploy

No RETRY_AT > READY for a run at attempt 4 or more before its retry_at; distinct issues per hour and the top-10 share move as described in AGT-4673.

…GT-4675)

The ramp from AGT-4673 backs a failing run off, but idle fill spends one budget
per free slot, in priority order, on RETRY_AT rows whose backoff has not elapsed,
so the highest-priority failing run was lifted ahead of 36 READY tasks as soon as
a slot freed: AX-1844 failed attempt 8, was backed off at 20:33:01 and was READY
and claimed by 20:33:19.
Leave a RETRY_AT run alone once its attempt number reaches the ramp, and share
the threshold with retryAtFor through RETRY_RAMP_FROM_ATTEMPT.
@unohee
unohee merged commit 3eed7ae into main Oct 3, 2026
7 checks passed
@unohee
unohee deleted the fix/agt-4675-idle-fill-ramp branch October 3, 2026 11:58
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