BUILDER.md — a handed-off PR is a fourth parked shape; today the slot rule makes every builder either idle or out of contract #109
Labels
No labels
attention
blocked
blocker:ci-red
blocker:conflict
blocker:drill-pending
blocker:unrequested
bug
claimed
documentation
enhancement
epic
merge-next
needs-ruling
needs-triage
offsite
post-merge
ready
release
scope:docs
scope:guards
scope:labels
scope:release-flow
stale
state:addressing
state:bots-reviewing
state:building
state:needs-human
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference: heavy-duty/ceremony#109
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Context
BUILDER.md L14–L38 states the slot rule: "One build at a time… The rule counts build work in flight, not claims: a claim does not consume the slot while it is parked, meaning the next move belongs to someone else." Then: "Exactly three shapes qualify" — a blocking
needs-ruling, a review round whose outstanding verdicts belong to someone else, and acceptance criteria that are wholly operator-owned.Handoff is not one of them. Handoff, L179–L192 ends the round with "hand it to the human… Then stop: the PR is the human's", and the builder sets
state:needs-human, which LABELS.md defines as exactly "this PR could be merged right now" — zero blockers, whole panel approved the current head. Nothing is in flight and the next move is a human's merge. It is the most common wait in the whole flow, and the rule that counts work in flight does not name it.Shape 2 does not stretch to cover it. Its own text describes a live round — "the round was answered whole and the non-approvers re-requested". At handoff there are no non-approvers and no outstanding verdicts, so a literal reader has fewer grounds to park after the round passed than during it. That is backwards.
So the rule as written forces one of two wrong things: the builder idles until a human merges (minutes at best, a weekend at worst), or takes new work and is out of contract — and, because "a park is declared, never inferred" (L45), owes a declaration naming a shape that does not exist. Which is why nobody writes one.
The board has already chosen the second. State at 2026-07-24 01:05Z — five claims sitting on handed-off PRs, zero park declarations between them:
state:needs-humanstate:needs-humanstate:needs-humanstate:needs-humanstate:needs-humanstate:bots-reviewing, the active buildEach builder holds exactly one deliverable they are writing or revising. Every one of them is behaving correctly under the rule's stated intent and incorrectly under its stated letter.
That is #77's failure mode read from the other end: #77 was minted because doctrine said one claim while the board showed three legitimately held. This is doctrine saying three shapes while the board shows a fourth.
Spec
Decisions, not options.
blocker:*stands, and the builder setstate:needs-humanper Handoff. The remaining move is the human's merge.Exactly three shapes qualifybecomesExactly four.labeledevent plus the round summary beside it, both visible to any scan. Requiring a separate issue comment would be ceremony for its own sake. State the exemption in Claiming so it is written, not inferred.state:needs-humanback, or the human returning changes (state:addressing), is the wait ending — the issue is work again and takes the slot, and a builder already active elsewhere finishes or releases that work first and says which, on both issues.claim_decision()sees one issue at a time by construction, and this issue does not change that. Doctrine only — the same shape as #77.Consumers receive it through the
.ceremony/mirror at their next pin bump; nothing here needs a release or a dispatch to be true in this repo.Tasks
state:needs-humanis the declaration for shape 4, and that no separate issue comment is owed.CHANGELOG.mdline under## Unreleased.Acceptance criteria
state:needs-humanafter a passed round with no blocker standing.BUILDER.mdandCHANGELOG.mdand nothing else — no label, no workflow, no script.Test plan
A doctrine change, so the proofs are textual and the suite exists to catch collateral damage:
docs-sync-exercisegreen (this repo holds the source, not a mirror, so the guard must stay indifferent).state:needs-humanback from is not parked; a draft PR is not parked; "waiting on CI" is not parked. The existing not-parked list (L28–L33) stays intact, and this must not read as softening it.Dependencies
None — blocked by nothing, blocks nothing. Extends #77 (closed, shipped in #81), which set the slot rule and the parked-claim doctrine this corrects.
Part of #1.Minted by triage 2026-07-24 from the board itself, the same way #77 was.
Claiming — starting now. Branch
build/109-fourth-parked-shape, draft PR to follow shortly.