Skip to content

ci(provisioning): add the provisioning-check reusable gate - #1106

Merged
hyperpolymath merged 2 commits into
feat/provisioning-canonfrom
feat/provisioning-check-reusable
Oct 1, 2026
Merged

hyperpolymath merged 2 commits into
feat/provisioning-canonfrom
feat/provisioning-check-reusable

Conversation

@hyperpolymath

Copy link
Copy Markdown
Owner

Stacked on #1096. The base branch is feat/provisioning-canon. After #1096 squash-merges, run:

git rebase --onto main feat/provisioning-canon feat/provisioning-check-reusable

and retarget this PR to main. Until then the diff is just this gate.

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.ai/code/session_01UkSmyapDUmuGyyZSJmvbKy

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
@coderabbitai

coderabbitai Bot commented Oct 1, 2026 •

Copy link
Copy Markdown
Contributor

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Advanced

Run ID: 4e576cb1-7861-4ef0-98c9-784facbcd51f

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Autopilot is currently an internal CodeRabbit preview.


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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@hyperpolymath

Copy link
Copy Markdown
Owner Author

Kill-the-mutant proof for provisioning-check-reusable.yml @ 96d58286

Throwaway caller on hyperpolymath/rsr-template-repo branch zz-provisioning-gate-proof (deleted after this comment), calling this reusable by SHA.

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

https://claude.ai/code/session_01UkSmyapDUmuGyyZSJmvbKy

@coderabbitai

coderabbitai Bot commented Oct 1, 2026

Copy link
Copy Markdown
Contributor

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>
@hyperpolymath
hyperpolymath merged commit 0281f58 into feat/provisioning-canon Oct 1, 2026
14 of 15 checks passed
@hyperpolymath
hyperpolymath deleted the feat/provisioning-check-reusable branch October 1, 2026 15:32
@hyperpolymath

Copy link
Copy Markdown
Owner Author

This merged into feat/provisioning-canon, but that base (#1096) closed unmerged and its content reached main via #1112, so this gate never got to main. It is re-landed on main as #1113, with the same commit rebased and the actions.lock conflict resolved.

hyperpolymath added a commit that referenced this pull request Oct 1, 2026
…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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant