Fleet scope and cross-repo discovery — the two guards, the runner hole, the roster question (epic) #56

Closed
opened 2026-07-23 10:44:46 +00:00 by dan-claude-bot · 8 comments
dan-claude-bot commented 2026-07-23 10:44:46 +00:00 (Migrated from github.com)

Accepted from discussion #55 — "Where the fleet may work — three scopes, two guards, one registry", filed at @danmt's request. This epic carries the decisions triage made in accepting it, the corrections that verification forced on the proposal's own evidence, and the one question that is not triage's to answer.

All line references pinned at 2f0d3c6.

Context — the incidents, re-verified

The proposal named two failures. Both are real; neither is quite the failure it was reported as, and the difference changes what the guards must say. Every claim below was checked against the API, not taken from the report.

The proposal said What is actually true Consequence
dan-claude-bot/incubator#89 "has sat since 01:20Z with zero reviews and zero requested reviewers" — a discovery failure #89 is a draft. Drafts are invisible to the panel on purpose (BUILDER.md L28-30) and it owes no request yet. The builder also did link it on the authorizing issue, at 01:17Z on #16 #89 is not evidence of anything. The push-side guard survives on other grounds (below); its trigger point is ready-for-review, not draft-open
Kimi missed heavy-duty/rig#112 because its poll list is heavy-duty/ceremony alone True — and there is a second, independent cause. rig#112's own diff sets panel=claude-bot-andresmgsl codex-bot-andresmgsl grok-bot-andresmgsl: kimi is not on rig's panel at all. Even with perfect discovery, no verdict of kimi's would ever have been required there Discovery is half the fix. The other half is a roster question — escalated below, D7
The builder requested reviewers on rig#112 It requested two of three: ready_for_review + codex + grok by the builder at 00:34Z, then kimi requested by @danmt at 01:24Z, 50 minutes later. But by rig's panel= line the builder was correct: panel minus author = codex + grok The gap is not a forgotten request. It is that "the whole panel" is ambiguous the moment the PR leaves the repo the issue lives in — ceremony's five-name bench is not rig's panel, and doctrine never says which one governs

Nine hours on, rig#112 still has no verdict from kimi, and both required verdicts (codex, grok) approve the current head 3c72c1b. Closed out (triage, 2026-07-23): kimi approved 3c72c1b at 10:42Z9h18m after @danmt's off-roster request at 01:24Z. All three verdicts now approve the head, and rig#112 has carried state:needs-human since 10:47Z. The incident is over; what it evidenced is not — the delay is measured, not hypothetical, and neither guard nor ruling exists yet.

So: one closed discovery failure that took 9h18m to produce an off-roster verdict (the delay is the evidence; D1–D4 stand on it), one live ambiguity (which roster is "the panel" — D7, unruled), one live hole with no incident yet (the self-hosted runner), and one proposal artifact — the registry — that has exactly one true row and no readers.

Decisions — children must not reopen these

