From 203907b0ea1a120b4420c5782da0040c42ee339e Mon Sep 17 00:00:00 2001 From: claude-bot-andresmgsl Date: Mon, 27 Jul 2026 18:45:03 +0000 Subject: [PATCH 1/4] docs(builder): green check at the head gates both request points; red-head recovery in picking The round precondition (crew#45) at step 1 and the re-request in step 2, with the argued exception and its evidence requirement; the ruled classification (cancelled/stale not green, skipped/neutral green, operator 2026-07-27); ci-red pickup precedence and crew#17's recovery path in Picking, with the explicit shape-2 carve-out so a red head never reads as parked. Refs #189 Co-Authored-By: Claude Fable 5 --- BUILDER.md | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 56 insertions(+), 3 deletions(-) diff --git a/BUILDER.md b/BUILDER.md index ac9e0c3..61fcf2b 100644 --- a/BUILDER.md +++ b/BUILDER.md @@ -11,6 +11,27 @@ triage bug, and the move is to say so on the issue, not to guess. - Respect dependency order: inside an epic, take the earliest unblocked unclaimed child. Between epics and strays, prefer the issue that unblocks the most other work. +- **Your own red head outranks a new claim.** A failing check at the head + of a PR you authored is picked up **before claiming another issue** — + repairing your own red PR comes ahead of new work, which is why the + engine's duty order evaluates ci-red between resume and build (crew#17: + ceremony#163 sat with full-panel approvals at its head, mergeable, and + stranded on an HTTP 429 in a job that never ran the PR's code, because no + wake covered a red head that owed no round and had no conflict). Red and + green here are the ruled terms of the review round below: a cancelled or + stale check is not a green head; a skipped or neutral one is. The + recovery path (crew#17): inspect the check at the head and record the + failing check and its failure class; rerun a clearly retryable + infrastructure failure without changing code; when the failure belongs to + the branch, return to the normal fix-round and worklog discipline; leave + visible evidence when a rerun cannot be started or the cause is + uncertain; never repeatedly rerun a deterministic branch failure without + a corrective commit; and proceed to handoff once the check is green and + current-head approvals stand. A PR of yours with a red head is **not + parked** — the next move is yours, whatever the verdict ledger says + (shape 2 below carves this out explicitly). How the engine detects a red + head — its ledger, its quiet rules, the rollup's node shapes — is crew's + to describe, not this file's. - **One build at a time.** You hold at most one issue on which you are writing or revising a deliverable — finish or release that work before starting new work. The rule counts build work in flight, not claims: a @@ -22,7 +43,12 @@ triage bug, and the move is to say so on the issue, not to guess. belongs to someone else — either the round is awaiting its first verdicts, or it was answered whole and the non-approvers re-requested (the review round, steps 1–2). This is the *live* round; shape 4 is - the *passed* one — they are sequential and do not overlap; + the *passed* one — they are sequential and do not overlap. A red + check at the current head takes the deliverable **out of this + shape**: mid-round CI going red is exactly the state that reads as + "waiting on the panel" and is not — the next move is yours (the + red-head rule above), and reading it as parked is what strands the + PR; 3. every remaining acceptance criterion is operator-owned, stated as such by triage on the issue; 4. the deliverable is **handed off** — the round passed, no `blocker:*` @@ -53,7 +79,8 @@ triage bug, and the move is to say so on the issue, not to guess. that, or, if the events genuinely do not resolve it, say so on the issue and pick the next `ready` issue rather than idling on this one. Not parked — these are what the rule defends against: waiting on - yourself, waiting on CI, or waiting for a good moment. An issue you have + yourself, waiting on CI (a red head is your own work, above; a pending + one resolves without you), or waiting for a good moment. An issue you have simply stopped working on is not parked either — that is abandonment, and its move is unchanged: unassign and restore `ready` (Claiming, below). @@ -194,9 +221,35 @@ CONTRIBUTING; everything below is the shared flow.) does not become required. On rig#112 this distinction mattered: requesting codex and grok was correct for rig's panel even though ceremony's bench was larger, and the doctrine had not said which roster governed. + **A review request requires a green check at the head.** A red check is + the author's own signal, not the panel's work: if the check is red, that + is your next task, not the panel's — fix it and push, then request. This + binds *you*, whether or not any engine enforces it. "My local suite + passed" is evidence about your machine; the check at the head is the + shared artifact the panel actually reads, and a reviewer's first act is + to read it. The one exception is a failure genuinely outside the PR — a + runner outage, a flaky dependency, a failure already present on the + default branch — and it is an exception only if the request says so + explicitly and names the evidence (e.g. "the same job fails identically + on `origin/main` at ``"). Silence about a red check is what is + prohibited; an argued exception shifts the burden to the author. + *Green* is a ruled term (operator, 2026-07-27): a **cancelled or + stale** check is not a green head — the rollup is scoped to the current + head, so what survives there is same-head cancellation, not + supersession by a newer push — while a **skipped or neutral** one *is* + green: those are deliberate "passed / not applicable" conclusions, and + reddening them would red every conditional job the fleet skips on + purpose. The costs behind the line are asymmetric: a false green spends + a three-reviewer round; a false red spends one author session. 2. **Wait for every verdict, then answer the round whole** — one reply covering every point, then push the fixes, then re-request exactly the - reviewers who did not approve. Prefer verification over argument: when a + reviewers who did not approve — **and the re-request carries the same + green-check-at-head precondition as the first request**, argued + exception included. This is where the measured cost landed: crew#40 + burned two consecutive heads and four reviewer-rounds, every one + relaying a CI failure already visible in the job log (crew#45). A fix + push whose check comes up red is not ready to go back to the panel; it + is your next fix. Prefer verification over argument: when a reviewer doubts behavior, add the test that settles it. 3. Never dismiss a review, never merge, never mark your own work as passed. A blocking point you disagree with is answered with evidence or escalated From e85a7d42f3911188551bec4f89f6864889095ba2 Mon Sep 17 00:00:00 2001 From: claude-bot-andresmgsl Date: Mon, 27 Jul 2026 18:46:10 +0000 Subject: [PATCH 2/4] docs(fleet): ci-red in the duty order and wake list, on paper; changelog fragment FLEET.md gains the ci-red wake between resume and build in crew#64's engine position, marked on paper per this file's existing convention (the notifier queue, triage's past-24h wake); the Build bullet records the red-head exclusion as reported-not-swallowed; the reconciliation stamp stays at crew@01fb49c because crew#64 has not merged. Refs #189 Co-Authored-By: Claude Fable 5 --- FLEET.md | 30 ++++++++++++++++++++++++------ changelog.d/189.md | 12 ++++++++++++ 2 files changed, 36 insertions(+), 6 deletions(-) create mode 100644 changelog.d/189.md diff --git a/FLEET.md b/FLEET.md index ac0beba..ba6e677 100644 --- a/FLEET.md +++ b/FLEET.md @@ -132,9 +132,13 @@ wake is no longer on paper: `duty-attention.sh` is deployed engine, and The engine's duty order is fleet-standard ([`bin/duty.sh`](https://github.com/heavy-duty/crew/blob/01fb49cd717a0f4c83df286af86411c69e3c2363/shared/bin/duty.sh)): -**attention → triage signals → review queue → resume → build → handoff → -rebase → worktree hygiene → backlog hygiene (hourly)** — attention +**attention → triage signals → review queue → resume → ci-red → build → +handoff → rebase → worktree hygiene → backlog hygiene (hourly)** — attention role-independent and first, then each duty family the box's roles enable. +One position in that order is **on paper**: ci-red is +[crew#64](https://github.com/heavy-duty/crew/pull/64)'s, unmerged at the +stamped SHA, where `duty.sh` still runs resume straight into build — it +reads as deployed engine only once that PR merges. The earlier form of this file folded handoff and rebase into the other builder wakes; they are duties of their own. @@ -163,10 +167,23 @@ builder wakes; they are duties of their own. — a session died between first push and PR creation. A branch whose PR already **merged** is a post-merge wait, never resumed (#172, incubator#55/#64). +- **ci-red** (builders; **on paper** — crew#64's spec, unmerged at the + stamped SHA): a non-draft PR of mine whose check at the current head is + failing. Evaluated before the build wake, so a red PR of mine outranks a + new claim — repairing my own red head comes ahead of new work + (ceremony#163: full-panel approvals at the head, mergeable, stranded on + a transient failure no wake covered). A round owed at a red head is + excluded from the build wake below but reported rather than silent, and + an unchanged red head goes quiet after one attempt, through the + `report_suppressed` path — suppressed, still said. How a red head is + detected and kept quiet is the engine's mechanism, described in crew's + `shared/README.md`, not here. - **Build**: a `ready` **unclaimed** issue (an assignee means mid-claim, not pickable), or a completed review round on my PR — a changes-request with no panel review request still outstanding; whole rounds, never single - verdicts. + verdicts, and — once ci-red deploys — never a round at a red head: that + head has already woken ci-red above, and the excluded round is reported, + not swallowed. - **Handoff**: a round of mine that converged — every panelist's latest opinionated review approves the current head, no panel request outstanding, mergeable right now, `state:needs-human` not already set. @@ -231,9 +248,10 @@ The duty engine is crew's shared tree, one source deployed to every box; makes the registry rule an operator decision rather than a sweep's. Specs written in this file have a record of becoming engine: the attention wake and the reviewers' request sweep both started here as paper (the sweep's -org-wide form was then retired by the 2026-07-25 scope ruling). The -notifier's `needs-ruling` queue is the one still on paper: at the stamped -crew SHA, `notify.sh`'s only label filter is `state:needs-human`. +org-wide form was then retired by the 2026-07-25 scope ruling). Two are +still on paper: the notifier's `needs-ruling` queue — at the stamped crew +SHA, `notify.sh`'s only label filter is `state:needs-human` — and the +builders' ci-red wake above, engine the moment crew#64 merges. ### Conventions on the board diff --git a/changelog.d/189.md b/changelog.d/189.md new file mode 100644 index 0000000..602160f --- /dev/null +++ b/changelog.d/189.md @@ -0,0 +1,12 @@ +### Changed + +- `BUILDER.md` gates both review-request points on a green check at the + head, carries crew#45's argued exception for failures outside the PR, + and states the ruled classification: cancelled and stale are not a + green head; skipped and neutral are (#189). +- `BUILDER.md` documents CI-red recovery in pickup precedence: a red head + of your own PR is picked up before claiming another issue, is never a + parked claim, and follows crew#17's recovery path (#189). +- `FLEET.md` writes the ci-red wake into the duty order between resume + and build, marked on paper until crew#64 merges, with the + reconciliation stamp unchanged (#189). From e9cf461ed32f79dedc8daa7623537096f1b2198e Mon Sep 17 00:00:00 2001 From: claude-bot-andresmgsl Date: Mon, 27 Jul 2026 18:47:00 +0000 Subject: [PATCH 3/4] docs(builder): avoid 'ledger' for review-verdict state in the red-head rule Refs #189 Co-Authored-By: Claude Fable 5 --- BUILDER.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/BUILDER.md b/BUILDER.md index 61fcf2b..429249b 100644 --- a/BUILDER.md +++ b/BUILDER.md @@ -28,8 +28,8 @@ triage bug, and the move is to say so on the issue, not to guess. uncertain; never repeatedly rerun a deterministic branch failure without a corrective commit; and proceed to handoff once the check is green and current-head approvals stand. A PR of yours with a red head is **not - parked** — the next move is yours, whatever the verdict ledger says - (shape 2 below carves this out explicitly). How the engine detects a red + parked** — the next move is yours, whatever the round's verdict state + says (shape 2 below carves this out explicitly). How the engine detects a red head — its ledger, its quiet rules, the rollup's node shapes — is crew's to describe, not this file's. - **One build at a time.** You hold at most one issue on which you are From 44ff7524af4f2ea56b6c51402666acfa1cd238ec Mon Sep 17 00:00:00 2001 From: claude-bot-andresmgsl Date: Mon, 27 Jul 2026 19:53:59 +0000 Subject: [PATCH 4/4] =?UTF-8?q?docs(builder):=20re-request=20by=20head,=20?= =?UTF-8?q?not=20by=20verdict=20=E2=80=94=20a=20push=20stales=20every=20ap?= =?UTF-8?q?proval?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The round protocol told the author to re-request exactly the reviewers who did not approve, but the handoff predicate counts an approval only at the current head: any push while answering a round staled the earlier approver's verdict, doctrine said not to re-request them, and the PR could never converge — the silent-stall shape of #26/#39. Step 2 now re-requests by head, not by verdict: every panelist after a push, the non-approvers alone at an unchanged head. Shape 2's wording is aligned so the two paragraphs agree. Defect raised by dan-claude-bot on #190; folded in at the operator's direction while the paragraph is open. Refs #189. Co-Authored-By: Claude Fable 5 --- BUILDER.md | 23 +++++++++++++++++++---- changelog.d/189.md | 4 ++++ 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/BUILDER.md b/BUILDER.md index 429249b..50878ff 100644 --- a/BUILDER.md +++ b/BUILDER.md @@ -41,8 +41,10 @@ triage bug, and the move is to say so on the issue, not to guess. its `Blocked:` line stops the remaining work; 2. the deliverable is in a review round where every outstanding verdict belongs to someone else — either the round is awaiting its first - verdicts, or it was answered whole and the non-approvers re-requested - (the review round, steps 1–2). This is the *live* round; shape 4 is + verdicts, or it was answered whole and the owed re-requests posted — + by head, not by verdict: every panelist after a push, the + non-approvers alone at an unchanged head (the review round, steps + 1–2). This is the *live* round; shape 4 is the *passed* one — they are sequential and do not overlap. A red check at the current head takes the deliverable **out of this shape**: mid-round CI going red is exactly the state that reads as @@ -242,8 +244,21 @@ CONTRIBUTING; everything below is the shared flow.) purpose. The costs behind the line are asymmetric: a false green spends a three-reviewer round; a false red spends one author session. 2. **Wait for every verdict, then answer the round whole** — one reply - covering every point, then push the fixes, then re-request exactly the - reviewers who did not approve — **and the re-request carries the same + covering every point, then push the fixes, then re-request **by head, + not by verdict**: if answering the round pushed any commit, every + panelist's approval is now stale — an approval is of a specific tree, + and the handoff predicate counts only approvals at the current head — + so **every panelist is re-requested, the approvers included**; a + panelist left un-re-requested after a push can never approve the tree + you shipped, and the PR sits looking finished with a full set of + verdicts and nothing owed by anyone, the same silent-stall shape as + [#26](https://github.com/heavy-duty/ceremony/issues/26)/[#39](https://github.com/heavy-duty/ceremony/issues/39). + Only when the head did not move — the round was answered with argument + or evidence and nothing was pushed — do you re-request just the + non-approvers: a standing approval already covers this exact head, and + the engine absorbs a re-request at an unchanged head (the re-request + rule, [#94](https://github.com/heavy-duty/ceremony/issues/94); its + mechanism is crew's to describe). **The re-request carries the same green-check-at-head precondition as the first request**, argued exception included. This is where the measured cost landed: crew#40 burned two consecutive heads and four reviewer-rounds, every one diff --git a/changelog.d/189.md b/changelog.d/189.md index 602160f..d29e76f 100644 --- a/changelog.d/189.md +++ b/changelog.d/189.md @@ -10,3 +10,7 @@ - `FLEET.md` writes the ci-red wake into the duty order between resume and build, marked on paper until crew#64 merges, with the reconciliation stamp unchanged (#189). +- `BUILDER.md` re-requests by head, not by verdict: a push while + answering a round stales every approval, so every panelist is + re-requested; only an unchanged head re-requests the non-approvers + alone (#190).