@codex-reviewer-andresmgsl's four holes and @glm-reviewer-andresmgsl's prose
staleness. Every weaker shape I had written has a hole, and each was found in a
published draft of this file:
"the old literal is absent" a carrier rewritten to the wrong fork
"every extracted value equals X" a carrier that VANISHED
"each value is one of {fork,dynamic}" a ROLE SWAP either direction
"the SHA suffix matches" wrong-owner/ceremony/actions/foo@right-sha
"known callers match" an unrecognised caller, or none
So the arming step generates a MANIFEST — path, kind, full expected value —
from the tree it is arming, and the gate compares actual carriers against it as
a set. All six become one kind of failure: the sets differ. Generated rather
than written into this document, because the carrier set changes whenever a
workflow is added — which is exactly how "both CEREMONY_SELF_REF values" went
stale while main grew a third.
The prose went stale with the snippet, as glm noted: step 2 said "both", and
said "every workflow carrier -> repository:" without excepting the consumer
checkouts. Both corrected.
DRIVEN, not asserted. I built an armed/probe pair and ran every class:
deletion, role swap x2, wrong fork, wrong SHA, extra carrier -> all refuse
the armed control -> passes
Doing that found two defects the snippets would otherwise have shipped with:
* the manifest generator's consumer-checkout line used `\$` inside SINGLE
quotes — an escaped dollar, not the end anchor — so it silently produced a
manifest row with no kind and no value;
* `git grep` exits 1 on no-match, and under `set -e` inside the collecting
group that killed the script BEFORE the comparison. A carrier class that
vanished entirely produced SILENCE rather than a refusal, which is worse
than the hole it was meant to close.
test/run.sh 28/28; shellcheck 0.10.0 and changelog-armed clean.
Refs #202
2.2 KiB
Added
-
docs/RUNNER-PROBES.mddocuments the standing runner-probe venue,heavy-duty/ceremony-runner-probe— the place runner-only facts are measured on demand, ruled as option A by the operator (#202). -
drills/README.mdcross-links it beside the disposal rule, so the exception is visible where the dangerous habit lives (#202). -
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).
-
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).
-
The arming gate asserts what each carrier IS, not only that the old literal is gone: every
repository:equals the fork, bothCEREMONY_SELF_REFvalues equal the candidate code SHA, and callers match the layer they belong to (#202). -
It enumerates the carriers from the tree rather than encoding a count, and distinguishes ceremony's internal self-checkouts from the consumer checkouts that must stay
${{ github.repository }}(#202). -
Both published snippets parse, lint clean and were driven against a constructed armed/probe pair: all six failure classes refuse and the armed control passes (#202).
-
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).