docs(builder): WIP — tighter register across every section

This commit is contained in:
cndgrr 2026-08-04 13:14:35 +00:00
parent 6ebdd2efd9
commit e3ec95bb37

View file

@ -12,58 +12,53 @@ triage bug, and the move is to say so on the issue, not to guess.
prefer the issue that unblocks the most other work. Where a repository prefer the issue that unblocks the most other work. Where a repository
adopts version epics, [RELEASES.md](RELEASES.md) governs the choice among adopts version epics, [RELEASES.md](RELEASES.md) governs the choice among
release-window members. release-window members.
- **Your own red head outranks a new claim.** A failing check at the head of - **Your own red head outranks a new claim.** Pick up a failing check at the
a PR you authored is picked up before claiming another issue; a red head head of a PR you authored before claiming another issue: a red head that
that owes no round and holds no conflict is otherwise nobody's next move, owes no round and holds no conflict is otherwise nobody's next move, and
and the PR strands mergeable (#163). The recovery path: record the failing the PR strands mergeable (#163). Record the failing check and its failure
check and its failure class; rerun a clearly retryable infrastructure class; rerun a clearly retryable infrastructure failure without changing
failure without changing code; when the failure belongs to the branch, code; return to the normal fix-round and worklog discipline when the
return to the normal fix-round and worklog discipline; leave visible failure belongs to the branch; leave visible evidence when a rerun cannot
evidence when a rerun cannot be started or the cause is uncertain; never be started or the cause is uncertain; never repeatedly rerun a
repeatedly rerun a deterministic branch failure without a corrective deterministic branch failure without a corrective commit; hand off once
commit; and hand off once the check is green and current-head approvals the check is green and current-head approvals stand. Such a PR is **not
stand. Such a PR is **not parked** — the next move is yours whatever the parked**, whatever the round's verdict state says. Red and green are the
round's verdict state says. Red and green are the review round's ruled review round's ruled terms below; how the engine detects a red head is
terms below; how the engine detects a red head is crew's to describe, not crew's to describe, not this file's.
this file's. - **One build at a time**: at most one issue on which you are writing or
- **One build at a time.** You hold at most one issue on which you are revising a deliverable, finished or released before you start new work.
writing or revising a deliverable — finish or release that work before The rule counts build work in flight, not claims — a **parked** claim,
starting new work. The rule counts build work in flight, not claims: a whose next move belongs to someone else, does not consume the slot.
**parked** claim, one whose next move belongs to someone else, does not Exactly five shapes park:
consume the slot. Exactly five shapes park: 1. `needs-ruling` is set, the escalation names a decider, and its
1. the issue carries `needs-ruling`, its escalation names a decider, and `Blocked:` line stops the remaining work;
its `Blocked:` line stops the remaining work; 2. a **live** review round holds the deliverable, every outstanding
2. the deliverable is in a **live** review round, every outstanding
verdict someone else's — awaiting its first verdicts, or answered whole verdict someone else's — awaiting its first verdicts, or answered whole
with the owed re-requests posted, by head and not by verdict (steps 12 with the owed re-requests posted, by head and not by verdict (steps 12
below). A red check at the current head takes it **out of this shape**: below). A red check at the current head takes it out of this shape: the
that state reads as waiting on the panel and is not, the next move is next move is yours, and reading that as parked strands the PR;
yours, and reading it as parked strands the PR;
3. every remaining acceptance criterion is operator-owned, stated as such 3. every remaining acceptance criterion is operator-owned, stated as such
by triage on the issue; by triage on the issue;
4. the deliverable is **handed off** — the round passed, no `blocker:*` 4. the deliverable is **handed off** — the round passed, no `blocker:*`
stands, `state:needs-human` is set per Handoff (below), and the merge stands, `state:needs-human` is set per Handoff, and the merge is the
is the human's. Shapes 2 and 4 are sequential and never overlap; human's. Shapes 2 and 4 are sequential and never overlap;
5. the claim is **held by directive** — triage or the operator stopped the 5. the claim is **held by directive** — triage or the operator stopped the
work, the direction names what the hold waits on, and only they end it; work, the direction names what the hold waits on, and only they end it.
this is never "waiting for a good moment". A hold ends the way it A hold ends the way it started, **on the labels**: where labels and
started, **on the labels**: where the queue labels and any prose prose disagree the most recent queue-label event by the hold's owner
disagree about whether it stands, the most recent queue-label event by governs, an operator being free to lift by label alone (#149, #151). So
the hold's owner governs and the prose is stale until corrected, an read the issue's label events
operator being free to lift by label alone (#149, #151). So before
standing down *or* standing up, read the issue's **label events**
(`gh api /repos/{owner}/{repo}/issues/{n}/timeline`), not only its (`gh api /repos/{owner}/{repo}/issues/{n}/timeline`), not only its
comments; acting on the labels against stale prose, say so in the claim comments, before standing down *or* standing up; where you act on the
— name the events, their timestamps and their actor, and invite the labels against stale prose, say so in the claim — name the events, their
correction. Refusing to claim through the contradiction is not a timestamps and their actor, and invite the correction. Refusing to claim
resting place either: where the events genuinely do not resolve it, say through the contradiction is no resting place either: where the events
so on the issue and pick the next `ready` issue. do not resolve it, say so on the issue and pick the next `ready` issue.
Not parked: waiting on yourself, waiting on CI (a red head is your own Not parked: waiting on yourself, on CI (a red head is your own work; a
work; a pending one resolves without you), or waiting for a good moment. pending one resolves without you), or for a good moment. An issue you have
An issue you have simply stopped working on is abandoned, not parked — simply stopped working on is abandoned, not parked — unassign and restore
unassign and restore `ready` (Claiming, below). The rule counts work and `ready`. The rule counts work and not claims because parked claims are
not claims because parked claims are legitimately held beside the one legitimately held beside the one active build (#15, #16, #73).
active build (#15, #16, #73).
## Claiming ## Claiming
@ -72,38 +67,34 @@ triage bug, and the move is to say so on the issue, not to guess.
activity is what the staleness sweep reclaims, unless `offsite` records activity is what the staleness sweep reclaims, unless `offsite` records
that its PR lives in another repository. that its PR lives in another repository.
- **A park is declared, never inferred.** Comment on the issue naming what - **A park is declared, never inferred.** Comment on the issue naming what
the claim waits on and who owns the next move; no new label, because the the claim waits on and who owns the next move; no new label, the comment
comment is the activity that feeds the same reclaim clock the being the activity that feeds the same reclaim clock the `needs-ruling`
`needs-ruling` (#52) and `offsite` (#68) exemptions already guard. Shape 4 (#52) and `offsite` (#68) exemptions guard. Shape 4 owes no separate
alone owes no separate comment — the factual handoff comment plus the comment: the handoff comment plus the `state:needs-human` write already
`state:needs-human` write already name the wait (the merge) and its owner name the wait (the merge) and its owner (the human).
(the human), both visible to any scan.
- **A declaration stands until the park's facts change.** A resumption that - **A declaration stands until the park's facts change.** A resumption that
finds nothing changed posts nothing, because re-declaring on every resume finds nothing changed posts nothing, because re-declaring on every resume
floods the record with audits each saying nothing changed (#177); silence floods the record with audits each saying nothing changed (#177). One new
while parked is compliant, not abandonment-shaped. One new comment is owed comment is owed each time the facts change — the named wait resolves or
each time the facts change — the named wait resolves or changes hands, the changes hands, the parked shape changes, or the claim unparks. A parked
parked shape changes, or the claim unparks. The one place silence costs: a claim with **no open PR** still feeds the 48-hour reclaim clock, so
parked claim with **no open PR** still feeds the 48-hour reclaim clock, so
refresh the declaration before that window closes; that refresh is the refresh the declaration before that window closes; that refresh is the
only repeat a park ever owes, at the reclaim window's cadence and not any only repeat a park owes, at the reclaim window's cadence.
duty loop's.
- **Pick up `attention` before anything else.** Post a short pickup comment - **Pick up `attention` before anything else.** Post a short pickup comment
and remove `attention`; the removal is the ack. A demand on a parked claim and remove `attention`; the removal is the ack. A demand on a parked claim
is usually its unpark, so take the slot back rather than leaving the is usually its unpark, so take the slot back — unless the demand *is* the
demand parked — unless the demand *is* the park, where the pickup comment park, where the pickup comment doubles as the declaration and the slot
doubles as the declaration and the slot stays free. stays free.
- **A directed hold keeps its bookkeeping visible.** The PR carries - **A directed hold keeps its bookkeeping visible.** The PR carries
`blocked` with a comment naming what it waits on; the issue stays `blocked` with a comment naming what it waits on; the issue stays
`claimed` and carries `attention` until the builder acknowledges it. `claimed` and carries `attention` until the builder acknowledges it.
Nobody unassigns the issue, and the 48-hour reclaim does not fire because Nobody unassigns the issue, and the 48-hour reclaim does not fire because
the claim has an open PR. the claim has an open PR.
- **Unparking is a claim like any other.** The parked issue is work again - **Unparking is a claim like any other** and takes the slot: if you are
and takes the slot; if you are already active elsewhere, finish or release active elsewhere, finish or release that work first and say which you did
that work first and say which you did on both issues. Nothing counts on both issues. Nothing counts claims per builder and no reconciler path
claims per builder and no reconciler path enforces any of this — the enforces this — the discipline is the declaration, not a counter, and no
discipline is the declaration, not a counter, and no such machinery should such machinery should be built expecting it to have been specified here.
be built expecting it to have been specified here.
- **Abandoning is fine; ghosting is not.** Say where you got to, push the - **Abandoning is fine; ghosting is not.** Say where you got to, push the
branch if it holds anything useful, unassign, and restore `ready`. branch if it holds anything useful, unassign, and restore `ready`.
@ -114,48 +105,47 @@ triage bug, and the move is to say so on the issue, not to guess.
phase is yours. phase is yours.
- **`Closes #N` does not cross repos.** A PR in a different repo from its - **`Closes #N` does not cross repos.** A PR in a different repo from its
authorizing issue says `Part of <owner>/<repo>#N`, sets `offsite`, and authorizing issue says `Part of <owner>/<repo>#N`, sets `offsite`, and
comments the draft PR link on that issue in the same step; triage closes comments the draft PR link on that issue in the same step. Triage closes
that issue by hand once its acceptance criteria are met, and at that that issue by hand once its acceptance criteria are met; at that handoff
handoff the builder reports whether the PR merged or closed and clears the builder reports whether the PR merged or closed and clears `offsite`
`offsite` in the same comment. The cross-repo merge never closes the in the same comment. The cross-repo merge never closes the authorizing
authorizing issue (#13, #16). issue (#13, #16).
- **`Closes #N` does not survive a post-merge criterion.** Where the issue's - **`Closes #N` does not survive a post-merge criterion.** Where the issue's
body states that a criterion can only be checked after the merge — a live body states that a criterion can only be checked after the merge — a live
proof of a workflow trigger, a released-artifact check, anything whose proof of a workflow trigger, a released-artifact check, anything whose
subject does not exist until the change is on the base branch — the subject does not exist until the change is on the base branch — the
same-repo PR says `Refs #N` and triage closes by hand on the evidence. The same-repo PR says `Refs #N` and triage closes by hand on the evidence. The
merge releases the claim: the issue moves to `post-merge`, the builder merge releases the claim: the issue moves to `post-merge`, the builder
walks away, and triage owns verification and closure; corrective work is a walks away, and triage owns verification and closure, returning it to
fresh `ready` issue any builder claims from current `main`, the original `ready` or minting a fresh issue where corrective work is needed, which
builder holding no special standing. The issue body is what says so — you any builder claims from current `main`. The issue body is what says so —
never judge which issues qualify, and absent that instruction `Closes #N` you never judge which issues qualify, and absent that instruction
remains the default (#151). `Closes #N` is the default (#151).
- On a `Refs #N` PR, never put a closing keyword (`close`, `closes`, - On a `Refs #N` PR, never put a closing keyword (`close`, `closes`,
`closed`, `fix`, `fixes`, `fixed`, `resolve`, `resolves`, `resolved`) `closed`, `fix`, `fixes`, `fixed`, `resolve`, `resolves`, `resolved`)
immediately before `#N` anywhere in the body, including the sentence immediately before `#N` anywhere in the body, including the sentence
explaining why the PR does not close it: GitHub reads the whole body by explaining why the PR does not close it: GitHub reads the body by
adjacency, not intent, and a code span does not protect the phrase (#200, adjacency, not intent, and a code span does not protect the phrase (#200,
#218). Put the number first (`#N is closed by hand`) or omit it. #218). Put the number first (`#N is closed by hand`) or omit it.
- **The issue's acceptance criteria are your definition of done.** Reproduce - **The issue's acceptance criteria are your definition of done.** Reproduce
them as a checklist in the PR body and check them honestly as you go; a them as a checklist in the PR body and check them honestly as you go; a
criterion that turns out wrong or unreachable goes back to triage to be criterion that turns out wrong or unreachable goes back to triage to be
amended, never silently shipped short. amended, never silently shipped short.
- **Every behavior change writes one fragment**, `changelog.d/<issue>.md`, - **Every behavior change writes one fragment**, `changelog.d/<issue>.md`
named for the authorizing issue (`<repo>-<issue>.md` cross-repo): the named for the authorizing issue (`<repo>-<issue>.md` cross-repo): the
exact prose that will be published and nothing else — `- ` bullets, and in exact prose to be published and nothing else — `- ` bullets, plus in a
a grouped repo the `### Added` / `### Changed` / `### Fixed` headings grouped repo the `### Added` / `### Changed` / `### Fixed` headings inside
inside the fragment, a rarer kind only when a change genuinely is one. An the fragment, a rarer kind only where a change genuinely is one. An entry
entry is at most 300 characters, so a genuinely long change ships several is at most 300 characters, so a genuinely long change ships several short
short entries, never one long one; wrapping an entry over continuation entries; wrapping one over continuation lines never counts against it. It
lines is fine and never counts against it (#167). Every entry **ends with **ends with its issue citation**: one `(` group of `#N`, `repo#N` or
its issue citation**: a single `(` group of `#N`, `repo#N` or `owner/repo#N` separated by `, `, then `)`, then the final `.` and nothing
`owner/repo#N` references separated by `, `, then `)`, then the final `.` after it — `(#262).`, or `(#236, #250).` where an entry honestly lands
and nothing after it — `(#262).` locally, `(#236, #250).` when one entry two — and it need not name the fragment's own issue, which the filename
honestly lands two. The citation need not name the fragment's own issue, carries. The fragment guard reds a longer entry (#167) and an uncited one
which the filename already carries (#262). The fragment guard reds a (#262) alike. Never edit `CHANGELOG.md` for an entry: the release PR
longer entry and an uncited one alike. Never edit `CHANGELOG.md` for an assembles the section from the fragments (#112), and the monotonic guard
entry: the release PR assembles the section from the fragments (#112), and refuses anything that deletes a shipped heading.
the monotonic guard refuses anything that deletes a shipped heading.
- Follow the repo's conventions file and match the code you touch. Tests are - Follow the repo's conventions file and match the code you touch. Tests are
not optional: the issue's test plan is the floor, not the ceiling. not optional: the issue's test plan is the floor, not the ceiling.
- **A write-capable job gets a repo-owned script, not a third-party action.** - **A write-capable job gets a repo-owned script, not a third-party action.**
@ -163,19 +153,19 @@ triage bug, and the move is to say so on the issue, not to guess.
`id-token: write`, deploy secrets), default to a script in the repo that a `id-token: write`, deploy secrets), default to a script in the repo that a
test can drive; a third-party action there needs an established publisher test can drive; a third-party action there needs an established publisher
and a full-commit-SHA pin, and read-only jobs still SHA-pin. The full rule and a full-commit-SHA pin, and read-only jobs still SHA-pin. The full rule
and the red-flag profile a reviewer will apply are in REVIEWER.md §What and the red-flag profile a reviewer applies are in REVIEWER.md §What you
you review against, item 2 (#216). review against, item 2 (#216).
- **Scope discipline: the PR does the issue — whole, and nothing else.** - **Scope discipline: the PR does the issue — whole, and nothing else.**
Adjacent problems you discover go to a **discussion**, or a comment on the Adjacent problems go to a **discussion**, or a comment on the relevant
relevant issue, where triage will do its job. You do not mint issues — issue, where triage does its job. You do not mint issues — nobody but
nobody but triage does — and you do not fix drive-by findings in the same triage does — and you do not fix drive-by findings in the same PR, because
PR, because a reviewer cannot converge on a widening target. a reviewer cannot converge on a widening target.
## The review round ## The review round
(If you are reading this as `.ceremony/BUILDER.md` in a governed repo: (Read as `.ceremony/BUILDER.md` in a governed repo: repo-specific facts such
repo-specific facts such as the panel roster live in that repo's own as the panel roster live in that repo's own CONTRIBUTING, and the shared
CONTRIBUTING; the shared flow lives here and is not restated there.) flow lives here.)
1. Mark ready-for-review; request **the whole panel**: the PR repo's 1. Mark ready-for-review; request **the whole panel**: the PR repo's
`panel[<your-login>]=` line if it defines one, else its `panel=` line, `panel[<your-login>]=` line if it defines one, else its `panel=` line,
@ -186,70 +176,61 @@ CONTRIBUTING; the shared flow lives here and is not restated there.)
ready-for-review rather than guessing. You may request an off-panel ready-for-review rather than guessing. You may request an off-panel
reviewer, saying that their verdict is advisory and does not become reviewer, saying that their verdict is advisory and does not become
required. required.
**A review request requires a green check at the head**, and this binds **A review request requires a green check at the head**, and that binds
you whether or not any engine enforces it: a red check is the author's you whether or not any engine enforces it: a red check is the author's
own signal, not the panel's work, so fix it and push, then request. The own signal, not the panel's work, so fix it and push, then request. The
one exception is a failure genuinely outside the PR — a runner outage, a one exception is a failure genuinely outside the PR — a runner outage, a
flaky dependency, a failure already present on the default branch — and flaky dependency, a failure already present on the default branch — and
only if the request says so explicitly and names the evidence ("the same only where the request says so explicitly and names the evidence ("the
job fails identically on `origin/main` at `<sha>`"); silence about a red same job fails identically on `origin/main` at `<sha>`"). Silence about a
check is what is prohibited, while an argued exception shifts the burden red check is what is prohibited; an argued exception shifts the burden to
to the author. the author.
*Green* is a ruled term (operator, 2026-07-27), read in two steps, *Green* is a ruled term (operator, 2026-07-27), read in two steps,
because a head carries more rollup entries than it has checks. **First because a head carries more rollup entries than it has checks. **First
pick the entry that is a check's word at this head: its newest entry by find the check's word at this head**: its newest entry by start time,
start time, a `CANCELLED` entry never being that word while the same except that a `CANCELLED` entry is never the word while the same check
check carries a non-cancelled entry at the same head** — say *start* and has a non-cancelled entry at that head. Date entries by start and not by
mean it, since a cancelled run does not stop when its replacement begins completion — a cancelled run outlives its replacement's start, so the
and a reader who dates entries by completion picks the corpse. Where other reading picks the corpse. A check whose every entry at the head is
*every* entry a check has at the head is cancelled, nothing survives to cancelled has not reported at all and stays not-green by the classes
be its word: that check has not reported, and it stays not-green by the below; that is a collapse, not a new class, and the gate partitions the
classes below. That is a collapse and not a new class — the gate's same way, dropping a cancelled entry only where its context keeps a
carve-out likewise drops a cancelled entry only where its context keeps a non-cancelled survivor (#139, #276).
non-cancelled survivor, leaving an all-cancelled context blocking, so
doctrine and gate partition alike on a mixed context (#139, #276).
**Then classify that entry from its `conclusion`, never its `status`**, **Then classify that entry from its `conclusion`, never its `status`**,
which can still disagree with it (#259). An entry with no conclusion is which can still disagree with it (#259). No conclusion at all is neither
neither class: a configured run still in progress is not green, and class: a configured run still in progress is not green, and waiting on it
waiting for it is compliance, not a stall, so picking the newest entry is compliance, not a stall. **Cancelled or stale** is not green — *stale*
never settles a live one. **Cancelled or stale** is not a green head — means a superseded head's check, which a head-scoped rollup never shows,
*stale* means a check belonging to a superseded head, which the so what survives there is same-head cancellation. **Skipped or neutral**
head-scoped rollup does not show anyway, so what survives there is *is* green: those are deliberate "passed / not applicable" conclusions,
same-head cancellation — while **skipped or neutral** *is* green, those and reddening them would red every conditional job the fleet skips on
being deliberate "passed / not applicable" conclusions whose reddening purpose. **No checks configured** is the third ruled case, not an argued
would red every conditional job the fleet skips on purpose. A head with exception: nothing is configured, so nothing is waited for and the
**no checks configured** is the third ruled case, not an argued request goes out at once, no evidence owed. That rules
exception: nothing is configured, so there is nothing to wait for and the nothing-configured, never nothing-answered-yet — a pending run has an
request goes out straight away with no evidence owed, the owner, CI — and the machine partitions alike, admitting the ask on
argued-exception path existing for a check that ran and came up red. That `SUCCESS` and on `NONE` (#236). The costs behind the line are asymmetric:
rules nothing-configured, never nothing-answered-yet: a pending run has a false green spends a three-reviewer round, a false red one author
an owner, CI, and is waited on as above, and the machine partitions the session. What the *machine* drops from the rollup before grading is
same way, admitting the ask on `SUCCESS` and on `NONE` alike (#236). The crew's to describe.
costs behind the line are asymmetric: a false green spends a
three-reviewer round; a false red spends one author session. What the
*machine* drops from the rollup before grading is crew's to describe.
2. **Wait for every verdict, then answer the round whole** — one reply 2. **Wait for every verdict, then answer the round whole** — one reply
covering every point and stating what changed and what was verified. That covering every point and stating what changed and what was verified. That
reply is the written round record: the engine mirrors it under the PR reply is the written round record: the engine mirrors it under the PR
body's **Round log**, newest last, appending the author's comments posted body's **Round log**, newest last, so the builder owes the reply and no
after the round's newest verdict with `<!-- round:<head-sha> -->` (an separate body edit, and a round answered without one is recorded as such
existing marker makes a retry a no-op), so the builder owes the reply and and never blocks handoff.
no separate body edit; a round the builder left unanswered is recorded as Then push the fixes and re-request **by head, not by verdict**. A push
such and never blocks handoff.
Then push the fixes, and re-request **by head, not by verdict**. A push
makes every approval stale — an approval is of a specific tree, and the makes every approval stale — an approval is of a specific tree, and the
handoff predicate counts only approvals at the current head — so **every handoff predicate counts only approvals at the current head — so **every
panelist is re-requested, the approvers included**; a panelist left panelist is re-requested, the approvers included**; one left
un-re-requested after a push can never approve the tree you shipped, and un-re-requested can never approve the tree you shipped, and the PR sits
the PR sits looking finished with a full set of verdicts and nothing owed looking finished with nothing owed by anyone (#26, #39). Only where the
by anyone (#26, #39). Only where the head did not move — the round head did not move — the round answered with argument or evidence, nothing
answered with argument or evidence, nothing pushed — do you re-request pushed — do you re-request just the non-approvers, a standing approval
just the non-approvers, a standing approval already covering this exact already covering this exact head (#94). **The re-request carries the same
head and the engine absorbing a re-request at an unchanged one (#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 green-check-at-head precondition as the first request**, argued exception
included: a fix push whose check comes up red is your next fix, not the included: a fix push whose check comes up red is your next fix, not the
panel's. Prefer verification over argument — when a reviewer doubts panel's. Prefer verification over argument — where a reviewer doubts
behavior, add the test that settles it. behavior, add the test that settles it.
3. Never dismiss a review, never merge, never mark your own work as passed. 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 A blocking point you disagree with is answered with evidence or escalated
@ -260,22 +241,20 @@ CONTRIBUTING; the shared flow lives here and is not restated there.)
owes what. An engine may convert a PR back to draft when a round closes, so owes what. An engine may convert a PR back to draft when a round closes, so
that mid-round saves stop firing CI on a ready PR; ceremony implements no that mid-round saves stop firing CI on a ready PR; ceremony implements no
such conversion and this passage specifies none, but whoever meets a such conversion and this passage specifies none, but whoever meets a
mid-round draft reads it as the draft always read — the draft phase is yours mid-round draft reads it as a draft always read — the draft phase is yours
and the panel cannot see it (Building, above) — while the round outranks the and the panel cannot see it — while the round outranks the draft, so you
draft, so you still owe it whole, the fixes and the reply and the flip still owe it whole, the fixes and the reply and the flip
([LABELS.md](LABELS.md)'s `state:building` row says the same in the ([LABELS.md](LABELS.md)'s `state:building` row, #205). **Ready-for-review is
machine's voice, #205). **Ready-for-review is the act that ends the round, the act that ends the round, and it is the builder's alone**: the flip
and it is the builder's alone**: the flip asserts that the round was asserts that the round was answered whole, the one judgement about a round
answered whole, which is the one judgement about a round its author cannot its author cannot delegate, so an engine may draft a PR but only the builder
delegate to a machine, so an engine may draft a PR but only the builder
undrafts it. **Where a draft suppressed the checks, green is proven at the undrafts it. **Where a draft suppressed the checks, green is proven at the
flip and the request still follows it**: marking ready is what runs the flip and the request still follows it**: marking ready is what runs the
checks the draft held back, so the order is flip, let the head answer, then checks the draft held back, so the order is flip, let the head answer, then
request — step 1's precondition and not a second one — and the argued request — step 1's precondition, not a second one. Waiting there is
exception stays the only way past a red one. Waiting there is compliance, compliance, not a stall, and `blocker:unrequested` does not fire while a
not a stall, and the machine reads it the same way: `blocker:unrequested` head's checks are pending or red, because the one blocker that demands an
does not fire while a head's checks are pending or red, because the one act has to know when the act is permitted (#236).
blocker that demands an act has to know when the act is permitted (#236).
## The ruling ask ## The ruling ask
@ -343,9 +322,9 @@ builder's behalf, in order:
the head SHA, and a pointer to the PR body's **Round log**. the head SHA, and a pointer to the PR body's **Round log**.
The builder composes no new summary at handoff: the authored record already The builder composes no new summary at handoff: the authored record already
lives in the Round log, mirrored mechanically from each whole-round reply. lives in the Round log, mirrored from each whole-round reply. The label write
The label write is optimistic — the reconciler validates it and takes it is optimistic — the reconciler validates it and takes it back if the PR is
back if the PR is not actually mergeable-right-now. Then stop: the PR is the not actually mergeable-right-now. Then stop: the PR is the human's, and the
human's, and the claim is now parked as shape 4 (Picking, above), the claim is parked as shape 4 (Picking, above), that handoff comment being its
handoff comment being its declaration and your build slot free. Address what declaration and your build slot free. Address what comes back
comes back (`state:addressing`) and re-hand-off the same way. (`state:addressing`) and re-hand-off the same way.