docs(runner-probes): bind caller kind to its path class
All checks were successful
CI / test (pull_request) Successful in 3m8s
CI / release-exercise (pull_request) Successful in 10s
CI / self-guards (pull_request) Successful in 6s
CI / action-exercise (pull_request) Successful in 6s
CI / docs-sync-exercise (pull_request) Successful in 6s
Refs guard / refs-not-closing (pull_request) Has been skipped
labels / labels (pull_request) Successful in 8s

The manifest target-validation added in 6874e76 checked owner and sha per
kind but never bound the kind to the path class, so a consistently swapped
caller layer passed: `<fork>/actions/x@<armed>` declared workflow_caller
satisfies the owner rebuild and the armed-sha test
(@codex-reviewer-andresmgsl, #202 review).

Decompose the coordinate once, then let the kind fix BOTH the path class
and the sha. Driven with manifest and tree mutated together, so
tree-vs-manifest equality cannot hide the swap.

Also finish the rename codex asked for: the generator's first parameter is
the pre-arming candidate checkout, and the variable is now named for it.

Refs #202
This commit is contained in:
clad2 2026-08-05 15:33:20 +00:00
parent 6874e76c04
commit 368621dcea

View file

@ -144,6 +144,7 @@ So:
| "each value is one of {fork, dynamic}" | a **role swap**: an internal checkout made dynamic, a consumer checkout pointed at the fork | | "each value is one of {fork, dynamic}" | a **role swap**: an internal checkout made dynamic, a consumer checkout pointed at the fork |
| "the SHA suffix matches" | `wrong-owner/ceremony/actions/foo@<right-sha>` | | "the SHA suffix matches" | `wrong-owner/ceremony/actions/foo@<right-sha>` |
| "known callers match" | an **unrecognised** caller, or none at all | | "known callers match" | an **unrecognised** caller, or none at all |
| "the owner and the sha are right for the kind" | a **layer swap**: `…/actions/x@<armed>` labelled a workflow caller satisfies both |
So the arming step **writes a manifest** — one line per carrier, `path`, So the arming step **writes a manifest** — one line per carrier, `path`,
`kind`, `full expected value` — and the gate compares the tree's actual `kind`, `full expected value` — and the gate compares the tree's actual
@ -167,14 +168,14 @@ So:
# produced no file and no diagnostic when a probe exercised only one layer # produced no file and no diagnostic when a probe exercised only one layer
# (@codex-reviewer-andresmgsl). A probe need not use both. # (@codex-reviewer-andresmgsl). A probe need not use both.
set -euo pipefail set -euo pipefail
armed="$1"; probe="$2"; fork="$3"; code_sha="$4"; armed_sha="$5" # $1 = pre-arming candidate="$1"; probe="$2"; fork="$3"; code_sha="$4"; armed_sha="$5"
# shellcheck disable=SC2016 # `${{ github.repository }}` is literal YAML, not a shell expansion # shellcheck disable=SC2016 # `${{ github.repository }}` is literal YAML, not a shell expansion
{ {
git -C "$armed" grep -n 'CEREMONY_SELF_REF:' -- .github/workflows \ git -C "$candidate" grep -n 'CEREMONY_SELF_REF:' -- .github/workflows \
| cut -d: -f1,2 | sed "s|$|\tself_ref\t$code_sha|" || true | cut -d: -f1,2 | sed "s|$|\tself_ref\t$code_sha|" || true
git -C "$armed" grep -n 'repository: heavy-duty/ceremony' -- .github/workflows \ git -C "$candidate" grep -n 'repository: heavy-duty/ceremony' -- .github/workflows \
| cut -d: -f1,2 | sed "s|$|\tinternal_repo\t$fork|" || true | cut -d: -f1,2 | sed "s|$|\tinternal_repo\t$fork|" || true
git -C "$armed" grep -n 'repository: ${{ github.repository }}' -- .github/workflows \ git -C "$candidate" grep -n 'repository: ${{ github.repository }}' -- .github/workflows \
| cut -d: -f1,2 | sed 's|$|\tconsumer_repo\t${{ github.repository }}|' || true | cut -d: -f1,2 | sed 's|$|\tconsumer_repo\t${{ github.repository }}|' || true
# Callers record the COMPLETE expected coordinate, not just the sha: the # Callers record the COMPLETE expected coordinate, not just the sha: the
# path is as rewritable as the owner, and a manifest that stores only the # path is as rewritable as the owner, and a manifest that stores only the
@ -219,10 +220,29 @@ So:
internal_repo) [ "$want" = "$fork" ] || fail "manifest $loc: internal repo should be $fork" ;; internal_repo) [ "$want" = "$fork" ] || fail "manifest $loc: internal repo should be $fork" ;;
consumer_repo) [ "$want" = '${{ github.repository }}' ] \ consumer_repo) [ "$want" = '${{ github.repository }}' ] \
|| fail "manifest $loc: consumer checkout must stay dynamic" ;; || fail "manifest $loc: consumer checkout must stay dynamic" ;;
workflow_caller) [ "$want" = "$fork/${want#*/ceremony/}" ] || fail "manifest $loc: caller owner" # THE KIND MUST BIND TO THE PATH CLASS, not only to the owner and the
[ "${want##*@}" = "$armed_sha" ] || fail "manifest $loc: workflow caller should be the ARMED sha" ;; # sha. The path class is what SAYS which layer a caller is, so checking
action_caller) [ "$want" = "$fork/${want#*/ceremony/}" ] || fail "manifest $loc: caller owner" # the sha against the kind while letting the kind float free accepts a
[ "${want##*@}" = "$code_sha" ] || fail "manifest $loc: action caller should be the CANDIDATE sha" ;; # consistent layer swap — `…/actions/x@<armed>` declared workflow_caller
# passes every owner and sha test (@codex-reviewer-andresmgsl, #202
# review). Decompose once, then let the kind fix BOTH coordinates.
workflow_caller|action_caller)
owner="${want%%/ceremony/*}"; rest="${want#*/ceremony/}"
path="${rest%@*}"; sha="${want##*@}"
[ "$owner/ceremony" = "$fork" ] \
|| fail "manifest $loc: caller owner should be $fork"
case "$kind" in
workflow_caller)
case "$path" in .github/workflows/?*) : ;;
*) fail "manifest $loc: workflow_caller must resolve at .github/workflows/<file>, not '$path'" ;;
esac
[ "$sha" = "$armed_sha" ] || fail "manifest $loc: workflow caller should be the ARMED sha" ;;
action_caller)
case "$path" in actions/?*) : ;;
*) fail "manifest $loc: action_caller must resolve at actions/<name>, not '$path'" ;;
esac
[ "$sha" = "$code_sha" ] || fail "manifest $loc: action caller should be the CANDIDATE sha" ;;
esac ;;
*) fail "manifest $loc: unknown kind '$kind'" ;; *) fail "manifest $loc: unknown kind '$kind'" ;;
esac esac
done <"$manifest" done <"$manifest"