Skip to content

ci: restore block YAML so the actions-lock gate can read the pins - #73

Merged
hyperpolymath merged 3 commits into
mainfrom
fix/block-yaml-for-actions-lock-gate
Oct 9, 2026
Merged

hyperpolymath merged 3 commits into
mainfrom
fix/block-yaml-for-actions-lock-gate

Conversation

@hyperpolymath

@hyperpolymath hyperpolymath commented Oct 8, 2026 •

Copy link
Copy Markdown
Owner

Summary

This fixes the one red job left on main after #72: Governance › Actions lockfile verify (run 37857359718, job 113584648380). Two separate defects stand in the way. This PR clears the first; the second needs a standards change.

  1. The gate cannot read KYAML. Fixed here. scripts/check-actions-lock-gate.sh@900c42c, lines 66–68, accepts a pin only as @[a-f0-9]{40} followed by whitespace or end of line. It also exempts standards reusables only in the unquoted form uses: hyperpolymath/standards/. KYAML writes uses: "…@<sha>",, so the four workflows ci: refresh standards pins to 900c42c; fix mirror startup failure #72 converted all read as unpinned and the gate exits 1. The lock-debt ledger excuses only exit 3. Restoring block YAML turns that into exit 3, which is ledgerable (hyperpolymath/jaffascript is line 117 of standards .machine_readable/lock-allow.txt).
  2. The ledger is unreachable. Needs fix(governance): make the actions-lock ledger reachable under bash -e standards#1209. The step runs under the runner's default bash -e, so gate exit 3 kills it before rc=$? and the ledger check ever run. Since standards 4f7f02ca, no ledgered repository has been excused. On this branch the job now fails with exit 3 instead of exit 1, which shows that part 1 works.

Depends on hyperpolymath/standards#1209. Once that merges, this PR bumps all four standards pins to its merge commit. The check should then go green through the ledger. Do not merge before that: on 900c42c it stays red.

Changes

  • governance.yml, scorecard.yml, mirror.yml and secret-scanner.yml go back to block YAML. For governance, mirror and secret-scanner, the parsed data is identical to main, checked with a yq -o json 'sort_keys(..)' compare. Pins, permissions, triggers and secrets maps are unchanged.
  • scorecard.yml: the workflow-level permissions: read-all becomes contents: read. This answers SonarCloud githubactions:S8234, the one PR-scoped issue (api/issues/search?pullRequest=73, total=1). No effective permission changes: the only job, analysis, declares its own map, and a job-level map replaces the workflow-level one. That map is unchanged.
  • This follows the estate rule: a workflow converts to KYAML only once the repo's gates read KYAML. This gate does not yet, and that is recorded as a finding for standards.

📌 New pins

RSR Quality Checklist

Required

  • Tests pass: n/a. This PR changes CI workflow files only, and the workflows' runs on this PR are the test.
  • Code is formatted: block YAML, the repo's form before ci: refresh standards pins to 900c42c; fix mirror startup failure #72.
  • Linter is clean: actionlint on the four files exits 0.
  • No banned language patterns: YAML only.
  • No unsafe blocks: n/a, no Rust changed.
  • No banned functions: n/a, no source or proofs changed.
  • SPDX headers present: unchanged from main (MPL-2.0).
  • No secrets or credentials: the mirror map passes secret references only.

