docs(runner-probes): the checker binds the manifest to its target, and the snippets lint clean standalone (#202)
All checks were successful
CI / test (pull_request) Successful in 3m8s
CI / release-exercise (pull_request) Successful in 11s
CI / self-guards (pull_request) Successful in 7s
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
All checks were successful
CI / test (pull_request) Successful in 3m8s
CI / release-exercise (pull_request) Successful in 11s
CI / self-guards (pull_request) Successful in 7s
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
@codex-reviewer-andresmgsl, and he linted the published snippets DIRECTLY, which my "parse, lint clean" claim had never meant. 1. THE CHECKER DID NOT CHECK THE TARGET. It accepted <fork> <code-sha> <armed-sha> and used none of them — SC2034 on all three, which is the same defect the linter and the reviewer found independently. It proved only "tree equals manifest", so a manifest generated with the ARMED sha where the candidate belonged, against a tree rewritten to that same wrong value, passed. Wrong-but-consistent is exactly what this gate exists to reject. Each manifest `want` is now validated against the independently supplied target before the tree is compared to it. 2. ONE ORDER, NOT TWO. Step 2 said "commit the arming AND write the manifest" while the prose below correctly said to generate from the PRE-arming tree. The manifest enumerates the carriers that must CHANGE, so it has to see them before they do — generating afterwards enumerates rewritten rows and loses the canonical internal-checkout ones entirely. The generator's first parameter is <candidate-checkout> now, and says so. 3. THE SNIPPETS LINT CLEAN STANDALONE. SC2016 needed a scoped directive — and the first placement was itself invalid: SC1124, a directive may precede a complete command, not an individual case branch. The checker's mktemp gets a trap. Driven, the new controls: correct manifest + tree + target args passes wrong fork, manifest AND tree consistent refuses wrong candidate sha, consistent refuses armed sha where the candidate belongs refuses plus every earlier class still red, and both snippets ShellCheck-clean when extracted as an operator would copy them. test/run.sh 28/28; repository shellcheck 0.10.0 and changelog-armed clean. Refs #202
This commit is contained in:
parent
20f4b287f7
commit
6874e76c04
2 changed files with 46 additions and 8 deletions
|
|
@ -37,8 +37,19 @@
|
|||
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: deletion, both role swaps, wrong owner, wrong
|
||||
- Both published snippets are ShellCheck-clean when extracted and linted
|
||||
directly, not merely as part of the repository sweep (#202).
|
||||
|
||||
- The checker validates the MANIFEST against the target it was given, so a
|
||||
manifest that describes a wrong arming consistently — wrong fork, or the
|
||||
armed SHA where the candidate belongs — refuses instead of matching a tree
|
||||
rewritten to the same wrong value (#202).
|
||||
|
||||
- The manifest is generated from the PRE-arming tree, which is the only order
|
||||
that enumerates the carriers that must change (#202).
|
||||
|
||||
- Both published snippets were driven against a constructed candidate/probe
|
||||
pair: deletion, both role swaps, wrong owner, wrong
|
||||
SHA, wrong path, a deleted caller class and an extra carrier all refuse, and
|
||||
the armed control passes (#202).
|
||||
|
||||
|
|
|
|||
|
|
@ -113,7 +113,11 @@ So:
|
|||
the **candidate code SHA**. Never create a branch on
|
||||
`heavy-duty/ceremony` named like a tag: it shadows that tag for every
|
||||
consumer until somebody remembers to delete it.
|
||||
2. **Commit the arming on top of it, and write the manifest.** In that same
|
||||
2. **Write the manifest FIRST, from the pre-arming tree, then commit the
|
||||
arming.** The manifest enumerates the carriers *that must change*, so it is
|
||||
generated before they do — running it afterwards would enumerate
|
||||
already-rewritten rows and lose the canonical internal-checkout ones
|
||||
entirely (@codex-reviewer-andresmgsl, #202 review). In that same
|
||||
fork branch rewrite, for **every** carrier the manifest below enumerates:
|
||||
ceremony's own internal `repository:` checkouts → `<identity>/ceremony`, and
|
||||
**every** `CEREMONY_SELF_REF` value → the **candidate code SHA** from step 1.
|
||||
|
|
@ -152,7 +156,10 @@ So:
|
|||
|
||||
```sh
|
||||
#!/usr/bin/env bash
|
||||
# write-manifest <armed-checkout> <probe-checkout> <fork> <code-sha> <armed-sha>
|
||||
# write-manifest <candidate-checkout> <probe-checkout> <fork> <code-sha> <armed-sha>
|
||||
#
|
||||
# Run against the PRE-ARMING tree and the UNPINNED probe: this records what
|
||||
# each carrier must BECOME, so it has to see them before they change.
|
||||
#
|
||||
# `|| true` on every extraction, for the same reason the checker needs it:
|
||||
# git grep exits 1 on no-match and `set -e` would abort BEFORE the manifest
|
||||
|
|
@ -160,7 +167,8 @@ So:
|
|||
# produced no file and no diagnostic when a probe exercised only one layer
|
||||
# (@codex-reviewer-andresmgsl). A probe need not use both.
|
||||
set -euo pipefail
|
||||
armed="$1"; probe="$2"; fork="$3"; code_sha="$4"; armed_sha="$5"
|
||||
armed="$1"; probe="$2"; fork="$3"; code_sha="$4"; armed_sha="$5" # $1 = pre-arming
|
||||
# shellcheck disable=SC2016 # `${{ github.repository }}` is literal YAML, not a shell expansion
|
||||
{
|
||||
git -C "$armed" grep -n 'CEREMONY_SELF_REF:' -- .github/workflows \
|
||||
| cut -d: -f1,2 | sed "s|$|\tself_ref\t$code_sha|" || true
|
||||
|
|
@ -182,8 +190,7 @@ So:
|
|||
[ "$callers" -gt 0 ] || { echo "manifest: no ceremony callers found in $probe" >&2; exit 1; }
|
||||
```
|
||||
|
||||
Run it against the **pre-arming** tree — that is what enumerates the
|
||||
carriers that must change — then arm, then check:
|
||||
Then arm — rewrite and commit — and check the result against it:
|
||||
|
||||
```sh
|
||||
#!/usr/bin/env bash
|
||||
|
|
@ -200,7 +207,27 @@ So:
|
|||
[ "$(grep -cE '(workflow|action)_caller' "$manifest" || true)" -gt 0 ] \
|
||||
|| fail "manifest names no ceremony callers — it cannot prove an arming"
|
||||
|
||||
actual="$(mktemp)"
|
||||
# THE MANIFEST ITSELF IS CHECKED AGAINST THE TARGET, not trusted. Comparing
|
||||
# only tree-vs-manifest proves consistency, and a manifest generated with the
|
||||
# armed SHA where the candidate SHA belonged — or with the wrong fork —
|
||||
# describes a WRONG arming perfectly. The tree would then match it and the
|
||||
# gate would pass (@codex-reviewer-andresmgsl, #202 review).
|
||||
# shellcheck disable=SC2016 # `${{ github.repository }}` below is literal YAML
|
||||
while IFS=$'\t' read -r loc kind want; do
|
||||
case "$kind" in
|
||||
self_ref) [ "$want" = "$code_sha" ] || fail "manifest $loc: self_ref should be the CANDIDATE sha" ;;
|
||||
internal_repo) [ "$want" = "$fork" ] || fail "manifest $loc: internal repo should be $fork" ;;
|
||||
consumer_repo) [ "$want" = '${{ github.repository }}' ] \
|
||||
|| fail "manifest $loc: consumer checkout must stay dynamic" ;;
|
||||
workflow_caller) [ "$want" = "$fork/${want#*/ceremony/}" ] || fail "manifest $loc: caller owner"
|
||||
[ "${want##*@}" = "$armed_sha" ] || fail "manifest $loc: workflow caller should be the ARMED sha" ;;
|
||||
action_caller) [ "$want" = "$fork/${want#*/ceremony/}" ] || fail "manifest $loc: caller owner"
|
||||
[ "${want##*@}" = "$code_sha" ] || fail "manifest $loc: action caller should be the CANDIDATE sha" ;;
|
||||
*) fail "manifest $loc: unknown kind '$kind'" ;;
|
||||
esac
|
||||
done <"$manifest"
|
||||
|
||||
actual="$(mktemp)"; trap 'rm -f "$actual"' EXIT
|
||||
{
|
||||
git -C "$armed" grep -nP '(?<=CEREMONY_SELF_REF: ")[^"]+' -- .github/workflows \
|
||||
| sed -E 's/^([^:]+):([0-9]+):.*CEREMONY_SELF_REF: "([^"]*)".*/\1:\2\tself_ref\t\3/' || true
|
||||
|
|
|
|||
Loading…
Reference in a new issue