docs(drills): the standing runner-probe venue, and why it is not a drill (#202)
@andres ruled option A (#5631): one standing never-archived repo. This is the
runbook half.
The distinction the document exists to make: a drill is disposable by design
and ends with the builder archiving it. This venue is the opposite — it exists
so that runner-only facts can be measured on demand, and archiving it defeats
the purpose. That is not hypothetical: all three drill repos were archived
correctly, by the rule, and each then had to be un-archived or replaced. The
request came three times in two days across #192 and #198 and never became
anything.
What the runbook pins, all of it measured rather than asserted:
* a probe MUST run as an Actions job under ${{ github.token }} — the same
DELETE answers 500 there and 204 under a PAT, so a probe run any other way
produces a confident wrong answer;
* probe results are written into the forge, not left in a job log, because
logs age out and #192's run 701 survived only because it wrote into an
issue;
* no probe touches ceremony's own board — the venue exists so the live board
is not the fixture;
* the three probes it already owes (#192's live label lift, #205's dispatch
measurement, a 0.6.0 consumer exercise after #198).
STANDING THE REPO UP IS THE OPERATOR'S STEP, and this is the part I could not
do rather than the part I chose not to. Measured today with this identity:
POST /api/v1/orgs/heavy-duty/repos -> 403 not allowed in organization
POST /api/v1/user/repos -> 201 personal namespace only
Same shape as the drill delete: a deliberate boundary, not a misconfiguration.
The runbook says so, says not to retry it, and says not to work around it by
using a personal namespace where the org's runner and secrets do not reach.
test/run.sh 22/22, shellcheck 0.10.0, actionlint, self-ref all clean.
Refs #202
2026-08-05 13:16:20 +00:00
|
|
|
### Added
|
|
|
|
|
|
docs(runner-probes): its own document, an arming procedure, and the evidence boundary made consistent (#202)
@codex-reviewer-andresmgsl's four gaps.
1. BRANCH UPDATED TO CURRENT MAIN. The commit's parent was pre-#204 dad99dd, so
its green 22-file run did not contain the six test files and rules that
landed with the sync. Merged main in — no rewrite — and re-verified against
the 28-file suite the operator would actually receive.
2. WHO MAY RESET IT is now a section, and it says operator-owned until ruled
otherwise, with content reset separated from archive/delete/admin. The
access policy is set when the repo is created, which is the operator's step,
so the two belong together. Flagged for @andres rather than assumed.
3. AN EXECUTABLE ARMING PROCEDURE replaces "install whatever the probe needs":
fork ref and canonical SHA, caller stubs pinned to it, BOTH
CEREMONY_SELF_REF carriers rewritten, the event invoked recorded by name,
and what reset removes afterwards. It reuses the drill rehearsal's fork-ref
pattern rather than inventing a floating pin, including its rule against
ever creating a tag-shaped branch on heavy-duty/ceremony.
4. THE EVIDENCE CONTRADICTION IS RESOLVED. "Write results into an issue in this
repo" and "no probe touches ceremony's board" could not both be followed in
a file where "this repo" reads as ceremony. The job now writes raw results
into the PROBE repo, and a human carries the issue URL and run number to the
ceremony issue. The probe workflow holds no credential and no code path that
can write to ceremony, which is what makes the two rules compatible.
Placement: the operational contract moves to docs/RUNNER-PROBES.md, with a
short cross-link in drills/README.md beside the disposal rule it excepts — the
exception stays visible where the dangerous habit lives, and neither document
grows a second top-level heading.
test/run.sh 28/28 on the updated branch; shellcheck 0.10.0, actionlint,
self-ref, marker, vendored and changelog-armed clean.
Refs #202
2026-08-05 13:40:28 +00:00
|
|
|
- `docs/RUNNER-PROBES.md` documents the standing runner-probe venue,
|
docs(drills): the standing runner-probe venue, and why it is not a drill (#202)
@andres ruled option A (#5631): one standing never-archived repo. This is the
runbook half.
The distinction the document exists to make: a drill is disposable by design
and ends with the builder archiving it. This venue is the opposite — it exists
so that runner-only facts can be measured on demand, and archiving it defeats
the purpose. That is not hypothetical: all three drill repos were archived
correctly, by the rule, and each then had to be un-archived or replaced. The
request came three times in two days across #192 and #198 and never became
anything.
What the runbook pins, all of it measured rather than asserted:
* a probe MUST run as an Actions job under ${{ github.token }} — the same
DELETE answers 500 there and 204 under a PAT, so a probe run any other way
produces a confident wrong answer;
* probe results are written into the forge, not left in a job log, because
logs age out and #192's run 701 survived only because it wrote into an
issue;
* no probe touches ceremony's own board — the venue exists so the live board
is not the fixture;
* the three probes it already owes (#192's live label lift, #205's dispatch
measurement, a 0.6.0 consumer exercise after #198).
STANDING THE REPO UP IS THE OPERATOR'S STEP, and this is the part I could not
do rather than the part I chose not to. Measured today with this identity:
POST /api/v1/orgs/heavy-duty/repos -> 403 not allowed in organization
POST /api/v1/user/repos -> 201 personal namespace only
Same shape as the drill delete: a deliberate boundary, not a misconfiguration.
The runbook says so, says not to retry it, and says not to work around it by
using a personal namespace where the org's runner and secrets do not reach.
test/run.sh 22/22, shellcheck 0.10.0, actionlint, self-ref all clean.
Refs #202
2026-08-05 13:16:20 +00:00
|
|
|
`heavy-duty/ceremony-runner-probe` — the place runner-only facts are measured
|
|
|
|
|
on demand, ruled as option A by the operator (#202).
|
|
|
|
|
|
docs(runner-probes): its own document, an arming procedure, and the evidence boundary made consistent (#202)
@codex-reviewer-andresmgsl's four gaps.
1. BRANCH UPDATED TO CURRENT MAIN. The commit's parent was pre-#204 dad99dd, so
its green 22-file run did not contain the six test files and rules that
landed with the sync. Merged main in — no rewrite — and re-verified against
the 28-file suite the operator would actually receive.
2. WHO MAY RESET IT is now a section, and it says operator-owned until ruled
otherwise, with content reset separated from archive/delete/admin. The
access policy is set when the repo is created, which is the operator's step,
so the two belong together. Flagged for @andres rather than assumed.
3. AN EXECUTABLE ARMING PROCEDURE replaces "install whatever the probe needs":
fork ref and canonical SHA, caller stubs pinned to it, BOTH
CEREMONY_SELF_REF carriers rewritten, the event invoked recorded by name,
and what reset removes afterwards. It reuses the drill rehearsal's fork-ref
pattern rather than inventing a floating pin, including its rule against
ever creating a tag-shaped branch on heavy-duty/ceremony.
4. THE EVIDENCE CONTRADICTION IS RESOLVED. "Write results into an issue in this
repo" and "no probe touches ceremony's board" could not both be followed in
a file where "this repo" reads as ceremony. The job now writes raw results
into the PROBE repo, and a human carries the issue URL and run number to the
ceremony issue. The probe workflow holds no credential and no code path that
can write to ceremony, which is what makes the two rules compatible.
Placement: the operational contract moves to docs/RUNNER-PROBES.md, with a
short cross-link in drills/README.md beside the disposal rule it excepts — the
exception stays visible where the dangerous habit lives, and neither document
grows a second top-level heading.
test/run.sh 28/28 on the updated branch; shellcheck 0.10.0, actionlint,
self-ref, marker, vendored and changelog-armed clean.
Refs #202
2026-08-05 13:40:28 +00:00
|
|
|
- `drills/README.md` cross-links it beside the disposal rule, so the exception
|
|
|
|
|
is visible where the dangerous habit lives (#202).
|
|
|
|
|
|
docs(drills): the standing runner-probe venue, and why it is not a drill (#202)
@andres ruled option A (#5631): one standing never-archived repo. This is the
runbook half.
The distinction the document exists to make: a drill is disposable by design
and ends with the builder archiving it. This venue is the opposite — it exists
so that runner-only facts can be measured on demand, and archiving it defeats
the purpose. That is not hypothetical: all three drill repos were archived
correctly, by the rule, and each then had to be un-archived or replaced. The
request came three times in two days across #192 and #198 and never became
anything.
What the runbook pins, all of it measured rather than asserted:
* a probe MUST run as an Actions job under ${{ github.token }} — the same
DELETE answers 500 there and 204 under a PAT, so a probe run any other way
produces a confident wrong answer;
* probe results are written into the forge, not left in a job log, because
logs age out and #192's run 701 survived only because it wrote into an
issue;
* no probe touches ceremony's own board — the venue exists so the live board
is not the fixture;
* the three probes it already owes (#192's live label lift, #205's dispatch
measurement, a 0.6.0 consumer exercise after #198).
STANDING THE REPO UP IS THE OPERATOR'S STEP, and this is the part I could not
do rather than the part I chose not to. Measured today with this identity:
POST /api/v1/orgs/heavy-duty/repos -> 403 not allowed in organization
POST /api/v1/user/repos -> 201 personal namespace only
Same shape as the drill delete: a deliberate boundary, not a misconfiguration.
The runbook says so, says not to retry it, and says not to work around it by
using a personal namespace where the org's runner and secrets do not reach.
test/run.sh 22/22, shellcheck 0.10.0, actionlint, self-ref all clean.
Refs #202
2026-08-05 13:16:20 +00:00
|
|
|
- The runbook states that the drill disposal rule does **not** apply to it.
|
|
|
|
|
Archiving it defeats its purpose, and that is exactly how the three existing
|
|
|
|
|
drill repos each became unavailable (#202).
|
|
|
|
|
|
|
|
|
|
- It records that a probe must run as an Actions job under the workflow token:
|
|
|
|
|
the same call answers 500 there and 204 under a PAT, so a probe run any other
|
|
|
|
|
way produces a confident wrong answer (#202).
|
|
|
|
|
|
|
|
|
|
- Creating the repo is recorded as the operator's step, measured rather than
|
|
|
|
|
assumed: a fleet identity gets 403 on org repo creation and 201 in its own
|
|
|
|
|
namespace (#202).
|
docs(runner-probes): its own document, an arming procedure, and the evidence boundary made consistent (#202)
@codex-reviewer-andresmgsl's four gaps.
1. BRANCH UPDATED TO CURRENT MAIN. The commit's parent was pre-#204 dad99dd, so
its green 22-file run did not contain the six test files and rules that
landed with the sync. Merged main in — no rewrite — and re-verified against
the 28-file suite the operator would actually receive.
2. WHO MAY RESET IT is now a section, and it says operator-owned until ruled
otherwise, with content reset separated from archive/delete/admin. The
access policy is set when the repo is created, which is the operator's step,
so the two belong together. Flagged for @andres rather than assumed.
3. AN EXECUTABLE ARMING PROCEDURE replaces "install whatever the probe needs":
fork ref and canonical SHA, caller stubs pinned to it, BOTH
CEREMONY_SELF_REF carriers rewritten, the event invoked recorded by name,
and what reset removes afterwards. It reuses the drill rehearsal's fork-ref
pattern rather than inventing a floating pin, including its rule against
ever creating a tag-shaped branch on heavy-duty/ceremony.
4. THE EVIDENCE CONTRADICTION IS RESOLVED. "Write results into an issue in this
repo" and "no probe touches ceremony's board" could not both be followed in
a file where "this repo" reads as ceremony. The job now writes raw results
into the PROBE repo, and a human carries the issue URL and run number to the
ceremony issue. The probe workflow holds no credential and no code path that
can write to ceremony, which is what makes the two rules compatible.
Placement: the operational contract moves to docs/RUNNER-PROBES.md, with a
short cross-link in drills/README.md beside the disposal rule it excepts — the
exception stays visible where the dangerous habit lives, and neither document
grows a second top-level heading.
test/run.sh 28/28 on the updated branch; shellcheck 0.10.0, actionlint,
self-ref, marker, vendored and changelog-armed clean.
Refs #202
2026-08-05 13:40:28 +00:00
|
|
|
|
docs(runner-probes): arming is two layers, because a commit cannot contain its own SHA (#202)
@codex-reviewer-andresmgsl found that the procedure was not executable as
written, and the reason is structural rather than a wording slip.
The candidate's workflows carry `repository: heavy-duty/ceremony` beside
`ref: ${{ env.CEREMONY_SELF_REF }}`, so arming must rewrite them. But
rewriting CREATES A NEW COMMIT, and a commit cannot embed its own object ID. So
a single-layer arming is self-referential: pin the callers to the pre-rewrite
SHA and they load the UNARMED workflows; pin them to the post-rewrite SHA and
you are asking that commit to contain itself. My step 3 asked for exactly that.
Two layers, stated as a table because the distinction is the whole thing:
candidate code SHA the immutable tree under test — actions/, lib/
armed workflow SHA a child commit whose workflows point at the fork and
whose CEREMONY_SELF_REF is the candidate code SHA
And callers pin by layer, because they are not the same thing: composite
actions to the candidate code SHA, reusable workflows to the armed SHA, which
is the only revision whose inner checkout is rewritten.
The completeness check becomes a mechanical non-zero gate — `git grep` for
executable `uses:`/`repository:` carriers over the ARMED tree, exiting non-zero
on any hit — rather than "every remaining hit must be prose". A partial rewrite
does not announce itself: it silently tests canonical main.
The result issue records both SHAs, not one, or a later reader cannot tell
which tree answered.
test/run.sh 28/28; shellcheck 0.10.0 and changelog-armed clean.
Refs #202
2026-08-05 13:54:44 +00:00
|
|
|
- It carries an executable two-layer arming procedure: an immutable candidate
|
|
|
|
|
code SHA and an armed workflow commit on top of it. A single layer is
|
|
|
|
|
self-referential — rewriting a workflow makes a new commit, and a commit
|
|
|
|
|
cannot contain its own object ID (#202).
|
|
|
|
|
|
|
|
|
|
- Callers are pinned by layer: composite actions to the candidate code SHA,
|
|
|
|
|
reusable workflows to the armed SHA, which is the only revision whose inner
|
|
|
|
|
checkout points at the fork (#202).
|
|
|
|
|
|
docs(runner-probes): the arming gate asserts what each carrier IS, not that a literal is gone (#202)
@codex-reviewer-andresmgsl: absence of the canonical coordinate is not proof of
correct arming. The negative grep stays green if CEREMONY_SELF_REF names a tag,
the ARMED sha, or any other commit; if a carrier was rewritten to the wrong
fork; if an executable carrier lives outside .github; or if a carrier simply
disappeared rather than being rewritten.
So the gate is positive now: every `repository:` must equal the recorded fork,
both CEREMONY_SELF_REF values must equal the CANDIDATE CODE sha (not the armed
one — that is the self-reference this two-layer shape exists to avoid), and
callers must match their layer: reusable workflows the armed sha, composite
actions the code sha.
With a COUNT beside the comparison. `n -eq 2` is the part that catches a
carrier which vanished, which a per-value loop cannot see — the same shape as
counting the call sites a pin is guarding rather than only checking the ones
that are there.
The canonical-coordinate grep stays as a cheap extra rather than as the proof.
Wording, same review: steps 1 and 2 advance the tip of ONE fork branch, so
reset removes that branch, not "candidate and armed branches".
test/run.sh 28/28; shellcheck 0.10.0 and changelog-armed clean.
Refs #202
2026-08-05 14:02:08 +00:00
|
|
|
- The arming gate asserts what each carrier IS, not only that the old literal
|
|
|
|
|
is gone: every `repository:` equals the fork, both `CEREMONY_SELF_REF` values
|
|
|
|
|
equal the candidate code SHA, and callers match the layer they belong to
|
|
|
|
|
(#202).
|
|
|
|
|
|
|
|
|
|
- It counts the `CEREMONY_SELF_REF` carriers as well as comparing them, which
|
|
|
|
|
is what catches one that vanished rather than being rewritten (#202).
|
docs(runner-probes): its own document, an arming procedure, and the evidence boundary made consistent (#202)
@codex-reviewer-andresmgsl's four gaps.
1. BRANCH UPDATED TO CURRENT MAIN. The commit's parent was pre-#204 dad99dd, so
its green 22-file run did not contain the six test files and rules that
landed with the sync. Merged main in — no rewrite — and re-verified against
the 28-file suite the operator would actually receive.
2. WHO MAY RESET IT is now a section, and it says operator-owned until ruled
otherwise, with content reset separated from archive/delete/admin. The
access policy is set when the repo is created, which is the operator's step,
so the two belong together. Flagged for @andres rather than assumed.
3. AN EXECUTABLE ARMING PROCEDURE replaces "install whatever the probe needs":
fork ref and canonical SHA, caller stubs pinned to it, BOTH
CEREMONY_SELF_REF carriers rewritten, the event invoked recorded by name,
and what reset removes afterwards. It reuses the drill rehearsal's fork-ref
pattern rather than inventing a floating pin, including its rule against
ever creating a tag-shaped branch on heavy-duty/ceremony.
4. THE EVIDENCE CONTRADICTION IS RESOLVED. "Write results into an issue in this
repo" and "no probe touches ceremony's board" could not both be followed in
a file where "this repo" reads as ceremony. The job now writes raw results
into the PROBE repo, and a human carries the issue URL and run number to the
ceremony issue. The probe workflow holds no credential and no code path that
can write to ceremony, which is what makes the two rules compatible.
Placement: the operational contract moves to docs/RUNNER-PROBES.md, with a
short cross-link in drills/README.md beside the disposal rule it excepts — the
exception stays visible where the dangerous habit lives, and neither document
grows a second top-level heading.
test/run.sh 28/28 on the updated branch; shellcheck 0.10.0, actionlint,
self-ref, marker, vendored and changelog-armed clean.
Refs #202
2026-08-05 13:40:28 +00:00
|
|
|
|
|
|
|
|
- Probe results are written to an issue in the probe repo and carried to the
|
|
|
|
|
ceremony issue by a human, so the probe holds no path that can write to the
|
|
|
|
|
live board (#202).
|