Skip to content

feat(provisioning): a package.json provisions bun, deno and pnpm; deno and pnpm leave the banned list - #1255

Merged
hyperpolymath merged 3 commits into
mainfrom
claude/new-session-ywdrth
Oct 14, 2026
Merged

hyperpolymath merged 3 commits into
mainfrom
claude/new-session-ywdrth

Conversation

@hyperpolymath

@hyperpolymath hyperpolymath commented Oct 14, 2026 •

Copy link
Copy Markdown
Owner

Summary

This is the provisioning half of your 2026-10-14 ruling:

for everything that requires one of these things to operate, built into the repo/environment set up (e.g. containers, guix, mise, etc. etc.)

standards#1249 ruled Bun > Deno > pnpm > npm, from one package.json that 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:

Before Effect on a compliant repository
BANNED_TOOLS and the deed's :banned-tools list deno and pnpm doctor PV-W23 warns on a mise.toml that pins them
PV-W30 calls deno.lock a "Deno leftover" warns on a lock every package must carry
PV-W34 calls pnpm-lock.yaml an npm/yarn/pnpm leftover the same
a package.json provisions only bun js-runtimes regen, the only lock writer, also needs deno and pnpm

The 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.json now provisions bun deno pnpm. That covers:

      • the mise tools;
      • the doctor's binary probe;
      • the remedy text (mise use bun@latest deno@latest pnpm@latest);
      • the Guix gap.

      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, denojs and pnpm leave BANNED_TOOLS. node and nodejs stay banned, so npm, the last resort, is never provisioned.

    • PV-W30 no longer reports deno.lock. A deno.json, deno.jsonc or import_map.json now gets an info line instead of a warning (your "Notice only" answer).

    • PV-W34 no longer reports pnpm-lock.yaml. package-lock.json, yarn.lock and tsconfig.json still warn.

    • The PV-W23 message reads "Bun > Deno > pnpm".

  • provisioning-standard_praxis.deed:
    • :banned-tools loses the same three names. It must stay one list with BANNED_TOOLS, and launch-scaffolder tests that.
    • :guix-gaps gains deno and pnpm.
  • Prose updates (the same policy, in words) in:
    • PROVISIONING-STANDARD.adoc §4;
    • mise.toml.tmpl;
    • llm-warmup-dev.adoc.tmpl;
    • the PV-W30/W34 rows of 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:

What follows.

  • Each repository picks this up the next time its engine is re-synced (provision-set realign). Until then, provisioning-check reports the drift.
  • rsr-template-repo is next. Once this merges, I'll re-sync it, together with its CLAUDE.md language lines, which still say "Deny … Deno".

Testing

Fixture:

  • a package.json;
  • a mise.toml pinning just, shellcheck, bun, deno and pnpm;
  • the three locks.

Old engine against new:

0.5.0 0.6.0
langs bun bun
mise-tools just shellcheck bun just shellcheck bun deno pnpm
guix-gaps bun bun deno pnpm
mise-banned exit 1, deno pnpm exit 0
doctor, policy drift WARN PV-W30 deno.lock, WARN PV-W34 pnpm-lock.yaml PASS no nix / make / python / npm leftovers

Controls on 0.6.0:

  • node = "22" in mise.toml: mise-banned exits 1 and names node.
  • A package-lock.json: WARN PV-W34 package-lock.json ….
  • A deno.json: info PV-W30 deno.json — authored for Deno (permitted, tier 2) ….

Gates:

deed_lint.js provisioning-standard_praxis.deed   OK
deed :banned-tools == BANNED_TOOLS                agree (17 names)
bash -n / shellcheck -S warning provision-lib.sh  clean
check-lock-sync.sh                                OK
check-exemption-ratchet.sh origin/main            Exemption ratchet: OK.
check-language-policy.sh                          language policy OK
test_governance_reusable_shape.sh                 passed=14 failed=0
  control: rename "Debt ratchet" locally          FAIL: job names drifted … (< Debt ratchet / > Debt ratchets)

Local suite caveat. Run in this sandbox, run-shell-test-suite.sh fails 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: the ijson-jcs binary, deno, gh-actions-lock, and Go yq. On CI, the same suite at 7fcbc4a6 failed 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

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

