BUILDER.md / REVIEWER.md / FLEET.md — the cross-repo discovery guards: which panel, which link, which wake #57
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#57
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?
Part of #56.
ready— blocked by nothing. Independent of the sibling child (the runner guard); either may land first.Context
Accepted from discussion #55. The evidence table and the seven decisions are in #56 — read the epic first, and do not reopen a D in this PR. In particular D7 is live: whether the bench roster should be uniform across governed repos is @danmt's call, so this PR must not change any roster.
All line references pinned at
2f0d3c6.The one-sentence version of the gap: every rule in BUILDER.md and REVIEWER.md silently assumes the PR is in the same repo as the issue. The day that stopped being true (2026-07-23, rig#112 built against ceremony #13), three things had no answer — which roster is "the whole panel", how a PR links back to an issue in another repo when
Closes #Ncannot cross repos, and how a reviewer ever hears about it. A human filled all three gaps by hand.Spec
Three files. No behavior lives in code here — this is doctrine plus the descriptive map — so the density bar is "a builder in a fresh box, reading only these files, does the right thing on a cross-repo PR."
1. BUILDER.md — the push side
(a) The review round, step 1 (L52-53) reads today:
It gains the cross-repo answer, as a sub-point of step 1 (not a new numbered step — the round rhythm stays four steps):
.github/labels.confpanel=line is the machine's own answer (the reconciler'sREQUIRED_BOTSis exactly that list minus the author); its CONTRIBUTING roster is the human-readable one. When a repo has both,panel=governs, because that is what the state machine reads.Carry the why in the text, per the repo's comment convention: on rig#112 the builder requested codex and grok and was correct — rig's
panel=is three names — while ceremony's bench is five, and a human had to add kimi 50 minutes later. Nothing was disobeyed; the doctrine simply did not say which roster it meant.(b) Building (L28-30) gains the cross-repo linkage rule, beside
Closes #N:Closes #Ndoes not cross repos. When the PR is in a different repo from the issue, the body carriesPart of <owner>/<repo>#Ninstead, and the issue is closed by hand — by triage, when the acceptance criteria are met — never by the merge.This half is codification of what builders already do right — rig#112's body opens with
Part of heavy-duty/ceremony#13, and both #13 and #16 carry draft-open link comments. Say that in the text; a rule that reads as a reprimand for a thing nobody did wrong ages badly.(c) The draft rule survives untouched. The request obligation attaches at ready-for-review (step 1), the link obligation at draft-open.
dan-claude-bot/incubator#89is a draft that has already linked: it owes nothing, and any wording implying otherwise contradicts L28-30's "drafts are invisible to the reviewer panel on purpose".2. REVIEWER.md — the pull side
A new short section,
## Where you review, placed between "What you review against" and "What you do not do". Three bullets, no more:heavy-dutyrepo, and on any fleet member's fork. You do not need to be told separately that you may review there, and you do not wait for a repo to appear on a list. Review is read-plus-comment: reversible, no blast radius, and somebody already decided it should happen at the moment they requested you.panel=minus the author, and nothing else.Live case to cite: @danmt requested kimi on rig#112 at 01:24Z; kimi is not on rig's
panel=, and nine hours later the request is still unanswered. Both halves of that sentence are defects, and they are different defects.3. FLEET.md — the wake conditions
Reviewers (L57-59) reads today:
It becomes two triggers, ordered:
gh search prs --review-requested=@me --state=openis repo-independent; the existing per-head dedup is unchanged.)Add one sentence to the same section stating the honest limit:
~/duty/repos.txtand the duty scripts live inside each box and are the operator's to change. This file is descriptive; the edit is the spec each box's script is updated against, and until an operator does that, the trigger exists on paper only. That sentence is not hedging — it is the difference between a document that describes the fleet and one that quietly lies about it.4. What this PR does not touch
CONTRIBUTING.md's roster and panel paragraphs (L61-88) — including "Each governed repo names its own roster in its CONTRIBUTING". Whether the bench is uniform across repos is D7, @danmt's ruling, live on the epic. Making rig's panel five names is not a doc edit and is not in scope here.actions/labels-reconcile/— D3 describes what it already computes. If a reader thinks the doctrine and the code disagree, that is a bug report on the epic, not a fix in this PR..ceremony/— this repo is the source of the mirror, not a consumer of it (same as #51).5. Changelog
One line under
## Unreleased, inserted above the## 0.1.0heading — never typed over it (the monotonic guard exists because of exactly that edit):Tasks
Part of <owner>/<repo>#Nfor cross-repo PRs, the draft-open link comment on the authorizing issue, and who closes the issue.## Where you reviewsection, three bullets.## Unreleased, inserted above## 0.1.0.Acceptance criteria
panel=as the governing source when a repo has both apanel=line and a prose roster.Closes #Ndoes not cross repos, gives thePart of <owner>/<repo>#Nreplacement, and says the authorizing issue is closed by triage, not by the merge.heavy-dutyand on fleet forks, that it is not panel membership, and what an off-panel reviewer does with its verdict (post it, mark it advisory).labels-reconcilebehavior changes anywhere in the diff.CHANGELOG.mdcarries one line under## Unreleased, above the## 0.1.0heading.bash test/run.sh, shellcheck, actionlint, and the four self-guards.Test plan
This is a doctrine change; be honest about what a test can and cannot prove.
Mechanical (must pass):
bash test/run.sh— the suite is content-agnostic about doctrine prose, so a green run proves only that nothing else broke. Say so in the PR body rather than implying the suite reviewed the text.docs-sync-exercisein CI stays green — the vendored set's file list (docs/VENDORED.txt) is unchanged; only bytes inside two of its files change, which is exactly what the mirror is designed to carry.changelog-armed/changelog-monotonicself-guards go green on the new changelog line, andchangelog-monotonicwould go red if the line were typed over the## 0.1.0heading instead of inserted above it. Do not construct that failure by hand — ci.yml'saction-exercisejob already runs it on a scratch history every PR.The cases that must fail (behavioral — the reviewer checks these against the live artifacts, not against a runner):
Dependencies
Part of #56. Blocked by nothing. Blocks nothing — the sibling guard is independent, and D7's ruling changes rosters, not this text.
Starting this build. I will implement the cross-repo linkage, panel-selection, reviewer-authorization, and wake-condition doctrine exactly as specified, without changing any roster or reconciler behavior.