As Applicable

  • .machine_readable/* updated: n/a, no project-state change.
  • Documentation, TOPOLOGY.md, CHANGELOG: n/a, CI only.
  • New dependencies: none.
  • ABI/FFI: n/a.

Testing

I ran the real gate script, check-actions-lock-gate.sh@900c42c, locally:

  • This branch (block YAML): exit 3, missing-lock debt. CI agrees (run 37857649612: Process completed with exit code 3).
  • Control, the KYAML files from main: exit 1, which matches main's CI failure.

On standards#1209 I ran the whole step script under /usr/bin/bash -e:

  • Fixed step + this branch's files + GITHUB_REPOSITORY=hyperpolymath/jaffascript: exit 0, with the LEDGERED notice.
  • Unfixed step: exit 3.
  • An unledgered name: exit 3.

Other checks:

  • yq parsed-data compare against main: identical for three files. For scorecard, the only difference is the permissions value above.

Red checks on this head

  • governance / Actions lockfile verify: expected until the pin bump after standards#1209 (above).

🤖 Generated with Claude Code

https://claude.ai/code/session_01GpUzjdhWFi26k6s7AWxYcf

#72 converted the four workflows it edited to KYAML. Governance on main
589e1be then went red in "Actions lockfile verify": standards
scripts/check-actions-lock-gate.sh@900c42c (lines 66-68) accepts a pin
only as `@<40 hex>` followed by whitespace or end of line, and exempts
standards reusables only as an unquoted `uses: hyperpolymath/standards/`.
KYAML's `uses: "…@<sha>",` fails both, so all four SHA-pinned refs were
reported as unpinned (exit 1, which the lock-debt ledger cannot excuse).

Block YAML gives the gate's exit 3 (missing lockfile), and
hyperpolymath/jaffascript is on the shrink-only lock-allow.txt ledger,
so the step passes. The parsed data of all four files is identical to
main (yq JSON compare); only the serialisation changes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GpUzjdhWFi26k6s7AWxYcf
@coderabbitai

coderabbitai Bot commented Oct 8, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

Note

Currently processing new changes in this PR. This may take a few minutes, please wait...

⚙️ Run configuration
  • Configuration used: Organization UI
  • Review profile: ASSERTIVE
  • Plan: Advanced
  • Run ID: 9e38f70e-ac25-4322-be72-1fea30bc34df
📥 Commits

Reviewing files that changed from the base of the PR and between f028d1f and 54e6a34.

📒 Files selected for processing (1)
  • .github/workflows/scorecard.yml
 ______________________________________________________
< GPU fans at max RPM: ready to blow away regressions. >
 ------------------------------------------------------
  \
   \   \
        \ /\
        ( )
      .( o ).

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Organization UI
  • Review profile: ASSERTIVE
  • Plan: Advanced
  • Run ID: 701cde53-d54c-4b41-ba48-91d5263cd0de
📥 Commits

Reviewing files that changed from the base of the PR and between 589e1be and f028d1f.

📒 Files selected for processing (4)
  • .github/workflows/governance.yml
  • .github/workflows/mirror.yml
  • .github/workflows/scorecard.yml
  • .github/workflows/secret-scanner.yml

Included review availability: This review used your included allowance. Your plan provides up to 1 included review per hour; 0 remain after this review.

📜 Recent review details
⏰ Context from checks skipped due to timeout. (10)
  • GitHub Check: governance / Validate Hypatia Baseline
  • GitHub Check: governance / Workflow security linter
  • GitHub Check: governance / Exemption ratchet
  • GitHub Check: governance / Code quality + docs
  • GitHub Check: governance / Guix packaging policy (Nix retired)
  • GitHub Check: governance / Debt ratchet
  • GitHub Check: governance / Security policy checks
  • GitHub Check: analyze (actions, none)
  • GitHub Check: Hypatia Neurosymbolic Analysis
  • GitHub Check: semgrep-cloud-platform/scan
⚠️ CI failures not shown inline (11)

GitHub Actions: Governance / 3_governance _ Workflow security linter.txt: ci: restore block YAML so the actions-lock gate can read the pins

Conclusion: failure

View job details

##[group]Run # GitHub Actions REJECTS a workflow with duplicate keys: the run is
 �[36;1m# GitHub Actions REJECTS a workflow with duplicate keys: the run is�[0m
 �[36;1m# `failure` with no jobs, no log and no check run. Nothing else here�[0m
 �[36;1m# can see it, because yaml.safe_load silently keeps the LAST�[0m
 �[36;1m# duplicate and reports success — so the file "parses" and every�[0m
 �[36;1m# other lint passes. Measured 2026-08-05: nine workflows in hypatia�[0m
 �[36;1m# were dead this way, including a CodeQL workflow with zero�[0m
 �[36;1m# successful runs in its entire lifetime.�[0m
 �[36;1mset -euo pipefail�[0m
 �[36;1mSCRIPT=".standards-dupkey/scripts/check-workflow-duplicate-keys.sh"�[0m
 �[36;1m# Self-hosting fallback: when THIS repository is standards, its own�[0m
 �[36;1m# working tree already holds the script, and during a rename that copy�[0m
 �[36;1m# is the only correct one — the pinned main checkout still has the old�[0m
 �[36;1m# name. Preferring the fetched copy keeps every other caller on the�[0m
 �[36;1m# canonical version.�[0m
 �[36;1mif [ ! -f "$SCRIPT" ] && [ -f scripts/check-workflow-duplicate-keys.sh ]; then�[0m
 �[36;1m  SCRIPT="scripts/check-workflow-duplicate-keys.sh"�[0m
 �[36;1m  echo "Using this repository's own copy (standards self-lint)."�[0m
 �[36;1mfi�[0m
 �[36;1mif [ ! -f "$SCRIPT" ]; then�[0m
 �[36;1m  echo "::error::duplicate-key checker not found — neither fetched from" \�[0m

GitHub Actions: Governance / governance _ Workflow security linter: ci: restore block YAML so the actions-lock gate can read the pins

Conclusion: failure

View job details

##[group]Run # GitHub Actions REJECTS a workflow with duplicate keys: the run is
 �[36;1m# GitHub Actions REJECTS a workflow with duplicate keys: the run is�[0m
 �[36;1m# `failure` with no jobs, no log and no check run. Nothing else here�[0m
 �[36;1m# can see it, because yaml.safe_load silently keeps the LAST�[0m
 �[36;1m# duplicate and reports success — so the file "parses" and every�[0m
 �[36;1m# other lint passes. Measured 2026-08-05: nine workflows in hypatia�[0m
 �[36;1m# were dead this way, including a CodeQL workflow with zero�[0m
 �[36;1m# successful runs in its entire lifetime.�[0m
 �[36;1mset -euo pipefail�[0m
 �[36;1mSCRIPT=".standards-dupkey/scripts/check-workflow-duplicate-keys.sh"�[0m
 �[36;1m# Self-hosting fallback: when THIS repository is standards, its own�[0m
 �[36;1m# working tree already holds the script, and during a rename that copy�[0m
 �[36;1m# is the only correct one — the pinned main checkout still has the old�[0m
 �[36;1m# name. Preferring the fetched copy keeps every other caller on the�[0m
 �[36;1m# canonical version.�[0m
 �[36;1mif [ ! -f "$SCRIPT" ] && [ -f scripts/check-workflow-duplicate-keys.sh ]; then�[0m
 �[36;1m  SCRIPT="scripts/check-workflow-duplicate-keys.sh"�[0m
 �[36;1m  echo "Using this repository's own copy (standards self-lint)."�[0m
 �[36;1mfi�[0m
 �[36;1mif [ ! -f "$SCRIPT" ]; then�[0m
 �[36;1m  echo "::error::duplicate-key checker not found — neither fetched from" \�[0m

GitHub Actions: Governance / 4_governance _ Actions lockfile verify.txt: ci: restore block YAML so the actions-lock gate can read the pins

Conclusion: failure

View job details

##[group]Run set -uo pipefail
 �[36;1mset -uo pipefail�[0m
 �[36;1m# Stage the gate, the verifier and the exemption ledger. When THIS�[0m
 �[36;1m# repository is standards, its own working tree already holds all�[0m
 �[36;1m# three (self-lint); every other caller uses the pinned checkout.�[0m
 �[36;1mif [ "$GITHUB_REPOSITORY" = hyperpolymath/standards ]; then�[0m
 �[36;1m  SRC=scripts�[0m
 �[36;1m  LEDGERSRC=.machine_readable�[0m
 �[36;1m  echo "Using this repository's own gate + verifier + ledger (standards self-lint)."�[0m
 �[36;1melse�[0m
 �[36;1m  SRC=.standards-lock/scripts�[0m
 �[36;1m  LEDGERSRC=.standards-lock/.machine_readable�[0m
 �[36;1mfi�[0m
 �[36;1mfor f in check-actions-lock-gate.sh update-actions-lock.sh; do�[0m
 �[36;1m  if [ ! -f "$SRC/$f" ]; then�[0m
 �[36;1m    echo "::error::actions-lock gate: $f not found in $SRC (pinned standards checkout failed?)"�[0m

GitHub Actions: Governance / governance _ Actions lockfile verify: ci: restore block YAML so the actions-lock gate can read the pins

Conclusion: failure

View job details

##[group]Run set -uo pipefail
 �[36;1mset -uo pipefail�[0m
 �[36;1m# Stage the gate, the verifier and the exemption ledger. When THIS�[0m
 �[36;1m# repository is standards, its own working tree already holds all�[0m
 �[36;1m# three (self-lint); every other caller uses the pinned checkout.�[0m
 �[36;1mif [ "$GITHUB_REPOSITORY" = hyperpolymath/standards ]; then�[0m
 �[36;1m  SRC=scripts�[0m
 �[36;1m  LEDGERSRC=.machine_readable�[0m
 �[36;1m  echo "Using this repository's own gate + verifier + ledger (standards self-lint)."�[0m
 �[36;1melse�[0m
 �[36;1m  SRC=.standards-lock/scripts�[0m
 �[36;1m  LEDGERSRC=.standards-lock/.machine_readable�[0m
 �[36;1mfi�[0m
 �[36;1mfor f in check-actions-lock-gate.sh update-actions-lock.sh; do�[0m
 �[36;1m  if [ ! -f "$SRC/$f" ]; then�[0m
 �[36;1m    echo "::error::actions-lock gate: $f not found in $SRC (pinned standards checkout failed?)"�[0m

GitHub Actions: Governance / 9_governance _ Code quality + docs.txt: ci: restore block YAML so the actions-lock gate can read the pins

Conclusion: failure

View job details

##[group]Run set -eo pipefail
 �[36;1mset -eo pipefail�[0m
 �[36;1m# Arming policy, and the evidence it rests on: standards#991.�[0m
 �[36;1m#�[0m
 �[36;1m#   retired-filename -> BLOCKS. A STABLE predicate:�[0m
 �[36;1m#   the retired `.a2ml` spelling of the launcher standard was�[0m
 �[36;1m#   deleted upstream on 2026-09-22�[0m
 �[36;1m#   (standards#952) and stays deleted, so a caller that is clean�[0m
 �[36;1m#   today cannot become defective without editing the citation�[0m
 �[36;1m#   itself. Measured 2026-09-22 over EVERY clone in the estate --�[0m
 �[36;1m#   595 scanned, 553 carrying an origin/main. 432 reference this�[0m
 �[36;1m#   reusable workflow, but only 12 do so at a MUTABLE ref (@main),�[0m
 �[36;1m#   and a new step reaches ONLY those 12: a caller pinned at a SHA�[0m
 �[36;1m#   freezes this whole file, this step included, so it can never�[0m
 �[36;1m#   receive the step at all. The real gate was run against all 12:�[0m
 �[36;1m#   12/12 rc=0, retired=0. Five slugs do carry the retired literal�[0m
 �[36;1m#   (tma-mark2, canonical-ums, the-nash-equilibrium,�[0m
 �[36;1m#   launch-scaffolder, trigger) and their overlap with the armed 12�[0m
 �[36;1m#   is ZERO -- so arming this tier reds ZERO live callers. A�[0m
 �[36;1m#   known-answer positive control fired (rc=1) on three of those�[0m
 �[36;1m#   defective repos through the identical harness, so the twelve�[0m
 �[36;1m#   zeros are a real measurement and not a broken probe.�[0m
 �[36;1m#�[0m
 �[36;1m#   stale-version -> WARNS, and does not block. A TIME-DEPENDENT�[0m
 �[36;1m#   predicate: the gate compares against its own CURRENT_VERSION, so�[0m
 �[36;1m#   every correctly-citing caller flips to defect the moment the�[0m
 �[36;1m#   standard bumps, having done nothing. A baked-in cutoff DATE does�[0m
 �[36;1m#   not cure that -- the #505 split above can use one because its�[0m
 �[36;1m#   missing-CONTRIBUTING population is static, while this population�[0m
 �[36;1m#   is regenerated at every...

GitHub Actions: Governance / governance _ Code quality + docs: ci: restore block YAML so the actions-lock gate can read the pins

Conclusion: failure

View job details

##[group]Run set -eo pipefail
 �[36;1mset -eo pipefail�[0m
 �[36;1m# Arming policy, and the evidence it rests on: standards#991.�[0m
 �[36;1m#�[0m
 �[36;1m#   retired-filename -> BLOCKS. A STABLE predicate:�[0m
 �[36;1m#   the retired `.a2ml` spelling of the launcher standard was�[0m
 �[36;1m#   deleted upstream on 2026-09-22�[0m
 �[36;1m#   (standards#952) and stays deleted, so a caller that is clean�[0m
 �[36;1m#   today cannot become defective without editing the citation�[0m
 �[36;1m#   itself. Measured 2026-09-22 over EVERY clone in the estate --�[0m
 �[36;1m#   595 scanned, 553 carrying an origin/main. 432 reference this�[0m
 �[36;1m#   reusable workflow, but only 12 do so at a MUTABLE ref (@main),�[0m
 �[36;1m#   and a new step reaches ONLY those 12: a caller pinned at a SHA�[0m
 �[36;1m#   freezes this whole file, this step included, so it can never�[0m
 �[36;1m#   receive the step at all. The real gate was run against all 12:�[0m
 �[36;1m#   12/12 rc=0, retired=0. Five slugs do carry the retired literal�[0m
 �[36;1m#   (tma-mark2, canonical-ums, the-nash-equilibrium,�[0m
 �[36;1m#   launch-scaffolder, trigger) and their overlap with the armed 12�[0m
 �[36;1m#   is ZERO -- so arming this tier reds ZERO live callers. A�[0m
 �[36;1m#   known-answer positive control fired (rc=1) on three of those�[0m
 �[36;1m#   defective repos through the identical harness, so the twelve�[0m
 �[36;1m#   zeros are a real measurement and not a broken probe.�[0m
 �[36;1m#�[0m
 �[36;1m#   stale-version -> WARNS, and does not block. A TIME-DEPENDENT�[0m
 �[36;1m#   predicate: the gate compares against its own CURRENT_VERSION, so�[0m
 �[36;1m#   every correctly-citing caller flips to defect the moment the�[0m
 �[36;1m#   standard bumps, having done nothing. A baked-in cutoff DATE does�[0m
 �[36;1m#   not cure that -- the #505 split above can use one because its�[0m
 �[36;1m#   missing-CONTRIBUTING population is static, while this population�[0m
 �[36;1m#   is regenerated at every...

GitHub Actions: Governance / 10_governance _ Well-Known (RFC 9116 + RSR).txt: ci: restore block YAML so the actions-lock gate can read the pins

Conclusion: failure

View job details

##[group]Run SECTXT=""
 �[36;1mSECTXT=""�[0m
 �[36;1m[ -f ".well-known/security.txt" ] && SECTXT=".well-known/security.txt"�[0m
 �[36;1m[ -f "security.txt" ] && SECTXT="security.txt"�[0m
 �[36;1mif [ -z "$SECTXT" ]; then�[0m
 �[36;1m  echo "::warning::No security.txt found."�[0m
 �[36;1m  exit 0�[0m
 �[36;1mfi�[0m
 �[36;1mgrep -q "^Contact:" "$SECTXT" || { echo "::error::Missing Contact field"; exit 1; }�[0m

GitHub Actions: Governance / governance _ Well-Known (RFC 9116 + RSR): ci: restore block YAML so the actions-lock gate can read the pins

Conclusion: failure

View job details

##[group]Run SECTXT=""
 �[36;1mSECTXT=""�[0m
 �[36;1m[ -f ".well-known/security.txt" ] && SECTXT=".well-known/security.txt"�[0m
 �[36;1m[ -f "security.txt" ] && SECTXT="security.txt"�[0m
 �[36;1mif [ -z "$SECTXT" ]; then�[0m
 �[36;1m  echo "::warning::No security.txt found."�[0m
 �[36;1m  exit 0�[0m
 �[36;1mfi�[0m
 �[36;1mgrep -q "^Contact:" "$SECTXT" || { echo "::error::Missing Contact field"; exit 1; }�[0m

GitHub Actions: Governance / governance _ Well-Known (RFC 9116 + RSR): ci: restore block YAML so the actions-lock gate can read the pins

Conclusion: failure

View job details

##[group]Run MIXED=$(grep -rE 'src="http://|href="http://' --include="*.html" --include="*.htm" . 2>/dev/null | grep -vE 'localhost|127\.0\.0\.1|example\.com|lol/|node_modules/|third-party/|vendor/' | head -5)
 �[36;1mMIXED=$(grep -rE 'src="http://|href="http://' --include="*.html" --include="*.htm" . 2>/dev/null | grep -vE 'localhost|127\.0\.0\.1|example\.com|lol/|node_modules/|third-party/|vendor/' | head -5)�[0m
 �[36;1mif [ -n "$MIXED" ]; then�[0m
 �[36;1m  echo "::error::Mixed content (HTTP in HTML)"�[0m

GitHub Actions: Governance / 14_governance _ Security policy checks.txt: ci: restore block YAML so the actions-lock gate can read the pins

Conclusion: failure

View job details

##[group]Run set -uo pipefail
 �[36;1mset -uo pipefail�[0m
 �[36;1mDIR=.github/canonical-references�[0m
 �[36;1mif [ ! -d "$DIR" ]; then�[0m
 �[36;1m  echo "ℹ️  [R5] no $DIR/ — skipped (repo has not opted in)"�[0m
 �[36;1m  exit 0�[0m
 �[36;1mfi�[0m
 �[36;1m# Rule files are read with yq, never a hand parser (YAML-POLICY Y-1); this�[0m
 �[36;1m# gate previously parsed them with Python, which the estate bans.�[0m
 �[36;1mif ! command -v yq >/dev/null 2>&1 || ! command -v jq >/dev/null 2>&1; then�[0m
 �[36;1m  echo "❌ [R5] yq and jq are required on the runner for YAML rule parsing"�[0m
 �[36;1m  exit 2�[0m
 �[36;1mfi�[0m
 �[36;1mmapfile -t files < <(find "$DIR" -maxdepth 1 -type f \( -name '*.yml' -o -name '*.yaml' \) ! -name '.*' | LC_ALL=C sort)�[0m
 �[36;1mif [ "${#files[@]}" -eq 0 ]; then�[0m
 �[36;1m  echo "ℹ️  [R5] $DIR/ has no .yml/.yaml rules — skipped"�[0m
 �[36;1m  exit 0�[0m
 �[36;1mfi�[0m
 �[36;1m�[0m
 �[36;1merr=$(mktemp)�[0m
 �[36;1mtrap 'rm -f "$err"' EXIT�[0m
 �[36;1mtotal=0�[0m
 �[36;1mfor rf in "${files[@]}"; do�[0m
 �[36;1m  if ! cfg=$(yq -o json '.' "$rf" 2>&1); then�[0m
 �[36;1m    echo "❌ [R5] $rf: not parseable YAML: $cfg"; total=$((total + 1)); continue�[0m
 �[36;1m  fi�[0m
 �[36;1m  if [ "$(jq -r 'type' <<<"$cfg")" != object ]; then�[0m
 �[36;1m    echo "❌ [R5] $rf: top-level must be a mapping"; total=$((total + 1)); continue�[0m
 �[36;1m  fi�[0m
 �[36;1m  rid=$(jq -r --arg b "$(basename "$rf")" 'if has("id") then .id | tostring else $b end' <<<"$cfg")�[0m
 �[36;1m  desc=$(jq -r '.description // ""' <<<"$cfg")�[0m
 �[36;1m  canon=$(jq -r '.canonical_pointer // ""' <<<"$cfg")�[0m
 �[36;1m  mapfile -t pats < <(jq -r '(.patterns // [])[]' <<<"$cfg")�[0m
 �[36;1m  mapfile -t includes < <(jq -r '((.scope // {}).include // [])[]' <<<"$cfg")�[0m
 �[36;1m  if [ "${#pats[@]}" -eq 0 ] || [ "${#includes[@]}" -eq 0 ]; then�[0m
 �[36;1m    echo "❌ [R5:$rid] missing patterns or scope.include in $rf"�[0m
 �[36;1m    total=$((total + 1)); continue�[0m
 �[36...

GitHub Actions: Governance / governance _ Security policy checks: ci: restore block YAML so the actions-lock gate can read the pins

Conclusion: failure

View job details

##[group]Run set -uo pipefail
 �[36;1mset -uo pipefail�[0m
 �[36;1mDIR=.github/canonical-references�[0m
 �[36;1mif [ ! -d "$DIR" ]; then�[0m
 �[36;1m  echo "ℹ️  [R5] no $DIR/ — skipped (repo has not opted in)"�[0m
 �[36;1m  exit 0�[0m
 �[36;1mfi�[0m
 �[36;1m# Rule files are read with yq, never a hand parser (YAML-POLICY Y-1); this�[0m
 �[36;1m# gate previously parsed them with Python, which the estate bans.�[0m
 �[36;1mif ! command -v yq >/dev/null 2>&1 || ! command -v jq >/dev/null 2>&1; then�[0m
 �[36;1m  echo "❌ [R5] yq and jq are required on the runner for YAML rule parsing"�[0m
 �[36;1m  exit 2�[0m
 �[36;1mfi�[0m
 �[36;1mmapfile -t files < <(find "$DIR" -maxdepth 1 -type f \( -name '*.yml' -o -name '*.yaml' \) ! -name '.*' | LC_ALL=C sort)�[0m
 �[36;1mif [ "${#files[@]}" -eq 0 ]; then�[0m
 �[36;1m  echo "ℹ️  [R5] $DIR/ has no .yml/.yaml rules — skipped"�[0m
 �[36;1m  exit 0�[0m
 �[36;1mfi�[0m
 �[36;1m�[0m
 �[36;1merr=$(mktemp)�[0m
 �[36;1mtrap 'rm -f "$err"' EXIT�[0m
 �[36;1mtotal=0�[0m
 �[36;1mfor rf in "${files[@]}"; do�[0m
 �[36;1m  if ! cfg=$(yq -o json '.' "$rf" 2>&1); then�[0m
 �[36;1m    echo "❌ [R5] $rf: not parseable YAML: $cfg"; total=$((total + 1)); continue�[0m
 �[36;1m  fi�[0m
 �[36;1m  if [ "$(jq -r 'type' <<<"$cfg")" != object ]; then�[0m
 �[36;1m    echo "❌ [R5] $rf: top-level must be a mapping"; total=$((total + 1)); continue�[0m
 �[36;1m  fi�[0m
 �[36;1m  rid=$(jq -r --arg b "$(basename "$rf")" 'if has("id") then .id | tostring else $b end' <<<"$cfg")�[0m
 �[36;1m  desc=$(jq -r '.description // ""' <<<"$cfg")�[0m
 �[36;1m  canon=$(jq -r '.canonical_pointer // ""' <<<"$cfg")�[0m
 �[36;1m  mapfile -t pats < <(jq -r '(.patterns // [])[]' <<<"$cfg")�[0m
 �[36;1m  mapfile -t includes < <(jq -r '((.scope // {}).include // [])[]' <<<"$cfg")�[0m
 �[36;1m  if [ "${#pats[@]}" -eq 0 ] || [ "${#includes[@]}" -eq 0 ]; then�[0m
 �[36;1m    echo "❌ [R5:$rid] missing patterns or scope.include in $rf"�[0m
 �[36;1m    total=$((total + 1)); continue�[0m
 �[36...
🔇 Additional comments (4)
.github/workflows/governance.yml (1)

2-21: LGTM!

.github/workflows/mirror.yml (1)

3-31: LGTM!

.github/workflows/scorecard.yml (1)

2-21: LGTM!

.github/workflows/secret-scanner.yml (1)

11-27: LGTM!


📝 Summary

Summary by CodeRabbit

  • Chores
    • Updated the formatting of several automation workflows. Their triggers, permissions, concurrency settings and reusable workflow references remain unchanged, so there are no changes to the workflows’ behaviour or to the end-user experience.

Walkthrough

Four GitHub Actions workflow files were rewritten from JSON-style syntax to standard YAML. Their documented triggers, concurrency settings, permissions, reusable workflow references, schedule, and secret mappings were retained.

Changes

Workflow syntax conversion

Layer / File(s) Summary
Convert workflow definitions
.github/workflows/governance.yml, .github/workflows/mirror.yml, .github/workflows/scorecard.yml, .github/workflows/secret-scanner.yml
The four workflow definitions now use standard YAML syntax. Their documented triggers, concurrency settings, permissions, reusable workflow references, schedule, and secret mappings remain unchanged.

Priority: ⬇️ Low

Estimated code review effort: 1 (Trivial) | ~4 minutes

Change: Bug fix

Merge Risk: ⚪ Minimal · up to f028d

The four workflows retain their documented configuration, and actionlint accepts them. The gate’s reported result was not independently verified, but no actionable merge-blocking risk is established.

Architecture Summary

Architecture risk: 🔵 Low · up to f028d

The changed surface does not map to a changed system, dependency edge, entrypoint, or external dependency.

Changed systems: None identified.

Architecture concerns
No architecture-level concerns identified.

Review details

Before / after behavior

  • observed — Modified behavior in .github/workflows/governance.yml: The workflow configuration is rewritten in YAML; its triggers, concurrency group and cancellation behaviour, permissions, and pinned reusable workflow remain unchanged.
  • observed — Modified behavior in .github/workflows/mirror.yml: The workflow configuration was converted from JSON-style syntax to YAML; its triggers, concurrency settings, permissions, reusable workflow reference, and explicit secret mappings are unchanged.
  • observed — Modified behavior in .github/workflows/scorecard.yml: The workflow definition is reformatted from JSON-style syntax to YAML. Its triggers, schedule (23 4 * * 1), reusable workflow reference and permission values are retained.
  • observed — Modified behavior in .github/workflows/secret-scanner.yml: The workflow configuration is rewritten from JSON-style YAML to standard YAML. Its triggers, concurrency settings, contents: read permission, scan job and pinned reusable workflow reference are unchanged.
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 0…
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Description check Passed The description includes the required Summary, Changes, RSR Quality Checklist, Testing and Screenshots sections. It explains the defect, the scope of the workflow changes, test results and the depende…
Title check Passed The title clearly identifies the CI change and its purpose: restoring block YAML so the actions-lock gate can read pinned references.
  • Autopilot · 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

A rabbit checks the YAML lines,
Four workflows neatly realign.
The triggers stay, the settings too,
The secrets keep their mapped-through view.
I hop away; the syntax shines!

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

@github-actions

github-actions Bot commented Oct 8, 2026

Copy link
Copy Markdown

🔍 Hypatia Security Scan

Findings: 58 issues detected

Severity Count
🔴 Critical 6
🟠 High 25
🟡 Medium 27

⚠️ Action Required: Critical security issues found!

View findings
[
  {
    "reason": "Job `triage` in label-triage.yml has no `timeout-minutes:` declaration. Default is 6 hours — a stuck codeload fetch or runner hang can burn budget. Add `timeout-minutes: 10` (or proportional).",
    "type": "missing_timeout_minutes",
    "file": ".github/workflows/label-triage.yml",
    "action": "flag",
    "rule_module": "workflow_audit",
    "severity": "medium",
    "recipe_id": "recipe-add-workflow-timeout-minutes",
    "job": "triage"
  },
  {
    "reason": "Job `sync` in labels.yml has no `timeout-minutes:` declaration. Default is 6 hours — a stuck codeload fetch or runner hang can burn budget. Add `timeout-minutes: 10` (or proportional).",
    "type": "missing_timeout_minutes",
    "file": ".github/workflows/labels.yml",
    "action": "flag",
    "rule_module": "workflow_audit",
    "severity": "medium",
    "recipe_id": "recipe-add-workflow-timeout-minutes",
    "job": "sync"
  },
  {
    "line": 38,
    "reason": "job in .github/workflows/labels.yml references `secrets.*` but does not install `step-security/harden-runner` — review outbound-egress monitoring",
    "type": "RE001",
    "file": ".github/workflows/labels.yml",
    "action": "report",
    "rule_module": "research_extensions",
    "severity": "medium"
  },
  {
    "line": 44,
    "reason": "job in .github/workflows/push-email-notify.yml references `secrets.*` but does not install `step-security/harden-runner` — review outbound-egress monitoring",
    "type": "RE001",
    "file": ".github/workflows/push-email-notify.yml",
    "action": "report",
    "rule_module": "research_extensions",
    "severity": "medium"
  },
  {
    "line": 82,
    "reason": "job in .github/workflows/hypatia-scan.yml references `secrets.*` but does not install `step-security/harden-runner` — review outbound-egress monitoring",
    "type": "RE001",
    "file": ".github/workflows/hypatia-scan.yml",
    "action": "report",
    "rule_module": "research_extensions",
    "severity": "medium"
  },
  {
    "line": 52,
    "reason": "job in .github/workflows/label-triage.yml references `secrets.*` but does not install `step-security/harden-runner` — review outbound-egress monitoring",
    "type": "RE001",
    "file": ".github/workflows/label-triage.yml",
    "action": "report",
    "rule_module": "research_extensions",
    "severity": "medium"
  },
  {
    "line": 33,
    "reason": "workflow .github/workflows/labels.yml:33 job `sync` has no `timeout-minutes:` — defaults to 360 min on hang",
    "type": "WH006",
    "file": ".github/workflows/labels.yml",
    "action": "report",
    "rule_module": "workflow_hardening",
    "severity": "medium"
  },
  {
    "line": 47,
    "reason": "workflow .github/workflows/label-triage.yml:47 job `triage` has no `timeout-minutes:` — defaults to 360 min on hang",
    "type": "WH006",
    "file": ".github/workflows/label-triage.yml",
    "action": "report",
    "rule_module": "workflow_hardening",
    "severity": "medium"
  },
  {
    "line": null,
    "reason": "workflow .github/workflows/hypatia-scan.yml uploads SARIF to code scanning but masks the scanner's failure (`|| true` / `|| echo 0`) and never asserts the findings artefact is a non-empty array. When the scanner fails, this uploads a SARIF with zero results, and GitHub AUTO-CLOSES every previously-open alert for that category — silently, with the job green.",
    "type": "WH014",
    "file": ".github/workflows/hypatia-scan.yml",
    "action": "report",
    "rule_module": "workflow_hardening",
    "severity": "high"
  },
  {
    "reason": "Code scanning (Hypatia): hypatia/workflow_audit/scorecard_wrapper_missing_job_permissions -- Hypatia workflow_audit: scorecard_wrapper_missing_job_permissions -- 0 day(s) old",
    "type": "CSA001",
    "file": ".github/workflows/scorecard.yml",
    "action": "update",
    "rule_module": "code_scanning_alerts",
    "severity": "high"
  }
]

Powered by Hypatia Neurosymbolic CI/CD Intelligence

SonarCloud githubactions:S8234 on #73. The analysis job declares its own
map, which replaces the workflow-level one, so `read-all` reached no job;
`contents: read` states the same effective permissions.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GpUzjdhWFi26k6s7AWxYcf
@github-actions

github-actions Bot commented Oct 8, 2026

Copy link
Copy Markdown

🔍 Hypatia Security Scan

Findings: 58 issues detected

Severity Count
🔴 Critical 6
🟠 High 25
🟡 Medium 27

⚠️ Action Required: Critical security issues found!

View findings
[
  {
    "reason": "Job `triage` in label-triage.yml has no `timeout-minutes:` declaration. Default is 6 hours — a stuck codeload fetch or runner hang can burn budget. Add `timeout-minutes: 10` (or proportional).",
    "type": "missing_timeout_minutes",
    "file": ".github/workflows/label-triage.yml",
    "action": "flag",
    "rule_module": "workflow_audit",
    "severity": "medium",
    "recipe_id": "recipe-add-workflow-timeout-minutes",
    "job": "triage"
  },
  {
    "reason": "Job `sync` in labels.yml has no `timeout-minutes:` declaration. Default is 6 hours — a stuck codeload fetch or runner hang can burn budget. Add `timeout-minutes: 10` (or proportional).",
    "type": "missing_timeout_minutes",
    "file": ".github/workflows/labels.yml",
    "action": "flag",
    "rule_module": "workflow_audit",
    "severity": "medium",
    "recipe_id": "recipe-add-workflow-timeout-minutes",
    "job": "sync"
  },
  {
    "line": 38,
    "reason": "job in .github/workflows/labels.yml references `secrets.*` but does not install `step-security/harden-runner` — review outbound-egress monitoring",
    "type": "RE001",
    "file": ".github/workflows/labels.yml",
    "action": "report",
    "rule_module": "research_extensions",
    "severity": "medium"
  },
  {
    "line": 44,
    "reason": "job in .github/workflows/push-email-notify.yml references `secrets.*` but does not install `step-security/harden-runner` — review outbound-egress monitoring",
    "type": "RE001",
    "file": ".github/workflows/push-email-notify.yml",
    "action": "report",
    "rule_module": "research_extensions",
    "severity": "medium"
  },
  {
    "line": 82,
    "reason": "job in .github/workflows/hypatia-scan.yml references `secrets.*` but does not install `step-security/harden-runner` — review outbound-egress monitoring",
    "type": "RE001",
    "file": ".github/workflows/hypatia-scan.yml",
    "action": "report",
    "rule_module": "research_extensions",
    "severity": "medium"
  },
  {
    "line": 52,
    "reason": "job in .github/workflows/label-triage.yml references `secrets.*` but does not install `step-security/harden-runner` — review outbound-egress monitoring",
    "type": "RE001",
    "file": ".github/workflows/label-triage.yml",
    "action": "report",
    "rule_module": "research_extensions",
    "severity": "medium"
  },
  {
    "line": 33,
    "reason": "workflow .github/workflows/labels.yml:33 job `sync` has no `timeout-minutes:` — defaults to 360 min on hang",
    "type": "WH006",
    "file": ".github/workflows/labels.yml",
    "action": "report",
    "rule_module": "workflow_hardening",
    "severity": "medium"
  },
  {
    "line": 47,
    "reason": "workflow .github/workflows/label-triage.yml:47 job `triage` has no `timeout-minutes:` — defaults to 360 min on hang",
    "type": "WH006",
    "file": ".github/workflows/label-triage.yml",
    "action": "report",
    "rule_module": "workflow_hardening",
    "severity": "medium"
  },
  {
    "line": null,
    "reason": "workflow .github/workflows/hypatia-scan.yml uploads SARIF to code scanning but masks the scanner's failure (`|| true` / `|| echo 0`) and never asserts the findings artefact is a non-empty array. When the scanner fails, this uploads a SARIF with zero results, and GitHub AUTO-CLOSES every previously-open alert for that category — silently, with the job green.",
    "type": "WH014",
    "file": ".github/workflows/hypatia-scan.yml",
    "action": "report",
    "rule_module": "workflow_hardening",
    "severity": "high"
  },
  {
    "reason": "Code scanning (Hypatia): hypatia/workflow_audit/scorecard_wrapper_missing_job_permissions -- Hypatia workflow_audit: scorecard_wrapper_missing_job_permissions -- 0 day(s) old",
    "type": "CSA001",
    "file": ".github/workflows/scorecard.yml",
    "action": "update",
    "rule_module": "code_scanning_alerts",
    "severity": "high"
  }
]

Powered by Hypatia Neurosymbolic CI/CD Intelligence

@coderabbitai

coderabbitai Bot commented Oct 9, 2026 •

Copy link
Copy Markdown
Contributor

✅ Coding Agent task started: View task and status

The task will inspect the CI failures, validate its fix, and commit the fix to this branch automatically.

Note: Fixing CI failures is a beta feature and may encounter errors. Expect some limitations and changes as we gather feedback and continue to improve it.

hyperpolymath added a commit that referenced this pull request Oct 9, 2026
## Summary

This removes two tracked duplicate trees, each nested inside the
directory it copies: `verification/verification/` and
`www/.well-known/.well-known/`. The removal was first part of the
licence PR #74. It moved here so that #74 contains only the licence
change and stays under CodeRabbit's 100-file review limit.

The two PRs change no file in common, so they can merge in either order.

## Changes

- **Deleted `verification/verification/`** (28 files), a copy of
`verification/`.
- **Deleted `www/.well-known/.well-known/`** (3 files), a copy of
`www/.well-known/`.
- Nothing else changes.

30 of the 31 files match their outer copy line for line, apart from SPDX
and copyright lines. 15 of them carry the retired PMPL header. The 31st,
`verification/verification/README.adoc`, also has a title line, `=
Verification Pillar`. #74 adds that title and the copyright line to the
outer `verification/README.adoc`. If this PR merges first, the outer
README simply lacks the title until #74 lands; no content is lost.

## 📌 New pins

- **Head SHA: `31fd364ba67f7497c715599b47cbb518357c76bb`**
- None. No action `uses:`, `actions.lock`, lockfile or container digest
is added or changed.

## RSR Quality Checklist

### Required

- [ ] Tests pass: n/a. Only duplicate copies are deleted; no source,
proof or test that is built or run changes.
- [ ] Code is formatted: n/a, nothing is added.
- [x] Linter is clean: no file is added or edited.
- [x] No banned language patterns: nothing is added.
- [ ] No `unsafe` blocks: n/a, no Rust changed.
- [ ] No banned functions: n/a, no source or proofs added.
- [ ] SPDX license headers: n/a, the PR only deletes files.
- [x] No secrets or credentials.

### As Applicable

- [ ] `.machine_readable/*.a2ml` updated: no. A2ML is retired. 9 of the
deleted files are `.a2ml` duplicates
(`verification/verification/0.1-AI-MANIFEST.a2ml` and one
`0.2-AI-MANIFEST.a2ml` in each of its 8 subdirectories). Their outer
copies are unchanged.
- [ ] Documentation updated: n/a, no document refers to the deleted
paths except the signed historical record below.
- [ ] `TOPOLOGY.md`: n/a.
- [ ] `CHANGELOG`: not updated, since only duplicates are removed.
- [ ] New dependencies: none.
- [ ] ABI/FFI: n/a.

## Testing

- **Each deleted file was compared with its outer copy**, ignoring SPDX
lines, copyright lines and bare `<!--` / `-->` lines. Result: 30 files
have no difference. `verification/verification/README.adoc` differs only
by its title line, which is described above.
- Positive control: a copy of
`verification/verification/proofs/0.2-AI-MANIFEST.a2ml` with one planted
line reported 1 differing line.
- Limit: the comparison is line-based. It shows that the outer copy
keeps every non-licence line of the inner one. It says nothing about
which licence header is correct, which is #74's subject.
- **No dangling references:** `git grep -nE
'verification/verification|\.well-known/\.well-known' origin/main`
matches only `docs/AFFIRMATION.adoc:213-214`, the signed affirmation
that records this duplicate. It is left unchanged.
- **No overlap with #74:** `comm -12` of the two PRs' file lists is
empty.

## Red checks on this head

- `governance / Actions lockfile verify` is red on `main` (`589e1be`) as
well. It is fixed by #73 together with hyperpolymath/standards#1209, and
this PR does not touch it.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

https://claude.ai/code/session_01GpUzjdhWFi26k6s7AWxYcf

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
hyperpolymath added a commit that referenced this pull request Oct 9, 2026
…facts (#77)

## Summary

This carries out four owner decisions of 2026-10-09 that #74 and #76
left open:

1. **Delete the nested `.machine_readable/.machine_readable/` copy** (75
files), after checking its diverging files for anything worth keeping.
2. **Keep `.github/FUNDING.yml` (`github: hyperpolymath`) and delete
`.github/funding.yml` (`github: metadatastician`).**
3. **Delete the unused `LICENSES/AGPL-3.0-or-later.txt`.**
4. **Delete the two PMPL exhibits in `docs/legal/`** and fix the three
files that refer to them.

It changes no file that #73, #74 or #76 changes in a conflicting way.
`git merge-tree` against each of their heads is clean (see Testing), so
the four PRs can merge in any order.

## Changes

- **Deleted `.machine_readable/.machine_readable/`** (75 files). #40
(`cc60f66`) added it in a single commit. 53 of its files contain PMPL
text. 17 differ from their outer copy beyond SPDX and copyright lines,
and 3 exist only inside it:
- **The 5 non-A2ML files are rattlescript-era template residue.** They
name `rattlescript`, `k9-svc` and `.machine_readable/contractiles/k9/`,
where the outer copies name `jaffascript` and `self-validating`. The
files are `README.adoc`, `ai/PLACEHOLDERS.adoc`,
`configs/git-cliff/cliff.toml`,
`contractiles/self-validating/README.adoc` and
`contractiles/self-validating/examples/setup-repo.k9.ncl`.
- **The only content among those 5 that the outer copy lacked** was the
README's title (`= .machine_readable Pillar`) and copyright line. Both
are now appended to `.machine_readable/README.adoc`, after its existing
comment lines.
- **12 A2ML files diverge.** 2 of them name rattlescript, and 10 name
neither repo. The 3 inner-only files are `ECOSYSTEM.a2ml`, `META.a2ml`
and `STATE.a2ml` in the old root layout. A2ML is retired, so all of them
go with the tree. Every outer A2ML file is unchanged.
- **Deleted `.github/funding.yml`.** It differs from
`.github/FUNDING.yml` only in letter case, so the two collide on a
case-insensitive checkout (Windows, macOS). `FUNDING.yml` stays:
`github`, `ko_fi` and `liberapay` all name `hyperpolymath`.
- **Deleted `LICENSES/AGPL-3.0-or-later.txt`.** No file in the repo is
AGPL-licensed. Every AGPL mention is a rule against it, or the deny list
in `.machine_readable/compliance/rust/deny.toml`, which is kept.
`LICENSES/` now holds `MPL-2.0.txt` and `CC-BY-SA-4.0.txt`.
- **Deleted `docs/legal/EXHIBIT-A-ETHICAL-USE.txt` and
`docs/legal/EXHIBIT-B-QUANTUM-SAFE.txt`**, the PMPL exhibits. Their
references are fixed:
- **`Justfile` and `.machine_readable/contractiles/Justfile`** (still
byte-identical): `validate-rsr` now checks for `LICENSES/MPL-2.0.txt`
and `LICENSES/CC-BY-SA-4.0.txt`. Before, it checked
`licensing/exhibits/EXHIBIT-{A,B}-*.txt` and
`licensing/texts/PMPL-1.0-or-later.txt`, under a `licensing/` directory
that does not exist, so it always reported all three as missing.
- **`docs/RSR_OUTLINE.adoc`**: the two exhibit rows in the file table
and the two exhibit lines in the tree are replaced by one `LICENSES/`
entry. The three places that described `LICENSE` as PMPL-1.0-or-later
now say MPL-2.0, which is what `LICENSE` already contains on `main`. The
rest of this template outline is untouched; its other stale claims are
listed below.

### Not changed

- `docs/legal/0.2-AI-MANIFEST.a2ml`, the remaining file in
`docs/legal/`. It does not refer to the exhibits.
- `docs/governance/MAINTENANCE-CHECKLIST.adoc:119`. It names
`docs/legal/` as a folder, which still exists.
- `LICENSE` and `LICENSES/MPL-2.0.txt`. Their "Exhibit A/B" text is the
MPL-2.0 licence's own exhibits, not the PMPL files.
- **Other stale claims in `docs/RSR_OUTLINE.adoc`**: the Palimpsest
badges on line 5, ReScript listed as Tier 1, `guix.scm` OR `flake.nix`,
"Python outside `salt/`" and "npm, Bun, pnpm, yarn (use Deno)", which
contradicts the estate's Bun-only rule. They are left for a separate
change, because this PR only fixes the references to the deleted files.

## 📌 New pins

- **Head SHA: `da27c4fa1ee2368fcb32f0a3e4609aefa9a3b260`**
- None. No action `uses:`, `actions.lock`, lockfile or container digest
is added or changed.

## RSR Quality Checklist

### Required

- [ ] Tests pass: n/a. No source, proof or test is changed.
`validate-rsr` was run before and after; see Testing.
- [ ] Code is formatted: n/a. The only code edit is one `for` line in
each Justfile, and `just --summary` parses both.
- [x] Linter is clean: standards `scripts/check-licence-consistency.sh`
exits 0 (see Testing).
- [x] No banned language patterns: nothing is added.
- [ ] No `unsafe` blocks: n/a, no Rust changed.
- [ ] No banned functions: n/a, no source or proofs changed.
- [x] SPDX license headers present: each of the 4 edited files keeps its
existing header. No file is added.
- [x] No secrets or credentials.

### As Applicable

- [ ] `.machine_readable/STATE.a2ml` / `ECOSYSTEM.a2ml` / `META.a2ml`
updated: no. A2ML is retired, and the outer A2ML files are unchanged.
- [x] Documentation updated: `docs/RSR_OUTLINE.adoc` and
`.machine_readable/README.adoc`.
- [ ] `TOPOLOGY.md`: n/a, the architecture is unchanged.
- [ ] `CHANGELOG`: not updated, since only duplicates and unused licence
files are removed.
- [ ] New dependencies: none.
- [ ] ABI/FFI: n/a.

## Testing

All checks ran on this head `da27c4f` against `main` at `589e1be`.

- **File list:** `git diff --name-status origin/main HEAD` shows 79 `D`
and 4 `M` (the two Justfiles, `docs/RSR_OUTLINE.adoc` and
`.machine_readable/README.adoc`). It shows no `A`.
- **No dangling references:** `git grep -nIE
'\.machine_readable/\.machine_readable|funding\.yml|AGPL-3\.0-or-later\.txt|EXHIBIT-[AB]|licensing/(exhibits|texts)'`
on this head matches nothing. The same pattern matches a planted line,
so it can find these paths.
- **`validate-rsr`**, run with `just --justfile Justfile validate-rsr`
because the root also holds a lowercase `justfile` (see below):
- On `main` it reports 6 missing paths: the 3 exhibit and PMPL paths,
and 3 old-layout A2ML paths.
- On this head it reports only the 3 A2ML paths
(`.machine_readable/{STATE,META,ECOSYSTEM}.a2ml`). They are missing on
`main` too, and this PR does not touch them.
- Positive control: with `LICENSES/CC-BY-SA-4.0.txt` removed from a copy
of this head, it also reports `LICENSES/CC-BY-SA-4.0.txt` as missing.
  - No workflow under `.github/` runs `validate-rsr`.
- **Standards `scripts/check-licence-consistency.sh`**, run from the
standards clone at `1ffe86b3`: exit 0 on both `main` and this head. Its
warning lines drop from 107 to 56, because the nested tree's PMPL
headers are gone.
- **AsciiDoc:** `asciidoctor --failure-level=WARN` reports no warnings
on either edited `.adoc`, before or after. The README title parses as
`.machine_readable Pillar`. The first table in `RSR_OUTLINE.adoc` goes
from 21 rows to 20 and stays at 2 columns.
- **No conflict with open PRs:** `git merge-tree --write-tree` of this
head with #73 (`0bee4f4`), #74 (`97377c5`) and #76 (`31fd364`) exits 0
for each. Positive control: a planted conflicting edit to
`.machine_readable/README.adoc` makes it exit 1.
- **Docstrings:** standards `.githooks/docstring-scan.sh --range
origin/main..HEAD --check` finds 0 touched functions.
- **Code-scanning alerts this PR introduces**, checked by hand because
`squabble verify-satisfied` does not evaluate them yet. Open alerts were
keyed on (rule, path), for `refs/pull/77/merge` against
`refs/heads/main`: 32 against 44. The PR-minus-main set is empty.
Control: main-minus-PR has 12 keys (Scorecard, plus Hypatia
CSA001/CSA003), which shows the diff can find a difference.

### Found while doing this, not fixed here

The repo root holds both **`Justfile`** (the RSR template, 1,545 lines)
and **`justfile`** (jaffascript's own 29-line runner for `affinescript
check/run/build --face jaffa`). As a result, a bare `just` in the root
fails with "multiple candidate justfiles", and on a case-insensitive
checkout one file overwrites the other. Merging them needs an owner
decision, so this PR leaves them alone.

## Red checks on this head

All 27 check-runs (paginated) and both legacy statuses had reported at
2026-10-09T00:00Z.

- `governance / Actions lockfile verify` is red on `main` (`589e1be`) as
well. It is fixed by #73 together with hyperpolymath/standards#1209, and
this PR does not touch it.
- Every other check-run is green: 20 `github-actions` runs, CodeQL,
Hypatia, SonarCloud, CodeFactor, GitGuardian and Semgrep. The only
required context, `scan / gitleaks`, is green.
- Statuses: CodeRabbit reports "Review rate limited", so it gave no
review (it never blocks). Codeac reports "1 errors and 4 warnings" with
state `success`, the same as on `main` `589e1be`.

## Screenshots

n/a, no UI change.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

https://claude.ai/code/session_01GpUzjdhWFi26k6s7AWxYcf

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
hyperpolymath added a commit that referenced this pull request Oct 9, 2026
## Summary

This puts jaffascript on the two-tier licence rule: **MPL-2.0 for code,
CC-BY-SA-4.0 for prose**.

**This relicenses existing files, at the owner's direction.** The
owner's instruction (2026-10-09) was "mpl-2.0 code, and cc-by-sa-4.0
prose". The edits follow standards
`docs/migrations/pmpl-to-mpl-sweep-runbook.adoc` §5 and §6: every file
was opened and changed individually from an explicit list, and only a
file's own SPDX declaration was flipped. There was no bulk substitution.
The runbook makes owner sign-off on the per-repo change-list the hard
gate, so **this PR is held for the owner's merge**: auto-merge is not
armed. The full list is below.

This PR's first commit also deleted two nested duplicate trees. That
removal is now its own PR, #76, so this PR contains only the licence
change and fits CodeRabbit's 100-file limit. The two PRs change no file
in common.

## Changes

- **18 code/config files: PMPL-1.0-or-later → MPL-2.0** (SPDX header
only).
- **31 prose files: MPL-2.0 → CC-BY-SA-4.0.** 30 change only the SPDX
header. `verification/README.adoc` also gains the title (`= Verification
Pillar`) and copyright line of its nested copy, which #76 deletes.
- **16 `.adoc` files had no SPDX header and now carry `CC-BY-SA-4.0`.**
`README.adoc` is one of them: its only `SPDX-License-Identifier` text
was in body prose at line 138, not a header.
- **4 shell scripts had no SPDX header and now carry `MPL-2.0`**, on
line 2 after the shebang. Their modes are unchanged and `bash -n` passes
on each.
- **The licence rule text now states the two-tier rule** in every place
that states it: `.github/copilot-instructions.md`,
`.github/GOVERNANCE.md` footer, `.github/pull_request_template.md`,
`.machine_readable/ai/.clinerules`, `.machine_readable/ai/.cursorrules`,
`.machine_readable/ai/.windsurfrules`,
`.machine_readable/ai/PLACEHOLDERS.adoc`,
`docs/practice/AI-CONVENTIONS.adoc`, `QUICKSTART-MAINTAINER.adoc`,
`TEST-NEEDS.adoc`, `llm-warmup-{dev,user}.adoc`.
- **Declared metadata:** `stapeln.toml`,
`docs/attribution/CITATION.cff`, `docs/attribution/CITATIONS.adoc` and
`www/.well-known/humans.txt` now name MPL-2.0.
- **`www/.well-known/ai.txt`** states both licences. The line "AI agents
must preserve Emotional Lineage per PMPL Section 3" is gone, because
PMPL no longer applies.
- **The `{{LICENSE}}` placeholder** in the template-substitution recipe,
in both `Justfile` and `.machine_readable/contractiles/Justfile`, now
becomes `MPL-2.0`.
- **`.machine_readable/compliance/reuse/dep5`** (an unconsumed
template):
  - The code stanzas now say MPL-2.0.
- A final `*.adoc *.md` stanza assigns CC-BY-SA-4.0. In dep5 the last
matching stanza wins.
- The `.machine_readable/*.a2ml` stanza still says PMPL, to match those
files' headers (see "Kept").

### Kept deliberately (runbook §6)

- **Every `.a2ml` header.** A2ML is retired, and the deed migration owns
those files. The licence check lists them as warnings, and that is
expected.
- **`verification/verification/` and `www/.well-known/.well-known/`**
keep their old headers here (15 PMPL), because #76 deletes both trees.
- **`.machine_readable/.machine_readable/`**, a nested copy of 75 files.
The owner decided to delete it, and #77 does.
- **`LICENSE`** (already the verbatim MPL-2.0 text) and **`LICENSES/`**.
#77 deletes the unused `LICENSES/AGPL-3.0-or-later.txt` and the two PMPL
exhibits `docs/legal/EXHIBIT-{A,B}-*.txt`.
- **`CODE_OF_CONDUCT.adoc`**, which is adapted from the Contributor
Covenant and so was not relabelled.
- **`www/.well-known/{ai,humans,security}.txt`** keep their MPL-2.0
header, because they are machine-read data rather than prose.
- **History and policy text that names PMPL as a fact:**
`docs/tech-debt-2026-05-26.adoc` (body), `docs/decisions/0001-*`,
`docs/STATE-VISUALIZER.adoc`, `docs/RSR_OUTLINE.adoc`,
`.machine_readable/compliance/rust/deny.toml`, the k9 example bodies,
`contractile.just:65`, and `Justfile:224`/`:1057` (licence-file
tooling). #77 updates `docs/RSR_OUTLINE.adoc`'s description of `LICENSE`
and the `Justfile:1057` check, because both referred to the exhibits it
deletes. Its changes merge cleanly with this PR.

<details><summary>Full change-list (69 files relabelled)</summary>

**PMPL-1.0-or-later → MPL-2.0**

- `container/compose.example.toml`
- `container/compose.toml`
- `container/Containerfile`
- `container/ct-build.sh`
- `container/deploy.k9.ncl`
- `container/entrypoint.sh`
- `container/.gatekeeper.yaml`
- `container/manifest.toml`
- `container/vordr.toml`
- `contractile.just`
- `.devcontainer/Containerfile`
- `.devcontainer/devcontainer.json`
- `features/ssg/ssg-bootstrap.sh`
- `.gitlab-ci.yml`
- `Justfile`
- `.machine_readable/contractiles/Justfile`
- `.pre-commit-config.yaml`
- `scripts/validate-template.sh`

**MPL-2.0 → CC-BY-SA-4.0**

- `AUDIT.adoc`
- `.claude/CLAUDE.md`
- `container/README.adoc`
- `.devcontainer/README.adoc`
- `EXPLAINME.adoc`
- `features/boj-server/README.adoc`
- `features/panic-attacker/README.adoc`
- `features/README.adoc`
- `features/ssg/README.adoc`
- `.machine_readable/README.adoc`
- `MAINTAINERS.adoc`
- `ROADMAP.adoc`
- `src/aspects/integrity/README.adoc`
- `src/aspects/observability/README.adoc`
- `src/aspects/README.adoc`
- `src/aspects/security/README.adoc`
- `src/contracts/README.adoc`
- `src/definitions/README.adoc`
- `src/errors/README.adoc`
- `src/interface/Abi/README.adoc`
- `src/interface/ffi/README.adoc`
- `src/interface/ffi/src/README.adoc`
- `src/interface/ffi/test/README.adoc`
- `src/interface/generated/abi/README.adoc`
- `src/interface/generated/README.adoc`
- `src/interface/README.adoc`
- `src/README.adoc`
- `TEMPLATE-STANDARDS-AUDIT.adoc`
- `tools/invariant-path/README.adoc`
- `verification/README.adoc`
- `www/.well-known/README.adoc`

**New CC-BY-SA-4.0 header**

- `.claude/PROJECT.adoc`
- `ARCHITECTURE.adoc`
- `CHANGELOG.adoc`
- `GOVERNANCE.adoc`
- `PROOF-NEEDS.adoc`
- `PROOF-STATUS.adoc`
- `READINESS.adoc`
- `README.adoc`
- `SECURITY.adoc`
- `TEST-NEEDS.adoc`
- `TOPOLOGY.adoc`
- `docs/reports/audit/audit-2026-04-15-post.adoc`
- `docs/tech-debt-2026-05-26.adoc`
- `llm-warmup-dev.adoc`
- `llm-warmup-user.adoc`
- `session/README.adoc`

**New MPL-2.0 header**

- `.machine_readable/scripts/forge/git-cleanup.sh`
- `scripts/invariant-path.sh`
- `session/dispatch.sh`
- `session/local-hooks.sh`

</details>

## 📌 New pins

- **Head SHA: `97377c577ca4c75d6a86e3dfe524a4efb26ebad6`**
- None. No action `uses:`, `actions.lock`, lockfile or container digest
is added or changed.

## RSR Quality Checklist

### Required

- [ ] Tests pass: n/a. No source, proof or test file is changed; every
change is a comment header, rule text or metadata.
- [ ] Code is formatted: n/a, for the same reason. The four shell
scripts gained one comment line each, and `bash -n` passes on all four.
- [x] Linter is clean: standards `scripts/check-licence-consistency.sh`
passes (see Testing).
- [x] No banned language patterns: no code was added.
- [ ] No `unsafe` blocks: n/a, no Rust changed.
- [ ] No banned functions: n/a, no source or proofs changed.
- [x] SPDX license headers present: every file this PR touches has one,
with two exceptions. `docs/attribution/CITATION.cff` carries its licence
in its `license:` field, and `.machine_readable/compliance/reuse/dep5`
is itself a licence declaration. Neither had a header before this PR.
- [x] No secrets or credentials.

### As Applicable

- [ ] `.machine_readable/*.a2ml` updated: no. A2ML is retired, and its
headers are left for the deed migration.
- [x] Documentation updated: the licence rule text is listed under
Changes.
- [ ] `TOPOLOGY.md`: n/a, the architecture is unchanged.
- [ ] `CHANGELOG`: not updated. The relicence is recorded in this PR and
in the commit message, which lists every file.
- [ ] New dependencies: none.
- [ ] ABI/FFI: n/a.

## Testing

- **Standards `scripts/check-licence-consistency.sh`** (the governance
"Licence consistency" job), run locally on this head `97377c5` from the
standards clone at `1ffe86b3`: **exit 0**. It lists the kept `.a2ml`
headers and the 15 PMPL headers in the two nested trees as warnings,
which is expected.
- Positive control, run on the first head `a1c7c57`: I planted a
`Cargo.toml` declaring `PMPL-1.0-or-later` in a copy of the tree. The
script reported `Licence-vs-manifest mismatch` and exited **1**. With
the plant removed it exited 0 again.
- Limit of this check: the manifest check reads only Cargo.toml,
package.json, pyproject.toml, mix.exs, Project.toml, `*.ipkg`, `*.cabal`
and similar files. jaffascript has none of them, and the check does not
read `stapeln.toml`. Planting PMPL in `stapeln.toml` still exited 0, so
that file's licence was checked by hand.
- **No collateral edits:** across all 84 files, every changed line that
is not an `SPDX-License-Identifier` line is in one of the 21 files named
under Changes (the rule text, the declared metadata, `ai.txt`, the two
Justfiles, `dep5` and `verification/README.adoc`). Measured with `git
diff origin/main HEAD`, counting `^[-+]` lines without
`SPDX-License-Identifier` per file.
- **The restore commit `97377c5` is exact:** after it, `git diff
--name-status origin/main HEAD` lists 84 files, all `M`, with no `D` or
`A`.
- The governance "Check SPDX headers + permissions" step reads only
`.github/workflows/*`, and this PR changes no workflow.

## Red checks on this head

- `governance / Actions lockfile verify` is red on `main` (`589e1be`) as
well. It is fixed by #73 together with hyperpolymath/standards#1209, and
this PR does not touch it.
- `Hypatia` (code scanning) fails because this PR edits both Justfiles,
so their open alerts count as "in code changed by this pull request".
The alerts predate this PR, with the same alert numbers on `main`, and
the check is not required. Deferred to #75, which has acceptance
criteria.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

https://claude.ai/code/session_01GpUzjdhWFi26k6s7AWxYcf

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
@sonarqubecloud

sonarqubecloud Bot commented Oct 9, 2026

Copy link
Copy Markdown

hyperpolymath added a commit to hyperpolymath/standards that referenced this pull request Oct 9, 2026
…#1209)

## Summary

The "Check locked or SHA-pinned actions" step (job **Actions lockfile
verify**) runs under the runner's default `bash -e {0}`. `set -uo
pipefail` does not clear `-e`. So the bare gate call followed by `rc=$?`
never reaches the capture. A gate exit 3 (missing lock) kills the step
before the shrink-only ledger `.machine_readable/lock-allow.txt` is
read.

The ledger has been unreachable since 4f7f02c (#899, 2026-09-22). Since
`ENFORCE_FROM` 2026-10-01, a lockless repository on the ledger and
pinned at or after 4f7f02c is red on this job, even though the ledger
was written to excuse it. Found on hyperpolymath/jaffascript#73: the job
log shows the gate's exit-3 error, then `Process completed with exit
code 3`, and neither ledger line is printed.

The fix is `rc=0; bash gate || rc=$?`. This file already uses the same
idiom at the two other exit-status captures that are not under `set +e`
(the grep scan and the launcher-currency check). I checked every other
`rc=$?` / `STATUS=$?` capture in `.github/workflows/` on main: all of
them sit under `set +e`, so this is the only instance.

## Type of change

- [x] 🐛 Bug fix (non-breaking change that fixes an issue)
- [ ] ✨ New feature — no
- [ ] 💥 Breaking change — no. A repository that is not on the ledger
keeps its exact exit code (3 or 1).
- [ ] 🕳️ Soundness fix — not a checker false-negative. It removes a
false *positive*: debt that is ledgered was reported as a violation.
- [ ] 📖 Documentation — no
- [ ] 🧹 Refactor / tech debt — no
- [ ] ⚡ Performance — no
- [x] 🔧 Build / CI / tooling

## 📌 New pins

- Head SHA: **`2029699dd59fc9b34ca3f6a093132b47dbf671e2`**
- No `uses:` refs, `actions.lock` entries, lockfile records or container
digests are added or changed.
- Callers reach this fix only by bumping their
`governance-reusable.yml@<sha>` pin to the merge commit.

## How has this been verified?

CI on this PR **cannot** exercise the changed path. Standards carries an
`actions.lock`, so its own gate exits 0 and the ledger branch is never
reached. I verified it locally instead.

Method: I extracted the step's `run:` script from this branch and from
`origin/main` with `yq '.jobs[].steps[]? | select(.name == "Check locked
or SHA-pinned actions") | .run'`. I ran each under `/usr/bin/bash -e`,
as the runner does, in a disposable directory holding:
- a caller's `.github/workflows/`
- `.standards-lock/{scripts,.machine_readable}` copied from this branch

`GITHUB_REPOSITORY` varied per row:

| variant | caller workflows | repository | rc | ledger branch |
|---|---|---|---|---|
| unfixed | block YAML (jaffascript#73) | hyperpolymath/jaffascript
(ledger line 117) | 3 | never reached |
| unfixed | block YAML | hyperpolymath/zz-not-ledgered | 3 | never
reached |
| unfixed | KYAML (jaffascript main 589e1be) | hyperpolymath/jaffascript
| 1 | never reached |
| **fixed** | block YAML | hyperpolymath/jaffascript | **0** |
`::notice::` … LEDGERED |
| **fixed** | block YAML | hyperpolymath/zz-not-ledgered | **3** | "NOT
among them" |
| **fixed** | KYAML | hyperpolymath/jaffascript | **1** | "NOT among
them" (exit 1 is not ledgerable) |

Also run:
- `actionlint`: 14 findings before and after. The sets are identical
once line numbers are stripped; all predate this PR (`job.workflow_sha`
unknown to the local actionlint, SC2086 info at line 45).
- Pre-commit hooks passed: SPDX, workflow SHA-pinning, lockfile
coverage, permissions.

## Checklist

- [x] My commits are **signed** (`git commit -S`): `git log
--format=%G?` reports `G`.
- [x] I ran the project's own checks/tests locally and they pass: the
pre-commit suite passed, and the planted-control matrix is above.
- [ ] New files carry the correct `SPDX-License-Identifier` — not
applicable: no new files.
- [x] Docs are updated, and no public claim now overstates what the code
does. The new comment states the mechanism.
- [x] I have not introduced a soundness hole. Not-ledgered repos and
exit-1 violations keep their exit codes (rows 5 and 6).

## Notes for reviewers

- I kept this to one concern. The same gate is also blind to KYAML:
`scripts/check-actions-lock-gate.sh:66-68` does not accept a quoted
`uses: "…@<sha>",`, so a KYAML workflow returns exit 1. That is logged
as a separate finding (the KYAML shim work in AGENTS.md §2a), not fixed
here.
- This file stays in block YAML: per #1207, standards' own gates do not
read KYAML yet.
- **Red check deferred:** `Registry + topology in sync` fails on `main`
too (every Registry Verify run since `bbcc722b`, the dependabot rustls
bump #1206, 2026-10-08 11:06Z). It is unrelated to this one-file
workflow change. Tracked by #1161 §2, which has acceptance criteria.
- **Red check deferred:** `Repo self-tests` fails on `main` too, at
`900c42c7`, `a695e379` and `bbcc722b` (Self Test run 37770790241 on
`900c42c7`). It was green at `d8a90cf8`. The same two files fail there
and on this head: `scripts/tests/build-registry-test.sh` and
`scripts/tests/build-scorecards-test.sh`. Both have the same cause as
the row above. The registry test reports `DRIFT:
.machine_readable/REGISTRY.a2ml is stale`. The 3 "broken passes" in the
scorecards test (`component-readiness-grades/M3`,
`estate-constitution/M2`, `neurosym-a2ml/M5`) all run `bash
scripts/build-registry.sh --check`. Tracked by #1161 §2. Its fix
(regenerate, or retire the check along with `.a2ml`) is the owner's
ruling, so this PR does not regenerate the registry.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

https://claude.ai/code/session_01GpUzjdhWFi26k6s7AWxYcf

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Oct 9, 2026

Copy link
Copy Markdown

🔍 Hypatia Security Scan

Findings: 54 issues detected

Severity Count
🔴 Critical 6
🟠 High 21
🟡 Medium 27

⚠️ Action Required: Critical security issues found!

View findings
[
  {
    "reason": "Job `triage` in label-triage.yml has no `timeout-minutes:` declaration. Default is 6 hours — a stuck codeload fetch or runner hang can burn budget. Add `timeout-minutes: 10` (or proportional).",
    "type": "missing_timeout_minutes",
    "file": ".github/workflows/label-triage.yml",
    "action": "flag",
    "rule_module": "workflow_audit",
    "severity": "medium",
    "recipe_id": "recipe-add-workflow-timeout-minutes",
    "job": "triage"
  },
  {
    "reason": "Job `sync` in labels.yml has no `timeout-minutes:` declaration. Default is 6 hours — a stuck codeload fetch or runner hang can burn budget. Add `timeout-minutes: 10` (or proportional).",
    "type": "missing_timeout_minutes",
    "file": ".github/workflows/labels.yml",
    "action": "flag",
    "rule_module": "workflow_audit",
    "severity": "medium",
    "recipe_id": "recipe-add-workflow-timeout-minutes",
    "job": "sync"
  },
  {
    "line": 38,
    "reason": "job in .github/workflows/labels.yml references `secrets.*` but does not install `step-security/harden-runner` — review outbound-egress monitoring",
    "type": "RE001",
    "file": ".github/workflows/labels.yml",
    "action": "report",
    "rule_module": "research_extensions",
    "severity": "medium"
  },
  {
    "line": 44,
    "reason": "job in .github/workflows/push-email-notify.yml references `secrets.*` but does not install `step-security/harden-runner` — review outbound-egress monitoring",
    "type": "RE001",
    "file": ".github/workflows/push-email-notify.yml",
    "action": "report",
    "rule_module": "research_extensions",
    "severity": "medium"
  },
  {
    "line": 82,
    "reason": "job in .github/workflows/hypatia-scan.yml references `secrets.*` but does not install `step-security/harden-runner` — review outbound-egress monitoring",
    "type": "RE001",
    "file": ".github/workflows/hypatia-scan.yml",
    "action": "report",
    "rule_module": "research_extensions",
    "severity": "medium"
  },
  {
    "line": 52,
    "reason": "job in .github/workflows/label-triage.yml references `secrets.*` but does not install `step-security/harden-runner` — review outbound-egress monitoring",
    "type": "RE001",
    "file": ".github/workflows/label-triage.yml",
    "action": "report",
    "rule_module": "research_extensions",
    "severity": "medium"
  },
  {
    "line": 33,
    "reason": "workflow .github/workflows/labels.yml:33 job `sync` has no `timeout-minutes:` — defaults to 360 min on hang",
    "type": "WH006",
    "file": ".github/workflows/labels.yml",
    "action": "report",
    "rule_module": "workflow_hardening",
    "severity": "medium"
  },
  {
    "line": 47,
    "reason": "workflow .github/workflows/label-triage.yml:47 job `triage` has no `timeout-minutes:` — defaults to 360 min on hang",
    "type": "WH006",
    "file": ".github/workflows/label-triage.yml",
    "action": "report",
    "rule_module": "workflow_hardening",
    "severity": "medium"
  },
  {
    "line": null,
    "reason": "workflow .github/workflows/hypatia-scan.yml uploads SARIF to code scanning but masks the scanner's failure (`|| true` / `|| echo 0`) and never asserts the findings artefact is a non-empty array. When the scanner fails, this uploads a SARIF with zero results, and GitHub AUTO-CLOSES every previously-open alert for that category — silently, with the job green.",
    "type": "WH014",
    "file": ".github/workflows/hypatia-scan.yml",
    "action": "report",
    "rule_module": "workflow_hardening",
    "severity": "high"
  },
  {
    "reason": "Code scanning (Hypatia): hypatia/workflow_audit/scorecard_wrapper_missing_job_permissions -- Hypatia workflow_audit: scorecard_wrapper_missing_job_permissions -- 0 day(s) old",
    "type": "CSA001",
    "file": ".github/workflows/scorecard.yml",
    "action": "update",
    "rule_module": "code_scanning_alerts",
    "severity": "high"
  }
]

Powered by Hypatia Neurosymbolic CI/CD Intelligence

@hyperpolymath
hyperpolymath merged commit 809e521 into main Oct 9, 2026
27 of 29 checks passed
@hyperpolymath
hyperpolymath deleted the fix/block-yaml-for-actions-lock-gate branch October 9, 2026 00:32
@coderabbitai

coderabbitai Bot commented Oct 9, 2026

Copy link
Copy Markdown
Contributor

Add Carrot credits or activate Agent usage billing to use Autopilot

hyperpolymath added a commit that referenced this pull request Oct 9, 2026
…78)

## Summary

This finishes the pin fix that #73 started. It moves the four
`hyperpolymath/standards` reusable-workflow pins from `900c42c7` to
`2e12b312`, the merge commit of hyperpolymath/standards#1209. That makes
`governance / Actions lockfile verify` pass again; it is red on `main`
(`809e521`).

**Why it is red on `main`.** #73 restored block YAML so the actions-lock
gate can read the pins, but it merged with the pins still at `900c42c7`.
At that SHA the gate step runs under `bash -e`. A bare `bash
check-actions-lock-gate.sh` followed by `rc=$?` therefore kills the step
when the gate exits 3 (missing-lock debt), before `rc` is read. The
shrink-only ledger, which lists `hyperpolymath/jaffascript`, never gets
the chance to excuse that debt. standards#1209 reads the exit code with
`|| rc=$?`, so the ledger is reached.

## Changes

- `.github/workflows/governance.yml`, `mirror.yml`, `scorecard.yml` and
`secret-scanner.yml`: `@900c42c70b968e11a2bca04bf0ce050be5c286dc` →
`@2e12b312b529c51f095ce3b22cd35968f5aba898`.
- `.github/workflows/mirror.yml:23`: the comment naming the SHA at which
the seven secrets are "the callee's complete optional contract" now
names `2e12b312`. `mirror-reusable.yml` is byte-identical at the two
SHAs, so the contract has not changed.

### Not changed

- **The workflows stay in block YAML.** #73 explains why: the
actions-lock gate reads pins from block YAML, and that is still true at
`2e12b312`. Converting these files to KYAML would break the gate again.
- **No `actions.lock` is added.** jaffascript's missing lockfile is
ledgered debt in standards `.machine_readable/lock-allow.txt`. Writing
the lockfile and deleting that ledger line is separate work.

## 📌 New pins

- **Head SHA: `ac2edb24bb0287d5595bd4f19e53179947a04821`**
-
**`hyperpolymath/standards/.github/workflows/governance-reusable.yml@2e12b312b529c51f095ce3b22cd35968f5aba898`**
-
**`hyperpolymath/standards/.github/workflows/mirror-reusable.yml@2e12b312b529c51f095ce3b22cd35968f5aba898`**
-
**`hyperpolymath/standards/.github/workflows/scorecard-reusable.yml@2e12b312b529c51f095ce3b22cd35968f5aba898`**
-
**`hyperpolymath/standards/.github/workflows/secret-scanner-reusable.yml@2e12b312b529c51f095ce3b22cd35968f5aba898`**

All four resolve to no tag. `2e12b312` is the merge commit of
standards#1209 (2026-10-09T00:26:51Z), and `git merge-base --is-ancestor
2e12b312 origin/main` succeeds in the standards clone, so the pin is on
standards `main`. No lockfile record or container digest changes.

## RSR Quality Checklist

### Required

- [ ] Tests pass: n/a, no source or test changed. The gate step was
replayed locally (see Testing).
- [ ] Code is formatted: n/a. Five SHA strings changed, and `actionlint`
passes on all four files.
- [x] Linter is clean: `actionlint` exits 0 on the four edited
workflows.
- [x] No banned language patterns: nothing added.
- [ ] No `unsafe` blocks: n/a, no Rust changed.
- [ ] No banned functions: n/a, no source or proofs changed.
- [x] SPDX license headers present: the four edited workflows keep their
existing headers. No file is added.
- [x] No secrets, credentials, or `.env` files.

### As Applicable

- [ ] `.machine_readable/*.a2ml`: no. A2ML is retired, and the project
state is unchanged.
- [ ] Documentation: n/a, no user-facing change.
- [ ] `TOPOLOGY.md`: n/a.
- [ ] `CHANGELOG`: not updated, since this is a CI pin bump.
- [ ] New dependencies: none. The four callees are already dependencies;
only their SHA moves.
- [ ] ABI/FFI: n/a.

## Testing

- **What changed between the two pins:** `git diff --stat 900c42c7
2e12b312` over the whole standards tree touches three files:
`governance-reusable.yml` (+7/−2, the fix),
`scripts/apply-tag-ruleset-canon.sh` and its test (#1210, not used by
callers). The gate's own scripts (`check-actions-lock-gate.sh`,
`update-actions-lock.sh`) and the ledger `lock-allow.txt` are identical
at both SHAs.
- **Local replay of the gate step.** I extracted the step body "Check
locked or SHA-pinned actions" from `governance-reusable.yml` at each SHA
with `yq`. I staged the gate scripts and ledger from the same SHA into
`.standards-lock/`, then ran the body with `bash -e` (the runner's
shell) against a `git archive` of the caller tree, with
`GITHUB_REPOSITORY=hyperpolymath/jaffascript`.

  | Standards SHA | Caller tree | Ledger | Exit | Output |
  |---|---|---|---|---|
| `900c42c7` | `main` `809e521` | as published | **3** | `MISSING-LOCK
DEBT (exit 3)`, the same error as the red job on `main` (job
113610554625) |
| `2e12b312` | this branch | as published | **0** | `actions-lock debt
is LEDGERED for hyperpolymath/jaffascript … 1 of 163 ledgered
repositories` |
| `2e12b312` | this branch | jaffascript's line removed | **3** | `162
ledgered repositories; hyperpolymath/jaffascript is NOT among them` |

The first row reproduces the red job on `main`. The third row shows the
replay can still fail, so the pass in the second row comes from the
ledger and not from a step that cannot fail.
- `actionlint` on the four edited workflows: exit 0.
- The real check is `governance / Actions lockfile verify` on this PR's
head. Its result is listed under "Red checks" below.

## Red checks on this head

_Filled in once the checks report._

## Screenshots

n/a, no UI change.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

https://claude.ai/code/session_01GpUzjdhWFi26k6s7AWxYcf

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