coderabbitai Bot commented Oct 14, 2026 •

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

You'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.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

Learn how review limits work.

Review configuration:

⚙️ Run configuration
  • Configuration used: Organization UI
  • Review profile: ASSERTIVE
  • Plan: Advanced
  • Run ID: 0f4b697c-a305-4f7e-8d56-0767a70ab72a
📥 Commits

Reviewing files that changed from the base of the PR and between 25824f3 and 56e1c2c.

📒 Files selected for processing: 6
  • 3-practice/provisioning/PROVISIONING-STANDARD.adoc
  • 3-practice/provisioning/provisioning-standard_praxis.deed
  • 3-practice/provisioning/templates/build/just/provision-lib.sh
  • 3-practice/provisioning/templates/docs/SETUP.adoc.tmpl
  • 3-practice/provisioning/templates/llm-warmup-dev.adoc.tmpl
  • 3-practice/provisioning/templates/mise.toml.tmpl
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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.

@github-actions

Copy link
Copy Markdown
Contributor

K9 contract conformance

run https://github.com/hyperpolymath/standards/actions/runs/38556116505

K9 normative contract typecheck

k9_contract.ncl typechecks

K9 contract self-test

== the bash mirrors cannot drift from the normative contract ==
ok   leash_levels mirrors k9_contract.ncl
ok   core_capabilities mirrors k9_contract.ncl
ok   contract_version mirrors k9_contract.ncl
ok   schema_major mirrors k9_contract.ncl
== capability arithmetic (§8) ==
ok   capability_ok fs.read accepted
ok   capability_ok rollback.apply accepted
ok   capability_ok x-acme.gpu.alloc accepted
ok   capability_ok x-acme rejected
ok   capability_ok x-.gpu rejected
ok   capability_ok fs.delete rejected
ok   capability_ok  rejected
== the extractor ==
ok   extracts pedigree.security.leash
ok   extracts pedigree.component_type
ok   extracts pedigree.metadata.name
ok   pedigree leash is not reported as top-level leash
ok   required_capabilities for a quiet component
ok   required_capabilities follows allow_network
== the envelope strip keeps line numbers (§3.6) ==
ok   line 1 becomes a comment
ok   line count is preserved
ok   schema_version stays on line 5
== L3: signature presence is not verification (§10) ==
ok   no verifier -> K9-C001 is SKIPPED, never a pass
ok   the skip states presence does not authorise 'Hunt
ok   verifier accepts -> verdict 'Verified, no K9-C001 finding
ok   verifier refuses -> K9-C001 error, verdict 'Rejected
== the fixture runner's attribution cannot be fooled by a filename ==
ok   every extracted finding is well-formed rule+layer
ok   the rule that really fired is attributed
ok   a rule named only in the filename is NOT attributed
ok   K9-C001 is present as a skipped finding
ok   and that same finding is NOT extractable as a rejection
== the dialect discriminator agrees with the coordination grammar (§4.3) ==
ok   magic file opening '---' is coordination
ok   magic file opening 'metadata:' is coordination
ok   plain file opening '---' is unclaimed
ok   plain file opening 'metadata:' is unclaimed
== no Nickel reserved word is used as an identifier ==
ok   the contract and all 27 fixtures avoid Nickel's reserved words

self-test: all assertions passed

K9 conformance fixtures

== positive controls (must pass) ==
ok   extension-capability.k9.ncl
ok   extension-fields.k9.ncl
ok   hunt-fully-granted.k9.ncl
ok   kennel-data.k9.ncl
ok   library-base.ncl
ok   yard-typed-config.k9.ncl

