drills/README.md — the standing runner-probe venue, and why the drill disposal rule does not apply to it (#202) #207

Merged
andres merged 14 commits from build/202-runner-probe-venue into main 2026-08-05 17:18:59 +00:00
2 changed files with 72 additions and 35 deletions
Showing only changes of commit dc87051c69 - Show all commits

View file

@ -33,8 +33,12 @@
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).
- 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).
- The published snippet parses, lints clean and runs: driven against an unarmed
tree it refuses, naming the carrier (#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

View file

@ -124,43 +124,76 @@ So:
- reusable-workflow callers →
`<identity>/ceremony/.github/workflows/<file>@<armed-workflow-sha>`, since
that is the only revision whose inner checkout is rewritten.
4. **Gate the arming POSITIVELY, against the armed tree.** Absence of the old
literal is not proof of correct arming: a negative grep stays green if
`CEREMONY_SELF_REF` names a tag, the *armed* SHA or some other commit; if a
carrier was rewritten to the wrong fork; if an executable carrier lives
outside `.github`; or if a carrier simply disappeared
(@codex-reviewer-andresmgsl, #202 review). So assert what each carrier
**is**, not merely what it is not:
4. **Gate the arming POSITIVELY, and against the tree each check is about.**
Absence of the old literal proves nothing: a negative grep stays green if
`CEREMONY_SELF_REF` names a tag or the *armed* SHA, if a carrier went to the
wrong fork, or if a carrier vanished instead of being rewritten. So assert
what each carrier **is** — and enumerate them, because the set is a property
of the current tree rather than a number to remember
(@codex-reviewer-andresmgsl, #202 review).
**The carriers on `main` today.** Re-derive this list each time rather than
trusting it; workflows come and go:
```sh
fork=<identity>/ceremony ; code_sha=<candidate-code-sha> ; armed_sha=<armed-workflow-sha>
fail() { echo "arming incomplete: $*" >&2; exit 1; }
# every self-checkout points at the fork
for v in $(git grep -hoP '(?<=repository:\s)\S+' -- .github); do
[ "$v" = "$fork" ] || fail "repository: $v"
done
# both CEREMONY_SELF_REF carriers name the CANDIDATE CODE sha
n=0
for v in $(git grep -hoP '(?<=CEREMONY_SELF_REF:\s)"?\K[^"]+' -- .github); do
[ "$v" = "$code_sha" ] || fail "CEREMONY_SELF_REF: $v"; n=$((n+1))
done
[ "$n" -eq 2 ] || fail "expected 2 CEREMONY_SELF_REF carriers, found $n"
# and in the PROBE repo: workflows pin the armed sha, actions the code sha
git grep -hoP '(?<=uses:\s)\S+' -- .github | while read -r u; do
case "$u" in
*/.github/workflows/*) [ "${u##*@}" = "$armed_sha" ] || fail "workflow caller $u" ;;
*/actions/*) [ "${u##*@}" = "$code_sha" ] || fail "action caller $u" ;;
esac
done
# the negative check stays, as a cheap extra rather than as the proof
! git grep -qE '(uses:|repository:)[[:space:]]*heavy-duty/ceremony' -- .github \
|| fail "canonical coordinate still present"
git grep -n 'CEREMONY_SELF_REF:' -- .github/workflows
git grep -n 'repository:' -- .github/workflows
```
**A count, not just a comparison**`n -eq 2` is what catches a carrier
that vanished rather than being rewritten, which a per-value loop alone
cannot see.
| carrier | on current `main` | armed value |
|---|---|---|
| `CEREMONY_SELF_REF` | `labels-sweep.yml`, `labels.yml`, `release.yml` | the **candidate code** SHA |
| internal self-checkout | `labels-sweep.yml`, `labels.yml`, `release.yml` ×2 | `<identity>/ceremony` |
| **consumer** checkout | `labels-sweep.yml`, `labels.yml`, `release-exercise.yml` | **unchanged**`${{ github.repository }}` |
That third row is the one an over-broad rewrite destroys. Those checkouts
fetch the **caller's** repository; pointing them at the fork changes what
the probe exercises into something else entirely.
```sh
#!/usr/bin/env bash
# check-arming <armed-checkout> <probe-checkout> <fork> <code-sha> <armed-sha>
set -euo pipefail
armed="$1"; probe="$2"; fork="$3"; code_sha="$4"; armed_sha="$5"
fail() { echo "arming incomplete: $*" >&2; exit 1; }
# (a) every self-ref carrier names the CANDIDATE CODE sha — enumerated, so a
# carrier that vanished is a failure rather than one fewer loop pass.
mapfile -t refs < <(git -C "$armed" grep -hoP '(?<=CEREMONY_SELF_REF: ")[^"]+' \
-- .github/workflows)
[ "${#refs[@]}" -gt 0 ] || fail "no CEREMONY_SELF_REF carriers found"
for v in "${refs[@]}"; do [ "$v" = "$code_sha" ] || fail "CEREMONY_SELF_REF=$v"; done
# (b) internal checkouts point at the fork; consumer checkouts stay dynamic.
mapfile -t repos < <(git -C "$armed" grep -hoP '(?<=repository: ).*' \
-- .github/workflows)
for v in "${repos[@]}"; do
case "$v" in
'${{ github.repository }}') ;; # the caller's repo — must NOT change
"$fork") ;; # an internal self-checkout, armed
*) fail "repository: $v" ;;
esac
done
# (c) in the PROBE repo: workflow callers pin the armed sha, action callers
# the code sha.
mapfile -t uses < <(git -C "$probe" grep -hoP '(?<=uses: ).*' -- .github)
for u in "${uses[@]}"; do
case "$u" in
*/.github/workflows/*@*) [ "${u##*@}" = "$armed_sha" ] || fail "workflow caller $u" ;;
*/actions/*@*) [ "${u##*@}" = "$code_sha" ] || fail "action caller $u" ;;
esac
done
# (d) the negative check, as a cheap extra rather than as the proof.
! git -C "$armed" grep -qE '(uses:|repository:)[[:space:]]*heavy-duty/ceremony' \
-- .github || fail "canonical coordinate still present"
```
**`mapfile`, not a pipeline.** `git grep | while … fail` runs the loop in a
subshell, so `fail` exits *that* subshell and the gate continues. Collect
first, validate after — and run under `set -euo pipefail`, which the snippet
declares rather than assumes.
5. **Invoke the probe by the event it is about**, and record which: a
`workflow_dispatch`, or the real board event under test. A probe that fires