Repository navigation
feat(provisioning): a package.json provisions bun, deno and pnpm; deno and pnpm leave the banned list - #1255
Conversation
…o and pnpm leave the banned list
The 2026-10-14 ruling (LANGUAGE-POLICY §1.3–§1.4, standards#1249) put
Bun > Deno > pnpm > npm and one package.json, every runtime. The
provisioning canon still enforced the old policy against it:
- BANNED_TOOLS (and the deed's :banned-tools) listed deno and pnpm, so
doctor's PV-W23 warned on a mise.toml that pins them;
- PV-W30 called deno.lock a Deno leftover and PV-W34 called
pnpm-lock.yaml one, though every package must now carry both;
- a package.json provisioned only bun, while js-runtimes regen needs all
three tools.
Now a package.json provisions bun, deno and pnpm (mise, remedy text, Guix
gap via mise); deno and pnpm leave both banned lists (node stays, so npm
is never provisioned); deno.lock and pnpm-lock.yaml are no longer
leftovers; a deno.json is a notice. provision-lib 0.5.0 -> 0.6.0.
Measured on a fixture (package.json, mise.toml with bun/deno/pnpm, the
three locks), old engine vs new:
mise-tools just shellcheck bun -> just shellcheck bun deno pnpm
mise-banned exit 1 'deno pnpm' -> exit 0
doctor WARN PV-W30 deno.lock,
WARN PV-W34 pnpm-lock.yaml -> PASS no ... leftovers
Controls: node in mise.toml is still banned (exit 1); package-lock.json
still warns PV-W34; deno.json is an info line.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Y6FD63UrriRBHqmhhEca9t
|
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 34 minutes. View limit details
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 |
K9 contract conformancerun https://github.com/hyperpolymath/standards/actions/runs/38556116505 K9 normative contract typecheckK9 contract self-testK9 conformance fixturesK9 corpus conformance (L2) |
standards#1249 added the `js-runtimes-provision` and `js-runtimes` jobs to governance-reusable.yml but not to the context-freeze list in tests/test_governance_reusable_shape.sh, so Self Test has been red on main since 25d23cf ("job names drifted from the frozen list"). The test's own header allows additions ("Adding a job is allowed (it adds a context)"); the equality check just needs the two names. A rename still fails (checked by renaming "Debt ratchet" locally). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Y6FD63UrriRBHqmhhEca9t
K9 contract conformancerun https://github.com/hyperpolymath/standards/actions/runs/38557133562 K9 normative contract typecheckK9 contract self-testK9 conformance fixturesK9 corpus conformance (L2) |
…1255/#1256) Self Test has been red on main since #1249 added the js-runtimes jobs to governance-reusable.yml without adding their names to the frozen context list. This is the identical change carried by #1255 and #1256, ported so this PR's Self Test can go green; it no-ops once either lands. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LiQzWJdcPfRU6YMDGRG8Xi
…ip as a pass (#1256) ## Problem The "Run panic-attack assail" step in `.github/workflows/hypatia-scan-reusable.yml` did nothing. Nothing in the job installed panic-attack. On main's Hypatia run at 7d2041a (run 38484072239, job 115593368840) the log says `panic-attack not available in CI — skipping`. The step then wrote a bare `[]` to `panic-attack-findings.json`, and that reads exactly like a clean scan. The CRG Immaculate-Guide evidence bullet (`COMPONENT-READINESS-GRADES.adoc`, the "`panic-attack assail` passes (no Critical/High findings)" line) treats that file as a pass. The "installed" branch was broken too: - `panic-attack assail .` without `--output` prints a human-readable banner, not JSON. - `2>&1` mixed stderr into the file. - `|| true` swallowed any failure. ## Change (owner ruling: both (a) and (b); stays advisory) **(a) Install from a pinned source commit.** The job builds panic-attack v2.5.5 at commit `2dc1393c` with `cargo install --git … --rev <sha> --locked`. `self-test.yml` already installs `ijson-jcs` the same way. - No release binary exists to checksum instead. The `v2.5.5` asset returns 404, and upstream's `release.yml` packages `README.md`, `ROADMAP.md` and `SECURITY.md`, which the repo does not have. - The binary is cached by commit with the `actions/cache` pin already in use. A restored binary is used only when cargo's `.crates.toml` names the pinned commit. - A failed build removes `~/.panic-attack`, so nothing half-built gets cached. - The build is capped at 10 minutes and the scan at 5. The job timeout rises from 30 to 45 minutes to match, so neither cap can fail the job. **(b) Make every non-result explicit.** `panic-attack-findings.json` is now a status envelope and never a bare array: ``` {status: "ran" | "not_run" | "error", tool, ref, reason, exit_code, counts, report} ``` - Each of these produces an explicit status, a `::warning`, and a step-summary section saying the scan is **not** a pass: tool missing, cargo missing, build failure, crash, the 5-minute cap, or a missing or invalid report. - A real run embeds panic-attack's own report and counts the unsuppressed findings by severity. Findings produce an advisory warning. They never gate. - The scan runs before the standards checkout, so it scans the caller's tree and not `.standards-checkout/scripts`. **Docs.** The CRG evidence bullet now says what counts in CI: `status: "ran"` with zero critical and zero high. ## Also in this PR: a fix for main's red Repo self-tests [#1249](#1249) added two jobs to `governance-reusable.yml`: `JS runtimes — environment provisions Bun first` and `JS runtimes — ${{ matrix.runtime }}`. It did not add them to the frozen job-name list in `tests/test_governance_reusable_shape.sh`. As a result, Repo self-tests fails on main and on every PR based on it, including [#1255](#1255), with "job names drifted from the frozen list". `gates.json` `context_freeze` allows adding a job, so commit b1d9cb3 adds both names to the list, and they are frozen from now on. Both are blocking jobs, so neither belongs in `never_required_contexts`. The test now passes 14 of 14. ## Consumers Nothing in this repo, `gitbot-fleet` or `hypatia` reads `panic-attack-findings.json` or the `hypatia-scan-findings` artifact. `panicbot` runs panic-attack itself. No consumer needs changes for the new shape. ## Verification - `scripts/tests/hypatia-blocking-gate-test.sh` now extracts and runs both new steps against fixtures, through Ruby and through the awk fallback (mawk and gawk), with 46 PASS on each. The new cases are: - the skip path (`not_run`, never `[]`) - clean, findings (suppressed findings excluded), crash, the 5-minute cap, no report, and a bad severity - install with no cargo, a stale cache from another commit, a valid cache, a failed build, an empty build, and a pinned build - the cargo arguments include `--rev <sha>` and `--locked` - With the old step body swapped back in, the new skip-path case fails and prints the bare `[]`. - End-to-end with the real pinned binary on this repo: `status: ran`, 10 critical, 1 high and 23 medium (unsuppressed), step exit 0. - The exact `cargo install` command builds v2.5.5 in about 3 minutes, and `.crates.toml` records `?rev=<sha>#<sha>`, which is what the cache check relies on. - `scripts/check-lock-sync.sh` passes. No new `uses:` was added. - `scripts/check-workflow-duplicate-keys.sh` and `scripts/check-inline-python.sh` pass. - The local full-suite run showed the same failure set with and without this PR. All of those failures but `test_governance_reusable_shape.sh` come from this container lacking `ijson-jcs`, bun, deno and mikefarah's `yq`. CI, which has those tools, failed only on `test_governance_reusable_shape.sh`, which the commit above fixes. ## Note Once merged, every estate caller's Hypatia run will show the real panic-attack counts as an advisory warning. This repo alone has 10 critical and 1 high. 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01N6my4F3ohjwFReLW8cYYqC --------- Co-authored-by: Claude <noreply@anthropic.com>
K9 contract conformancerun https://github.com/hyperpolymath/standards/actions/runs/38557566470 K9 normative contract typecheckK9 contract self-testK9 conformance fixturesK9 corpus conformance (L2) |
|
…n bumpers (#1254) ## Why `scripts/apply-workflow-pins-remote.sh`, the scheduled pin applier, fetches and commits only `*.yml`. The local `propagate-workflow-pins.sh` has the same gap. Both re-point `uses: hyperpolymath/standards/...@SHA` and leave `actions.lock` keyed to the old commit. `check-lock-sync.sh` rejects that state, and its own header records GitHub refusing such runs at startup. The ledger census in `apply-workflow-pins.yml` counts 200 of 368 governance callers with an `actions.lock`. A fix-mode run would therefore have opened PRs that stop those repos' reusable-calling workflows. This came up while fixing a stale `da2c748` pin, whose unpinned `gh-actions-lock` fails Actions lockfile verify. That fix landed in [resource-algebra#6](hyperpolymath/resource-algebra#6) and [rsr-template-repo#237](hyperpolymath/rsr-template-repo#237), and both needed this relock done by hand. ## What - **`scripts/relock-standards-pin.sh`** (new) moves a consumer's lock to the target standards commit: - re-keys the per-workflow entries; - rebuilds the standards dependency record from what the reusables called with a full pin use at the target; - copies the records those need verbatim from standards' own lock; - prunes only records the old standards record alone kept alive; - keeps `gh-actions-lock`'s record order. - **Short pins.** A short pin of 7 or more hex that prefixes the target is current. This matches the applier, which counts it FRESH and leaves it as written. It keeps its own short-keyed record, untouched. - **It is fail-closed.** It leaves the lock untouched and exits 1 when: - a workflow pins another standards commit, or a pin under 7 hex; - a reusable is absent at the target; - the old record is missing; - a needed record is in neither lock; - a workflow's standards entries would not name exactly the refs it pins. - **The applier** fetches `actions.lock` with the workflows and relocks it in the same verified commit. A repo whose lock can't follow is reported `LOCK-REFUSED` and not landed. In fix mode it fetches the target commit if the CI checkout lacks it, and a new known-answer control fails the run if the relock is missing. - **The propagator** relocks before staging and reports `RELOCKED` / `LOCK-REFUSED`. On a refusal it restores the workflows it rewrote, uncommitted edits included, stages nothing, and leaves the branch alone. Any refusal makes it exit 1. - **Ported:** the frozen job-name fix that #1255 and #1256 also carry. Self Test is red on main without it. ## Evidence - **Known answers.** On resource-algebra and rsr-template-repo, re-pinned from `da2c748` to `ae36881`, the relock reproduces byte for byte the locks verified by hand there. Both pass `check-lock-sync.sh`. resource-algebra's lock relocked to `934b879` passes the governance gate's own `update-actions-lock.sh --verify-local` with gh-actions-lock v0.2.0. - **`scripts/tests/relock-standards-pin-test.sh`**, offline, 16 checks: - the known answer, and idempotence; - eight refusals that leave the lock byte-identical; - the no-lock no-op; - short pins at 7, 12 and 39 hex, each passing `check-lock-sync.sh`. - **`scripts/tests/propagate-workflow-pins-test.sh`**: 29 of 29. - **Mutants**, all killed: - from the first round: no iteration, no pruning, no record copying, no stale-pin refusal, over-pruning, no sorting; - from the review round: exact-match only, every pin feeding the record, no 7-hex minimum, no consistency guard, no restore, no early return. - **Existing suites.** `check-lock-sync-test.sh` 13 of 13, and the applier's `--self-test`. The review round built on CodeRabbit's autofix commits (`cccec83`, `5fd1373`) and kept their tests. Not exercised: a live fix-mode applier run. It needs the dedicated App credential, and it is the owner's dispatch. 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01LiQzWJdcPfRU6YMDGRG8Xi --------- Co-authored-by: Claude <noreply@anthropic.com> Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
…ng engine 0.6.0 (#239) ## Summary The template still taught and enforced the 2026-08-26 "Deno is retired" rule. Your 2026-10-14 ruling replaced it, in standards `LANGUAGE-POLICY.adoc` §1.3–§1.4, on main since hyperpolymath/standards#1249: - the order is **Bun > Deno > pnpm > npm**; - there is one `package.json`; - its `bun.lock`, `deno.lock` and `pnpm-lock.yaml` are all written by `js-runtimes regen`. This PR is the template half of hyperpolymath/standards#1255, which promised it ("rsr-template-repo is next"). **One gate contradicted the ruling outright.** `runtime-policy.yml` failed every repository with more than one lockfile, so it failed every repository that follows the ruling: ``` ::error::Mixed toolchains: 3 package managers have lockfiles in this repository. ``` Every repository minted from this template carries that gate (resource-algebra does, for example), so the fix starts here. ## Changes - **`.github/workflows/runtime-policy.yml`**: - `bun.lock`, `deno.lock` and `pnpm-lock.yaml` count as one dependency graph, locked three ways. Governance's `JS runtimes — …` jobs check each lock against `package.json`. - An npm `package-lock.json` next to them is still "mixed toolchains" and fails. - A `deno.json` / `deno.jsonc` is a notice (your "Notice only" answer), not a warning. - File detection is unchanged; the header comment is rewritten to match. - **Provisioning engine re-synced** to standards `ed04132e` (engine 0.6.0, #1255): `build/just/provision-lib.sh`, `provision-modes.sh` and `provision-check.sh`. - `provision.just` was already identical. - Every line that only the template's copy had is an older revision of canon code, so the copy loses nothing local. - What changes: a `package.json` now provisions bun, deno and pnpm, and deno and pnpm leave the banned tools. The rest is canon's docstrings and the `.mise.toml` / `.tool-versions` / backend checks. - **The same policy in prose.** - The arrival pack's language block (`arrival-pack.ncl`), with `CLAUDE.md` regenerated by `just claude-md`. Nothing in that file was hand-edited. - The `mise.toml` comment. - `docs/SETUP.adoc` rows PV-W23, PV-W30 and PV-W34, and the dev warm-up's "Languages" line, copied from the canon templates. - The JS runtime block in `.cursorrules`, `.clinerules` and `.windsurfrules`. - `.github/copilot-instructions.md`. - The PR template's banned-languages line. - Two comments: `workflow-linter.yml` and `check-action-pinning.js`. - **`CHANGELOG.adoc`**: an entry under Unreleased / Changed. **Left as they are:** - `docs/governance/TEMPLATE-LINEAGE-AUDIT.adoc`, a dated audit record. - The "deno" keyword in `label-classifier.json`, which is a migration-label keyword. - copilot-instructions' TypeScript paragraph. It is stale against the 2026-08-27 "no TypeScript" tightening, which is a different ruling and out of scope here. ## RSR Quality Checklist ### Required - [x] Tests pass (see Testing) - [x] Code is formatted - [x] Linter is clean (shellcheck on the new gate script; workflow validation unchanged at 4 recommendations) - [x] No banned language patterns - [x] No `unsafe` blocks without `// SAFETY:` comments - [x] No banned functions - [x] SPDX license headers present on all new/modified source files (headers unchanged; no new files) - [x] No secrets, credentials, or `.env` files included ### As Applicable - [x] Documentation updated for user-facing changes - [x] `CHANGELOG` or release notes updated ## Testing **Gate, old step against new**, extracted from each workflow with yq and run in fixture directories: | Fixture | old | new | |---|---|---| | empty | rc=0 notice | rc=0 notice | | `bun.lock` + `deno.lock` + `pnpm-lock.yaml` | **rc=1** "Mixed toolchains: 3" | rc=0 | | `bun.lock` + `pnpm-lock.yaml` | **rc=1** | rc=0 | | `package-lock.json` + `bun.lock` | rc=1 | rc=1 | | `package-lock.json` alone | rc=0 warning | rc=0 warning | | `deno.json` + `deno.lock` | rc=0 warning ("being removed") | rc=0 notice | | `bun.lockb` alone | rc=0 | rc=0 | **Repository checks** (just 1.42.4, nickel 1.17.0, mikefarah yq 4.44.3): ``` build/just/provision-check.sh . provision-check: 0 FAIL, 0 WARN provision-lib.sh doctor same results as the old engine; only PASS wording differs .machine_readable/arrival-pack/verify.sh OK: CLAUDE.md arrival pack is in sync with the deed. just validate-repo-map repository map: up to date scripts/validate-template.sh . Validation PASSED (9 warnings; main: 9) tests/workflows/validate_workflows_test.sh Workflow validation PASSED (4 recommendations; main: 4) scripts/check-lock-sync.sh OK shellcheck -S warning (runtime-policy step) clean git diff --check clean ``` The doctor's failures here come from the sandbox (no Guix and similar), and they are the same under both engines. **What follows.** Repositories minted earlier keep the old `runtime-policy.yml` until it is re-synced. Any of them that adopts the three-lock layout goes red on Runtime Policy until then. 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01Y6FD63UrriRBHqmhhEca9t --- _Generated by [Claude Code](https://claude.ai/code/session_01Y6FD63UrriRBHqmhhEca9t)_ --------- Co-authored-by: Claude <noreply@anthropic.com>



Summary
This is the provisioning half of your 2026-10-14 ruling:
standards#1249 ruled Bun > Deno > pnpm > npm, from one
package.jsonthat carries every runtime's lock. The provisioning canon (3-practice/provisioning/) stamps every repository's mise, Guix and doctor. It still enforced the old policy, against that ruling:BANNED_TOOLSand the deed's:banned-toolslistdenoandpnpmmise.tomlthat pins themdeno.locka "Deno leftover"pnpm-lock.yamlan npm/yarn/pnpm leftoverpackage.jsonprovisions onlybunjs-runtimes regen, the only lock writer, also needs deno and pnpmThe PR also fixes a red Self Test on main that #1249 caused (second commit, below).
Changes
templates/build/just/provision-lib.sh, version 0.5.0 → 0.6.0:A
package.jsonnow provisionsbun deno pnpm. That covers:mise use bun@latest deno@latest pnpm@latest);Inside the Guix shell, deno and pnpm come from mise, as bun already does. I did not measure their Guix packages, and the comment says so.
deno,denojsandpnpmleaveBANNED_TOOLS.nodeandnodejsstay banned, so npm, the last resort, is never provisioned.PV-W30 no longer reports
deno.lock. Adeno.json,deno.jsoncorimport_map.jsonnow gets an info line instead of a warning (your "Notice only" answer).PV-W34 no longer reports
pnpm-lock.yaml.package-lock.json,yarn.lockandtsconfig.jsonstill warn.The PV-W23 message reads "Bun > Deno > pnpm".
provisioning-standard_praxis.deed::banned-toolsloses the same three names. It must stay one list withBANNED_TOOLS, and launch-scaffolder tests that.:guix-gapsgainsdenoandpnpm.PROVISIONING-STANDARD.adoc§4;mise.toml.tmpl;llm-warmup-dev.adoc.tmpl;docs/SETUP.adoc.tmpl.tests/test_governance_reusable_shape.sh(f22d5a6f) fixes a regression from feat(js): one package.json, every runtime — Bun > Deno > pnpm > npm (Rust tools/js-runtimes, in governance) #1249:JS runtimes — …jobs togovernance-reusable.ymlbut left them off this test's context-freeze list.25d23cf3("job names drifted from the frozen list").What follows.
provision-set realign). Until then,provisioning-checkreports the drift.CLAUDE.mdlanguage lines, which still say "Deny … Deno".Testing
Fixture:
package.json;mise.tomlpinning just, shellcheck, bun, deno and pnpm;Old engine against new:
langsbunbunmise-toolsjust shellcheck bunjust shellcheck bun deno pnpmguix-gapsbunbun deno pnpmmise-banneddeno pnpmWARN PV-W30 deno.lock,WARN PV-W34 pnpm-lock.yamlPASS no nix / make / python / npm leftoversControls on 0.6.0:
node = "22"inmise.toml:mise-bannedexits 1 and namesnode.package-lock.json:WARN PV-W34 package-lock.json ….deno.json:info PV-W30 deno.json — authored for Deno (permitted, tier 2) ….Gates:
Local suite caveat. Run in this sandbox,
run-shell-test-suite.shfails six other test files: ijson-jcs, js-runtimes, gh-actions-lock contract, actions-lock gate, kyaml-format and science-ci-security. Each one needs a tool the sandbox lacks: theijson-jcsbinary, deno,gh-actions-lock, and Goyq. On CI, the same suite at7fcbc4a6failed only the shape test ("1 of 86 test file(s) failed"), and this PR touches none of those six files.🤖 Generated with Claude Code
https://claude.ai/code/session_01Y6FD63UrriRBHqmhhEca9t
Generated by Claude Code