== negative controls (must fail, by the named rule) ==
ok   L0-K9-E001-bad-magic.k9.ncl (rejected by K9-E001 at L0)
ok   L0-K9-E002-nul-byte.k9.ncl (rejected by K9-E002 at L0)
ok   L0-K9-E003-crlf.k9.ncl (rejected by K9-E003 at L0)
ok   L0-K9-E004-no-spdx.k9.ncl (rejected by K9-E004 at L0)
ok   L0-K9-E005-unclaimed-body.k9.ncl (rejected by K9-E005 at L0)
ok   L0-K9-S012-library-with-pedigree.ncl (rejected by K9-S012 at L0)
ok   L0-K9-S014-stray-leash.ncl (rejected by K9-S014 at L0)
ok   L1-K9-S001-no-pedigree.k9.ncl (rejected by K9-S001 at L1)
ok   L1-K9-S002-wrong-major.k9.ncl (rejected by K9-S002 at L1)
ok   L1-K9-S003-todo-component-type.k9.ncl (rejected by K9-S003 at L1)
ok   L1-K9-S004-unknown-leash.k9.ncl (rejected by K9-S004 at L1)
ok   L1-K9-S005-missing-name.k9.ncl (rejected by K9-S005 at L1)
ok   L1-K9-S006-unknown-capability.k9.ncl (rejected by K9-S006 at L1)
ok   L1-K9-S007-ungranted-flag.k9.ncl (rejected by K9-S007 at L1)
ok   L1-K9-S008-hunt-signature-not-required.k9.ncl (rejected by K9-S008 at L1)
ok   L1-K9-S009-hunt-no-signature-block.k9.ncl (rejected by K9-S009 at L1)
ok   L1-K9-S010-hunt-empty-side-effects.k9.ncl (rejected by K9-S010 at L1)
ok   L1-K9-S011-recipes-at-yard.k9.ncl (rejected by K9-S011 at L1)
ok   L1-K9-S013-dangling-import.k9.ncl (rejected by K9-S013 at L1)
ok   L2-K9-N001-two-segment-version.k9.ncl (rejected by K9-N001 at L2)
ok   L2-K9-N001-wrong-field-type.k9.ncl (rejected by K9-N001 at L2)

fixtures: 6 positive, 21 negative (0 needing nickel), 0 failure(s)

K9 corpus conformance (L2)

[validate-k9] 14 conforming, 0 grandfathered (layer all, contract v1.0.0)

@hyperpolymath
hyperpolymath marked this pull request as ready for review October 14, 2026 11:26
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
@github-actions

Copy link
Copy Markdown
Contributor

K9 contract conformance

run https://github.com/hyperpolymath/standards/actions/runs/38557133562

K9 normative contract typecheck

k9_contract.ncl typechecks

K9 contract self-test

== the bash mirrors cannot drift from the normative contract ==
ok   leash_levels mirrors k9_contract.ncl
ok   core_capabilities mirrors k9_contract.ncl
ok   contract_version mirrors k9_contract.ncl
ok   schema_major mirrors k9_contract.ncl
== capability arithmetic (§8) ==
ok   capability_ok fs.read accepted
ok   capability_ok rollback.apply accepted
ok   capability_ok x-acme.gpu.alloc accepted
ok   capability_ok x-acme rejected
ok   capability_ok x-.gpu rejected
ok   capability_ok fs.delete rejected
ok   capability_ok  rejected
== the extractor ==
ok   extracts pedigree.security.leash
ok   extracts pedigree.component_type
ok   extracts pedigree.metadata.name
ok   pedigree leash is not reported as top-level leash
ok   required_capabilities for a quiet component
ok   required_capabilities follows allow_network
== the envelope strip keeps line numbers (§3.6) ==
ok   line 1 becomes a comment
ok   line count is preserved
ok   schema_version stays on line 5
== L3: signature presence is not verification (§10) ==
ok   no verifier -> K9-C001 is SKIPPED, never a pass
ok   the skip states presence does not authorise 'Hunt
ok   verifier accepts -> verdict 'Verified, no K9-C001 finding
ok   verifier refuses -> K9-C001 error, verdict 'Rejected
== the fixture runner's attribution cannot be fooled by a filename ==
ok   every extracted finding is well-formed rule+layer
ok   the rule that really fired is attributed
ok   a rule named only in the filename is NOT attributed
ok   K9-C001 is present as a skipped finding
ok   and that same finding is NOT extractable as a rejection
== the dialect discriminator agrees with the coordination grammar (§4.3) ==
ok   magic file opening '---' is coordination
ok   magic file opening 'metadata:' is coordination
ok   plain file opening '---' is unclaimed
ok   plain file opening 'metadata:' is unclaimed
== no Nickel reserved word is used as an identifier ==
ok   the contract and all 27 fixtures avoid Nickel's reserved words

self-test: all assertions passed

K9 conformance fixtures

