feat(provisioning): estate Provisioning Standard + launcher v0.5 provisioning modes - #1112
Merged
Merged
Conversation
Re-signed rebuild of #1096 (head 18dcefa) on current main. Two coderabbitai[bot] commits on that branch were unsigned, which required_signatures refuses even under squash. The tree equals 18dcefa apart from main's later #1087/#1098 files, plus: - hypatia:ignore eval_in_shell pragmas on 7 lines of provision-check.sh and provision-lib.sh. Each hit is the word "eval" (a verb name or the .eval/ directory), never the shell builtin. Inline pragmas, not baseline entries: the templates are minted into other repos, where the pragma travels with them. Control: hypatia@4065424 reports 7 findings before and 0 after. Original commits (feat/provisioning-canon): fd0658c feat(provisioning): estate provisioning standard + launcher v0.5 modes e7b134e fix(provisioning): detect ABI/FFI layout; launcher is generated 40010ef fix(provisioning): no curl|sh install hint; regenerate registry 206eb6c feat(provisioning): one placement resolver; zig found 3 dirs down 39b790f fix(provisioning): no faked zig/bun tests; one ai-install sentence eaf3a89 feat(provisioning): fmt-check verb, the check-only twin of fmt b234caf fix(provisioning): #1096 review — hook isolation, dispatch rc, quoting 89c1d32 fix(provisioning): one set of predicates for doctor and the CI gate 93342bf docs(provisioning): banned-tool mise.toml is replaced; app launchers 7e6f3db feat(provisioning): toolchain-refresh regenerates build/guix/crates.scm 9b57453 fix(provisioning): mise.lock checksums are checked per platform table 7475b18 docs(provisioning): document the awk helper in mise_lock_gaps e323e0a docs(provisioning): escape the [[ai-install]] anchor in prose 42b66c3 fix(provisioning): guix-only re-pin, tally-last doctor, artefact kinds b01a245 fix(provisioning): PV-W23 reads every mise config and backend bf7c97a fix(provisioning): a bare mise name with only npm backends is banned a00fcf3 Update 3-practice/provisioning/templates/launcher.sh.tmpl 71cad01 docs(provisioning): document shell template functions 18dcefa docs(provisioning): clarify template function behavior and exit statuses Co-Authored-By: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DAKujx2PXHcVSA7vncTNH1
Contributor
|
Warning Review limit reachedYou've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. Next included review available in 12 minutes. View limit detailsLimit details: You’ve used the included review currently available. Review configuration: ⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Advanced Run ID: 📒 Files selected for processing (24)
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 |
4 tasks
hyperpolymath
enabled auto-merge (squash)
October 1, 2026 14:51
auto-merge was automatically disabled
October 1, 2026 14:52
Repository rule violations found
This was referenced Oct 1, 2026
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>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Supersedes #1096. The content is identical, rebuilt on current
mainas one signed commit.Why a replacement
coderabbitai[bot](71cad01f,18dcefa2) were unsigned.required_signaturesrefuses a PR that has any unsigned commit on its head, even under squash (docs/SIGNING-POLICY.adoc§ Squash signs the result, not the PR branch). Their content (docstrings, now 74/74 covered) is kept.git merge --squash origin/feat/provisioning-canonontoorigin/main, thengit commit -S.git diff 18dcefa2 HEADshows only main's later fix(gitleaks): estate baseline — a documentation filename is not a secret #1087/docs(signing): squash signs the result, not the PR branch #1098 files plus the delta below. The original commit list is in the commit message.Delta vs #1096: Hypatia
eval_in_shellfalse positives#1096's
Hypatiacode-scanning check andgovernance / Validate Hypatia Baselinewere red on 4content_patterns/eval_in_shellfindings (provision-check.sh:23,provision-lib.sh:867,868,944). The rule is a bare\beval\b, and every hit is the word: theevalverb name, or the.eval/directory. None is the shell builtin.The fix is an inline
# hypatia:ignore eval_in_shell -- <reason>pragma on each line, not baseline entries:HYPATIA-BASELINE-FORMAT.adoclists "single new findings on freshly-introduced code" as a bad baseline entry, and the baseline is a ratcheted exemption ledger.4065424) also flags are pragma'd too, so a scanner bump does not turn this red again.Control: local
hypatia@4065424 scanover the two files reports 7eval_in_shellfindings on #1096's version and 0 on this branch.bash -nis clean for both scripts. Upstream rule precision is tracked upstream in hyperpolymath/hypatia#892 (eval_in_shellmatches the word, not the builtin in command position).CodeRabbit's last
CHANGES_REQUESTED(thelauncher.sh.tmplheader saying modes delegate to the Justfile) is already addressed in this content: l.25–29 say provisioning modes callbuild/just/provision-lib.shdirectly.Original description (#1096)
What
Phase 1 of the estate provisioning campaign. This PR is the canon every repository will be minted from, so that nobody who clones a repo has to search for how to install, configure, run, test, bench, diagnose or repair it.
New:
3-practice/provisioning/PROVISIONING-STANDARD.adoc(v1.0.0) andprovisioning-standard_praxis.deed(lints OK)provision.just: theprovision::module with every verbprovision-lib.sh: bash only, shellcheck cleanprovision-modes.sh: the launcher dispatchprovision-check.sh: the offline conformance checker, covering §8 items 1–5launcher.sh.tmplmise.toml(latest plusmise.lock)cargo-build-systempackage for Rust, acopy-build-systemsource package for everything else, plusmanifest.scmand a pinnedchannels.scmdocs/SETUP.adoc, the manual route, with a doctor-code troubleshooting tabledocs/AI_INSTALLATION_GUIDE.adocllm-warmup-{user,dev,maintainer}.adoc[[ai-install]]"Just say it" fragment (the neurophone pattern)provisioning_praxis.deedLauncher standard 0.6.0 (
launcher-standard.adocandlauncher-standard_praxis.deed)launcher.sh, profiled by archetype. Onlyapphas runtime modes; the others print N/A and exit 0.--setup,--doctor,--healand--ai-setupcall the engine directly (build/just/provision-lib.sh), so a repo's own rootdoctor/setup/healrecipe cannot shadow the canon.doctor-local,setup-localandheal-localrecipes. A failingdoctor-localis FAIL PV-E50.guix.scm: the licence field was a malformed ad-hoc licence object pointing at palimpsest-license. It is nowmpl2.0from(guix licenses), which is the licence the file's own SPDX header already declares. No licence changes.Verified
deed_lint.py:launcher-standard_praxis.deedandprovisioning-standard_praxis.deedprovision-check.shfixture:python, bannedaqua:denoland/deno, nomise.lock, guix stub, mechanical slot residue, README SPEC residue.--devdowngrades SPEC residue to a WARN.doctor-localgives PV-E50 and rc=1 via both./launcher.sh --doctorandjust doctor.doctorthat prints fake green is not executed by--doctor.podmanwithmetacall/guixat ae77aeb: the Rust source package derivation builds (guix build -d, rc=0). The non-Rust derivation and the real build were still running when this PR was opened.Known, not introduced here
main, with 5 unmapped top-level entries:arena-session-787,patches,ULTRAPLAN-2026-09-24.adoc,ULTRAPLAN-2026-09-29.adocandziz-drop. This PR adds no top-level entry, because3-practiceis already mapped.mod provisionin this repo's own Justfile is deferred to the pilot phase.Update: review round (head b234caf)
Commits since opening
206eb6c — one placement resolver.
build/. This resolves the CodeRabbit placement thread.39b790f — no faked zig/bun tests.
ai-setup.eaf3a89 — new
fmt-checkverb, the check-only twin offmt.cargo fmt --check,zig fmt --check,mix format --check-formatted,gleam format --check,dune build @fmt, and bun'sfmt-checkscript.qualitynow depends on this verb. Before, it silently ranlint.b234caf — the remaining review findings.
doctor-local.shnow runs sourced in a subshell. Anexitor a trippedset -eis FAIL PV-E51, and the checks it completed still count.hp_provision_or_returnreplaces&& exit $?, which reported success for a failing mode.ai-warmupargument is now quoted.7e6f3db —
toolchain-refreshregeneratesbuild/guix/crates.scm.guix.scm.cargo.tmplalready promised this, but nothing implemented it. The new lib verbcrates-scmrunsguix import crate --lockfile.GUIXmay name a container wrapper.Cargo.lock, because a containerised guix loses its exit status. Otherwise the run fails with the new code PV-E41 and the old file stays. PV-E41 is in the deed, the lib and the SETUP table: all three hold the same 28 codes.Cargo.lock:guix replgives(length %crate-inputs)= 151 andorigin?=#t;094fd79 — merge
main; the provisioning modes are launcher standard 0.6.0.maintook 0.5.0 for the(js-runtime)clause (D224, feat(launcher-standard): add the (js-runtime) bun/bunx launch route, v0.5.0 (D224) #1100). That number is published with that meaning, so the archetype and provisioning obligations move to 0.6.0 (2026-10-01). Updated together: the deed, the.adoc, the currency gate'sCURRENT_VERSION, the launcher template andprovision-modes.sh.--self-test: 4 mutants seeded, all detected.Measured on rsr-template-repo (the first consumer; that PR follows)
doctor-hook cases:
exit 3set -e; falsefail./launcher.sh --doctor: rc 0 when clean, rc 1 with a failing hook.just doctor18/0/0,just validatepass,provision-check --dev0 FAIL / 0 WARN, shellcheck clean.fmt-check: rc 0 on clean code; a mis-formatted mutant gives rc 1.Guix, via
metacall/guixat ae77aeb:guix build -f guix.scm: rc 0.guix shell -m manifest.scm --dry-run: rc 0.channels.scmevaluates to the same pinned commit.just registry-checkOK.check-launcher-standard-currencyOK.Red checks: none is a required check. Classified:
main: the constitution hash, dogfood-gate, and the ULTRAPLAN / arena-session-787 / patches / ziz-drop entries. fix: restore standards main to green: lock-gate pin, registry regen, uuid-v7, map roots, canon 2.1.2, docstring calibration #1088 fixes them.CURRENT_VERSIONdrift is fixed in b234caf.main.eval_in_shellfindings are false positives on theevalverb name: a comment, the.eval/report directory, acaselabel, and the verb list. Nothing here calls the builtin.governance / Validate Hypatia Baseline,scan / Hypatia Neurosymbolic AnalysisandHypatia→ eval_in_shell matches the word "eval" anywhere, not the builtin in command position hypatia#892. On 094fd79 the baseline gate kept exactly six findings:eval_in_shellatprovision-check.sh:23andprovision-lib.sh:17,732,733,742,804, all the wordeval. The same three checks are green onmain8cfad82. Renaming the user-facingevalverb to satisfy the scanner would be the wrong arm.uuid-v7.ymlbaseline findings are fixed by fix: restore standards main to green: lock-gate pin, registry regen, uuid-v7, map roots, canon 2.1.2, docstring calibration #1088.REGISTRY.a2ml. If it merges first, regenerate the registry here.Placement labels (elegance arm)
provision-set --checkwill prove it is equal to canon. This is the elegant long-term arm.channels.scmis minted, not engine (departure, labelled).toolchain-refreshre-pins it per repo by design, so a byte-compare would go red after every weekly refresh. Instead it is checked for a 40-hex commit pin.Update: one banned list, backends and bare names (heads b01a245, bf7c97a)
Found by the 8-repo pilot (launch-scaffolder#67).
:banned-toolsand the engine'sBANNED_TOOLShad diverged. They are now one 20-item list, plus a new:banned-backends ("npm" "pipx" "pip" "go"). launch-scaffolder tests that the deed and the engine agree.mise.toml,.mise.tomland.tool-versions.npm:prettier)..tool-versionspython +.mise.toml"npm:prettier"→[python npm:prettier] rc=1; clean →[] rc=0.prettierresolves only tonpm:prettier.mise registry, which works offline.prettier→[prettier] rc=1;shfmt/zig/an unknownjest→[] rc=0.Next
provision-setgenerator and theprovisioning-check.ymlgate🤖 Generated with Claude Code
https://claude.ai/code/session_01DAKujx2PXHcVSA7vncTNH1