# Decision Source
D1 The two guards land ahead of any registry. They fix a live failure and depend on nothing the registry provides. (Answers discussion #55's open question 3.) triage
D2 No rate limit on the reviewer's request trigger. (Answers open question 2.) A request can only come from a fleet identity or a human in an org of six accounts; the limit would be machinery for a threat that has not happened, and it would suppress exactly the signal the guard exists to carry. Revisit on the first abuse, not before triage
D3 A review request is authorization, not panel membership. Convergence stays measured against the target repo's panel (REQUIRED_BOTS = panel= minus author, labels-reconcile.sh L38-L47). An off-panel reviewer's verdict is advisory and says so in its body. This is not a new rule — it is what the reconciler already computes; doctrine has simply never said it, which is why rig#112 now reads as if it were waiting on a verdict no machine will ever require triage, describing existing machinery
D4 The panel for a cross-repo PR is the roster of the repo the PR is in, minus the author — not the roster of the repo the issue is in. If the PR's repo names no roster, the builder asks on the authorizing issue before marking ready-for-review, and triage answers. Nobody guesses a panel triage (D3's consequence; rig#112's ambiguity)
D5 The runner hole gets a guard in ceremony's guard family, not a settings toggle and not a per-repo script — pull_request-triggered work must never reach a self-hosted runner. Verified live: heavy-duty/incubator's deploy.yml job runs on [self-hosted, ci-runner] and is push-triggered; pr-checks.yml is pull_request-triggered and ubuntu-latest. Nothing is wrong today — the guard is what keeps it that way once fork PRs run workflows there (#16's ruling) triage
D6 FLEET.yml is not minted now. Today it would carry one adopted: true row (ceremony), four rows that restate #13–#16, and no reader — every box's duty script is operator-owned and would need changing to read it. Revisit when #13 lands and there are two adopted repos to disagree about. A registry minted before it has readers is a file that goes stale in a week triage
D7 Three things are @danmt's call, not triage's — the build-scope boundary, whether the bench roster is uniform across governed repos, and the org-wide fork-PR settings. Escalated in the comment below, with options and a recommendation for each TRIAGE.md outcome 3
D8 A cross-repo claim is exempt from the reclaim clock, on the label alone. offsite, named by @danmt. The failure it fixes is real and mis-attributed in the proposal: the reclaim that runs on this board is the in-repo sweep's claim_decision, not the triage box's hygiene.sh. The box script is the operator's and gets a spec, never a claim of done — the same constraint FLEET.md carries above. #68 triage, from discussion #67
D9 Trust first, verify only to nudge. @danmt: "we can verify, but only if we already trust so we dont have to verify everything." So: the label alone exempts (#68), and a separate, later, quieter pass (#69) reads the timeline the sweep already fetches and comments once when every visible cross-repo PR has closed. It never clears the flag and never reclaims. An unreadable reference resolves to silence triage, from discussion #67
D10 offsite does not touch the epic-completion nudge — not as a preference but because there is no interaction to have. The nudge fires on children being closed; an offsite child is open. Recorded so nobody builds the suppression @danmt left to triage's judgement triage, from discussion #67

Constraints the children must preserve

  • FLEET.md is descriptive, not doctrine (its own status header). The duty scripts that implement wake conditions live inside each box and are the operator's to change. A FLEET.md edit is a spec for that change, never a substitute for it — and a child that claims a wake condition works because a document says so is lying.
  • Doctrine ships as a vendored mirror. BUILDER.md and REVIEWER.md are in the .ceremony/ set; this repo is the source, so no re-sync happens here — consumers get the change at their next pin bump (CONTRIBUTING, "How the other repos use this").
  • Guards are consumed by reference — no fourth copy. The new guard follows the family's shape exactly: actions/<name>/action.yml + <name>.sh + test/<name>.test.sh, mawk-compatible, set -euo pipefail, shellcheck- and actionlint-clean.
  • The roster paragraph in CONTRIBUTING is not touched by any child. Whether kimi belongs on rig's panel is D7's ruling, and a child that quietly made the bench uniform would be deciding it.

Task list

  • #57 — the two discovery guards: BUILDER.md (push side), REVIEWER.md (pull side), FLEET.md's wake conditions. Landed 2026-07-23 in #62 (5e283ec), closed 11:37Z. The box-side implementation of the reviewer wake condition remains the operator's, as the constraint above requires — FLEET.md specifies it, it does not claim it done.
  • #58actions/runner-isolated: no pull_request-triggered job on a self-hosted runner. Landed 2026-07-23 in #60 (merged 12:24Z), closed the same minute. Red-run evidence on a scratch fork branch (run 30002684920), and ceremony runs the guard on its own tree (ci.yml L77).
  • #68offsite: the label, the doctrine, and the claim-reclaim exemption. The machine-readable half of #57's cross-repo linkage rule — a claim whose PR lives in another repo has no local PR by construction, so the reclaim clock reads it as abandoned. Landed 2026-07-23 in #70 (e9928f1), closed 13:07Z. Verified on main: claim_clock_exempt pauses only the reclaim clock — test/issueflow-reconcile.test.sh pins "a 10-day-quiet offsite claim is not reclaimed", "an unassigned offsite claim is still flagged", "offsite alone still needs triage", and "no reconciler mutation names offsite (#68 D4)". Accepted from discussion 67 (D8–D10 below).
  • #69 — the offsite stale-flag nudge: when every cross-referenced PR the sweep can see is closed, say so once. Reads the timeline the sweep already fetches; comments and never acts. Landed 2026-07-23 in #71 (553409c), closed 13:43Z. offsite_resolved_decision nudges on all-closed and stays quiet on an open or unreadable one ("one open offsite PR keeps quiet", "an unreadable offsite PR keeps quiet"); the flag is never cleared and the claim never changed.
  • The offsite label does not exist on this board yet — a maintainer must dispatch the labels workflow. The taxonomy row landed with #70 (labels-reconcile.sh L394, offsite|CFD3D7|…), but the bootstrap only writes labels when dispatched. Triage cannot do it: POST /repos/heavy-duty/ceremony/labels returns 404 at triage permission (attempted 2026-07-23). Until it runs, the three live offsite claims — #14 (box#164), #15 (cast#143), #16 (incubator#25) — carry the exemption's code and not its flag, so the 48-hour reclaim clock still reads them as local claims with no PR. Same shape as #50's post-merge dispatch item, same one-dispatch fix. @danmt.
  • The registry (FLEET.yml) — deliberately not minted (D6), and gated on D7's ruling besides. If the ruling enumerates build targets rather than opening heavy-duty/*, the registry becomes load-bearing and gets minted then; if the boundary is the org, it may never be needed. Tracked here so the omission is a decision on the board rather than a gap in it.

Flag status (triage, 2026-07-23): this epic now carries needs-ruling. D7's escalation has been live and unruled since 10:46Z; the label was unappliable until the bootstrap dispatch ran at 11:48Z, which is why it arrives an hour late rather than with the escalation. Nothing is blocked on the ruling — the two discovery children have landed, the two offsite children are queued behind #52, and D6 holds independently of all four.

Definition of done

  • A builder opening a PR outside the issue's repo knows, from BUILDER.md alone, which panel to request and how to link the PR back — without asking anyone. — done in #57 (5e283ec): BUILDER.md names the PR repo's panel= as the answer, CONTRIBUTING as its human-readable form, panel= governing on disagreement, and ask triage, do not guess when the PR repo names no roster; the linkage rule (Part of <owner>/<repo>#N + comment the draft link on the authorizing issue, triage closes by hand) is at L26-L35.
  • A reviewer knows, from REVIEWER.md alone, that a request anywhere in the org is its authorization, and that being requested off-panel makes its verdict advisory rather than a gate. — done in #57 (5e283ec): REVIEWER.md L46-L55, carrying D3 verbatim and citing rig#112 as the case that proved authorization and membership must not be conflated.
  • FLEET.md's reviewer wake conditions name the request trigger and say it is evaluated before the repo-list poll; the box-side implementation is named as the operator's follow-up, not claimed as done. — done in #57 (5e283ec): FLEET.md L57-L68 — request-first ordering with its reason (it reaches repos the list does not name), dedup against the reviewer's own latest review SHA rather than the lagging search index, and the explicit "until an operator makes them, the request trigger exists on paper only".
  • A pull_request-triggered job that runs on a self-hosted runner fails CI in any repo carrying the guard, proven red once on a scratch fixture, and ceremony runs the guard on itself. — done in #58 (#60, merged 12:24Z): the guard is red on claude-bot-andresmgsl/ceremony#2's scratch runs-on: self-hosted workflow (run 30002684920), caught twice — once by the self-guards step, once independently by the unit suite's own-tree case — and .github/workflows/ci.yml runs ./actions/runner-isolated on ceremony itself.
  • A claimed issue whose deliverable is a PR in another repo is not reclaimed as abandoned, and a flag that outlives its PR is surfaced rather than left standing — done in #68 (#70, e9928f1) and #69 (#71, 553409c), verified on main against the suite rather than off the PR bodies. One caveat, tracked as an open task above: the behaviour is real in the code and unreachable on this board until a maintainer dispatch creates the offsite label, so today's three cross-repo claims are still on the ordinary reclaim clock.
  • D7's three questions are ruled, recorded here as decisions, and the flag closed out per LABELS.md.
Accepted from discussion [#55](https://github.com/heavy-duty/ceremony/discussions/55) — "Where the fleet may work — three scopes, two guards, one registry", filed at @danmt's request. This epic carries the decisions triage made in accepting it, the **corrections that verification forced on the proposal's own evidence**, and the one question that is not triage's to answer. All line references pinned at [`2f0d3c6`](https://github.com/heavy-duty/ceremony/tree/2f0d3c65af0d467240a8b00be0924c2edebabbf4). ## Context — the incidents, re-verified The proposal named two failures. Both are real; **neither is quite the failure it was reported as**, and the difference changes what the guards must say. Every claim below was checked against the API, not taken from the report. | The proposal said | What is actually true | Consequence | |---|---|---| | `dan-claude-bot/incubator#89` "has sat since 01:20Z with zero reviews and zero requested reviewers" — a discovery failure | **#89 is a draft.** Drafts are invisible to the panel *on purpose* ([BUILDER.md L28-30](https://github.com/heavy-duty/ceremony/blob/2f0d3c65af0d467240a8b00be0924c2edebabbf4/BUILDER.md#L28-L30)) and it owes no request yet. The builder also *did* link it on the authorizing issue, at [01:17Z on #16](https://github.com/heavy-duty/ceremony/issues/16#issuecomment-5051946745) | #89 is **not** evidence of anything. The push-side guard survives on other grounds (below); its trigger point is ready-for-review, not draft-open | | Kimi missed `heavy-duty/rig#112` because its poll list is `heavy-duty/ceremony` alone | True — *and there is a second, independent cause*. rig#112's own diff sets `panel=claude-bot-andresmgsl codex-bot-andresmgsl grok-bot-andresmgsl`: **kimi is not on rig's panel at all.** Even with perfect discovery, no verdict of kimi's would ever have been required there | Discovery is half the fix. The other half is a roster question — escalated below, D7 | | The builder requested reviewers on rig#112 | It requested **two of three**: `ready_for_review` + `codex` + `grok` by the builder at 00:34Z, then **`kimi` requested by @danmt at 01:24Z**, 50 minutes later. But by rig's `panel=` line the builder was *correct*: panel minus author = codex + grok | The gap is not a forgotten request. It is that **"the whole panel" is ambiguous the moment the PR leaves the repo the issue lives in** — ceremony's five-name bench is not rig's panel, and doctrine never says which one governs | ~~Nine hours on, [rig#112](https://github.com/heavy-duty/rig/pull/112) still has no verdict from kimi, and both required verdicts (codex, grok) approve the current head `3c72c1b`.~~ **Closed out (triage, 2026-07-23): kimi approved `3c72c1b` at 10:42Z** — **9h18m** after @danmt's off-roster request at 01:24Z. All three verdicts now approve the head, and rig#112 has carried `state:needs-human` since 10:47Z. The incident is over; **what it evidenced is not** — the delay is measured, not hypothetical, and neither guard nor ruling exists yet. So: one *closed* discovery failure that took 9h18m to produce an off-roster verdict (the delay is the evidence; D1–D4 stand on it), one live ambiguity (which roster is "the panel" — D7, unruled), one live hole with no incident yet (the self-hosted runner), and one proposal artifact — the registry — that has exactly one true row and no readers. ## Decisions — children must not reopen these | # | Decision | Source | |---|---|---| | **D1** | **The two guards land ahead of any registry.** They fix a live failure and depend on nothing the registry provides. (Answers discussion #55's open question 3.) | triage | | **D2** | **No rate limit on the reviewer's request trigger.** (Answers open question 2.) A request can only come from a fleet identity or a human in an org of six accounts; the limit would be machinery for a threat that has not happened, and it would suppress exactly the signal the guard exists to carry. Revisit on the first abuse, not before | triage | | **D3** | **A review request is authorization, not panel membership.** Convergence stays measured against the target repo's panel (`REQUIRED_BOTS` = `panel=` minus author, [labels-reconcile.sh L38-L47](https://github.com/heavy-duty/ceremony/blob/2f0d3c65af0d467240a8b00be0924c2edebabbf4/actions/labels-reconcile/labels-reconcile.sh#L38-L47)). An off-panel reviewer's verdict is advisory and says so in its body. This is not a new rule — it is what the reconciler already computes; doctrine has simply never said it, which is why rig#112 now reads as if it were waiting on a verdict no machine will ever require | triage, describing existing machinery | | **D4** | **The panel for a cross-repo PR is the roster of the repo the *PR* is in**, minus the author — not the roster of the repo the *issue* is in. If the PR's repo names no roster, the builder asks on the authorizing issue before marking ready-for-review, and triage answers. Nobody guesses a panel | triage (D3's consequence; rig#112's ambiguity) | | **D5** | **The runner hole gets a guard in ceremony's guard family**, not a settings toggle and not a per-repo script — `pull_request`-triggered work must never reach a self-hosted runner. Verified live: `heavy-duty/incubator`'s `deploy.yml` job runs on `[self-hosted, ci-runner]` and is `push`-triggered; `pr-checks.yml` is `pull_request`-triggered and `ubuntu-latest`. Nothing is wrong today — the guard is what keeps it that way once fork PRs run workflows there ([#16's ruling](https://github.com/heavy-duty/ceremony/issues/16#issuecomment-5056705884)) | triage | | **D6** | **`FLEET.yml` is not minted now.** Today it would carry one `adopted: true` row (ceremony), four rows that restate #13–#16, and no reader — every box's duty script is operator-owned and would need changing to read it. Revisit when #13 lands and there are two adopted repos to disagree about. A registry minted before it has readers is a file that goes stale in a week | triage | | **D7** | **Three things are @danmt's call, not triage's** — the build-scope boundary, whether the bench roster is uniform across governed repos, and the org-wide fork-PR settings. Escalated in the comment below, with options and a recommendation for each | TRIAGE.md outcome 3 | | **D8** | **A cross-repo claim is exempt from the reclaim clock, on the label alone.** `offsite`, named by @danmt. The failure it fixes is real and mis-attributed in the proposal: the reclaim that runs on this board is the in-repo sweep's `claim_decision`, not the triage box's `hygiene.sh`. The box script is the operator's and gets a spec, never a claim of done — the same constraint FLEET.md carries above. **#68** | triage, from discussion #67 | | **D9** | **Trust first, verify only to nudge.** @danmt: *"we can verify, but only if we already trust so we dont have to verify everything."* So: the label alone exempts (#68), and a separate, later, quieter pass (**#69**) reads the timeline the sweep already fetches and comments once when every visible cross-repo PR has closed. It never clears the flag and never reclaims. An unreadable reference resolves to silence | triage, from discussion #67 | | **D10** | **`offsite` does not touch the epic-completion nudge** — not as a preference but because there is no interaction to have. The nudge fires on children being *closed*; an offsite child is *open*. Recorded so nobody builds the suppression @danmt left to triage's judgement | triage, from discussion #67 | ## Constraints the children must preserve - **`FLEET.md` is descriptive, not doctrine** ([its own status header](https://github.com/heavy-duty/ceremony/blob/2f0d3c65af0d467240a8b00be0924c2edebabbf4/FLEET.md#L3-L10)). The duty scripts that implement wake conditions live inside each box and are the operator's to change. A FLEET.md edit is a *spec* for that change, never a substitute for it — and a child that claims a wake condition works because a document says so is lying. - **Doctrine ships as a vendored mirror.** BUILDER.md and REVIEWER.md are in the `.ceremony/` set; this repo is the *source*, so no re-sync happens here — consumers get the change at their next pin bump ([CONTRIBUTING, "How the other repos use this"](https://github.com/heavy-duty/ceremony/blob/2f0d3c65af0d467240a8b00be0924c2edebabbf4/CONTRIBUTING.md#L104-L119)). - **Guards are consumed by reference — no fourth copy.** The new guard follows the family's shape exactly: `actions/<name>/action.yml` + `<name>.sh` + `test/<name>.test.sh`, mawk-compatible, `set -euo pipefail`, shellcheck- and actionlint-clean. - **The roster paragraph in CONTRIBUTING is not touched by any child.** Whether kimi belongs on rig's panel is D7's ruling, and a child that quietly made the bench uniform would be deciding it. ## Task list - [x] **#57** — the two discovery guards: BUILDER.md (push side), REVIEWER.md (pull side), FLEET.md's wake conditions. **Landed 2026-07-23** in #62 (`5e283ec`), closed 11:37Z. The box-side implementation of the reviewer wake condition remains the operator's, as the constraint above requires — FLEET.md specifies it, it does not claim it done. - [x] **#58** — `actions/runner-isolated`: no `pull_request`-triggered job on a self-hosted runner. **Landed 2026-07-23** in #60 (merged 12:24Z), closed the same minute. Red-run evidence on a scratch fork branch ([run 30002684920](https://github.com/claude-bot-andresmgsl/ceremony/actions/runs/30002684920)), and ceremony runs the guard on its own tree ([ci.yml L77](https://github.com/heavy-duty/ceremony/blob/cf69d8ce9ef0cb62a784e6fa823274141d7aa729/.github/workflows/ci.yml#L77)). - [x] **#68** — `offsite`: the label, the doctrine, and the claim-reclaim exemption. The machine-readable half of #57's cross-repo linkage rule — a claim whose PR lives in another repo has no local PR *by construction*, so the reclaim clock reads it as abandoned. **Landed 2026-07-23** in #70 (`e9928f1`), closed 13:07Z. Verified on `main`: [`claim_clock_exempt`](https://github.com/heavy-duty/ceremony/blob/553409c/actions/issueflow-reconcile/issueflow-reconcile.sh) pauses *only* the reclaim clock — `test/issueflow-reconcile.test.sh` pins *"a 10-day-quiet offsite claim is not reclaimed"*, *"an unassigned offsite claim is still flagged"*, *"offsite alone still needs triage"*, and *"no reconciler mutation names offsite (#68 D4)"*. Accepted from [discussion 67](https://github.com/heavy-duty/ceremony/discussions/67) (D8–D10 below). - [x] **#69** — the `offsite` stale-flag nudge: when every cross-referenced PR the sweep can see is closed, say so once. Reads the timeline the sweep already fetches; comments and never acts. **Landed 2026-07-23** in #71 (`553409c`), closed 13:43Z. `offsite_resolved_decision` nudges on all-closed and stays quiet on an open or unreadable one (*"one open offsite PR keeps quiet"*, *"an unreadable offsite PR keeps quiet"*); the flag is never cleared and the claim never changed. - [ ] **The `offsite` label does not exist on this board yet — a maintainer must dispatch the labels workflow.** The taxonomy row landed with #70 ([`labels-reconcile.sh` L394](https://github.com/heavy-duty/ceremony/blob/553409c/actions/labels-reconcile/labels-reconcile.sh#L394), `offsite|CFD3D7|…`), but the bootstrap only writes labels when dispatched. Triage cannot do it: `POST /repos/heavy-duty/ceremony/labels` returns 404 at `triage` permission (attempted 2026-07-23). Until it runs, the three live offsite claims — #14 ([box#164](https://github.com/heavy-duty/box/pull/164)), #15 ([cast#143](https://github.com/heavy-duty/cast/pull/143)), #16 ([incubator#25](https://github.com/heavy-duty/incubator/pull/25)) — carry the exemption's code and not its flag, so the 48-hour reclaim clock still reads them as local claims with no PR. Same shape as #50's post-merge dispatch item, same one-dispatch fix. @danmt. - [ ] **The registry (`FLEET.yml`) — deliberately not minted** (D6), and gated on D7's ruling besides. If the ruling enumerates build targets rather than opening `heavy-duty/*`, the registry becomes load-bearing and gets minted then; if the boundary is the org, it may never be needed. Tracked here so the omission is a decision on the board rather than a gap in it. **Flag status (triage, 2026-07-23):** this epic now carries `needs-ruling`. D7's escalation has been live and unruled since [10:46Z](https://github.com/heavy-duty/ceremony/issues/56#issuecomment-5057506832); the label was unappliable until the bootstrap dispatch [ran at 11:48Z](https://github.com/heavy-duty/ceremony/actions/runs/30004512442), which is why it arrives an hour late rather than with the escalation. Nothing is blocked on the ruling — the two discovery children have landed, the two `offsite` children are queued behind #52, and D6 holds independently of all four. ## Definition of done - [x] A builder opening a PR outside the issue's repo knows, from BUILDER.md alone, which panel to request and how to link the PR back — without asking anyone. — **done in #57** (`5e283ec`): [BUILDER.md](https://github.com/heavy-duty/ceremony/blob/ca9a1a0/BUILDER.md#L58-L67) names the PR repo's `panel=` as the answer, CONTRIBUTING as its human-readable form, `panel=` governing on disagreement, and *ask triage, do not guess* when the PR repo names no roster; the linkage rule (`Part of <owner>/<repo>#N` + comment the draft link on the authorizing issue, triage closes by hand) is at [L26-L35](https://github.com/heavy-duty/ceremony/blob/ca9a1a0/BUILDER.md#L26-L35). - [x] A reviewer knows, from REVIEWER.md alone, that a request anywhere in the org is its authorization, and that being requested off-panel makes its verdict advisory rather than a gate. — **done in #57** (`5e283ec`): [REVIEWER.md L46-L55](https://github.com/heavy-duty/ceremony/blob/ca9a1a0/REVIEWER.md#L46-L55), carrying D3 verbatim and citing rig#112 as the case that proved authorization and membership must not be conflated. - [x] FLEET.md's reviewer wake conditions name the request trigger and say it is evaluated before the repo-list poll; the box-side implementation is named as the operator's follow-up, not claimed as done. — **done in #57** (`5e283ec`): [FLEET.md L57-L68](https://github.com/heavy-duty/ceremony/blob/ca9a1a0/FLEET.md#L57-L68) — request-first ordering with its reason (it reaches repos the list does not name), dedup against the reviewer's own latest review SHA rather than the lagging search index, and the explicit *"until an operator makes them, the request trigger exists on paper only"*. - [x] A `pull_request`-triggered job that runs on a self-hosted runner fails CI in any repo carrying the guard, proven red once on a scratch fixture, and ceremony runs the guard on itself. — **done in #58** (#60, merged 12:24Z): the guard is red on [claude-bot-andresmgsl/ceremony#2](https://github.com/claude-bot-andresmgsl/ceremony/pull/2)'s scratch `runs-on: self-hosted` workflow ([run 30002684920](https://github.com/claude-bot-andresmgsl/ceremony/actions/runs/30002684920)), caught twice — once by the `self-guards` step, once independently by the unit suite's own-tree case — and `.github/workflows/ci.yml` runs `./actions/runner-isolated` on ceremony itself. - [x] A `claimed` issue whose deliverable is a PR in another repo is not reclaimed as abandoned, and a flag that outlives its PR is surfaced rather than left standing — **done in #68** (#70, `e9928f1`) **and #69** (#71, `553409c`), verified on `main` against the suite rather than off the PR bodies. **One caveat, tracked as an open task above:** the behaviour is real in the code and unreachable on this board until a maintainer dispatch creates the `offsite` label, so today's three cross-repo claims are still on the ordinary reclaim clock. - [ ] D7's three questions are ruled, recorded here as decisions, and the flag closed out per [LABELS.md](https://github.com/heavy-duty/ceremony/blob/2f0d3c65af0d467240a8b00be0924c2edebabbf4/LABELS.md#L63-L92).
dan-claude-bot commented 2026-07-23 10:46:25 +00:00 (Migrated from github.com)

Escalation — @danmt, three rulings. This is D7 of the epic above, raised under the escalation contract (LABELS.md): the question, the options, a recommendation, and the decider named. Nothing is blocked on you — #57 and #58 are ready and a builder can start either right now. R2 is the one worth reading first: a live PR in rig is waiting on it.

The label is missing, and that is a known gap, not an oversight. needs-ruling does not exist on this repo yet — the bootstrap dispatch is still the open item on #50's task list, and triage holds triage permission, so gh label create 404s and gh workflow run 403s for me. So this comment is the flag; I will apply the label the moment the dispatch runs. This is the second escalation to spend its life invisible to the board, which is the argument for running it.


R1 — Where may a builder build? (discussion #55, open question 1)

Today there is no rule; each box answers from its own duty script.

  • (a) Any heavy-duty/* repo, authorised by a ceremony-minted issue that names the target repo. The issue is the token — the pattern #13 and #16 already ran.
  • (b) Enumerate build targets explicitly in a registry file that you merge.

Recommendation: (a). The authorisation already exists per target, in a reviewable artifact with a spec attached; (b) copies it into a second place that can disagree with the first, and the copy is the thing that goes stale. What actually went wrong in incubator was not authority — it would have been granted in ten seconds — it was a whole build cycle spent against a dead namespace. An enumeration does not check for informedness; an issue that names the target does.

R2 — Is the reviewer bench fleet-wide, or per-repo? rig#112 is waiting on this

Not in the proposal — it surfaced while verifying it, and it is the sharper half of the kimi incident. ceremony's panel= is four bots; rig's is three — kimi is not on it. You requested kimi on rig#112 by hand at 01:24Z, which reads like you expect the bench to be the same everywhere. The machine disagrees: required verdicts are panel= minus the author, so kimi's verdict there is not required and never was.

  • (a) One fleet bench. Every governed repo's panel= carries the same four bot identities; the panel is that list minus the author. Applied as a one-line change per repo, at its next pin bump.
  • (b) Per-repo rosters stay authoritative (status quo). An off-roster request is legitimate but advisory — which is already exactly how the reconciler behaves, and what #57 writes down.
  • (c) Per-repo, with a floor: at least three, cross-vendor.

Recommendation: (a). CONTRIBUTING claims convergence "always means three cross-vendor approvals of the current head" — that claim is only true if the bench is the same everywhere. rig's three-name panel is a pre-conversion artifact, not a decision anyone made.

The consequence is immediate, which is why this is first: under (a), kimi's verdict becomes required on rig#112 and that PR is not converged — it is waiting on a reviewer that cannot see it until #57's wake condition reaches kimi's box. Under (b), rig#112 is converged right now on codex + grok (both approving head 3c72c1b, no blocker standing), and your kimi request is advisory. One word from you unsticks it either way.

R3 — Fork-PR workflow settings: org-wide, or per repo?

You ruled this for incubator on #16 — option (a), enable, with "send write tokens" and "send secrets" both off. The proposal asks to make that org-wide, and adds "require approval off".

  • (a) Org-wide now, all three toggles as ruled for incubator.
  • (b) Org-wide, but keep "require approval" ON until #58's runner guard is adopted in incubator — the only repo in the family with a self-hosted runner.
  • (c) Per repo, as today.

Recommendation: (b). Approval-off is safe because the other two are off and nothing pull_request-triggered touches the self-hosted runner — and that second half is currently a sentence in pr-checks.yml's header, kept true by whoever remembers it. #58 turns it into a gate. The cost of (b) is one approval click per fork PR in incubator until #58 lands and is adopted there; the cost of getting it wrong is unreviewed fork code executing on the tailnet runner. If you prefer (a), say so and it is done — the exposure is small and the org is six accounts — but it should be a decision, not a default.


Answer inline, in any order — no format required. I judge when agreement is reached, record each ruling as a decision in the epic's D-table, and return the epic to its flow in the same comment (D6/D7 of #50).

**Escalation — @danmt, three rulings.** This is D7 of the epic above, raised under the escalation contract ([LABELS.md](https://github.com/heavy-duty/ceremony/blob/2f0d3c65af0d467240a8b00be0924c2edebabbf4/LABELS.md#L63-L92)): the question, the options, a recommendation, and the decider named. Nothing is blocked on you — #57 and #58 are `ready` and a builder can start either right now. **R2 is the one worth reading first: a live PR in rig is waiting on it.** > **The label is missing, and that is a known gap, not an oversight.** `needs-ruling` does not exist on this repo yet — the bootstrap dispatch is still the open item on [#50's task list](https://github.com/heavy-duty/ceremony/issues/50), and triage holds `triage` permission, so `gh label create` 404s and `gh workflow run` 403s for me. So this comment is the flag; I will apply the label the moment the dispatch runs. This is the second escalation to spend its life invisible to the board, which is the argument for running it. --- ### R1 — Where may a builder build? (discussion #55, open question 1) Today there is no rule; each box answers from its own duty script. - **(a) Any `heavy-duty/*` repo, authorised by a ceremony-minted issue that names the target repo.** The issue is the token — the pattern #13 and #16 already ran. - **(b) Enumerate build targets explicitly in a registry file that you merge.** **Recommendation: (a).** The authorisation already exists per target, in a reviewable artifact with a spec attached; (b) copies it into a second place that can disagree with the first, and the copy is the thing that goes stale. What actually went wrong in incubator was not authority — it would have been granted in ten seconds — it was a whole build cycle spent against a dead namespace. An enumeration does not check for informedness; an issue that names the target does. ### R2 — Is the reviewer bench fleet-wide, or per-repo? ⏳ *rig#112 is waiting on this* Not in the proposal — it surfaced while verifying it, and it is the sharper half of the kimi incident. **ceremony's `panel=` is four bots; rig's is three — kimi is not on it.** You requested kimi on [rig#112](https://github.com/heavy-duty/rig/pull/112) by hand at 01:24Z, which reads like you expect the bench to be the same everywhere. The machine disagrees: required verdicts are `panel=` minus the author, so kimi's verdict there is not required and never was. - **(a) One fleet bench.** Every governed repo's `panel=` carries the same four bot identities; the panel is that list minus the author. Applied as a one-line change per repo, at its next pin bump. - **(b) Per-repo rosters stay authoritative** (status quo). An off-roster request is legitimate but advisory — which is already exactly how the reconciler behaves, and what #57 writes down. - **(c) Per-repo, with a floor**: at least three, cross-vendor. **Recommendation: (a).** [CONTRIBUTING](https://github.com/heavy-duty/ceremony/blob/2f0d3c65af0d467240a8b00be0924c2edebabbf4/CONTRIBUTING.md#L76-L84) claims convergence "always means three cross-vendor approvals of the current head" — that claim is only true if the bench is the same everywhere. rig's three-name panel is a pre-conversion artifact, not a decision anyone made. **The consequence is immediate, which is why this is first:** under (a), kimi's verdict becomes required on rig#112 and that PR is **not** converged — it is waiting on a reviewer that cannot see it until #57's wake condition reaches kimi's box. Under (b), rig#112 **is** converged right now on codex + grok (both approving head `3c72c1b`, no blocker standing), and your kimi request is advisory. One word from you unsticks it either way. ### R3 — Fork-PR workflow settings: org-wide, or per repo? You ruled this for incubator on [#16](https://github.com/heavy-duty/ceremony/issues/16#issuecomment-5056705884) — option (a), enable, with "send write tokens" and "send secrets" both off. The proposal asks to make that org-wide, and adds "require approval **off**". - **(a) Org-wide now**, all three toggles as ruled for incubator. - **(b) Org-wide, but keep "require approval" ON** until #58's runner guard is adopted in incubator — the only repo in the family with a self-hosted runner. - **(c) Per repo, as today.** **Recommendation: (b).** Approval-off is safe *because* the other two are off and nothing `pull_request`-triggered touches the self-hosted runner — and that second half is currently a sentence in `pr-checks.yml`'s header, kept true by whoever remembers it. #58 turns it into a gate. The cost of (b) is one approval click per fork PR in incubator until #58 lands and is adopted there; the cost of getting it wrong is unreviewed fork code executing on the tailnet runner. If you prefer (a), say so and it is done — the exposure is small and the org is six accounts — but it should be a decision, not a default. --- Answer inline, in any order — no format required. I judge when agreement is reached, record each ruling as a decision in the epic's D-table, and return the epic to its flow in the same comment (D6/D7 of #50).
dan-claude-bot commented 2026-07-23 12:03:28 +00:00 (Migrated from github.com)

Triage: needs-ruling is now on this epic — the flag, not a new question.

D7's escalation to @danmt has been live and unruled since 10:46Z: three questions (the build-scope boundary, roster uniformity, org-wide fork-PR settings), each with options and a recommendation. It carried the full D4 contract from the moment it was posted; what it did not carry was the label, because needs-ruling did not exist on this repo until the bootstrap dispatch ran at 11:48Z. That gap was tracked on #50's task list, and applying the flag here the moment the dispatch landed was the item's stated consequence.

So: nothing new is being asked, and the ball has not moved — it was already yours. The board now says so, which is the whole point of the label (LABELS.md). Per D5/D6 it stays up until agreement is reached, not until you reply, and triage — as the setter — closes it out: the ruling recorded here as a decision in one comment, the label removed, the epic returned to flow, all in that same comment.

Nothing is blocked on it. Both children are in flight (#57 landed in #62; #58 is claimed with #60 open), and D6 keeps FLEET.yml unminted independent of the ruling. What the rulings gate is whether the registry ever becomes load-bearing, and whether the bench roster is uniform across governed repos.

**Triage: `needs-ruling` is now on this epic** — the flag, not a new question. D7's escalation to @danmt has been live and unruled since [10:46Z](https://github.com/heavy-duty/ceremony/issues/56#issuecomment-5057506832): three questions (the build-scope boundary, roster uniformity, org-wide fork-PR settings), each with options and a recommendation. It carried the full D4 contract from the moment it was posted; what it did not carry was the label, because `needs-ruling` did not exist on this repo until the bootstrap dispatch [ran at 11:48Z](https://github.com/heavy-duty/ceremony/actions/runs/30004512442). That gap was tracked on #50's task list, and applying the flag here the moment the dispatch landed was the item's stated consequence. So: nothing new is being asked, and the ball has not moved — it was already yours. The board now says so, which is the whole point of the label ([LABELS.md](https://github.com/heavy-duty/ceremony/blob/2f0d3c65af0d467240a8b00be0924c2edebabbf4/LABELS.md#L63-L92)). Per D5/D6 it stays up until agreement is *reached*, not until you reply, and triage — as the setter — closes it out: the ruling recorded here as a decision in one comment, the label removed, the epic returned to flow, all in that same comment. Nothing is blocked on it. Both children are in flight (#57 landed in #62; #58 is claimed with #60 open), and D6 keeps `FLEET.yml` unminted independent of the ruling. What the rulings gate is whether the registry ever becomes load-bearing, and whether the bench roster is uniform across governed repos.
github-actions[bot] commented 2026-07-23 12:24:46 +00:00 (Migrated from github.com)

Every issue referenced by this epic's task list is closed. Please close the epic or extend its task list.

<!-- issueflow:epic-complete --> Every issue referenced by this epic's task list is closed. Please close the epic or extend its task list.
dan-claude-bot commented 2026-07-23 12:35:03 +00:00 (Migrated from github.com)

Triage: nudge answered — the epic is extended, not complete.

The sweep was right that every issue on the task list had closed. #58 landed in #60 at 12:24Z, joining #57; both definition-of-done items they owned are now checked with their evidence.

Two new children take their place, accepted from discussion 67:

  • #68offsite: the label, the doctrine, the claim-reclaim exemption. blocked by #52.
  • #69 — the stale-flag nudge. blocked by #68.

They belong here rather than under #50 because they finish what #57 started: #57 gave cross-repo work its human-readable linkage, and the sweep still cannot read it. #13 and #16 are both claimed with no local PR by construction right now, and only today's comment traffic is keeping them off the reclaim clock.

Three decisions recorded in the D-table above, D8–D10 — the label is exempt on trust alone, verification only ever nudges, and the epic-completion nudge has no interaction with offsite to build.

needs-ruling stays up. D7's three questions (10:46Z) are still unanswered, and the flag clears on agreement, not on activity elsewhere. @danmt — R2 is the one with a queue behind it.

**Triage: nudge answered — the epic is extended, not complete.** The sweep was right that every issue on the task list had closed. #58 landed in #60 at 12:24Z, joining #57; both definition-of-done items they owned are now checked with their evidence. Two new children take their place, accepted from [discussion 67](https://github.com/heavy-duty/ceremony/discussions/67): - **#68** — `offsite`: the label, the doctrine, the claim-reclaim exemption. `blocked` by #52. - **#69** — the stale-flag nudge. `blocked` by #68. They belong here rather than under #50 because they finish what #57 started: #57 gave cross-repo work its human-readable linkage, and the sweep still cannot read it. #13 and #16 are both claimed with no local PR *by construction* right now, and only today's comment traffic is keeping them off the reclaim clock. Three decisions recorded in the D-table above, D8–D10 — the label is exempt on trust alone, verification only ever nudges, and the epic-completion nudge has no interaction with `offsite` to build. `needs-ruling` **stays up.** D7's three questions ([10:46Z](https://github.com/heavy-duty/ceremony/issues/56#issuecomment-5057506832)) are still unanswered, and the flag clears on agreement, not on activity elsewhere. @danmt — R2 is the one with a queue behind it.
dan-claude-bot commented 2026-07-23 13:05:22 +00:00 (Migrated from github.com)

Triage, epic hygiene — the task list's #68 line was stale, no scope change.

It still read "blocked by #52". #52 landed at 12:41Z in #64 (dfcfd45) — the rewrite of the same call site — so the sweep cleared #68 to ready that minute and @codex-bot-andresmgsl claimed it at 12:46Z; PR #70 is open and in review. The line now says that.

#69 stays blocked — verified, not assumed: its blocker is #68, which is open. The D7 escalation to @danmt from 10:46Z is still unruled, so needs-ruling stays up on this epic.

Triage, epic hygiene — the task list's #68 line was stale, no scope change. It still read *"`blocked` by #52"*. #52 landed at 12:41Z in #64 (`dfcfd45`) — the rewrite of the same call site — so the sweep cleared #68 to `ready` that minute and @codex-bot-andresmgsl claimed it at 12:46Z; PR #70 is open and in review. The line now says that. #69 stays `blocked` — verified, not assumed: its blocker is #68, which is open. The D7 escalation to @danmt from 10:46Z is still unruled, so `needs-ruling` stays up on this epic.
dan-claude-bot commented 2026-07-23 14:04:11 +00:00 (Migrated from github.com)

Triage, epic hygiene — both offsite children have landed; one operator action now blocks the flag from working on this board.

Checked against main and the live board, not off the PR bodies.

  • #68 merged 13:07Z in #70 (e9928f1). claim_clock_exempt pauses only the reclaim clock — missing assignees, queue conflicts, epic completion and the PR side are untouched, pinned by "an unassigned offsite claim is still flagged", "offsite alone still needs triage" and "no reconciler mutation names offsite (#68 D4)".
  • #69 merged 13:43Z in #71 (553409c). The nudge fires only when every cross-referenced PR the sweep can see is closed; an open or unreadable one keeps it quiet, and it never clears the flag or touches the claim.

Both task-list lines and the fourth definition-of-done item are checked with that evidence.

@danmt — one dispatch is owed, and it is the same one #50 needed. The offsite row is in the taxonomy on main (labels-reconcile.sh L394) but the label does not exist on heavy-duty/ceremony — the bootstrap only writes labels on manual dispatch, and nothing has dispatched since #70 merged. I cannot create it: POST /repos/heavy-duty/ceremony/labels 404s at triage permission (attempted today).

The cost of waiting is concrete. Three claims are offsite right now — #14 (box#164), #15 (cast#143), #16 (incubator#25) — and none can carry the flag, so all three sit on the ordinary 48-hour reclaim clock with no local PR to save them. Every one is active today, so nothing is at risk this minute; a quiet night is what would cost a builder their claim. This is not a ruling and it does not touch D7 — it is a button.

D7 stays unruled and needs-ruling stays up, unchanged since 10:46Z.

**Triage, epic hygiene — both `offsite` children have landed; one operator action now blocks the flag from working on this board.** Checked against `main` and the live board, not off the PR bodies. - **#68** merged 13:07Z in #70 (`e9928f1`). `claim_clock_exempt` pauses only the reclaim clock — missing assignees, queue conflicts, epic completion and the PR side are untouched, pinned by *"an unassigned offsite claim is still flagged"*, *"offsite alone still needs triage"* and *"no reconciler mutation names offsite (#68 D4)"*. - **#69** merged 13:43Z in #71 (`553409c`). The nudge fires only when every cross-referenced PR the sweep can see is closed; an open or unreadable one keeps it quiet, and it never clears the flag or touches the claim. Both task-list lines and the fourth definition-of-done item are checked with that evidence. **@danmt — one dispatch is owed, and it is the same one #50 needed.** The `offsite` row is in the taxonomy on `main` ([`labels-reconcile.sh` L394](https://github.com/heavy-duty/ceremony/blob/553409c/actions/labels-reconcile/labels-reconcile.sh#L394)) but the label does not exist on heavy-duty/ceremony — the bootstrap only writes labels on manual dispatch, and nothing has dispatched since #70 merged. I cannot create it: `POST /repos/heavy-duty/ceremony/labels` 404s at `triage` permission (attempted today). The cost of waiting is concrete. Three claims are offsite right now — #14 ([box#164](https://github.com/heavy-duty/box/pull/164)), #15 ([cast#143](https://github.com/heavy-duty/cast/pull/143)), #16 ([incubator#25](https://github.com/heavy-duty/incubator/pull/25)) — and none can carry the flag, so all three sit on the ordinary 48-hour reclaim clock with no local PR to save them. Every one is active today, so nothing is at risk this minute; a quiet night is what would cost a builder their claim. This is not a ruling and it does not touch D7 — it is a button. D7 stays unruled and `needs-ruling` stays up, unchanged since [10:46Z](https://github.com/heavy-duty/ceremony/issues/56#issuecomment-5057506832).
danmt commented 2026-07-23 14:11:43 +00:00 (Migrated from github.com)

what needs ruling? whats the choice?

what needs ruling? whats the choice?
dan-claude-bot commented 2026-07-23 14:18:34 +00:00 (Migrated from github.com)

Closing from the sherpa session at @danmt's request, who asked for the
ceremony-side gap check and this write-up. Verified against the tree and the
API, not read off the epic.

Closing: ceremony's half of this epic is done. What remains is not ceremony's
to answer, and it moves to the crew repo @danmt is standing up.

And answering the question directly, @danmt — what needs ruling, what's the
choice?
Two of the three no longer need you at all.

What landed

D1–D4 the two discovery guards #57 (5e283ec) — BUILDER.md's panel + linkage rules, REVIEWER.md's "a request is authorisation, not membership", FLEET.md's request-before-poll ordering
D5 the runner hole #58 (#60, merged 12:24Z) — actions/runner-isolated, proven red on a scratch runs-on: self-hosted fixture, and ceremony runs it on itself
D8–D10 the cross-repo claim exemption #68 (#70) and #69 (#71) — offsite in the taxonomy, the staleness skip at issueflow-reconcile.sh L109, and the trust-first verify pass at L195–316 that nudges once when every referenced PR has closed and never clears the flag itself

The offsite label is now live on this board — @danmt dispatched the labels
workflow at ~14:15Z, and it exists as offsite | CFD3D7 | Issue deliverable is a PR in another repository — claim clock paused. That was the last open task
here. The three live cross-repo claims — #14 (box#164),
#15 (cast#143), #16
(incubator#25, merged) —
still need the label applied; that is a reconciler tick, not work, and it is
triage's.

Nothing is missing from ceremony's side. No follow-up issue filed. The gap
check was the point of this pass and it came back clean: the exemption is real
in the code, not just declared in a table.

The three rulings, as they stand now

R2 — bench fleet-wide or per-repo? Overtaken by events. Its forcing case was
rig#112 waiting on kimi. Kimi approved at 10:42:29Z once the request trigger
reached its box, and @danmt merged at 11:58:33Z with all three verdicts in. The
PR converged under either answer, so nothing is stuck. The general question
survives — is panel= uniform across governed repos — but it is now a fleet
question with no live casualty, which is exactly the kind that belongs in crew
alongside the roster it describes.

R3 — fork-PR settings. Its precondition landed. The recommendation was (b),
keep require approval ON until #58's guard exists, because "nothing
pull_request-triggered touches the self-hosted runner" was a sentence in a
header rather than a gate. #58 merged at 12:24Z and is that gate. So (a) —
org-wide, write tokens off, secrets off, approval off — now costs what (b) was
protecting against, which is nothing. Both repos in question are flipped
already; canonical turned out never to have been off. This needs recording, not
deciding.

R1 — where may a builder build? Genuinely open, and better answered in crew.
The choice is unchanged: (a) any heavy-duty/* repo authorised by an issue that
names the target, or (b) an enumerated registry. Triage recommended (a) and I
agree — an enumeration is a copy of the authorisation that can disagree with it.
But R1 and D6 (FLEET.yml, deliberately not minted because "today it'd have
one real row and no reader") are the same question wearing two hats, and crew
gives both an answer: it is the roster, and the duty loops that would read
FLEET.yml live in it.

There is a second reason to move rather than force it. R1 and R2 are questions
about how the fleet works, and the fleet's actual behaviour currently exists as
five untracked ~/duty directories on five disposable boxes that nobody has
compared. Ruling now means ruling with less information than a week from now,
when those are in git and readable side by side.

Handoff to crew

Carried over, and nothing else: R1 (build boundary), R2 (bench
uniformity), D6 (FLEET.yml — the registry, its readers, its schema).
needs-ruling comes off this epic with this comment: the flag marked a decision
blocking this board, and this board is no longer where the decision lives.

What ceremony keeps is what passes the test crew's split is drawn on — could a
team with no agents adopt this?
The release workflow, the guard family
including runner-isolated, labels-reconcile and its taxonomy, the doctrine
in LABELS.md and CONTRIBUTING: yes. The roster, the wake conditions, the duty
loops: no, and those go.

> Closing from the sherpa session at @danmt's request, who asked for the > ceremony-side gap check and this write-up. Verified against the tree and the > API, not read off the epic. **Closing: ceremony's half of this epic is done. What remains is not ceremony's to answer, and it moves to the `crew` repo @danmt is standing up.** And answering the question directly, @danmt — *what needs ruling, what's the choice?* Two of the three no longer need you at all. ## What landed | | | |---|---| | **D1–D4** the two discovery guards | **#57** (`5e283ec`) — BUILDER.md's panel + linkage rules, REVIEWER.md's "a request is authorisation, not membership", FLEET.md's request-before-poll ordering | | **D5** the runner hole | **#58** (#60, merged 12:24Z) — `actions/runner-isolated`, proven red on a scratch `runs-on: self-hosted` fixture, and ceremony runs it on itself | | **D8–D10** the cross-repo claim exemption | **#68** (#70) and **#69** (#71) — `offsite` in the taxonomy, the staleness skip at `issueflow-reconcile.sh` L109, and the trust-first verify pass at L195–316 that nudges once when every referenced PR has closed and never clears the flag itself | **The `offsite` label is now live on this board** — @danmt dispatched the labels workflow at ~14:15Z, and it exists as `offsite | CFD3D7 | Issue deliverable is a PR in another repository — claim clock paused`. That was the last open task here. The three live cross-repo claims — #14 ([box#164](https://github.com/heavy-duty/box/pull/164)), #15 ([cast#143](https://github.com/heavy-duty/cast/pull/143)), #16 ([incubator#25](https://github.com/heavy-duty/incubator/pull/25), merged) — still need the label *applied*; that is a reconciler tick, not work, and it is triage's. **Nothing is missing from ceremony's side. No follow-up issue filed.** The gap check was the point of this pass and it came back clean: the exemption is real in the code, not just declared in a table. ## The three rulings, as they stand now **R2 — bench fleet-wide or per-repo? Overtaken by events.** Its forcing case was rig#112 waiting on kimi. Kimi approved at 10:42:29Z once the request trigger reached its box, and @danmt merged at 11:58:33Z with all three verdicts in. The PR converged under either answer, so nothing is stuck. The *general* question survives — is `panel=` uniform across governed repos — but it is now a fleet question with no live casualty, which is exactly the kind that belongs in crew alongside the roster it describes. **R3 — fork-PR settings. Its precondition landed.** The recommendation was (b), keep *require approval* ON until #58's guard exists, because "nothing `pull_request`-triggered touches the self-hosted runner" was a sentence in a header rather than a gate. #58 merged at 12:24Z and is that gate. So (a) — org-wide, write tokens off, secrets off, approval off — now costs what (b) was protecting against, which is nothing. Both repos in question are flipped already; canonical turned out never to have been off. This needs recording, not deciding. **R1 — where may a builder build? Genuinely open, and better answered in crew.** The choice is unchanged: (a) any `heavy-duty/*` repo authorised by an issue that names the target, or (b) an enumerated registry. Triage recommended (a) and I agree — an enumeration is a copy of the authorisation that can disagree with it. But R1 and **D6** (`FLEET.yml`, deliberately not minted because "today it'd have one real row and no reader") are the same question wearing two hats, and crew gives both an answer: it *is* the roster, and the duty loops that would read FLEET.yml live in it. There is a second reason to move rather than force it. R1 and R2 are questions about how the fleet works, and the fleet's actual behaviour currently exists as five untracked `~/duty` directories on five disposable boxes that nobody has compared. Ruling now means ruling with less information than a week from now, when those are in git and readable side by side. ## Handoff to crew Carried over, and nothing else: **R1** (build boundary), **R2** (bench uniformity), **D6** (`FLEET.yml` — the registry, its readers, its schema). `needs-ruling` comes off this epic with this comment: the flag marked a decision blocking *this* board, and this board is no longer where the decision lives. What ceremony keeps is what passes the test crew's split is drawn on — *could a team with no agents adopt this?* The release workflow, the guard family including `runner-isolated`, `labels-reconcile` and its taxonomy, the doctrine in LABELS.md and CONTRIBUTING: yes. The roster, the wake conditions, the duty loops: no, and those go.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: heavy-duty/ceremony#56
No description provided.