== positive controls (must pass) ==
ok   extension-capability.k9.ncl
ok   extension-fields.k9.ncl
ok   hunt-fully-granted.k9.ncl
ok   kennel-data.k9.ncl
ok   library-base.ncl
ok   yard-typed-config.k9.ncl

== negative controls (must fail, by the named rule) ==
ok   L0-K9-E001-bad-magic.k9.ncl (rejected by K9-E001 at L0)
ok   L0-K9-E002-nul-byte.k9.ncl (rejected by K9-E002 at L0)
ok   L0-K9-E003-crlf.k9.ncl (rejected by K9-E003 at L0)
ok   L0-K9-E004-no-spdx.k9.ncl (rejected by K9-E004 at L0)
ok   L0-K9-E005-unclaimed-body.k9.ncl (rejected by K9-E005 at L0)
ok   L0-K9-S012-library-with-pedigree.ncl (rejected by K9-S012 at L0)
ok   L0-K9-S014-stray-leash.ncl (rejected by K9-S014 at L0)
ok   L1-K9-S001-no-pedigree.k9.ncl (rejected by K9-S001 at L1)
ok   L1-K9-S002-wrong-major.k9.ncl (rejected by K9-S002 at L1)
ok   L1-K9-S003-todo-component-type.k9.ncl (rejected by K9-S003 at L1)
ok   L1-K9-S004-unknown-leash.k9.ncl (rejected by K9-S004 at L1)
ok   L1-K9-S005-missing-name.k9.ncl (rejected by K9-S005 at L1)
ok   L1-K9-S006-unknown-capability.k9.ncl (rejected by K9-S006 at L1)
ok   L1-K9-S007-ungranted-flag.k9.ncl (rejected by K9-S007 at L1)
ok   L1-K9-S008-hunt-signature-not-required.k9.ncl (rejected by K9-S008 at L1)
ok   L1-K9-S009-hunt-no-signature-block.k9.ncl (rejected by K9-S009 at L1)
ok   L1-K9-S010-hunt-empty-side-effects.k9.ncl (rejected by K9-S010 at L1)
ok   L1-K9-S011-recipes-at-yard.k9.ncl (rejected by K9-S011 at L1)
ok   L1-K9-S013-dangling-import.k9.ncl (rejected by K9-S013 at L1)
ok   L2-K9-N001-two-segment-version.k9.ncl (rejected by K9-N001 at L2)
ok   L2-K9-N001-wrong-field-type.k9.ncl (rejected by K9-N001 at L2)

fixtures: 6 positive, 21 negative (0 needing nickel), 0 failure(s)

K9 corpus conformance (L2)

[validate-k9] 14 conforming, 0 grandfathered (layer all, contract v1.0.0)

hyperpolymath pushed a commit that referenced this pull request Oct 14, 2026
…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
hyperpolymath added a commit that referenced this pull request Oct 14, 2026
…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>
@github-actions

Copy link
Copy Markdown
Contributor

K9 contract conformance

run https://github.com/hyperpolymath/standards/actions/runs/38557566470

K9 normative contract typecheck

k9_contract.ncl typechecks

K9 contract self-test

== the bash mirrors cannot drift from the normative contract ==
ok   leash_levels mirrors k9_contract.ncl
ok   core_capabilities mirrors k9_contract.ncl
ok   contract_version mirrors k9_contract.ncl
ok   schema_major mirrors k9_contract.ncl
== capability arithmetic (§8) ==
ok   capability_ok fs.read accepted
ok   capability_ok rollback.apply accepted
ok   capability_ok x-acme.gpu.alloc accepted
ok   capability_ok x-acme rejected
ok   capability_ok x-.gpu rejected
ok   capability_ok fs.delete rejected
ok   capability_ok  rejected
== the extractor ==
ok   extracts pedigree.security.leash
ok   extracts pedigree.component_type
ok   extracts pedigree.metadata.name
ok   pedigree leash is not reported as top-level leash
ok   required_capabilities for a quiet component
ok   required_capabilities follows allow_network
== the envelope strip keeps line numbers (§3.6) ==
ok   line 1 becomes a comment
ok   line count is preserved
ok   schema_version stays on line 5
== L3: signature presence is not verification (§10) ==
ok   no verifier -> K9-C001 is SKIPPED, never a pass
ok   the skip states presence does not authorise 'Hunt
ok   verifier accepts -> verdict 'Verified, no K9-C001 finding
ok   verifier refuses -> K9-C001 error, verdict 'Rejected
== the fixture runner's attribution cannot be fooled by a filename ==
ok   every extracted finding is well-formed rule+layer
ok   the rule that really fired is attributed
ok   a rule named only in the filename is NOT attributed
ok   K9-C001 is present as a skipped finding
ok   and that same finding is NOT extractable as a rejection
== the dialect discriminator agrees with the coordination grammar (§4.3) ==
ok   magic file opening '---' is coordination
ok   magic file opening 'metadata:' is coordination
ok   plain file opening '---' is unclaimed
ok   plain file opening 'metadata:' is unclaimed
== no Nickel reserved word is used as an identifier ==
ok   the contract and all 27 fixtures avoid Nickel's reserved words

