Skip to main content

settle

Function settle 

Source
pub fn settle(
    task: &mut Task,
    verdict: Verdict,
    detail: &str,
    max_attempts: usize,
)
Expand description

Record a finished run against the task it came from.

Kept pure and separate from the loop because this mapping is the retry policy, and a policy that can only be exercised by spawning a graph is a policy nobody checks. The table:

run statustask becomesattempt spent
parked at a boundaryFailed (requeued)no
Merged, ReadyDoneyes
Stalled, quota hitFailed (requeued)no
Failed, quota hit, no viable cand.Failed (requeued)no
Stalled, no quotaFailed, or Heldyes
Blocked with a PRHeldyes
Blocked, Failed otherwiseFailed, or Heldyes
VerifiedNoopHeldyes
anything non-terminalFailed, or Heldyes

The VerifiedNoop row is independent of the Failed-quota row above it, deliberately: every candidate agreeing there is nothing to write is not a machine fact about a rate limit, it is an unverified claim about the task that a human still has to check — see RunStatus::VerifiedNoop’s own doc and Task::handed_off. Held rather than Done on purpose: the claim could be wrong (a misread instruction, a stale check), and closing the task automatically on an implementer’s say-so would be the exact failure mode task 391f’s own audit was raised to avoid. attempt spent is yes here for the same reason it is on the Blocked-with-a-PR row just above, which settles through the same Task::handed_off: Held is not Failed-and-requeued, so nothing retries this task on the same unverified claim regardless of whether the one already-spent attempt is refunded, and Task::release resets the count to zero anyway the moment a human looks at the evidence and lets it run again.

The Stalled-quota and Failed-quota rows are the ones worth reading twice, together. A quorum lost to rate limits is a property of the machine and not of the task, so the attempt is refunded and a reset quota picks the work up where it stopped — and that is just as true when every implement seat lost the same race and after_implement bails with nothing to judge, which surfaces as Failed rather than Stalled but is the same machine fact. The no_viable_candidates guard is what keeps that row narrow: a Failed run that produced a real candidate which then lost for some other reason still spends the attempt, exactly like the quorum lost to judges that answered with the wrong shape is ordinary flakiness, and refunding that takes the bound off the retry loop entirely: run e633 stalled with quota: [] after two judges wrote unusable JSON, was refunded, and the next attempt paid for a fresh hour-long implement wave before it could fail the same way. max_attempts exists precisely so that cannot repeat forever.

A non-terminal status means execute returned while the graph was still mid-flight, which is a bug rather than a verdict; it is treated as a failure so that a task cannot loop on it either.

left_pr splits the Blocked row, and it is the difference between a run that failed and a run that finished into a gate. See Task::handed_off.