ci(provisioning): add the provisioning-check reusable gate - #1106
Conversation
provisioning-check-reusable.yml checks a caller against the provisioning
canon at the workflow's own commit (job.workflow_sha), in two steps that
report separately:
- engine drift: build/just/{provision.just,provision-lib.sh,
provision-modes.sh,provision-check.sh} must be byte-identical to the
canon. channels.scm is not compared: toolchain-refresh re-pins it per
repo, and provision-check.sh checks the pin instead.
- conformance: the canon provision-check.sh (not the caller's copy) runs
against the caller without --dev, so template residue fails.
just 1.56.0 is installed from the release tarball pinned by sha256; no
new action is used. actions.lock gains the section by hand (the lock's
membership check is global, so a missing section would go unnoticed),
and canon.lock lists the reusable under [canon.workflows].
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UkSmyapDUmuGyyZSJmvbKy
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Advanced Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Kill-the-mutant proof for
|
| Run | Head | What it is | Result |
|---|---|---|---|
| 36860220890 | 0aee524 |
caller + workflows: lock entry, no dependencies: record for standards@96d58286 |
startup_failure, jobs=0 — a dangling lock edge (actions.lock must be transitively closed) |
| 36860399302 | 681fd3f |
control: lock graph closed | success |
| 36860559504 | 3c0d625 |
mutant: python added to mise.toml [tools] + one comment line appended to build/just/provision-lib.sh |
failure |
Per step (job provisioning / Provisioning set conforms):
| Step | Control | Mutant |
|---|---|---|
| Checkout caller / canon, stage canon | success | success |
| Install just (sha256-verified) | success | success |
| Engine files match the canon | success | failure — engine drift: build/just/provision-lib.sh differs from the canon at standards@96d58286… |
| Provisioning set conforms (provision-check.sh) | success | failure — mise.toml names banned tools: python; mise.lock does not pin: python |
Each check is killed by its own fault and reports independently (!cancelled()), so one cannot mask the other; the infrastructure steps stay green in both, so the red is the gate's verdict, not a setup failure.
Caller note for the fan-out: a caller's actions.lock needs the dependencies: record for hyperpolymath/standards@<sha> (with its actions/checkout use), not only the workflows: entry — run 36860220890 is what omitting it looks like.
🤖 Generated with Claude Code
|
Autopilot could not be updated. Open Coding to check access and billing. |
…eusable Signed-off-by: Jonathan D.A. Jewell <6759885+hyperpolymath@users.noreply.github.com>
…1106 onto main) (#1113) **Re-land of #1106 onto `main`.** #1106 merged at 15:32Z into its stacked base `feat/provisioning-canon`, but #1096 (that base) was closed unmerged. Its content reached `main` as #1112 instead, so the gate never reached `main`. `.github/workflows/provisioning-check-reusable.yml` is absent on `main` at `1b6e19ea`. This is #1106's single commit replayed onto `main` (signed). The workflow and `canon.lock` are byte-identical to #1106's merged head `a6649bca`. The only conflict was `.github/workflows/actions.lock`: #1084 added `harden-runner` under `propagate-hooks.yml` next to where this PR adds its section, and both are kept. `gh actions-lock --no-fix` passes 56 of 57 workflows. The one failure is the `signed-push-smoke.yml` local-action error, which #1084 records as already failing before this change. A diff of the `3-practice/provisioning` tree between `feat/provisioning-canon` and `main` shows that only this gate was stranded. The template differences there are newer `hypatia:ignore` annotations that `main` has and the dead base lacks. KYAML for this workflow follows in a separate PR. That PR first moves the grep-reading workflow gates (lock-selfcheck, validate-actions-lock, governance permissions check, duplicate-keys) to `yq` (YAML-POLICY Y-1), because each of them would falsely fail a flow-style file. ## What `.github/workflows/provisioning-check-reusable.yml`, the CI gate from `3-practice/provisioning`. It checks the caller against the canon at the workflow's own commit (`job.workflow_sha`), in two steps that report separately: | Step | Fails when | |---|---| | Engine files match the canon | any `build/just/{provision.just,provision-lib.sh,provision-modes.sh,provision-check.sh}` is missing or differs byte-for-byte | | Provisioning set conforms | the **canon** `provision-check.sh`, run without `--dev`, reports FAIL. It loads `provision-lib.sh` from its own directory, so a drifted caller copy cannot vouch for itself | - `channels.scm` is deliberately not compared byte-for-byte: `toolchain-refresh` re-pins it per repository. `provision-check.sh` checks its pin instead. - `just` 1.56.0 comes from the release tarball, pinned by sha256 (the same pin as launch-scaffolder#67). No new `uses:` is added. - `actions.lock` gains the section by hand (checkout only). `canon.lock` lists the reusable as `provisioning` under `[canon.workflows]`. ## Evidence (local dry run of both steps; the CI proof follows on a throwaway caller) | Case | cmp step | provision-check | |---|---|---| | rsr-template-repo #213 head (control) | pass | pass | | mutant: `fmt-check` recipe removed | pass | **FAIL** | | mutant: `python` added to `mise.toml` | pass | **FAIL** (banned tool + unpinned) | | mutant: `provision-lib.sh` changed | **FAIL** | pass | | mutant reverted | pass | pass | The third mutant is why there are two steps: an engine edit that leaves conformance intact is caught only by the byte comparison. ## Known, not new - actionlint does not know the `job.workflow_sha` context. It reports the same thing 4 times on `allowlist-preflight-reusable.yml`. - `gh actions-lock` gives this file the same `sha-as-ref` advisory that every SHA-pinned workflow here carries (94 on the base, 95 with this one). 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01W5CoaksP2Bg21HpDCgFgwS Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Stacked on #1096. The base branch is
feat/provisioning-canon. After #1096 squash-merges, run:and retarget this PR to
main. Until then the diff is just this gate.What
.github/workflows/provisioning-check-reusable.yml, the CI gate from3-practice/provisioning. It checks the caller against the canon at the workflow's own commit (job.workflow_sha), in two steps that report separately:build/just/{provision.just,provision-lib.sh,provision-modes.sh,provision-check.sh}is missing or differs byte-for-byteprovision-check.sh, run without--dev, reports FAIL. It loadsprovision-lib.shfrom its own directory, so a drifted caller copy cannot vouch for itselfchannels.scmis deliberately not compared byte-for-byte:toolchain-refreshre-pins it per repository.provision-check.shchecks its pin instead.just1.56.0 comes from the release tarball, pinned by sha256 (the same pin as launch-scaffolder#67). No newuses:is added.actions.lockgains the section by hand (checkout only).canon.locklists the reusable asprovisioningunder[canon.workflows].Evidence (local dry run of both steps; the CI proof follows on a throwaway caller)
fmt-checkrecipe removedpythonadded tomise.tomlprovision-lib.shchangedThe third mutant is why there are two steps: an engine edit that leaves conformance intact is caught only by the byte comparison.
Known, not new
job.workflow_shacontext. It reports the same thing 4 times onallowlist-preflight-reusable.yml.gh actions-lockgives this file the samesha-as-refadvisory that every SHA-pinned workflow here carries (94 on the base, 95 with this one).🤖 Generated with Claude Code
https://claude.ai/code/session_01UkSmyapDUmuGyyZSJmvbKy