self-test: all assertions passed

K9 conformance fixtures

== positive controls (must pass) ==
ok   extension-capability.k9.ncl
ok   extension-fields.k9.ncl
ok   hunt-fully-granted.k9.ncl
ok   kennel-data.k9.ncl
ok   library-base.ncl
ok   yard-typed-config.k9.ncl

== negative controls (must fail, by the named rule) ==
ok   L0-K9-E001-bad-magic.k9.ncl (rejected by K9-E001 at L0)
ok   L0-K9-E002-nul-byte.k9.ncl (rejected by K9-E002 at L0)
ok   L0-K9-E003-crlf.k9.ncl (rejected by K9-E003 at L0)
ok   L0-K9-E004-no-spdx.k9.ncl (rejected by K9-E004 at L0)
ok   L0-K9-E005-unclaimed-body.k9.ncl (rejected by K9-E005 at L0)
ok   L0-K9-S012-library-with-pedigree.ncl (rejected by K9-S012 at L0)
ok   L0-K9-S014-stray-leash.ncl (rejected by K9-S014 at L0)
ok   L1-K9-S001-no-pedigree.k9.ncl (rejected by K9-S001 at L1)
ok   L1-K9-S002-wrong-major.k9.ncl (rejected by K9-S002 at L1)
ok   L1-K9-S003-todo-component-type.k9.ncl (rejected by K9-S003 at L1)
ok   L1-K9-S004-unknown-leash.k9.ncl (rejected by K9-S004 at L1)
ok   L1-K9-S005-missing-name.k9.ncl (rejected by K9-S005 at L1)
ok   L1-K9-S006-unknown-capability.k9.ncl (rejected by K9-S006 at L1)
ok   L1-K9-S007-ungranted-flag.k9.ncl (rejected by K9-S007 at L1)
ok   L1-K9-S008-hunt-signature-not-required.k9.ncl (rejected by K9-S008 at L1)
ok   L1-K9-S009-hunt-no-signature-block.k9.ncl (rejected by K9-S009 at L1)
ok   L1-K9-S010-hunt-empty-side-effects.k9.ncl (rejected by K9-S010 at L1)
ok   L1-K9-S011-recipes-at-yard.k9.ncl (rejected by K9-S011 at L1)
ok   L1-K9-S013-dangling-import.k9.ncl (rejected by K9-S013 at L1)
ok   L2-K9-N001-two-segment-version.k9.ncl (rejected by K9-N001 at L2)
ok   L2-K9-N001-wrong-field-type.k9.ncl (rejected by K9-N001 at L2)

fixtures: 6 positive, 21 negative (0 needing nickel), 0 failure(s)

K9 corpus conformance (L2)

[validate-k9] 14 conforming, 0 grandfathered (layer all, contract v1.0.0)

@sonarqubecloud

Copy link
Copy Markdown

@hyperpolymath
hyperpolymath merged commit ed04132 into main Oct 14, 2026
70 checks passed
@hyperpolymath
hyperpolymath deleted the claude/new-session-ywdrth branch October 14, 2026 11:38
hyperpolymath added a commit that referenced this pull request Oct 14, 2026
…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>
hyperpolymath added a commit to hyperpolymath/rsr-template-repo that referenced this pull request Oct 14, 2026
…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>
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.

2 participants