Development record
the-budget-check-and-the-rate-limit-checkpoint
Summary
The rest of itd-2609201925079472 after spc-2609202134341288 closed: pieces 4 and 5 of that spec, which wait on a runner that reports its quota and its rate-limit responses (itd-2609201916056194).
- The budget check (criterion 7, from
itd-29): where the runner reports remaining quota, an estimate from the spec's size is compared before the run starts, and a run it exceeds is refused naming both numbers with no state written; a runner that reports none is named and the check is skipped out loud. - The rate-limit checkpoint (criterion 8, from
itd-29): a runner's rate-limit response ends the window early for the whole run, since every lane spends the same budget; every lane with work in flight is checkpointed to its own branch,next_eligible_atis written once, and the record names the lane the response came from (spc-2609202134341288, "The pace and the fix rounds, per lane").
The pace, the window clock and the ceiling with its parallel lanes (criteria 1 to 6 and 9) are built; spc-2609202134341288's design sections remain the record for them, as amended below.
Amendments to spc-2609202134341288
The closed spec is not reopened; these rulings amend its design and its criterion C4 from 2026-10-02, and the loop is built to them.
- A step's worktree is made only when a helper is free (ruling DR6d-1).
The product thinker, verbatim: "preparing parallel steps' worktrees: ONLY
WHEN A HELPER IS FREE — a step's worktree is made just before an agent takes
it; at most the agent ceiling's worth on disk." It reverses the eager opening
"The count" and C4 carried ("A stage the binary performs itself proceeds at
the ceiling", read as a ready step's worktree and brief made whatever the
ceiling). A lane opens for a ready spec step only while a slot is left for
its implementer beside every lane opened whose implementer is not out yet,
and fewer step worktrees than the ceiling are on disk (a lane holds one from
its worktree stage until it lands or is discarded); the opening call makes
its worktree, and its brief and implementer follow. A step waiting for a
helper has no worktree and waits under
waitingasstep <n>. C4 reads: a step made ready at the ceiling waits for a helper with no worktree, and its lane opens at the next free slot (as C6 already says of- needs: none). The stages the binary performs on a lane already open (its brief, a round's close, a landing step, a sync, a hold) still take no slot and are never held by the ceiling. - A missing preflight receipt holds only its lane (ruling DR6d-2). The
product thinker, verbatim: "missing preflight receipt for one lane: CARRY
ON, WAIT SHOWN — other lanes continue; the lane waits for its receipt like
the merge wait (contend, not refuse), and the status shows 'waiting for its
full check (since HH:MM)'." The landing's push without a receipt naming the
lane's head is a contention, as the forge's merge is: the call moves another
lane and names the wait under
blocked, and gives the wait (exit 3) only when nothing else moves. The time the wait began is written once, on the lane's landing ascheck_wait_since(a version-9 field), with a record entry, kept across calls and cleared by the push; the status shows it in UTC. The remedy still names how the receipt is minted. Landing stays one lane at a time: a landing waiting for its full check is a landing under way, so a sibling's landing waits behind it as it waits behind a merge. Who starts the check (ruling DR6d-2b) is a separate intent and is not built here.
Footprint
- packages: internal/core/implement/loop, the runner adapter itd-2609201916056194 delivers
- tests: a fake runner reporting quota over and under the estimate, one reporting none, and a rate-limit response mid-lane with two lanes in flight
Steps
No steps listed: the spec is built as one step. To split it, list the steps in order as 1. <title>, each with - packages: and - tests: indented beneath it; - landed: <pull request or commit> marks a step that has landed.
Frontmatter
| id | spc-2609301921521360 |
|---|---|
| type | spec |
| lifecycle | closed |
.abcd/development/specs/closed/spc-2609301921521360-the-budget-check-and-the-rate-limit.md
open on GitHub ↗ · commit history ↗
References1
- itd-2609201925079472An autonomous run paces itself by default, and one flag sets the paceimplements
mentions4
- dcn-26101000000000022026-10-10 — Four points spc-2609301921521360 left open, settled by lane-1 of run-2610100550297632 in building it (itd-2609201925079472 criteria 7 and 8). (1) A runner's quota is counted in agent runs (`runner.Quota.Remaining`, reported through the optional `runner.QuotaReporter`), and the estimate from the spec's size is the least the run starts: per step to build, one implementer and one round of the two reviewers, and the fidelity audit once for an intent; fix rounds and syncs are not foreseen. Neither shipped runner reports a quota (the claude CLI and opencode expose none a launch can read before it starts), so today every run names its runners and skips the check out loud; the comparison is reached by a runner that reports one. (2) The rate-limit response is read from the claude CLI's own events, a `rate_limit_event` whose `rate_limit_info.status` is `rejected` or an assistant message whose `error` is `rate_limit`, on a run that did not finish; opencode's error events carry no rate-limit shape this build has verified, so an opencode limit stays a refusal and falls back as before. A rate limit is never fallen back on: every route spends the budget the window paces. (3) "Checkpointed to its branch" reads as the restart of 2026-10-09 reads a gone agent (iss-2610080620372731): the limited agent's uncommitted work and partial receipt are saved aside for review, never built on, its worktree reset to the branch's last commit, and its await dropped so the first step after the pause hands the same work to a fresh agent; a limited validator has only its partial return saved aside, since it edits nothing and may share the worktree with its round. Every other lane with work in flight is checkpointed at its branch's head in the record and left running, its agents' receipts still taken inside the pause, because their agents are not this process's to stop. (4) The pause after a rate limit is the run's own pause minutes, not the reset time a harness reports (decision 2 of the intent), and a pause already running is kept.
- itd-29Domain Experts Run A Spec Autonomously And Recover From Anything Without Touching Git
- itd-2609201916056194A role runs through the command-line harness the operator chose, and every fall back to the host is recorded
- spc-2609202134341288an-autonomous-implementation-run-paces-itself-by-default-and