What happened
PR #2164 (fix for #2152: the coding child's push guard must certify the pushed changed set) took eight review verdicts across two ship attempts, and the second attempt ended at the round cap with the PR still not merge-ready. From 22:20Z on, four consecutive Changes requested verdicts each named a new case of the same invariant, at the same site (src/core/harness/pi/toolRules.ts):
| Verdict (UTC) |
Head |
Finding |
Line |
| 21:22 |
ce8a962 |
a receipt stays valid across an untracked HEAD change or a later failed formatter |
279, 302 |
| 22:20 |
57812d3 |
a compound push can mutate the tree after it is checked; dirty receipts do not identify the checked contents |
329, 290 |
| 22:31 |
785cccc |
an explicit refspec can push a tree other than the one that earned the receipt |
392 |
| 22:45 |
7d9719f |
only the first refspec is checked; a multi-refspec push publishes unchecked trees |
407 |
| 22:55 |
ff0b416 |
configured remote.<name>.push refspecs let an omitted-refspec push publish unchecked trees |
420 |
The ship parent (run 9c396421, thread key slack:C0BRRHKFLCB:1790021390.458049) ended with round cap reached at 22:55Z. Each round cost a fix child plus a review (about 10–15 minutes and roughly $1), and the attempt had to be recovered by hand with a directive coding run and a re-issue.
Every one of those findings is a case of one invariant: a push publishes only trees that earned the receipt, for every way the pushed tree can be selected (the checkout at the time of the check, each explicit refspec's source, each configured refspec's source, and the omitted-refspec default). The first Changes requested at that site could have named the invariant and its cases; instead each round widened the previous finding by one case, and the cap counted each widening as a full round.
Why it matters
- The round cap exists to stop a unit that is not converging. A unit that fixes exactly what it was told and is then told one more case each round is converging on the reviewer's schedule, and the cap ends it anyway.
- The cost is paid per round: a fix child, a review, a CI run and a wind-down slot each time.
- The recovery is manual (a directive fix and a re-issue), which is the path 0073 retires.
Product shape (either, or both)
- A finding names its invariant and all the cases the reviewer can see. When a review requests changes at a site, its finding states the invariant the code must hold and enumerates the cases it checked, not the first failing case only. The review agent's spec (
agent-review.md) gets the row; the verdict block carries the invariant so a later round can be checked against it.
- A round that only widens a prior finding does not count toward the cap. A
Changes requested whose every finding is at the same site as a prior round's finding and names the same invariant is a continuation: the fix round runs, the cap is not decremented, and the card says so ("widened F3; round cap unchanged").
The first shape prevents the pattern; the second stops it from ending a unit. Spec home: docs/reference/specs/agent-review.md (finding completeness) and agent-ship.md (what the cap counts).
Receipt runnable when
worker:bot ≥ <merge sha> and event: a PR whose second Changes requested verdict names the same file and invariant as the first; the card shows the round as a continuation, or the first verdict already listed the later case.
What happened
PR #2164 (fix for #2152: the coding child's push guard must certify the pushed changed set) took eight review verdicts across two ship attempts, and the second attempt ended at the round cap with the PR still not merge-ready. From 22:20Z on, four consecutive
Changes requestedverdicts each named a new case of the same invariant, at the same site (src/core/harness/pi/toolRules.ts):remote.<name>.pushrefspecs let an omitted-refspec push publish unchecked treesThe ship parent (run
9c396421, thread keyslack:C0BRRHKFLCB:1790021390.458049) ended withround cap reachedat 22:55Z. Each round cost a fix child plus a review (about 10–15 minutes and roughly $1), and the attempt had to be recovered by hand with a directive coding run and a re-issue.Every one of those findings is a case of one invariant: a push publishes only trees that earned the receipt, for every way the pushed tree can be selected (the checkout at the time of the check, each explicit refspec's source, each configured refspec's source, and the omitted-refspec default). The first
Changes requestedat that site could have named the invariant and its cases; instead each round widened the previous finding by one case, and the cap counted each widening as a full round.Why it matters
Product shape (either, or both)
agent-review.md) gets the row; the verdict block carries the invariant so a later round can be checked against it.Changes requestedwhose every finding is at the same site as a prior round's finding and names the same invariant is a continuation: the fix round runs, the cap is not decremented, and the card says so ("widened F3; round cap unchanged").The first shape prevents the pattern; the second stops it from ending a unit. Spec home:
docs/reference/specs/agent-review.md(finding completeness) andagent-ship.md(what the cap counts).Receipt runnable when
worker:bot ≥ <merge sha>and event: a PR whose secondChanges requestedverdict names the same file and invariant as the first; the card shows the round as a continuation, or the first verdict already listed the later case.