From d575f7cefcfe89ed8070529247159bb136dadf30 Mon Sep 17 00:00:00 2001 From: "Jonathan D.A. Jewell" <6759885+hyperpolymath@users.noreply.github.com> Date: Mon, 24 Aug 2026 12:17:37 +0100 Subject: [PATCH 1/2] fix(ci): recover standards validation gates --- .github/workflows/actions.lock | 40 +++---- .github/workflows/affinescript-verify.yml | 1 - .github/workflows/boj-build.yml | 2 - .github/workflows/casket-pages.yml | 2 - .github/workflows/debt-measure.yml | 1 - .github/workflows/deno-ci-reusable.yml | 20 +++- .github/workflows/doc-format.yml | 1 - .github/workflows/dyadt-verify.yml | 1 - .github/workflows/echidna-verify.yml | 4 - .github/workflows/governance-reusable.yml | 24 ++--- .github/workflows/instant-sync.yml | 1 - .../workflows/launcher-standard-lockstep.yml | 1 - .github/workflows/makefile-blocker.yml | 1 - .github/workflows/no-js-scan.yml | 1 - .github/workflows/pages.yml | 2 - .github/workflows/registry-verify.yml | 1 - .github/workflows/scorecard-enforcer.yml | 3 - .github/workflows/secret-scanner-reusable.yml | 4 +- .github/workflows/self-test.yml | 8 +- .github/workflows/signed-push-smoke.yml | 3 +- .github/workflows/spark-theatre-gate.yml | 1 - .hypatia-baseline.json | 9 ++ .machine_readable/REGISTRY.a2ml | 4 +- deno.json | 25 +++-- docs/GITLEAKS-ESTATE-BASELINE.adoc | 2 +- scripts/check-canonical-names.sh | 11 +- scripts/check-language-guide.sh | 6 +- scripts/check-ts-allowlist.ts | 39 +++++-- scripts/tests/actions-lock-update-test.sh | 100 ++++++++++++++++++ scripts/tests/deno-scope-test.sh | 26 +++++ scripts/tests/governance-gates-505-test.sh | 7 +- scripts/tests/wave0-false-green-test.sh | 20 +--- scripts/tests/wave5-language-guides-test.sh | 13 ++- scripts/tests/wave6-canonical-names-test.sh | 14 ++- scripts/update-actions-lock.sh | 67 ++++++++++++ 35 files changed, 356 insertions(+), 109 deletions(-) create mode 100755 scripts/tests/actions-lock-update-test.sh create mode 100755 scripts/tests/deno-scope-test.sh create mode 100755 scripts/update-actions-lock.sh diff --git a/.github/workflows/actions.lock b/.github/workflows/actions.lock index 48d685cb..cf075eaa 100644 --- a/.github/workflows/actions.lock +++ b/.github/workflows/actions.lock @@ -5,15 +5,7 @@ version: 'v0.0.2' workflows: '.github/workflows/affinescript-verify.yml': - 'actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1' - - 'ocaml/setup-ocaml@v3.7.1' - '.github/workflows/changelog.yml': [] - '.github/workflows/codeql.yml': [] - '.github/workflows/deno-ci.yml': [] - '.github/workflows/elixir-ci.yml': [] - '.github/workflows/governance.yml': [] - '.github/workflows/hypatia-scan.yml': [] - '.github/workflows/mirror.yml': [] - '.github/workflows/readme-derive.yml': [] + - 'ocaml/setup-ocaml@605a7e998e76e035b82c14d618a6e1010732c4ce' '.github/workflows/boj-build.yml': - 'actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1' '.github/workflows/casket-pages.yml': @@ -22,17 +14,20 @@ workflows: - 'actions/configure-pages@45bfe0192ca1faeb007ade9deae92b16b8254a0d' - 'actions/deploy-pages@cd2ce8fcbc39b97be8ca5fce6e763baed58fa128' - 'actions/upload-pages-artifact@fc324d3547104276b827a68afc52ff2a11cc49c9' - - 'haskell-actions/setup@v2.12.0' + - 'haskell-actions/setup@6037f33647c3f17758a2356c80fc4a53d7e0685d' '.github/workflows/changelog-reusable.yml': - 'actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1' + '.github/workflows/changelog.yml': [] '.github/workflows/codeql-reusable.yml': - 'actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1' - - 'github/codeql-action@v4.37.7' + - 'github/codeql-action@ff2f1c621b7f889edc0d3c761ac2e6a3f8cdb0dd' + '.github/workflows/codeql.yml': [] '.github/workflows/debt-measure.yml': - 'actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1' '.github/workflows/deno-ci-reusable.yml': - 'actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1' - 'denoland/setup-deno@22d081ff2d3a40755e97629de92e3bcbfa7cf2ed' + '.github/workflows/deno-ci.yml': [] '.github/workflows/doc-format.yml': - 'actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1' '.github/workflows/dyadt-verify.yml': @@ -45,18 +40,21 @@ workflows: - 'actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9' - 'actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1' - 'erlef/setup-beam@54075bcc5e249e4758d363f27d099f55d843f124' + '.github/workflows/elixir-ci.yml': [] '.github/workflows/governance-reusable.yml': - 'actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9' - 'actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1' - 'denoland/setup-deno@22d081ff2d3a40755e97629de92e3bcbfa7cf2ed' - 'editorconfig-checker/action-editorconfig-checker@840e866d93b8e032123c23bac69dece044d4d84c' - 'erlef/setup-beam@54075bcc5e249e4758d363f27d099f55d843f124' + '.github/workflows/governance.yml': [] '.github/workflows/hypatia-scan-reusable.yml': - 'actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9' - 'actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1' - 'actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a' - 'erlef/setup-beam@54075bcc5e249e4758d363f27d099f55d843f124' - - 'github/codeql-action@v4.37.7' + - 'github/codeql-action@ff2f1c621b7f889edc0d3c761ac2e6a3f8cdb0dd' + '.github/workflows/hypatia-scan.yml': [] '.github/workflows/instant-sync.yml': - 'peter-evans/repository-dispatch@28959ce8df70de7be546dd1250a005dd32156697' '.github/workflows/launcher-standard-lockstep.yml': @@ -65,8 +63,9 @@ workflows: - 'actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1' '.github/workflows/mirror-reusable.yml': - 'actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1' - - 'dtolnay/rust-toolchain@v1' + - 'dtolnay/rust-toolchain@6c977a6ca4077a0ceb28ffbe03f59d46e9ac8772' - 'webfactory/ssh-agent@e83874834305fe9a4a2997156cb26c5de65a8555' + '.github/workflows/mirror.yml': [] '.github/workflows/no-js-scan.yml': - 'actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1' '.github/workflows/pages.yml': @@ -75,12 +74,13 @@ workflows: - 'actions/upload-pages-artifact@fc324d3547104276b827a68afc52ff2a11cc49c9' '.github/workflows/readme-derive-reusable.yml': - 'actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1' + '.github/workflows/readme-derive.yml': [] '.github/workflows/registry-verify.yml': - 'actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1' '.github/workflows/rust-ci-reusable.yml': - 'actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1' - - 'dtolnay/rust-toolchain@v1' - - 'swatinem/rust-cache@v2.9.2' + - 'dtolnay/rust-toolchain@6c977a6ca4077a0ceb28ffbe03f59d46e9ac8772' + - 'swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6' '.github/workflows/scorecard-enforcer.yml': - 'actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1' - 'actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c' @@ -165,7 +165,7 @@ dependencies: commit: 'sha1-22d081ff2d3a40755e97629de92e3bcbfa7cf2ed' owner_id: 42048915 repo_id: 356423100 - 'dtolnay/rust-toolchain@v1': + 'dtolnay/rust-toolchain@6c977a6ca4077a0ceb28ffbe03f59d46e9ac8772': ref: 'v1' commit: 'sha1-6c977a6ca4077a0ceb28ffbe03f59d46e9ac8772' owner_id: 1940490 @@ -180,17 +180,17 @@ dependencies: commit: 'sha1-54075bcc5e249e4758d363f27d099f55d843f124' owner_id: 47606891 repo_id: 331103973 - 'github/codeql-action@v4.37.7': + 'github/codeql-action@ff2f1c621b7f889edc0d3c761ac2e6a3f8cdb0dd': ref: 'v4.37.7' commit: 'sha1-ff2f1c621b7f889edc0d3c761ac2e6a3f8cdb0dd' owner_id: 9919 repo_id: 259445878 - 'haskell-actions/setup@v2.12.0': + 'haskell-actions/setup@6037f33647c3f17758a2356c80fc4a53d7e0685d': ref: 'v2.12.0' commit: 'sha1-6037f33647c3f17758a2356c80fc4a53d7e0685d' owner_id: 75048950 repo_id: 623796603 - 'ocaml/setup-ocaml@v3.7.1': + 'ocaml/setup-ocaml@605a7e998e76e035b82c14d618a6e1010732c4ce': ref: 'v3.7.1' commit: 'sha1-605a7e998e76e035b82c14d618a6e1010732c4ce' owner_id: 1841483 @@ -205,7 +205,7 @@ dependencies: commit: 'sha1-28959ce8df70de7be546dd1250a005dd32156697' owner_id: 18365890 repo_id: 220359305 - 'swatinem/rust-cache@v2.9.2': + 'swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6': ref: 'v2.9.2' commit: 'sha1-6323deb102c322ba6fcbdcafc7e3dddab59af2b6' owner_id: 580492 diff --git a/.github/workflows/affinescript-verify.yml b/.github/workflows/affinescript-verify.yml index b46d681a..5f9a63d6 100644 --- a/.github/workflows/affinescript-verify.yml +++ b/.github/workflows/affinescript-verify.yml @@ -49,7 +49,6 @@ jobs: timeout-minutes: 20 name: AffineScript Verify runs-on: ubuntu-latest - timeout-minutes: 30 permissions: contents: read steps: diff --git a/.github/workflows/boj-build.yml b/.github/workflows/boj-build.yml index 7f2c44e9..ab800d98 100644 --- a/.github/workflows/boj-build.yml +++ b/.github/workflows/boj-build.yml @@ -29,7 +29,6 @@ jobs: trigger-boj: name: Trigger BoJ server runs-on: ubuntu-latest - timeout-minutes: 30 timeout-minutes: 10 # No job-level gate: the `secrets` context is not available in `if:` # (referencing it is an "Unrecognized named-value: 'secrets'" startup @@ -71,7 +70,6 @@ jobs: name: K9-SVC contractile validation timeout-minutes: 10 runs-on: ubuntu-latest - timeout-minutes: 30 steps: - name: Checkout uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 diff --git a/.github/workflows/casket-pages.yml b/.github/workflows/casket-pages.yml index d5bf276f..438f7940 100644 --- a/.github/workflows/casket-pages.yml +++ b/.github/workflows/casket-pages.yml @@ -21,7 +21,6 @@ jobs: build: timeout-minutes: 20 runs-on: ubuntu-latest - timeout-minutes: 30 steps: - name: Checkout uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v4 @@ -96,7 +95,6 @@ jobs: name: github-pages url: ${{ steps.deployment.outputs.page_url }} runs-on: ubuntu-latest - timeout-minutes: 30 needs: build steps: - name: Deploy to GitHub Pages diff --git a/.github/workflows/debt-measure.yml b/.github/workflows/debt-measure.yml index 12ac2eeb..7a3f80a8 100644 --- a/.github/workflows/debt-measure.yml +++ b/.github/workflows/debt-measure.yml @@ -37,7 +37,6 @@ jobs: measure: name: Measure and record runs-on: ubuntu-latest - timeout-minutes: 30 timeout-minutes: 15 permissions: contents: write diff --git a/.github/workflows/deno-ci-reusable.yml b/.github/workflows/deno-ci-reusable.yml index 60570063..e8824f2e 100644 --- a/.github/workflows/deno-ci-reusable.yml +++ b/.github/workflows/deno-ci-reusable.yml @@ -104,8 +104,16 @@ jobs: if: steps.detect.outputs.has_targets == 'true' || steps.detect.outputs.has_config == 'true' run: deno fmt --check - - name: Deno test - if: steps.detect.outputs.has_tests == 'true' + - name: Deno test (configured package) + # A config may intentionally own no tests yet. --permit-no-files keeps + # that honest scope green without discovering tests in nested products. + # Avoid requesting a coverage report for an explicitly empty scope: + # Deno prints "Error generating coverage report" even though it exits 0. + if: steps.detect.outputs.has_config == 'true' + run: deno test --allow-all --permit-no-files + + - name: Deno test (configless fallback) + if: steps.detect.outputs.has_config == 'false' && steps.detect.outputs.has_tests == 'true' run: deno test --allow-all --coverage=coverage - name: Deno type check @@ -113,7 +121,13 @@ jobs: # Soft-pass: `deno check` exits non-zero on unresolved imports we # don't yet require contributors to vendor. We surface output for # diagnostics but don't fail the gate. - run: deno check . || echo "::warning::deno check reported issues (non-blocking)." + run: | + if [ "${{ steps.detect.outputs.has_config }}" = "true" ] \ + && deno task 2>/dev/null | grep -q '^ci:check'; then + deno task ci:check + else + deno check . || echo "::warning::deno check reported issues (non-blocking)." + fi - name: Summary run: | diff --git a/.github/workflows/doc-format.yml b/.github/workflows/doc-format.yml index 38cd4691..986a373e 100644 --- a/.github/workflows/doc-format.yml +++ b/.github/workflows/doc-format.yml @@ -25,7 +25,6 @@ jobs: timeout-minutes: 10 name: Check Documentation Format runs-on: ubuntu-latest - timeout-minutes: 30 steps: - name: Checkout uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v4 diff --git a/.github/workflows/dyadt-verify.yml b/.github/workflows/dyadt-verify.yml index d0aa0abf..2a37a498 100644 --- a/.github/workflows/dyadt-verify.yml +++ b/.github/workflows/dyadt-verify.yml @@ -24,7 +24,6 @@ jobs: verify-claims: name: Verify CLAIMS.a2ml + conformance runs-on: ubuntu-latest - timeout-minutes: 30 timeout-minutes: 10 steps: - name: Checkout repository diff --git a/.github/workflows/echidna-verify.yml b/.github/workflows/echidna-verify.yml index 92c918c3..edca172f 100644 --- a/.github/workflows/echidna-verify.yml +++ b/.github/workflows/echidna-verify.yml @@ -46,7 +46,6 @@ jobs: agda-lol: name: Agda — lol/proofs runs-on: ubuntu-latest - timeout-minutes: 30 timeout-minutes: 20 steps: - name: Checkout @@ -88,7 +87,6 @@ jobs: idris2-a2ml: name: Idris2 — a2ml proofs runs-on: ubuntu-latest - timeout-minutes: 30 timeout-minutes: 20 steps: - name: Checkout @@ -157,7 +155,6 @@ jobs: idris2-avow: name: Idris2 — AVOW consent proofs runs-on: ubuntu-latest - timeout-minutes: 30 timeout-minutes: 20 steps: - name: Checkout @@ -227,7 +224,6 @@ jobs: name: Trust pipeline summary needs: [agda-lol, idris2-a2ml, idris2-avow] runs-on: ubuntu-latest - timeout-minutes: 30 if: always() steps: - name: Summarise diff --git a/.github/workflows/governance-reusable.yml b/.github/workflows/governance-reusable.yml index b68bb766..71d1f6fb 100644 --- a/.github/workflows/governance-reusable.yml +++ b/.github/workflows/governance-reusable.yml @@ -1088,25 +1088,25 @@ jobs: GH_TOKEN: ${{ github.token }} run: | if [ -f .github/workflows/actions.lock ]; then - # Lockfile repos: pin authority is actions.lock (the runner - # enforces it), so tag-style refs are legitimate. Verify every - # action ref has a lockfile entry instead of grepping for SHAs. + # The lockfile records transitive dependency evidence, while direct + # workflow references remain visibly SHA-pinned. Keep both layers: + # external analysers and GitHub's sha_pinning_required setting do + # not infer direct pins from actions.lock. gh extension install github/gh-actions-lock - gh actions-lock --verify-local - # Cross-repo reusable calls stay outside lockfile scope and must - # remain SHA-pinned inline (standards' own calls exempted, as in - # the grep below). - unpinned=$(grep -rnE "^[[:space:]]+uses:[[:space:]]*[A-Za-z0-9_.-]+/[A-Za-z0-9_.-]+/\.github/workflows/[^@]+@" .github/workflows/ | \ + bash scripts/update-actions-lock.sh --verify-local + unpinned=$(grep -rnE --include='*.yml' --include='*.yaml' \ + "^[[:space:]]+uses:" .github/workflows/ | \ grep -v "@[a-f0-9]\{40\}" | \ - grep -v "uses: hyperpolymath/standards/" || true) + grep -v "uses: \./\|uses: docker://\|uses: hyperpolymath/standards/" || true) if [ -n "$unpinned" ]; then - echo "ERROR: reusable workflow calls not SHA-pinned:" + echo "ERROR: direct workflow references not SHA-pinned:" echo "$unpinned" exit 1 fi - echo "Lockfile coverage verified; reusable calls SHA-pinned" + echo "Lockfile coverage verified; direct references SHA-pinned" else - unpinned=$(grep -rnE "^[[:space:]]+uses:" .github/workflows/ | \ + unpinned=$(grep -rnE --include='*.yml' --include='*.yaml' \ + "^[[:space:]]+uses:" .github/workflows/ | \ grep -v "@[a-f0-9]\{40\}" | \ grep -v "uses: \./\|uses: docker://\|uses: actions/github-script\|uses: hyperpolymath/standards/" || true) if [ -n "$unpinned" ]; then diff --git a/.github/workflows/instant-sync.yml b/.github/workflows/instant-sync.yml index 38ed8c49..16343c8b 100644 --- a/.github/workflows/instant-sync.yml +++ b/.github/workflows/instant-sync.yml @@ -25,7 +25,6 @@ jobs: dispatch: timeout-minutes: 10 runs-on: ubuntu-latest - timeout-minutes: 30 # Map the secret to env so step `if:`s can gate on its presence: the # `secrets` context is NOT available in `if:` (using it is an # "Unrecognized named-value: 'secrets'" startup failure). `env` IS diff --git a/.github/workflows/launcher-standard-lockstep.yml b/.github/workflows/launcher-standard-lockstep.yml index df5b7858..58b05819 100644 --- a/.github/workflows/launcher-standard-lockstep.yml +++ b/.github/workflows/launcher-standard-lockstep.yml @@ -31,7 +31,6 @@ jobs: timeout-minutes: 10 name: Verify launcher-standard lock-step runs-on: ubuntu-latest - timeout-minutes: 30 steps: - name: Checkout (full history for base/head diff) uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v4 diff --git a/.github/workflows/makefile-blocker.yml b/.github/workflows/makefile-blocker.yml index 3275cb3b..37d9cfbc 100644 --- a/.github/workflows/makefile-blocker.yml +++ b/.github/workflows/makefile-blocker.yml @@ -31,7 +31,6 @@ jobs: timeout-minutes: 10 name: Block Makefile Changes runs-on: ubuntu-latest - timeout-minutes: 30 steps: - name: Checkout uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v4 diff --git a/.github/workflows/no-js-scan.yml b/.github/workflows/no-js-scan.yml index 2dba23d5..3f6e9db0 100644 --- a/.github/workflows/no-js-scan.yml +++ b/.github/workflows/no-js-scan.yml @@ -40,7 +40,6 @@ jobs: timeout-minutes: 10 name: Scan for hand-authored JavaScript/TypeScript runs-on: ubuntu-latest - timeout-minutes: 30 steps: - name: Checkout uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v4 diff --git a/.github/workflows/pages.yml b/.github/workflows/pages.yml index 54e11939..a1f8b2e5 100644 --- a/.github/workflows/pages.yml +++ b/.github/workflows/pages.yml @@ -16,7 +16,6 @@ concurrency: jobs: build: runs-on: ubuntu-latest - timeout-minutes: 30 timeout-minutes: 15 container: image: ghcr.io/stefan-hoeck/idris2-pack@sha256:f0758996a931fb35d9ecb1de273c4d59dabe2a09b433afc7e357f65a08b7e1ff @@ -49,7 +48,6 @@ jobs: name: github-pages url: ${{ steps.deployment.outputs.page_url }} runs-on: ubuntu-latest - timeout-minutes: 30 timeout-minutes: 15 needs: build steps: diff --git a/.github/workflows/registry-verify.yml b/.github/workflows/registry-verify.yml index b39bb661..6827777a 100644 --- a/.github/workflows/registry-verify.yml +++ b/.github/workflows/registry-verify.yml @@ -24,7 +24,6 @@ jobs: verify: name: Registry + topology in sync runs-on: ubuntu-latest - timeout-minutes: 30 timeout-minutes: 10 steps: - name: Checkout repository diff --git a/.github/workflows/scorecard-enforcer.yml b/.github/workflows/scorecard-enforcer.yml index 81b34887..08899943 100644 --- a/.github/workflows/scorecard-enforcer.yml +++ b/.github/workflows/scorecard-enforcer.yml @@ -17,7 +17,6 @@ permissions: jobs: scorecard: runs-on: ubuntu-latest - timeout-minutes: 30 timeout-minutes: 15 permissions: security-events: write @@ -43,7 +42,6 @@ jobs: check-score: needs: scorecard runs-on: ubuntu-latest - timeout-minutes: 30 timeout-minutes: 10 steps: - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 @@ -67,7 +65,6 @@ jobs: check-critical: runs-on: ubuntu-latest - timeout-minutes: 30 timeout-minutes: 10 steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 diff --git a/.github/workflows/secret-scanner-reusable.yml b/.github/workflows/secret-scanner-reusable.yml index cba2d044..117fb7ed 100644 --- a/.github/workflows/secret-scanner-reusable.yml +++ b/.github/workflows/secret-scanner-reusable.yml @@ -224,7 +224,7 @@ jobs: echo "No reference to .gitleaks-estate.toml; nothing staged." fi - # Pinned by construction: job_workflow_sha is the commit of THIS reusable + # Pinned by construction: job.workflow_sha is the commit of THIS reusable # workflow, so the baseline always matches the workflow consuming it. A # caller pinned to an old SHA gets that SHA's baseline, not a moving one. - name: Estate baseline — fetch @@ -232,7 +232,7 @@ jobs: uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: repository: hyperpolymath/standards - ref: ${{ github.job_workflow_sha }} + ref: ${{ job.workflow_sha }} path: .estate-baseline-checkout sparse-checkout: config/gitleaks sparse-checkout-cone-mode: false diff --git a/.github/workflows/self-test.yml b/.github/workflows/self-test.yml index 3fafb908..b56135ae 100644 --- a/.github/workflows/self-test.yml +++ b/.github/workflows/self-test.yml @@ -31,7 +31,6 @@ jobs: tests: name: Repo self-tests runs-on: ubuntu-latest - timeout-minutes: 30 timeout-minutes: 15 steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 @@ -45,7 +44,12 @@ jobs: run: | set -uo pipefail - mapfile -t TESTS < <(find tests -maxdepth 1 -name '*.sh' -type f | sort) + mapfile -t TESTS < <( + { + find tests -maxdepth 1 -name '*.sh' -type f + find scripts/tests -maxdepth 1 -name '*.sh' -type f + } | sort + ) # Fail closed. If the suite is empty the discovery is broken, and a # green tick here would assert something untrue. diff --git a/.github/workflows/signed-push-smoke.yml b/.github/workflows/signed-push-smoke.yml index 2268abca..9e13cbfc 100644 --- a/.github/workflows/signed-push-smoke.yml +++ b/.github/workflows/signed-push-smoke.yml @@ -19,7 +19,6 @@ permissions: jobs: smoke: runs-on: ubuntu-latest - timeout-minutes: 30 # Safe here because `smoke` is a steps-job. Never add timeout-minutes to a # job that `uses:` a reusable workflow — it is an illegal key there and # GitHub refuses to parse the ENTIRE file, killing every job in it. @@ -51,7 +50,7 @@ jobs: git commit -m "test(signed-push): verified-commit smoke [run ${GITHUB_RUN_ID}]" - name: Push the local commit as Verified (via the App) - uses: $/.github/actions/signed-push + uses: ./.github/actions/signed-push with: app-id: ${{ vars.APP_ID }} private-key: ${{ secrets.APP_PRIVATE_KEY }} diff --git a/.github/workflows/spark-theatre-gate.yml b/.github/workflows/spark-theatre-gate.yml index 3c4f36b9..88908f21 100644 --- a/.github/workflows/spark-theatre-gate.yml +++ b/.github/workflows/spark-theatre-gate.yml @@ -64,7 +64,6 @@ jobs: timeout-minutes: 20 name: SPARK Theatre Gate runs-on: ubuntu-latest - timeout-minutes: 30 steps: - name: Checkout uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 diff --git a/.hypatia-baseline.json b/.hypatia-baseline.json index fcabe0f3..f8f5280b 100644 --- a/.hypatia-baseline.json +++ b/.hypatia-baseline.json @@ -889,5 +889,14 @@ "type": "zig_ptr_cast", "file_pattern": "**/zig-gateway/**", "note": "FFI boundary. A Zig shim crossing into a foreign runtime must reinterpret opaque pointers; the cast is unavoidable in the host language and the guarantee holds on the core's side of the boundary. Architectural, not deferred \u2014 it does not shrink over time." + }, + { + "severity": "critical", + "rule_module": "structural_drift", + "type": "SD004", + "file_pattern": ".machine_readable/6a2/*.a2ml", + "note": "TEMPORARY AUTHORITY CONFLICT (2026-08-24): Hypatia says the 6a2 directory is retired, but standards' registry generator, topology generator, readiness rules, template capability gates, and canonical documentation still consume this path. Do not move normative files to satisfy one downstream rule before the authority sources agree.", + "expires_at": "2026-09-30", + "tracking_issue": "hyperpolymath/standards#399" } ] diff --git a/.machine_readable/REGISTRY.a2ml b/.machine_readable/REGISTRY.a2ml index c167adc5..2bfdc577 100644 --- a/.machine_readable/REGISTRY.a2ml +++ b/.machine_readable/REGISTRY.a2ml @@ -45,7 +45,7 @@ name = "A2ML — Attested Markup Language" stream = "foundation" home = "a2ml/" canonical_doc = "a2ml/README.adoc" -source_hash = "sha256:7073dc4cf6ad5055f169e9530c49414551cc11bd58ae4fe95331c7fc47191f8b" +source_hash = "sha256:285f668b0e931add8ea50b358426ff58d9e28976ad4556a9eb0c77e451a8f46d" route = "the typed/verified machine-readable document format" [[spec]] @@ -54,7 +54,7 @@ name = "K9 Self-Validating Components" stream = "foundation" home = "k9-svc/" canonical_doc = "k9-svc/README.adoc" -source_hash = "sha256:b437293b12114367e7fbbf773e093fb1b187f455f4a49aee629df2a0a1da2fd4" +source_hash = "sha256:ef6c0fd37585c097ed78a704d6698da1262aa32a53d5079a8c8acf1c8a1b0c46" route = "self-validating components with embedded contracts + deploy logic" [[spec]] diff --git a/deno.json b/deno.json index 0b556655..0106545b 100644 --- a/deno.json +++ b/deno.json @@ -2,12 +2,10 @@ "_comment": [ "Canonical Deno config for hyperpolymath/standards.", "", - "Its job is to stop `deno lint`/`deno fmt` reporting on files that are", - "COMPILER OUTPUT rather than hand-authored source. Without this file the", - "deno-ci reusable falls back to scanning raw *.js, which swept in the four", - "bsc-generated axel-protocol/src/*.res.js artifacts and failed the lint on", - "prefer-const violations in generated code — code no human wrote and nobody", - "should edit.", + "This is the CI boundary for hand-authored Deno source owned by the standards", + "repository itself. Embedded products, vendored satellites, generated output,", + "and implementation trees covered by carve-out issues are not one root Deno", + "application and must be validated by their package configs or destination CI.", "", "The exclude list deliberately MIRRORS the one already used by this repo's", "own .github/workflows/no-js-scan.yml, which classifies *.res.js, *.res.mjs,", @@ -16,8 +14,21 @@ "actual defect; this makes them agree rather than inventing new policy.", "", "Per estate language policy the .affine sources are primary — every one of", - "those .res.js files already has an .affine sibling." + "those .res.js files already has an .affine sibling. The explicit include", + "sets below prevent a new nested product file silently expanding root CI." ], + "lint": { + "include": ["scripts/check-ts-allowlist.ts"] + }, + "fmt": { + "include": ["scripts/check-ts-allowlist.ts", "deno.json"] + }, + "test": { + "include": ["scripts/**/*_test.ts"] + }, + "tasks": { + "ci:check": "deno check scripts/check-ts-allowlist.ts" + }, "exclude": [ ".git", "node_modules", diff --git a/docs/GITLEAKS-ESTATE-BASELINE.adoc b/docs/GITLEAKS-ESTATE-BASELINE.adoc index f6c97f29..9cb2130a 100644 --- a/docs/GITLEAKS-ESTATE-BASELINE.adoc +++ b/docs/GITLEAKS-ESTATE-BASELINE.adoc @@ -77,7 +77,7 @@ entries with it. == Versioning -The baseline is fetched at `+${{ github.job_workflow_sha }}+` — the commit of the +The baseline is fetched at `+${{ job.workflow_sha }}+` — the commit of the reusable workflow itself. A caller pinned to an old SHA gets that SHA's baseline, not a moving target. The workflow and the baseline it stages can never disagree. diff --git a/scripts/check-canonical-names.sh b/scripts/check-canonical-names.sh index 15b230b0..e8173bc9 100755 --- a/scripts/check-canonical-names.sh +++ b/scripts/check-canonical-names.sh @@ -16,7 +16,7 @@ # Exit: 0 no new deprecated tokens · 1 a deprecated token was added · 2 usage set -uo pipefail -cd "$(git rev-parse --show-toplevel)" +cd "$(git rev-parse --show-toplevel)" || exit BASE="${1:-}" if [ -z "$BASE" ]; then @@ -31,7 +31,7 @@ declare -A REPL=( ["6a2"]="descriptiles" ["agent_instructions"]="bot_directives" is_excluded() { case "$1" in CANONICAL-NAMES.adoc|scripts/check-canonical-names.sh|scripts/tests/*|\ - *MIGRATION*|*migration*|*CHANGELOG*|*/6a2/*|.machine_readable/6a2/*) return 0 ;; + *MIGRATION*|*migration*|*CHANGELOG*|*/6a2/*) return 0 ;; esac return 1 } @@ -47,6 +47,13 @@ while IFS= read -r line; do "+"*) is_excluded "$current_file" && continue body="${line#+}" + # Hypatia baselines identify findings by their literal on-disk path. This + # narrow matcher records an existing legacy path; it does not name a new + # product, interface, or source location. + if [ "$current_file" = ".hypatia-baseline.json" ] && + printf '%s' "$body" | grep -Fq '"file_pattern": ".machine_readable/6a2/*.a2ml"'; then + continue + fi # Skip a line that is DESCRIBING the deprecation rather than using the old # name — it also mentions the canonical replacement or the mandate itself # (e.g. tooling comments, this guard's own wiring, docs about the rename). diff --git a/scripts/check-language-guide.sh b/scripts/check-language-guide.sh index b16de3cb..5827d193 100755 --- a/scripts/check-language-guide.sh +++ b/scripts/check-language-guide.sh @@ -9,7 +9,7 @@ # this fails loudly instead. # # Usage: check-language-guide.sh [guide.md ...] -# With no args, checks every standards/*-testing-guide.md. +# With no args, checks every docs/*-testing-guide.md. # Exit: 0 all valid · 1 a guide is missing a required section set -uo pipefail @@ -42,11 +42,11 @@ check_one() { # file if [ "$#" -gt 0 ]; then files=("$@") else - mapfile -t files < <(ls "$ROOT"/standards/*-testing-guide.md 2>/dev/null) + mapfile -t files < <(find "$ROOT/docs" -maxdepth 1 -type f -name '*-testing-guide.md' -print 2>/dev/null | LC_ALL=C sort) fi if [ "${#files[@]}" -eq 0 ]; then - echo "no language testing guides found (standards/*-testing-guide.md)"; exit 0 + echo "no language testing guides found (docs/*-testing-guide.md)"; exit 0 fi rc=0 diff --git a/scripts/check-ts-allowlist.ts b/scripts/check-ts-allowlist.ts index 3a6ba9e8..95717386 100644 --- a/scripts/check-ts-allowlist.ts +++ b/scripts/check-ts-allowlist.ts @@ -28,9 +28,17 @@ // Permission scope is `--allow-read` only. No network, no env, no write. const DIR_NAMES_ALLOWED = new Set([ - "bindings", "tests", "test", "scripts", - "mcp-adapter", "cli", "vendor", "examples", "ffi", - "node_modules", "benchmarks", + "bindings", + "tests", + "test", + "scripts", + "mcp-adapter", + "cli", + "vendor", + "examples", + "ffi", + "node_modules", + "benchmarks", ]); function builtinAllowed(p: string): boolean { @@ -71,7 +79,10 @@ function globToRegex(g: string): RegExp { return new RegExp("^" + out + "$"); } -interface Exemption { raw: string; rx: RegExp; } +interface Exemption { + raw: string; + rx: RegExp; +} function normalizeRepoPath(p: string): string { let out = p.trim(); @@ -222,16 +233,26 @@ async function main() { console.log("To resolve, choose one:"); console.log(" (a) migrate the file to AffineScript"); console.log(" (b) move to an allowlisted bridge path"); - console.log(" (c) add an entry to a 'TypeScript Exemptions' table in .claude/CLAUDE.md (Layer 2)"); - console.log(" (d) add a line to .governance-allowlist at the repo root (Layer 2.5 — typed infrastructure file)"); + console.log( + " (c) add an entry to a 'TypeScript Exemptions' table in .claude/CLAUDE.md (Layer 2)", + ); + console.log( + " (d) add a line to .governance-allowlist at the repo root (Layer 2.5 — typed infrastructure file)", + ); console.log(""); - console.log("See docs/EXEMPTION-MECHANISMS.adoc for the full mechanism reference."); + console.log( + "See docs/EXEMPTION-MECHANISMS.adoc for the full mechanism reference.", + ); if (exemptions.length > 0) { - console.log(`\n(Currently ${exemptions.length} exemption(s) parsed across both layers.)`); + console.log( + `\n(Currently ${exemptions.length} exemption(s) parsed across both layers.)`, + ); } Deno.exit(1); } - console.log(`✅ No TypeScript files outside allowlist (${exemptions.length} per-repo exemption(s) parsed across CLAUDE.md + .governance-allowlist).`); + console.log( + `✅ No TypeScript files outside allowlist (${exemptions.length} per-repo exemption(s) parsed across CLAUDE.md + .governance-allowlist).`, + ); } if (import.meta.main) { diff --git a/scripts/tests/actions-lock-update-test.sh b/scripts/tests/actions-lock-update-test.sh new file mode 100755 index 00000000..158b4c38 --- /dev/null +++ b/scripts/tests/actions-lock-update-test.sh @@ -0,0 +1,100 @@ +#!/usr/bin/env bash +# SPDX-License-Identifier: MPL-2.0 +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" +UPDATE="$SCRIPT_DIR/../update-actions-lock.sh" +WORK="$(mktemp -d)" +trap 'rm -rf "$WORK"' EXIT + +mkdir -p "$WORK/.github/workflows" "$WORK/bin" +cat > "$WORK/.github/workflows/ci.yml" <<'EOF' +# SPDX-License-Identifier: MPL-2.0 +# This workflow is managed by gh actions-lock. +name: CI +on: push +permissions: {} +jobs: + test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 +EOF + +cat > "$WORK/bin/fake-gh" <<'EOF' +#!/usr/bin/env bash +set -euo pipefail +if [ "${2:-}" = "--verify-local" ]; then + grep -q "actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1" \ + .github/workflows/actions.lock + sed -i 's#uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1#uses: actions/checkout@v7.0.1#' \ + .github/workflows/ci.yml + exit +fi +sed -i '1i# This workflow is managed by gh actions-lock.' .github/workflows/ci.yml +sed -i 's#actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1#actions/checkout@v7.0.1#' \ + .github/workflows/ci.yml +cat > .github/workflows/actions.lock <<'LOCK' +version: 'v0.0.2' +workflows: + '.github/workflows/ci.yml': + - 'actions/checkout@v7.0.1' +dependencies: + 'actions/checkout@v7.0.1': + ref: 'v7.0.1' + commit: 'sha1-3d3c42e5aac5ba805825da76410c181273ba90b1' + owner_id: 1 + repo_id: 2 +LOCK +EOF +chmod +x "$WORK/bin/fake-gh" + +cd "$WORK" +GH_BIN="$WORK/bin/fake-gh" bash "$UPDATE" .github/workflows >/dev/null + +grep -q 'uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1' \ + .github/workflows/ci.yml +[ "$(grep -c '^# This workflow is managed by gh actions-lock.$' .github/workflows/ci.yml)" -eq 1 ] +grep -q "'actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1':" \ + .github/workflows/actions.lock + +cp .github/workflows/ci.yml "$WORK/ci.before" +cp .github/workflows/actions.lock "$WORK/lock.before" +GH_BIN="$WORK/bin/fake-gh" bash "$UPDATE" .github/workflows >/dev/null +cmp -s "$WORK/ci.before" .github/workflows/ci.yml +cmp -s "$WORK/lock.before" .github/workflows/actions.lock + +echo "PASS: Actions lock refresh preserves inline SHA source and is idempotent" + +# Verification is mutating in released gh-actions-lock versions too. The safe +# verification mode must restore workflow bytes while leaving the lock intact. +cp .github/workflows/ci.yml "$WORK/ci.before-verify" +cp .github/workflows/actions.lock "$WORK/lock.before-verify" +GH_BIN="$WORK/bin/fake-gh" bash "$UPDATE" --verify-local .github/workflows >/dev/null +cmp -s "$WORK/ci.before-verify" .github/workflows/ci.yml +cmp -s "$WORK/lock.before-verify" .github/workflows/actions.lock +echo "PASS: Actions lock verification restores tool-authored workflow edits" + +# A failed refresh must restore both authored workflows and the previous +# lockfile; this is the production failure mode that left the original checkout +# half-rewritten when DNS resolution failed. +cp .github/workflows/ci.yml "$WORK/ci.before-failure" +cp .github/workflows/actions.lock "$WORK/lock.before-failure" +cat > "$WORK/bin/failing-gh" <<'EOF' +#!/usr/bin/env bash +set -euo pipefail +sed -i '1i# This workflow is managed by gh actions-lock.' .github/workflows/ci.yml +sed -i 's#actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1#actions/checkout@v7.0.1#' \ + .github/workflows/ci.yml +printf 'partial lock\n' > .github/workflows/actions.lock +exit 1 +EOF +chmod +x "$WORK/bin/failing-gh" + +if GH_BIN="$WORK/bin/failing-gh" bash "$UPDATE" .github/workflows >/dev/null 2>&1; then + echo "FAIL: simulated lock refresh unexpectedly succeeded" >&2 + exit 1 +fi +cmp -s "$WORK/ci.before-failure" .github/workflows/ci.yml +cmp -s "$WORK/lock.before-failure" .github/workflows/actions.lock +echo "PASS: failed Actions lock refresh rolls back partial generated edits" diff --git a/scripts/tests/deno-scope-test.sh b/scripts/tests/deno-scope-test.sh new file mode 100755 index 00000000..48c58875 --- /dev/null +++ b/scripts/tests/deno-scope-test.sh @@ -0,0 +1,26 @@ +#!/usr/bin/env bash +# SPDX-License-Identifier: MPL-2.0 +set -euo pipefail + +ROOT="$(cd "$(dirname "$0")/../.." && pwd)" +WORK="$(mktemp -d)" +trap 'rm -rf "$WORK"' EXIT + +mkdir -p "$WORK/scripts" "$WORK/lol" +cp "$ROOT/deno.json" "$WORK/deno.json" +printf 'const clean = 1;\nconsole.log(clean);\n' > "$WORK/scripts/check-ts-allowlist.ts" +printf 'const ignored: any = 1\n' > "$WORK/lol/product.ts" + +(cd "$WORK" && deno lint >/dev/null) +echo "PASS: nested product source does not expand root lint scope" + +printf 'const broken: any = 1;\n' > "$WORK/scripts/check-ts-allowlist.ts" +if (cd "$WORK" && deno lint >/dev/null 2>&1); then + echo "FAIL: root-owned lint violation did not block" >&2 + exit 1 +fi +echo "PASS: root-owned lint violation blocks" + +printf 'const clean = 1;\nconsole.log(clean);\n' > "$WORK/scripts/check-ts-allowlist.ts" +(cd "$WORK" && deno test --permit-no-files >/dev/null) +echo "PASS: explicit empty test scope does not discover nested product tests" diff --git a/scripts/tests/governance-gates-505-test.sh b/scripts/tests/governance-gates-505-test.sh index b69b4d2d..277d9244 100755 --- a/scripts/tests/governance-gates-505-test.sh +++ b/scripts/tests/governance-gates-505-test.sh @@ -110,9 +110,14 @@ assert "manifest.scm passes" 0 "Guix package management detected" \ env PKG_TODAY="$AFTER" "$PKG" "$r" r=$(mkrepo pkg-nix flake.nix) -assert "flake.nix passes as fallback" 0 "Nix package management detected" \ +assert "Nix-only packaging BLOCKS after retirement" 1 "Nix-only packaging is not compliant" \ env PKG_TODAY="$AFTER" "$PKG" "$r" +# Preserve the historical grace seam without reviving the retired policy: a +# pre-retirement Nix-only repo warns and makes no pass claim. +assert "Nix-only packaging warns before retirement" 0 "NOT YET ENFORCED" \ + env PKG_TODAY="2026-05-31" "$PKG" "$r" + # Same repo, both sides of the cutoff — the self-flipping proof. r=$(mkrepo pkg-none README.adoc) assert "no packaging warns pre-cutoff (no pass claimed)" 0 "NOT YET ENFORCED" \ diff --git a/scripts/tests/wave0-false-green-test.sh b/scripts/tests/wave0-false-green-test.sh index 17ba695b..7d6b4ba1 100755 --- a/scripts/tests/wave0-false-green-test.sh +++ b/scripts/tests/wave0-false-green-test.sh @@ -12,7 +12,7 @@ set -uo pipefail # * a2ml/scripts/check-6scm.sh (obsolete no-op / orphan drift / out-of-sync) # * scripts/check-mustfile-structure.sh (valid Mustfile / hollow check) # * rhodium-standard-repositories/rsr-audit.sh (bad format exits 4 / --format json works) -# * audit-contractiles.sh (loud error on zero repos) +# * audit-contractiles.sh (retired; Hypatia owns this audit) ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)" TMP="$(mktemp -d)" @@ -71,21 +71,11 @@ esac bash "$RSR" . text >/dev/null 2>&1; rc=$? if [ "$rc" -ge 0 ] && [ "$rc" -le 3 ]; then ok "bare positional 'text' returns a grade code ($rc)"; else bad "bare positional 'text' returned $rc"; fi -echo "== audit-contractiles.sh ==" -AC="$ROOT/audit-contractiles.sh" -# Runs against an explicit repo path with no hardcoded owner (/var/mnt/...) paths. -# Capture the output first (avoid pipefail masking the script's own exit code). -ac_out="$(bash "$AC" "$ROOT" 2>&1 || true)" -case "$ac_out" in - *"Contractile System Audit"*) ok "runs against an explicit repo path (no hardcoded owner paths)" ;; - *) bad "did not run against explicit repo path" ;; -esac -# No hardcoded owner path is USED (a quoted absolute /var/mnt/... array element); -# a prose mention in a comment is fine, an actual code path is not. -if grep -qE '^[[:space:]]*"/var/mnt/' "$AC"; then - bad "hardcoded owner path still used in code" +echo "== retired audit-contractiles.sh ==" +if [ -e "$ROOT/audit-contractiles.sh" ]; then + bad "retired personal-machine validator was reintroduced" else - ok "no hardcoded owner path used in code" + ok "retired personal-machine validator remains absent" fi echo diff --git a/scripts/tests/wave5-language-guides-test.sh b/scripts/tests/wave5-language-guides-test.sh index 8fcf81c6..8a611353 100755 --- a/scripts/tests/wave5-language-guides-test.sh +++ b/scripts/tests/wave5-language-guides-test.sh @@ -14,8 +14,13 @@ ok() { echo " ✅ $1"; pass=$((pass + 1)); } bad() { echo " ❌ $1"; fail=$((fail + 1)); } echo "== real guides pass ==" -bash "$CHK" >/dev/null 2>&1 && ok "estate guides pass structural lint" || bad "estate guides failed lint" -bash "$CHK" "$ROOT/standards/affinescript-testing-guide.md" >/dev/null 2>&1 && ok "affinescript guide valid" || bad "affinescript guide invalid" +guide_out="$(bash "$CHK" 2>&1)"; guide_rc=$? +if [ "$guide_rc" -eq 0 ] && printf '%s\n' "$guide_out" | grep -q 'affinescript-testing-guide.md'; then + ok "estate guides are discovered and pass structural lint" +else + bad "estate guides were missed or failed lint" +fi +bash "$CHK" "$ROOT/docs/affinescript-testing-guide.md" >/dev/null 2>&1 && ok "affinescript guide valid" || bad "affinescript guide invalid" echo "== rejects incomplete guides ==" # missing a required section @@ -32,9 +37,9 @@ printf '\n# Baz\n## Requirement ma bash "$CHK" "$g3" >/dev/null 2>&1 && bad "missing R1..R9 not caught" || ok "missing R1..R9 rejected" echo "== the stale duplicate snapshot is gone ==" -[ ! -f "$ROOT/standards/language-testing-standards-v1.0.0-2024-04-14.md" ] && ok "duplicate snapshot removed" || bad "duplicate snapshot still present" +[ ! -f "$ROOT/docs/language-testing-standards-v1.0.0-2024-04-14.md" ] && ok "duplicate snapshot removed" || bad "duplicate snapshot still present" echo "== the standard is v2.0.0 with RFC-2119 ==" -grep -q 'Version:\*\* 2.0.0' "$ROOT/standards/language-testing-standards.md" && grep -qi 'RFC-2119' "$ROOT/standards/language-testing-standards.md" && ok "standard refreshed to v2.0.0 RFC-2119" || bad "standard not refreshed" +grep -q 'Version:\*\* 2.0.0' "$ROOT/docs/language-testing-standards.md" && grep -qi 'RFC-2119' "$ROOT/docs/language-testing-standards.md" && ok "standard refreshed to v2.0.0 RFC-2119" || bad "standard not refreshed" echo echo "Wave-5 language-guides regression: $pass passed, $fail failed" diff --git a/scripts/tests/wave6-canonical-names-test.sh b/scripts/tests/wave6-canonical-names-test.sh index d3484d0b..ae88254e 100755 --- a/scripts/tests/wave6-canonical-names-test.sh +++ b/scripts/tests/wave6-canonical-names-test.sh @@ -7,12 +7,24 @@ set -uo pipefail ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)" CHK="$ROOT/scripts/check-canonical-names.sh" +TMP="$(mktemp -d)" +trap 'rm -rf "$TMP"' EXIT pass=0 fail=0 ok() { echo " ✅ $1"; pass=$((pass + 1)); } bad() { echo " ❌ $1"; fail=$((fail + 1)); } -cd "$ROOT" +# Exercise the guard in a private repository so unrelated changes in the caller's +# worktree cannot turn the clean-name case into a false failure. +mkdir -p "$TMP/repo/scripts" +cp "$CHK" "$TMP/repo/scripts/check-canonical-names.sh" +cd "$TMP/repo" || exit +git init -q +git config user.name "Standards regression test" +git config user.email "standards-regression@example.invalid" +git add scripts/check-canonical-names.sh +git commit -qm "baseline" +CHK="$TMP/repo/scripts/check-canonical-names.sh" echo "== guard blocks a newly-added deprecated token ==" f="wave6_guard_probe.txt" diff --git a/scripts/update-actions-lock.sh b/scripts/update-actions-lock.sh new file mode 100755 index 00000000..cc5c3f87 --- /dev/null +++ b/scripts/update-actions-lock.sh @@ -0,0 +1,67 @@ +#!/usr/bin/env bash +# SPDX-License-Identifier: MPL-2.0 +# +# Refresh actions.lock without letting gh actions-lock rewrite the canonical +# workflow source from inline SHA pins to tag references. +set -euo pipefail + +MODE=update +if [ "${1:-}" = "--verify-local" ]; then + MODE=verify + shift +fi + +WF_DIR="${1:-.github/workflows}" +GH_BIN="${GH_BIN:-gh}" + +[ -d "$WF_DIR" ] || { echo "update-actions-lock: no workflow directory: $WF_DIR" >&2; exit 1; } + +SNAPSHOT="$(mktemp -d)" +COMPLETE=false + +restore_workflows() { + find "$SNAPSHOT/workflows" -maxdepth 1 -type f -print0 2>/dev/null | + while IFS= read -r -d '' file; do + cp "$file" "$WF_DIR/$(basename "$file")" + done +} + +cleanup() { + status=$? + if [ "$COMPLETE" != true ]; then + restore_workflows + if [ -f "$SNAPSHOT/actions.lock" ]; then + cp "$SNAPSHOT/actions.lock" "$WF_DIR/actions.lock" + else + rm -f "$WF_DIR/actions.lock" + fi + fi + rm -rf "$SNAPSHOT" + exit "$status" +} +trap cleanup EXIT + +mkdir -p "$SNAPSHOT/workflows" +[ ! -f "$WF_DIR/actions.lock" ] || cp "$WF_DIR/actions.lock" "$SNAPSHOT/actions.lock" + +# gh actions-lock currently inserts its managed marker and rewrites direct SHA +# refs to their release tags. Those edits conflict with the estate's inline-SHA +# gate. Preserve every authored workflow while allowing the generated lockfile +# to change. +find "$WF_DIR" -maxdepth 1 -type f \( -name '*.yml' -o -name '*.yaml' \) -print0 | + while IFS= read -r -d '' file; do + cp "$file" "$SNAPSHOT/workflows/$(basename "$file")" + done + +if [ "$MODE" = update ]; then + "$GH_BIN" actions-lock + restore_workflows + bash "$(dirname "$0")/relock-sha-keys.sh" "$WF_DIR" +fi + +# Despite its name, --verify-local can migrate local `./` action paths to an +# invalid `$/` spelling. Treat verification as mutating and restore authored +# workflow bytes afterward too. +"$GH_BIN" actions-lock --verify-local +restore_workflows +COMPLETE=true From 96652242f015c9b6fae2d322e9cc9b57b2301239 Mon Sep 17 00:00:00 2001 From: "Jonathan D.A. Jewell" <6759885+hyperpolymath@users.noreply.github.com> Date: Mon, 24 Aug 2026 12:39:21 +0100 Subject: [PATCH 2/2] fix(ci): resolve migration clashes in recovery branch --- .github/workflows/registry-verify.yml | 4 +- .machine_readable/REGISTRY.a2ml | 22 +- .../contractiles/must/Mustfile.a2ml | 4 +- .../scorecards/a2ml-templates.scorecard.a2ml | 2 +- .../component-readiness-grades.scorecard.a2ml | 2 +- .../estate-constitution.scorecard.a2ml | 2 +- .../scorecards/hypatia-rules.scorecard.a2ml | 2 +- .../scorecards/k9-svc.scorecard.a2ml | 2 +- ...ession-management-standards.scorecard.a2ml | 2 +- .../toolchain-readiness-grades.scorecard.a2ml | 2 +- .../mcp-repo-guardian/lib/ocaml/Guards.affine | 2 +- .../mcp-repo-guardian/lib/ocaml/Index.affine | 2 +- .../lib/ocaml/Manifest.affine | 2 +- .../lib/ocaml/Session.affine | 2 +- .../mcp-repo-guardian/lib/ocaml/Types.affine | 2 +- .../mcp-repo-guardian/src/Guards.affine | 2 +- .../mcp-repo-guardian/src/Index.affine | 2 +- .../mcp-repo-guardian/src/Manifest.affine | 2 +- .../mcp-repo-guardian/src/Session.affine | 2 +- .../mcp-repo-guardian/src/Types.affine | 2 +- COMPLIANCE-DASHBOARD.adoc | 155 +++++-------- Justfile | 6 +- TOPOLOGY.adoc | 214 ++++++------------ a2ml/bindings/deno/src/A2ML.affine | 2 +- a2ml/bindings/deno/src/A2ML_Parser.affine | 2 +- a2ml/bindings/deno/src/A2ML_Renderer.affine | 2 +- a2ml/bindings/deno/src/A2ML_Types.affine | 2 +- a2ml/prototype/wasm/src/WasmDemo.affine | 2 +- axel-protocol/src/AxelApp.affine | 2 +- axel-protocol/src/AxelSts.affine | 2 +- axel-protocol/src/ProvenResult.affine | 2 +- axel-protocol/src/ProvenSafeUrl.affine | 2 +- axel-protocol/src/Tea.affine | 2 +- docs/affinescript-testing-guide.adoc | 2 + k9-svc/bindings/deno/src/K9.affine | 2 +- k9-svc/bindings/deno/src/K9_Parser.affine | 2 +- k9-svc/bindings/deno/src/K9_Renderer.affine | 2 +- k9-svc/bindings/deno/src/K9_Types.affine | 2 +- lol/src/Lang1000.affine | 2 +- lol/src/api/DigitalBiblePlatform.affine | 2 +- lol/src/crawlers/BibleCloud.affine | 2 +- lol/src/crawlers/BibleCom.affine | 2 +- lol/src/crawlers/Crawler.affine | 2 +- lol/src/crawlers/EBible.affine | 2 +- lol/src/crawlers/FindBible.affine | 2 +- lol/src/crawlers/PngScriptures.affine | 2 +- lol/src/cyc/OpenCyc.affine | 2 +- lol/src/utils/Http.affine | 2 +- lol/src/utils/Iso639.affine | 2 +- lol/src/utils/Statistics.affine | 2 +- lol/src/verisimdb/CorpusAnalyzer.affine | 2 +- lol/src/verisimdb/Export.affine | 2 +- lol/src/verisimdb/VeriSimDB.affine | 2 +- lol/test/Lang1000_test.affine | 2 +- lol/test/Vitest.affine | 2 +- lol/test/crawlers/Crawler_test.affine | 2 +- lol/test/utils/Iso639_test.affine | 2 +- lol/test/utils/Statistics_test.affine | 2 +- panll-panels/src/ComplianceMonitor.affine | 2 +- panll-panels/src/CrgDashboard.affine | 2 +- panll-panels/src/ProofHub.affine | 2 +- panll-panels/src/VcldbClient.affine | 2 +- scripts/build-registry.sh | 54 ++--- scripts/build-scorecards.sh | 88 +++---- scripts/check-language-guide.sh | 24 +- scripts/tests/wave3-scorecards-test.sh | 6 +- scripts/tests/wave5-language-guides-test.sh | 8 +- 67 files changed, 291 insertions(+), 406 deletions(-) diff --git a/.github/workflows/registry-verify.yml b/.github/workflows/registry-verify.yml index 6827777a..4e7264da 100644 --- a/.github/workflows/registry-verify.yml +++ b/.github/workflows/registry-verify.yml @@ -62,7 +62,7 @@ jobs: echo "" echo '```sh' echo "just registry # or: bash scripts/build-registry.sh" - echo "git add .machine_readable/REGISTRY.a2ml TOPOLOGY.md" + echo "git add .machine_readable/REGISTRY.a2ml TOPOLOGY.adoc" echo '```' echo "" echo "Install the pre-commit guard so this is caught before push:" @@ -90,7 +90,7 @@ jobs: { echo "### Compliance dashboard drift" echo "" - echo "COMPLIANCE-DASHBOARD.md is stale, a scorecard is malformed/orphaned," + echo "COMPLIANCE-DASHBOARD.adoc is stale, a scorecard is malformed/orphaned," echo "or a registered spec has no scorecard. Fix locally:" echo "" echo '```sh' diff --git a/.machine_readable/REGISTRY.a2ml b/.machine_readable/REGISTRY.a2ml index 2bfdc577..b783a941 100644 --- a/.machine_readable/REGISTRY.a2ml +++ b/.machine_readable/REGISTRY.a2ml @@ -36,7 +36,7 @@ name = "Hyperpolymath Estate Constitution" stream = "governance" home = "constitution/" canonical_doc = "constitution/README.adoc" -source_hash = "sha256:6c3aa978642e8b44361f57f6301686f373af699cdd80b582d13e7c5e00caed20" +source_hash = "sha256:7fbd1015a184d33391957e73f6348c7409b6298e15ef9c8bcd26bf1a6fd7d739" route = "the highest estate-level rules, authority precedence, assurance, contribution, exceptions, and known tensions" [[spec]] @@ -45,7 +45,7 @@ name = "A2ML — Attested Markup Language" stream = "foundation" home = "a2ml/" canonical_doc = "a2ml/README.adoc" -source_hash = "sha256:285f668b0e931add8ea50b358426ff58d9e28976ad4556a9eb0c77e451a8f46d" +source_hash = "sha256:2a54c3194a4a055bbbd0006963eac0a3a5a2c1e0dff683196c8feca48f538f52" route = "the typed/verified machine-readable document format" [[spec]] @@ -54,7 +54,7 @@ name = "K9 Self-Validating Components" stream = "foundation" home = "k9-svc/" canonical_doc = "k9-svc/README.adoc" -source_hash = "sha256:ef6c0fd37585c097ed78a704d6698da1262aa32a53d5079a8c8acf1c8a1b0c46" +source_hash = "sha256:5f0fab5714c30bf6a43845820a925d7b00d6727d17668061d3488ec093b0737d" route = "self-validating components with embedded contracts + deploy logic" [[spec]] @@ -135,7 +135,7 @@ name = "0-AI Gatekeeper Protocol" stream = "protocol" home = "0-ai-gatekeeper-protocol/" canonical_doc = "0-ai-gatekeeper-protocol/README.adoc" -source_hash = "sha256:52169e768b8d55a99f9190bffcbc696803fa591610365828b788cd8f7a09a917" +source_hash = "sha256:0c648b66962fa1c23ce74ed7d1e2e95163c143d5909d27f7ac8f310f29068cbf" route = "the AI-agent entry/gating protocol behind 0-AI-MANIFEST" [[spec]] @@ -144,7 +144,7 @@ name = "K9 Coordination Protocol" stream = "protocol" home = "k9-coordination-protocol/" canonical_doc = "k9-coordination-protocol/README.adoc" -source_hash = "sha256:ee8521e5db1ebd5156b0a866bfe6990ab18f62885c7133e0d66ebf038a370b84" +source_hash = "sha256:2cec6c00c8ead34bb7a90b214b59ffdf3d2b3884e02e2cbd2f353b3636b5db34" route = "multi-agent coordination on top of K9" [[spec]] @@ -162,7 +162,7 @@ name = "AXEL Protocol" stream = "protocol" home = "axel-protocol/" canonical_doc = "axel-protocol/README.adoc" -source_hash = "sha256:020e11cbab41cc5cb86182bc6ba93b58ee6b9bf29237d172e735363eebc5f27c" +source_hash = "sha256:6e4dce291ecdc20481f681d810db838a658af09a93c67cfa051d9d4427a24877" route = "age-gating + explicit-content enforcement" [[spec]] @@ -171,7 +171,7 @@ name = "Overlay Protocol" stream = "protocol" home = "overlay-protocol/" canonical_doc = "overlay-protocol/.machine_readable/6a2/ECOSYSTEM.a2ml" -source_hash = "sha256:59ed969ed2c189d31daa5a253d73f79ae9b2b8fdf690b24717a77a6803dc0f98" +source_hash = "sha256:b52752056328cc77708e1cbe9446324bc60d8e34d08471318a786d1e732521d3" route = "layered overlay composition spec" [[spec]] @@ -198,7 +198,7 @@ name = "CRG — Component Readiness Grades" stream = "readiness" home = "component-readiness-grades/" canonical_doc = "component-readiness-grades/README.adoc" -source_hash = "sha256:edf1d1b8035fcb67d2c27aba50b9e953ea2cb502ffbdc60fe96c147e9b1631d4" +source_hash = "sha256:30a65855c396c43955d3abf77623ecec5932347c9ff83b6ab510b99176acec83" route = "the X..A grading system for components" [[spec]] @@ -207,7 +207,7 @@ name = "TRG — Toolchain Readiness Grades" stream = "readiness" home = "toolchain-readiness-grades/" canonical_doc = "toolchain-readiness-grades/README.adoc" -source_hash = "sha256:c1741ef15ee180179c04529dc1378675fff55b245915d2b20b9cab89cc466092" +source_hash = "sha256:b887d7d3f3e08b4d7020f225a13dec97f089509cad4f1192b2cf31af5a74e3a8" route = "per-toolchain readiness profile templates" [[spec]] @@ -216,7 +216,7 @@ name = "RSR — Rhodium Standard Repositories" stream = "governance" home = "rhodium-standard-repositories/" canonical_doc = "rhodium-standard-repositories/README.adoc" -source_hash = "sha256:defbdce1c0a17d643b000b78b1a604f444dabcfd4e988375924e30f63291981c" +source_hash = "sha256:8b6478c4900181fa5ab17bccaf9dafe2c8e5d1c22bd03d7c3a7a3feaf048cb8c" route = "the repository-compliance standard every repo is graded against" [[spec]] @@ -225,7 +225,7 @@ name = "Session Management Standards" stream = "governance" home = "session-management-standards/" canonical_doc = "session-management-standards/README.adoc" -source_hash = "sha256:4b1a97d2ef91578b2c262f1af5b93577cb36d53d234c330947538f4eafc01a6c" +source_hash = "sha256:f97ff391eea3fc80a4ab0b94031cf4ad9a373f8699ca99f0f0daecfb968ac148" route = "continuity / verify / handover protocols" [[spec]] diff --git a/.machine_readable/contractiles/must/Mustfile.a2ml b/.machine_readable/contractiles/must/Mustfile.a2ml index a9210c12..9b605ac1 100644 --- a/.machine_readable/contractiles/must/Mustfile.a2ml +++ b/.machine_readable/contractiles/must/Mustfile.a2ml @@ -30,8 +30,8 @@ requirements — CI and pre-commit hooks fail if any check fails. - severity: critical ### security-policy -- description: SECURITY.md must exist -- run: test -f SECURITY.md +- description: SECURITY.adoc must exist +- run: test -f SECURITY.adoc - severity: critical ### ai-manifest diff --git a/.machine_readable/scorecards/a2ml-templates.scorecard.a2ml b/.machine_readable/scorecards/a2ml-templates.scorecard.a2ml index b7f285b3..0df12d00 100644 --- a/.machine_readable/scorecards/a2ml-templates.scorecard.a2ml +++ b/.machine_readable/scorecards/a2ml-templates.scorecard.a2ml @@ -44,7 +44,7 @@ text = "The spec MUST be tracked in the estate compliance dashboard with a score system = "COMPLIANCE-DASHBOARD.md rollup table (line 52) plus .machine_readable/scorecards/a2ml-templates.scorecard.a2ml" status = "pass" evidence = "COMPLIANCE-DASHBOARD.md line 52 lists `a2ml-templates` with real must/should/could scores (1/5, 1/3, 0/2) rather than the 'no scorecard' placeholder, and this file (.machine_readable/scorecards/a2ml-templates.scorecard.a2ml) is the tracked scorecard; rollup states 'Specs with a scorecard: 30 / 30'." -check = "grep -n \"^| \\`a2ml-templates\\`\" COMPLIANCE-DASHBOARD.md | grep -qv \"no scorecard\" && test -f .machine_readable/scorecards/a2ml-templates.scorecard.a2ml" +check = "grep -F '| `+a2ml-templates+`' COMPLIANCE-DASHBOARD.adoc | grep -qv 'no scorecard' && test -f .machine_readable/scorecards/a2ml-templates.scorecard.a2ml" effects = "The estate-wide rollup (1/28 specs scored, 50% system coverage) cannot include this spec's real compliance state, so any regression here is invisible at the estate level until this scorecard is produced and merged." [[should]] diff --git a/.machine_readable/scorecards/component-readiness-grades.scorecard.a2ml b/.machine_readable/scorecards/component-readiness-grades.scorecard.a2ml index 9101daa2..03751018 100644 --- a/.machine_readable/scorecards/component-readiness-grades.scorecard.a2ml +++ b/.machine_readable/scorecards/component-readiness-grades.scorecard.a2ml @@ -15,7 +15,7 @@ text = "The standard MUST define each grade (X, F, E, D, C, B, A) with its evide system = "none (manual file inspection; no CI validates prose/A2ML consistency)" status = "pass" evidence = "component-readiness-grades/COMPONENT-READINESS-GRADES.md §4 (lines 94-479, grade defs + evidence) and §7 (lines 442-479, transitions); mirrored in component-readiness-grades/COMPONENT-READINESS-GRADES.a2ml (grades block lines 17-80, transitions block lines 82-108)." -check = "test -f component-readiness-grades/COMPONENT-READINESS-GRADES.md && grep -q '^## 4\\. Grade Definitions' component-readiness-grades/COMPONENT-READINESS-GRADES.md && grep -q '^## 7\\.' component-readiness-grades/COMPONENT-READINESS-GRADES.md && test -f component-readiness-grades/COMPONENT-READINESS-GRADES.a2ml && grep -q '^(grades' component-readiness-grades/COMPONENT-READINESS-GRADES.a2ml && grep -q '^(transitions' component-readiness-grades/COMPONENT-READINESS-GRADES.a2ml" +check = "test -f component-readiness-grades/COMPONENT-READINESS-GRADES.adoc && grep -q '^=== 4\\. Grade Definitions' component-readiness-grades/COMPONENT-READINESS-GRADES.adoc && grep -q '^=== 7\\.' component-readiness-grades/COMPONENT-READINESS-GRADES.adoc && test -f component-readiness-grades/COMPONENT-READINESS-GRADES.a2ml && grep -q '^(grades' component-readiness-grades/COMPONENT-READINESS-GRADES.a2ml && grep -q '^(transitions' component-readiness-grades/COMPONENT-READINESS-GRADES.a2ml" effects = "Downstream repos rely on this doc as the single normative source for grade thresholds (a2ml/READINESS.md, k9-coordination-protocol/READINESS.md both cite it directly)." [[must]] diff --git a/.machine_readable/scorecards/estate-constitution.scorecard.a2ml b/.machine_readable/scorecards/estate-constitution.scorecard.a2ml index 612700a3..81dd2669 100644 --- a/.machine_readable/scorecards/estate-constitution.scorecard.a2ml +++ b/.machine_readable/scorecards/estate-constitution.scorecard.a2ml @@ -13,7 +13,7 @@ text = "The constitutional district MUST contain its declared canonical document system = "test: expected-path existence" status = "pass" evidence = "constitution/ contains README, estate, authority, assurance, contribution, exceptions, tensions, change-procedure, and agent-instruction sources." -check = "test -f constitution/README.adoc && test -f constitution/ESTATE-CONSTITUTION.adoc && test -f constitution/AUTHORITY-AND-PRECEDENCE.adoc && test -f constitution/ASSURANCE-CONSTITUTION.adoc && test -f constitution/CONTRIBUTION-CONSTITUTION.adoc && test -f constitution/EXCEPTIONS-AND-ANCHORS.adoc && test -f constitution/KNOWN-TENSIONS.adoc && test -f constitution/CHANGE-PROCEDURE.adoc && test -f constitution/AGENTS.md" +check = "test -f constitution/README.adoc && test -f constitution/ESTATE-CONSTITUTION.adoc && test -f constitution/AUTHORITY-AND-PRECEDENCE.adoc && test -f constitution/ASSURANCE-CONSTITUTION.adoc && test -f constitution/CONTRIBUTION-CONSTITUTION.adoc && test -f constitution/EXCEPTIONS-AND-ANCHORS.adoc && test -f constitution/KNOWN-TENSIONS.adoc && test -f constitution/CHANGE-PROCEDURE.adoc && test -f constitution/AGENTS.adoc" effects = "Missing sources would make the authority route incomplete." [[must]] diff --git a/.machine_readable/scorecards/hypatia-rules.scorecard.a2ml b/.machine_readable/scorecards/hypatia-rules.scorecard.a2ml index bbe985bf..624638c2 100644 --- a/.machine_readable/scorecards/hypatia-rules.scorecard.a2ml +++ b/.machine_readable/scorecards/hypatia-rules.scorecard.a2ml @@ -70,7 +70,7 @@ text = "hypatia-rules COULD have its own scorecards/*.scorecard.a2ml entry feedi system = "scripts/build-scorecards.sh (invoked via `just scorecards`) generates COMPLIANCE-DASHBOARD.md rows from .machine_readable/scorecards/*.scorecard.a2ml; this scorecard file feeds that generator directly." status = "pass" evidence = "hypatia-rules.scorecard.a2ml now exists at .machine_readable/scorecards/ and COMPLIANCE-DASHBOARD.md contains a real scored row for it ('| `hypatia-rules` | ❌ gap | 2/4 | 1/3 | 0/3 | 100% | 0/3 | 2026-07-03 |'), not a '⚠️ no scorecard' placeholder; the dashboard's own rollup now reads 'Specs with a scorecard: 30 / 30' with no remaining 'no scorecard' references. Verified via grep on 2026-07-17." -check = "test -f .machine_readable/scorecards/hypatia-rules.scorecard.a2ml && grep -qE \"^\\| \\`hypatia-rules\\` \\|\" COMPLIANCE-DASHBOARD.md" +check = "test -f .machine_readable/scorecards/hypatia-rules.scorecard.a2ml && grep -Fq '| `+hypatia-rules+` |' COMPLIANCE-DASHBOARD.adoc" effects = "COMPLIANCE-DASHBOARD.md explicitly lists hypatia-rules among the 27 (of 28) specs still needing a scorecard (line 58); its dashboard row reads '⚠️ no scorecard' with all dash placeholders (line 49), so estate rollup metrics (2/28 specs with scorecards after this one is added) undercount actual compliance posture." [[could]] diff --git a/.machine_readable/scorecards/k9-svc.scorecard.a2ml b/.machine_readable/scorecards/k9-svc.scorecard.a2ml index 9c0ed737..976356f9 100644 --- a/.machine_readable/scorecards/k9-svc.scorecard.a2ml +++ b/.machine_readable/scorecards/k9-svc.scorecard.a2ml @@ -104,7 +104,7 @@ text = "K9 COULD ship language bindings (Rust, Haskell, Gleam, Elixir, Deno) for system = "bindings/rust/src/{lib,parser,renderer,error}.rs (497-line parser), bindings/haskell/src/Data/K9/*.hs, bindings/gleam/src/k9_gleam/*.gleam (+ test/k9_gleam_test.gleam), bindings/elixir/lib/k9/*.ex, bindings/deno/mod.ts; bindings/gleam has a dedicated .github/workflows/ present, other bindings' CI status not independently confirmed in this pass." status = "pass" evidence = "Non-trivial, non-stub source files exist for all five bindings (e.g. bindings/rust/src/parser.rs 497 lines, bindings/rust/tests/crg_c_tests.rs 580 lines; bindings/haskell/src/Data/K9/Parser.hs 234 lines; bindings/gleam has a test/ directory with k9_gleam_test.gleam)." -check = "test $(wc -l < k9-svc/bindings/rust/src/parser.rs) -gt 100 && test $(wc -l < k9-svc/bindings/haskell/src/Data/K9/Parser.hs) -gt 100 && test -f k9-svc/bindings/gleam/test/k9_gleam_test.gleam && test -f k9-svc/bindings/elixir/lib/k9/parser.ex && test -f k9-svc/bindings/deno/mod.ts" +check = "test $(wc -l < k9-svc/bindings/rust/src/parser.rs) -gt 100 && test $(wc -l < k9-svc/bindings/haskell/src/Data/K9/Parser.hs) -gt 100 && test -f k9-svc/bindings/gleam/test/k9_gleam_test.gleam && test -f k9-svc/bindings/elixir/lib/k9/parser.ex && test -f k9-svc/bindings/deno/mod.affine" effects = "Consumers wanting to parse/render .k9 in Rust/Haskell/Gleam/Elixir/Deno ecosystems depend on these; if a binding's own CI is not wired up, drift from the canonical pedigree.ncl schema would go unnoticed (not independently verified here)." [[could]] diff --git a/.machine_readable/scorecards/session-management-standards.scorecard.a2ml b/.machine_readable/scorecards/session-management-standards.scorecard.a2ml index fcb6bdba..91559565 100644 --- a/.machine_readable/scorecards/session-management-standards.scorecard.a2ml +++ b/.machine_readable/scorecards/session-management-standards.scorecard.a2ml @@ -43,7 +43,7 @@ text = "The 'Directory Map' and 'Canonical Protocol Families' enumerated in READ system = "none (no automated drift check), but verified pass by direct filesystem inspection." status = "pass" evidence = "All 12 protocol directories (verify/{maintenance-sweep,substantial-completion,release-audit}, continuity/{repo-intake,checkpoint-before-major-change,planned-session-close,emergency-termination,recovery-operation}, handover/{full-transfer,collaborative-transfer,model-transfer,human-transfer}) and all 9 templates/ files listed in the README Directory Map exist exactly as named on disk." -check = "for d in verify/maintenance-sweep verify/substantial-completion verify/release-audit continuity/repo-intake continuity/checkpoint-before-major-change continuity/planned-session-close continuity/emergency-termination continuity/recovery-operation handover/collaborative-transfer handover/full-transfer handover/human-transfer handover/model-transfer; do test -d \"session-management-standards/$d\" || exit 1; done && for f in SESSION_STATE.adoc NEXT_STEPS.md SESSION_SUMMARY.md EMERGENCY-CHECKPOINT.md SUBSTANTIAL_COMPLETION_REPORT.md HANDOVER-REPORT.md RECOVERY-PLAN.md RELEASE_AUDIT.md MAINTENANCE_REPORT.md; do test -f \"session-management-standards/templates/$f\" || exit 1; done" +check = "for d in verify/maintenance-sweep verify/substantial-completion verify/release-audit continuity/repo-intake continuity/checkpoint-before-major-change continuity/planned-session-close continuity/emergency-termination continuity/recovery-operation handover/collaborative-transfer handover/full-transfer handover/human-transfer handover/model-transfer; do test -d \"session-management-standards/$d\" || exit 1; done && for f in SESSION_STATE.adoc NEXT_STEPS.adoc SESSION_SUMMARY.adoc EMERGENCY-CHECKPOINT.adoc SUBSTANTIAL_COMPLETION_REPORT.adoc HANDOVER-REPORT.adoc RECOVERY-PLAN.adoc RELEASE_AUDIT.adoc MAINTENANCE_REPORT.adoc; do test -f \"session-management-standards/templates/$f\" || exit 1; done" effects = "n/a — this is currently sound, so no downstream impact." [[should]] diff --git a/.machine_readable/scorecards/toolchain-readiness-grades.scorecard.a2ml b/.machine_readable/scorecards/toolchain-readiness-grades.scorecard.a2ml index 9d4b913c..94098f55 100644 --- a/.machine_readable/scorecards/toolchain-readiness-grades.scorecard.a2ml +++ b/.machine_readable/scorecards/toolchain-readiness-grades.scorecard.a2ml @@ -61,7 +61,7 @@ text = "The directory SHOULD include canonical exemplar audit documents (the 007 system = "none (manual presence check)" status = "pass" evidence = "references/007/ contains 25 audit-*.md files copied verbatim from the 007 project, including audit-lexer-mk2-tier-format.md, the originating exemplar named in README.adoc" -check = "test -f toolchain-readiness-grades/references/007/audit-lexer-mk2-tier-format.md && [ $(ls toolchain-readiness-grades/references/007/*.md | wc -l) -ge 25 ]" +check = "test -f toolchain-readiness-grades/references/007/audit-lexer-mk2-tier-format.adoc && [ $(find toolchain-readiness-grades/references/007 -maxdepth 1 -type f -name '*.adoc' | wc -l) -ge 25 ]" effects = "New audit authors in other toolchain repos have real precedent to model their own audits on; without these the format description in the spec alone would be harder to apply consistently." [[should]] diff --git a/0-ai-gatekeeper-protocol/mcp-repo-guardian/lib/ocaml/Guards.affine b/0-ai-gatekeeper-protocol/mcp-repo-guardian/lib/ocaml/Guards.affine index 9dea4df7..7feaeb4d 100644 --- a/0-ai-gatekeeper-protocol/mcp-repo-guardian/lib/ocaml/Guards.affine +++ b/0-ai-gatekeeper-protocol/mcp-repo-guardian/lib/ocaml/Guards.affine @@ -3,7 +3,7 @@ module Guards; -// SPDX-License-Identifier: PMPL-1.0-or-later +// SPDX-License-Identifier: MPL-2.0 // Access control guard module module AccessGuard = { diff --git a/0-ai-gatekeeper-protocol/mcp-repo-guardian/lib/ocaml/Index.affine b/0-ai-gatekeeper-protocol/mcp-repo-guardian/lib/ocaml/Index.affine index ba39776a..3b1d8468 100644 --- a/0-ai-gatekeeper-protocol/mcp-repo-guardian/lib/ocaml/Index.affine +++ b/0-ai-gatekeeper-protocol/mcp-repo-guardian/lib/ocaml/Index.affine @@ -3,7 +3,7 @@ module Index; -// SPDX-License-Identifier: PMPL-1.0-or-later +// SPDX-License-Identifier: MPL-2.0 // MCP SDK External Bindings module MCP = { diff --git a/0-ai-gatekeeper-protocol/mcp-repo-guardian/lib/ocaml/Manifest.affine b/0-ai-gatekeeper-protocol/mcp-repo-guardian/lib/ocaml/Manifest.affine index c2f8208a..9991ed88 100644 --- a/0-ai-gatekeeper-protocol/mcp-repo-guardian/lib/ocaml/Manifest.affine +++ b/0-ai-gatekeeper-protocol/mcp-repo-guardian/lib/ocaml/Manifest.affine @@ -3,7 +3,7 @@ module Manifest; -// SPDX-License-Identifier: PMPL-1.0-or-later +// SPDX-License-Identifier: MPL-2.0 // External Deno APIs @module("node:fs/promises") external readFile: (string, string) => promise = "readFile" diff --git a/0-ai-gatekeeper-protocol/mcp-repo-guardian/lib/ocaml/Session.affine b/0-ai-gatekeeper-protocol/mcp-repo-guardian/lib/ocaml/Session.affine index c1e64631..57d0c09c 100644 --- a/0-ai-gatekeeper-protocol/mcp-repo-guardian/lib/ocaml/Session.affine +++ b/0-ai-gatekeeper-protocol/mcp-repo-guardian/lib/ocaml/Session.affine @@ -3,7 +3,7 @@ module Session; -// SPDX-License-Identifier: PMPL-1.0-or-later +// SPDX-License-Identifier: MPL-2.0 // External Deno/Node crypto API @module("node:crypto") external randomUUID: unit => string = "randomUUID" diff --git a/0-ai-gatekeeper-protocol/mcp-repo-guardian/lib/ocaml/Types.affine b/0-ai-gatekeeper-protocol/mcp-repo-guardian/lib/ocaml/Types.affine index 717dcdb1..c8eb0b58 100644 --- a/0-ai-gatekeeper-protocol/mcp-repo-guardian/lib/ocaml/Types.affine +++ b/0-ai-gatekeeper-protocol/mcp-repo-guardian/lib/ocaml/Types.affine @@ -3,7 +3,7 @@ module Types; -// SPDX-License-Identifier: PMPL-1.0-or-later +// SPDX-License-Identifier: MPL-2.0 // AI.a2ml manifest structure struct canonicalLocations { { diff --git a/0-ai-gatekeeper-protocol/mcp-repo-guardian/src/Guards.affine b/0-ai-gatekeeper-protocol/mcp-repo-guardian/src/Guards.affine index 9dea4df7..7feaeb4d 100644 --- a/0-ai-gatekeeper-protocol/mcp-repo-guardian/src/Guards.affine +++ b/0-ai-gatekeeper-protocol/mcp-repo-guardian/src/Guards.affine @@ -3,7 +3,7 @@ module Guards; -// SPDX-License-Identifier: PMPL-1.0-or-later +// SPDX-License-Identifier: MPL-2.0 // Access control guard module module AccessGuard = { diff --git a/0-ai-gatekeeper-protocol/mcp-repo-guardian/src/Index.affine b/0-ai-gatekeeper-protocol/mcp-repo-guardian/src/Index.affine index ba39776a..3b1d8468 100644 --- a/0-ai-gatekeeper-protocol/mcp-repo-guardian/src/Index.affine +++ b/0-ai-gatekeeper-protocol/mcp-repo-guardian/src/Index.affine @@ -3,7 +3,7 @@ module Index; -// SPDX-License-Identifier: PMPL-1.0-or-later +// SPDX-License-Identifier: MPL-2.0 // MCP SDK External Bindings module MCP = { diff --git a/0-ai-gatekeeper-protocol/mcp-repo-guardian/src/Manifest.affine b/0-ai-gatekeeper-protocol/mcp-repo-guardian/src/Manifest.affine index c2f8208a..9991ed88 100644 --- a/0-ai-gatekeeper-protocol/mcp-repo-guardian/src/Manifest.affine +++ b/0-ai-gatekeeper-protocol/mcp-repo-guardian/src/Manifest.affine @@ -3,7 +3,7 @@ module Manifest; -// SPDX-License-Identifier: PMPL-1.0-or-later +// SPDX-License-Identifier: MPL-2.0 // External Deno APIs @module("node:fs/promises") external readFile: (string, string) => promise = "readFile" diff --git a/0-ai-gatekeeper-protocol/mcp-repo-guardian/src/Session.affine b/0-ai-gatekeeper-protocol/mcp-repo-guardian/src/Session.affine index c1e64631..57d0c09c 100644 --- a/0-ai-gatekeeper-protocol/mcp-repo-guardian/src/Session.affine +++ b/0-ai-gatekeeper-protocol/mcp-repo-guardian/src/Session.affine @@ -3,7 +3,7 @@ module Session; -// SPDX-License-Identifier: PMPL-1.0-or-later +// SPDX-License-Identifier: MPL-2.0 // External Deno/Node crypto API @module("node:crypto") external randomUUID: unit => string = "randomUUID" diff --git a/0-ai-gatekeeper-protocol/mcp-repo-guardian/src/Types.affine b/0-ai-gatekeeper-protocol/mcp-repo-guardian/src/Types.affine index 717dcdb1..c8eb0b58 100644 --- a/0-ai-gatekeeper-protocol/mcp-repo-guardian/src/Types.affine +++ b/0-ai-gatekeeper-protocol/mcp-repo-guardian/src/Types.affine @@ -3,7 +3,7 @@ module Types; -// SPDX-License-Identifier: PMPL-1.0-or-later +// SPDX-License-Identifier: MPL-2.0 // AI.a2ml manifest structure struct canonicalLocations { { diff --git a/COMPLIANCE-DASHBOARD.adoc b/COMPLIANCE-DASHBOARD.adoc index bd3ab516..ae28b686 100644 --- a/COMPLIANCE-DASHBOARD.adoc +++ b/COMPLIANCE-DASHBOARD.adoc @@ -1,121 +1,82 @@ -== Standards Compliance Dashboard (derived) +// SPDX-License-Identifier: CC-BY-SA-4.0 +// COMPLIANCE-DASHBOARD.adoc — DERIVED from .machine_readable/scorecards/*.scorecard.a2ml +// GENERATED FILE — DO NOT EDIT BY HAND. Run: just scorecards (scripts/build-scorecards.sh) + += Standards Compliance Dashboard (derived) ____ -Generated from `+.machine_readable/scorecards/.scorecard.a2ml+` -by `+scripts/build-scorecards.sh+`. One scorecard per LOCAL spec in -`+.machine_readable/REGISTRY.a2ml+`. Do not edit by hand — edit the -scorecards. +Generated from `+.machine_readable/scorecards/.scorecard.a2ml+` by +`+scripts/build-scorecards.sh+`. One scorecard per LOCAL spec in +`+.machine_readable/REGISTRY.a2ml+`. Do not edit by hand — edit the scorecards. *How to read this.* Each spec is audited as MUST / SHOULD / COULD -requirements. *MUST-status* is the compliance verdict: ✅ met (every -MUST passes or is manual-only) or ❌ gap (some MUST fails). *Systems -coverage* is the share of requirements with a real mechanical check -(`+system+` ≠ `+none+`) — the honest measure of _enforcement -vs. assertion_. *Aspirational* requirements (intentionally-unreachable -reach targets) are never counted as passing. +requirements. *MUST-status* is the compliance verdict: ✅ met (every MUST +passes or is manual-only) or ❌ gap (some MUST fails). *Systems coverage* +is the share of requirements with a real mechanical check (`+system+` ≠ `+none+`) +— the honest measure of _enforcement vs. assertion_. *Aspirational* +requirements (intentionally-unreachable reach targets) are never counted as +passing. ____ -=== Per-spec scorecards +== Per-spec scorecards -[width="100%",cols="16%,12%,12%,12%,12%,12%,12%,12%",options="header",] +[cols="16%,12%,12%,12%,12%,12%,12%,12%",options="header"] |=== -|Spec |MUST status |MUST (pass/total) |SHOULD (pass/total) |COULD -(pass/total) |Systems coverage |Grounded passes |Assessed -|`+estate-constitution+` |❌ gap |2/4 |1/1 |0/0 |60% |3/3 |2026-07-11 - -|`+a2ml+` |✅ met |4/5 |4/5 |0/3 |84% |8/8 |2026-07-03 - -|`+k9-svc+` |❌ gap |3/6 |3/5 |2/3 |100% |8/8 |2026-07-03 - -|`+contractiles+` |❌ gap |0/5 |0/3 |0/3 |54% |– |2026-07-03 - -|`+meta-a2ml+` |❌ gap |1/5 |1/4 |1/3 |83% |3/3 |2026-07-03 - -|`+state-a2ml+` |❌ gap |0/5 |1/4 |1/3 |50% |2/2 |2026-07-03 - -|`+ecosystem-a2ml+` |❌ gap |2/5 |0/4 |0/3 |41% |2/2 |2026-07-03 - -|`+agentic-a2ml+` |❌ gap |1/5 |0/4 |0/3 |100% |1/1 |2026-07-03 - -|`+neurosym-a2ml+` |❌ gap |1/5 |0/4 |1/3 |83% |2/2 |2026-07-03 - -|`+playbook-a2ml+` |❌ gap |1/5 |0/4 |0/3 |0% |1/1 |2026-07-03 - -|`+anchor-a2ml+` |❌ gap |0/5 |0/5 |0/3 |15% |– |2026-07-03 - -|`+0-ai-gatekeeper-protocol+` |❌ gap |3/5 |0/4 |0/2 |54% |3/3 -|2026-07-03 - -|`+k9-coordination-protocol+` |❌ gap |3/5 |2/4 |0/3 |100% |5/5 -|2026-07-03 - -|`+avow-protocol+` |❌ gap |0/5 |1/4 |0/3 |58% |1/1 |2026-07-03 - -|`+axel-protocol+` |❌ gap |0/5 |4/5 |0/3 |92% |4/4 |2026-07-03 - -|`+overlay-protocol+` |❌ gap |1/5 |0/4 |0/3 |50% |1/1 |2026-07-03 - -|`+adoption-readiness-grades+` |❌ gap |1/5 |1/4 |0/4 |84% |2/2 -|2026-07-03 - -|`+foundations-readiness-grades+` |❌ gap |2/5 |1/4 |0/2 |72% |3/3 -|2026-07-03 - -|`+component-readiness-grades+` |❌ gap |2/5 |2/4 |0/3 |66% |4/4 -|2026-07-03 - -|`+toolchain-readiness-grades+` |❌ gap |1/5 |2/4 |0/3 |83% |3/3 -|2026-07-03 - -|`+rhodium-standard-repositories+` |❌ gap |1/3 |1/2 |0/1 |50% |2/2 -|2026-07-03 - -|`+session-management-standards+` |❌ gap |1/5 |1/4 |0/3 |41% |2/2 -|2026-07-03 - -|`+did-you-actually-do-that+` |✅ met |5/5 |2/3 |0/2 |90% |7/7 -|2026-07-03 - -|`+ensaid-config+` |❌ gap |0/5 |0/3 |0/3 |90% |– |2026-07-03 - -|`+accessibility+` |❌ gap |2/5 |0/5 |0/3 |100% |2/2 |2026-07-03 - -|`+publication-pre-flight+` |❌ gap |0/5 |0/4 |0/2 |36% |– |2026-07-03 - -|`+release-pre-flight+` |❌ gap |4/5 |3/4 |0/2 |72% |7/7 |2026-07-03 - -|`+hypatia-rules+` |❌ gap |2/4 |1/3 |1/3 |100% |4/4 |2026-07-03 - -|`+a2ml-templates+` |❌ gap |1/5 |1/3 |0/2 |20% |2/2 |2026-07-03 +| Spec | MUST status | MUST (pass/total) | SHOULD (pass/total) | COULD (pass/total) | Systems coverage | Grounded passes | Assessed +| `+estate-constitution+` | ❌ gap | 2/4 | 1/1 | 0/0 | 60% | 3/3 | 2026-07-11 +| `+a2ml+` | ✅ met | 4/5 | 4/5 | 0/3 | 84% | 8/8 | 2026-07-03 +| `+k9-svc+` | ❌ gap | 3/6 | 3/5 | 2/3 | 100% | 8/8 | 2026-07-03 +| `+contractiles+` | ❌ gap | 0/5 | 0/3 | 0/3 | 54% | – | 2026-07-03 +| `+meta-a2ml+` | ❌ gap | 1/5 | 1/4 | 1/3 | 83% | 3/3 | 2026-07-03 +| `+state-a2ml+` | ❌ gap | 0/5 | 1/4 | 1/3 | 50% | 2/2 | 2026-07-03 +| `+ecosystem-a2ml+` | ❌ gap | 2/5 | 0/4 | 0/3 | 41% | 2/2 | 2026-07-03 +| `+agentic-a2ml+` | ❌ gap | 1/5 | 0/4 | 0/3 | 100% | 1/1 | 2026-07-03 +| `+neurosym-a2ml+` | ❌ gap | 1/5 | 0/4 | 1/3 | 83% | 2/2 | 2026-07-03 +| `+playbook-a2ml+` | ❌ gap | 1/5 | 0/4 | 0/3 | 0% | 1/1 | 2026-07-03 +| `+anchor-a2ml+` | ❌ gap | 0/5 | 0/5 | 0/3 | 15% | – | 2026-07-03 +| `+0-ai-gatekeeper-protocol+` | ❌ gap | 3/5 | 0/4 | 0/2 | 54% | 3/3 | 2026-07-03 +| `+k9-coordination-protocol+` | ❌ gap | 3/5 | 2/4 | 0/3 | 100% | 5/5 | 2026-07-03 +| `+avow-protocol+` | ❌ gap | 0/5 | 1/4 | 0/3 | 58% | 1/1 | 2026-07-03 +| `+axel-protocol+` | ❌ gap | 0/5 | 4/5 | 0/3 | 92% | 4/4 | 2026-07-03 +| `+overlay-protocol+` | ❌ gap | 1/5 | 0/4 | 0/3 | 50% | 1/1 | 2026-07-03 +| `+adoption-readiness-grades+` | ❌ gap | 1/5 | 1/4 | 0/4 | 84% | 2/2 | 2026-07-03 +| `+foundations-readiness-grades+` | ❌ gap | 2/5 | 1/4 | 0/2 | 72% | 3/3 | 2026-07-03 +| `+component-readiness-grades+` | ❌ gap | 2/5 | 2/4 | 0/3 | 66% | 4/4 | 2026-07-03 +| `+toolchain-readiness-grades+` | ❌ gap | 1/5 | 2/4 | 0/3 | 83% | 3/3 | 2026-07-03 +| `+rhodium-standard-repositories+` | ❌ gap | 1/3 | 1/2 | 0/1 | 50% | 2/2 | 2026-07-03 +| `+session-management-standards+` | ❌ gap | 1/5 | 1/4 | 0/3 | 41% | 2/2 | 2026-07-03 +| `+did-you-actually-do-that+` | ✅ met | 5/5 | 2/3 | 0/2 | 90% | 7/7 | 2026-07-03 +| `+ensaid-config+` | ❌ gap | 0/5 | 0/3 | 0/3 | 90% | – | 2026-07-03 +| `+accessibility+` | ❌ gap | 2/5 | 0/5 | 0/3 | 100% | 2/2 | 2026-07-03 +| `+publication-pre-flight+` | ❌ gap | 0/5 | 0/4 | 0/2 | 36% | – | 2026-07-03 +| `+release-pre-flight+` | ❌ gap | 4/5 | 3/4 | 0/2 | 72% | 7/7 | 2026-07-03 +| `+hypatia-rules+` | ❌ gap | 2/4 | 1/3 | 1/3 | 100% | 4/4 | 2026-07-03 +| `+a2ml-templates+` | ❌ gap | 1/5 | 1/3 | 0/2 | 20% | 2/2 | 2026-07-03 |=== -=== Estate rollup +== Estate rollup * *Specs registered (local):* 29 * *Specs with a scorecard:* 29 / 29 * *MUST requirements:* 44 passing / 142 total (71 failing) -* *Estate systems coverage:* 67% of 330 graded requirements have a -mechanical check -* *Grounded passes:* 82 / 82 (100%) pass rows carry an executable -`+check+` run by `+--verify+` +* *Estate systems coverage:* 67% of 330 graded requirements have a mechanical check +* *Grounded passes:* 82 / 82 (100%) pass rows carry an executable `+check+` run by `+--verify+` -=== How this dashboard stays honest +== How this dashboard stays honest .... -scorecards/*.scorecard.a2ml ──► scripts/build-scorecards.sh ──► COMPLIANCE-DASHBOARD.md +scorecards/*.scorecard.a2ml ──► scripts/build-scorecards.sh ──► COMPLIANCE-DASHBOARD.adoc (hand-authored) │ validated vs scorecard.schema.json ▼ just scorecards-check (CI) .... -* A `+pass+` requires cited `+evidence+`; the generator rejects a pass -without it. -* `+aspirational+` requirements never count as passing (no -intuition-plucked Grade-A gate can inflate a score — standards#446). +* A `+pass+` requires cited `+evidence+`; the generator rejects a pass without it. +* `+aspirational+` requirements never count as passing (no intuition-plucked + Grade-A gate can inflate a score — standards#446). * `+system = "none"+` is legal but visible, and lowers systems coverage. -* A pass MAY carry an executable `+check+`; `+--verify+` RUNS every such -check and *fails loudly if a claimed pass does not hold right now* -(DYADT applied to the scorecards themselves). Passes without a check are -reported as self-asserted — visible debt, tracked by the Grounded -column. +* A pass MAY carry an executable `+check+`; `+--verify+` RUNS every such check and + *fails loudly if a claimed pass does not hold right now* (DYADT applied to + the scorecards themselves). Passes without a check are reported as + self-asserted — visible debt, tracked by the Grounded column. * Regenerate after editing any scorecard: `+just scorecards+`. diff --git a/Justfile b/Justfile index a6e14eaf..b0725741 100644 --- a/Justfile +++ b/Justfile @@ -17,10 +17,10 @@ default: registry: @bash scripts/build-registry.sh -# Alias: same generator also (re)writes TOPOLOGY.md +# Alias: same generator also (re)writes TOPOLOGY.adoc topology: registry -# Fail if REGISTRY.a2ml or TOPOLOGY.md has drifted from the file tree +# Fail if REGISTRY.a2ml or TOPOLOGY.adoc has drifted from the file tree registry-check: @bash scripts/build-registry.sh --check @@ -87,7 +87,7 @@ hooks-install: scorecards: @bash scripts/build-scorecards.sh -# Fail if COMPLIANCE-DASHBOARD.md has drifted from the scorecards +# Fail if COMPLIANCE-DASHBOARD.adoc has drifted from the scorecards scorecards-check: @bash scripts/build-scorecards.sh --check diff --git a/TOPOLOGY.adoc b/TOPOLOGY.adoc index 7d628b4b..0c331f87 100644 --- a/TOPOLOGY.adoc +++ b/TOPOLOGY.adoc @@ -1,188 +1,106 @@ -== Hyperpolymath Standards — Topology (derived) +// SPDX-License-Identifier: CC-BY-SA-4.0 +// TOPOLOGY.adoc — DERIVED architecture map (generated from REGISTRY.a2ml + STATE.a2ml) +// GENERATED FILE — DO NOT EDIT BY HAND. Run: just topology (scripts/build-registry.sh) + += Hyperpolymath Standards — Topology (derived) ____ This file is *generated* from `+.machine_readable/REGISTRY.a2ml+` and -`+.machine_readable/6a2/STATE.a2ml+` by `+scripts/build-registry.sh+`. -It cannot freeze: every regeneration re-reads ground truth. Do not edit -by hand. +the canonical `+STATE.a2ml+` by `+scripts/build-registry.sh+`. +It cannot freeze: every regeneration re-reads ground truth. Do not edit by hand. ____ -* *Phase:* active  |  *Maturity:* experimental  |  *STATE last-updated:* -2026-06-03T00:00:00Z +* *Phase:* active | *Maturity:* experimental | *STATE last-updated:* 2026-06-03T00:00:00Z * *Registry entries:* 33 specs across 6 streams -* *Front door:* human → README.adoc; machine → 0-AI-MANIFEST.a2ml -* *Registry:* .machine_readable/REGISTRY.a2ml (index + source hashes) · -prose: REGISTRY.adoc +* *Front door:* human → link:README.adoc[README.adoc]; machine → link:0-AI-MANIFEST.a2ml[0-AI-MANIFEST.a2ml] +* *Registry:* link:.machine_readable/REGISTRY.a2ml[.machine_readable/REGISTRY.a2ml] (index + source hashes) · prose: link:REGISTRY.adoc[REGISTRY.adoc] -=== Specs by stream +== Specs by stream -==== Foundation — A2ML family + K9 + contractiles (Stream 1) +=== Foundation — A2ML family + K9 + contractiles (Stream 1) -[width="100%",cols="34%,33%,33%",options="header",] +[cols="34%,33%,33%",options="header"] |=== -|Spec |Home |If you want… -|A2ML — Attested Markup Language |link:a2ml/[`+a2ml/+`] |the -typed/verified machine-readable document format - -|K9 Self-Validating Components |link:k9-svc/[`+k9-svc/+`] -|self-validating components with embedded contracts + deploy logic - -|Contractiles (Must/Trust/Dust/Intend) -|link:contractiles/[`+contractiles/+`] |policy-enforcement primitives -the K9 layer is built from - -|META.a2ml spec |link:meta-a2ml/[`+meta-a2ml/+`] |architecture decisions -/ governance metadata format - -|STATE.a2ml spec |link:state-a2ml/[`+state-a2ml/+`] |project-state -metadata format (drives this registry’s topology) - -|ECOSYSTEM.a2ml spec |link:ecosystem-a2ml/[`+ecosystem-a2ml/+`] -|ecosystem-positioning metadata format - -|AGENTIC.a2ml spec |link:agentic-a2ml/[`+agentic-a2ml/+`] |AI-agent -operational gating / entropy budgets - -|NEUROSYM.a2ml spec |link:neurosym-a2ml/[`+neurosym-a2ml/+`] |symbolic -semantics / proof obligations - -|PLAYBOOK.a2ml spec |link:playbook-a2ml/[`+playbook-a2ml/+`] |executable -operational runbooks - -|ANCHOR.a2ml spec |link:anchor-a2ml/[`+anchor-a2ml/+`] -|project-recalibration intervention format +| Spec | Home | If you want… +| A2ML — Attested Markup Language | link:a2ml/[`+a2ml/+`] | the typed/verified machine-readable document format +| K9 Self-Validating Components | link:k9-svc/[`+k9-svc/+`] | self-validating components with embedded contracts + deploy logic +| Contractiles (Must/Trust/Dust/Intend) | link:contractiles/[`+contractiles/+`] | policy-enforcement primitives the K9 layer is built from +| META.a2ml spec | link:meta-a2ml/[`+meta-a2ml/+`] | architecture decisions / governance metadata format +| STATE.a2ml spec | link:state-a2ml/[`+state-a2ml/+`] | project-state metadata format (drives this registry's topology) +| ECOSYSTEM.a2ml spec | link:ecosystem-a2ml/[`+ecosystem-a2ml/+`] | ecosystem-positioning metadata format +| AGENTIC.a2ml spec | link:agentic-a2ml/[`+agentic-a2ml/+`] | AI-agent operational gating / entropy budgets +| NEUROSYM.a2ml spec | link:neurosym-a2ml/[`+neurosym-a2ml/+`] | symbolic semantics / proof obligations +| PLAYBOOK.a2ml spec | link:playbook-a2ml/[`+playbook-a2ml/+`] | executable operational runbooks +| ANCHOR.a2ml spec | link:anchor-a2ml/[`+anchor-a2ml/+`] | project-recalibration intervention format |=== -==== Language — AffineScript + language policy (Stream 2) +=== Language — AffineScript + language policy (Stream 2) -[width="100%",cols="34%,33%,33%",options="header",] +[cols="34%,33%,33%",options="header"] |=== -|Spec |Home |If you want… -|AffineScript .affine (faces / source documents) -|https://github.com/hyperpolymath/affinescript/blob/main/spec/affine.adoc[`+hyperpolymath/affinescript+`] -`+@ v2.0.0+` ⇗ |faces, canonical-lowering invariant, canonical islands, -idiom packs, mimicry bindings, project face policy - -|AffineScript .affex (face-interop manifest) -|https://github.com/hyperpolymath/affinescript/blob/main/spec/affex.adoc[`+hyperpolymath/affinescript+`] -`+@ v2.0.0+` ⇗ |derived regenerable manifest; declaration heads not full -bodies; format_version bumps independently - -|AffineScript .affmap (provenance) -|https://github.com/hyperpolymath/affinescript/blob/main/spec/affmap.adoc[`+hyperpolymath/affinescript+`] -`+@ v2.0.0+` ⇗ |provenance format; own pointer for independent staleness -tracking +| Spec | Home | If you want… +| AffineScript .affine (faces / source documents) | https://github.com/hyperpolymath/affinescript/blob/main/spec/affine.adoc[`+hyperpolymath/affinescript+`] `+@ v2.0.0+` ⇗ | faces, canonical-lowering invariant, canonical islands, idiom packs, mimicry bindings, project face policy +| AffineScript .affex (face-interop manifest) | https://github.com/hyperpolymath/affinescript/blob/main/spec/affex.adoc[`+hyperpolymath/affinescript+`] `+@ v2.0.0+` ⇗ | derived regenerable manifest; declaration heads not full bodies; format_version bumps independently +| AffineScript .affmap (provenance) | https://github.com/hyperpolymath/affinescript/blob/main/spec/affmap.adoc[`+hyperpolymath/affinescript+`] `+@ v2.0.0+` ⇗ | provenance format; own pointer for independent staleness tracking |=== -==== Protocols +=== Protocols -[width="100%",cols="34%,33%,33%",options="header",] +[cols="34%,33%,33%",options="header"] |=== -|Spec |Home |If you want… -|0-AI Gatekeeper Protocol -|link:0-ai-gatekeeper-protocol/[`+0-ai-gatekeeper-protocol/+`] |the -AI-agent entry/gating protocol behind 0-AI-MANIFEST - -|K9 Coordination Protocol -|link:k9-coordination-protocol/[`+k9-coordination-protocol/+`] -|multi-agent coordination on top of K9 - -|AVOW Protocol |link:avow-protocol/[`+avow-protocol/+`] -|consent-attested messaging / origin attribution - -|AXEL Protocol |link:axel-protocol/[`+axel-protocol/+`] |age-gating + -explicit-content enforcement - -|Overlay Protocol |link:overlay-protocol/[`+overlay-protocol/+`] -|layered overlay composition spec - -|Consent-Aware Web (AIBDP + HTTP 430) -|https://github.com/metadatastician/consent-aware-web/blob/main/README.adoc[`+metadatastician/consent-aware-web+`] -`+@ v0.2.0+` ⇗ |consent headers / AI-usage boundaries for HTTP; -extracted from this repo 2026-08-07 +| Spec | Home | If you want… +| 0-AI Gatekeeper Protocol | link:0-ai-gatekeeper-protocol/[`+0-ai-gatekeeper-protocol/+`] | the AI-agent entry/gating protocol behind 0-AI-MANIFEST +| K9 Coordination Protocol | link:k9-coordination-protocol/[`+k9-coordination-protocol/+`] | multi-agent coordination on top of K9 +| AVOW Protocol | link:avow-protocol/[`+avow-protocol/+`] | consent-attested messaging / origin attribution +| AXEL Protocol | link:axel-protocol/[`+axel-protocol/+`] | age-gating + explicit-content enforcement +| Overlay Protocol | link:overlay-protocol/[`+overlay-protocol/+`] | layered overlay composition spec +| Consent-Aware Web (AIBDP + HTTP 430) | https://github.com/metadatastician/consent-aware-web/blob/main/README.adoc[`+metadatastician/consent-aware-web+`] `+@ v0.2.0+` ⇗ | consent headers / AI-usage boundaries for HTTP; extracted from this repo 2026-08-07 |=== -==== Governance — RSR, gates, session standards +=== Governance — RSR, gates, session standards -[width="100%",cols="34%,33%,33%",options="header",] +[cols="34%,33%,33%",options="header"] |=== -|Spec |Home |If you want… -|Hyperpolymath Estate Constitution -|link:constitution/[`+constitution/+`] |the highest estate-level rules, -authority precedence, assurance, contribution, exceptions, and known -tensions - -|RSR — Rhodium Standard Repositories -|link:rhodium-standard-repositories/[`+rhodium-standard-repositories/+`] -|the repository-compliance standard every repo is graded against - -|Session Management Standards -|link:session-management-standards/[`+session-management-standards/+`] -|continuity / verify / handover protocols - -|DYADT — Did-You-Actually-Do-That -|link:did-you-actually-do-that/[`+did-you-actually-do-that/+`] -|post-action agent-claim verification (Tier 4 accountability) - -|ENSAID Config |link:ensaid-config/[`+ensaid-config/+`] |the ensaid -configuration standard - -|Accessibility Standard |link:accessibility/[`+accessibility/+`] |estate -accessibility requirements - -|Publication Pre-Flight -|link:publication-pre-flight/[`+publication-pre-flight/+`] |submission -gate (HOL + Zenodo checklists) - -|Release Pre-Flight (V1 Gate) -|link:release-pre-flight/[`+release-pre-flight/+`] |hard v1.0.0 audit -requirements +| Spec | Home | If you want… +| Hyperpolymath Estate Constitution | link:constitution/[`+constitution/+`] | the highest estate-level rules, authority precedence, assurance, contribution, exceptions, and known tensions +| RSR — Rhodium Standard Repositories | link:rhodium-standard-repositories/[`+rhodium-standard-repositories/+`] | the repository-compliance standard every repo is graded against +| Session Management Standards | link:session-management-standards/[`+session-management-standards/+`] | continuity / verify / handover protocols +| DYADT — Did-You-Actually-Do-That | link:did-you-actually-do-that/[`+did-you-actually-do-that/+`] | post-action agent-claim verification (Tier 4 accountability) +| ENSAID Config | link:ensaid-config/[`+ensaid-config/+`] | the ensaid configuration standard +| Accessibility Standard | link:accessibility/[`+accessibility/+`] | estate accessibility requirements +| Publication Pre-Flight | link:publication-pre-flight/[`+publication-pre-flight/+`] | submission gate (HOL + Zenodo checklists) +| Release Pre-Flight (V1 Gate) | link:release-pre-flight/[`+release-pre-flight/+`] | hard v1.0.0 audit requirements |=== -==== Readiness grading — ARG / FRG / CRG / TRG +=== Readiness grading — ARG / FRG / CRG / TRG -[width="100%",cols="34%,33%,33%",options="header",] +[cols="34%,33%,33%",options="header"] |=== -|Spec |Home |If you want… -|ARG — Adoption Readiness Grades -|link:adoption-readiness-grades/[`+adoption-readiness-grades/+`] -|per-language adoption-maturity profile templates - -|FRG — Foundations Readiness Grades -|link:foundations-readiness-grades/[`+foundations-readiness-grades/+`] -|per-language foundational-maturity profile templates - -|CRG — Component Readiness Grades -|link:component-readiness-grades/[`+component-readiness-grades/+`] |the -X..A grading system for components - -|TRG — Toolchain Readiness Grades -|link:toolchain-readiness-grades/[`+toolchain-readiness-grades/+`] -|per-toolchain readiness profile templates +| Spec | Home | If you want… +| ARG — Adoption Readiness Grades | link:adoption-readiness-grades/[`+adoption-readiness-grades/+`] | per-language adoption-maturity profile templates +| FRG — Foundations Readiness Grades | link:foundations-readiness-grades/[`+foundations-readiness-grades/+`] | per-language foundational-maturity profile templates +| CRG — Component Readiness Grades | link:component-readiness-grades/[`+component-readiness-grades/+`] | the X..A grading system for components +| TRG — Toolchain Readiness Grades | link:toolchain-readiness-grades/[`+toolchain-readiness-grades/+`] | per-toolchain readiness profile templates |=== -==== Integration — registry, hypatia rules, templates (Stream 3) +=== Integration — registry, hypatia rules, templates (Stream 3) -[width="100%",cols="34%,33%,33%",options="header",] +[cols="34%,33%,33%",options="header"] |=== -|Spec |Home |If you want… -|Standards Hypatia Rules |link:hypatia-rules/[`+hypatia-rules/+`] |the -dogfooding rules that scan THIS repo (incl. drift detection) - -|A2ML Templates |link:a2ml-templates/[`+a2ml-templates/+`] |copy-in -templates for the 7 A2ML files +| Spec | Home | If you want… +| Standards Hypatia Rules | link:hypatia-rules/[`+hypatia-rules/+`] | the dogfooding rules that scan THIS repo (incl. drift detection) +| A2ML Templates | link:a2ml-templates/[`+a2ml-templates/+`] | copy-in templates for the 7 A2ML files |=== -=== How this map stays honest +== How this map stays honest .... -file tree + STATE.a2ml ──► scripts/build-registry.sh ──► REGISTRY.a2ml ──► TOPOLOGY.md +file tree + STATE.a2ml ──► scripts/build-registry.sh ──► REGISTRY.a2ml ──► TOPOLOGY.adoc ▲ │ │ ▼ just registry / CI HYP-S006 (registry-staleness) (registry-verify.yml) emits doc.drift on hash mismatch .... -Regenerate after any spec change: `+just registry+` (writes -REGISTRY.a2ml + TOPOLOGY.md). CI (`+registry-verify.yml+`) runs -`+--check+` and fails the build if either is stale. +Regenerate after any spec change: `+just registry+` (writes REGISTRY.a2ml + TOPOLOGY.adoc). +CI (`+registry-verify.yml+`) runs `+--check+` and fails the build if either is stale. diff --git a/a2ml/bindings/deno/src/A2ML.affine b/a2ml/bindings/deno/src/A2ML.affine index faa8a16a..7f2000b2 100644 --- a/a2ml/bindings/deno/src/A2ML.affine +++ b/a2ml/bindings/deno/src/A2ML.affine @@ -3,7 +3,7 @@ module A2ML; -// SPDX-License-Identifier: PMPL-1.0-or-later +// SPDX-License-Identifier: MPL-2.0 // Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) // // A2ML — Main module for the A2ML (Attested Markup Language) parser library. diff --git a/a2ml/bindings/deno/src/A2ML_Parser.affine b/a2ml/bindings/deno/src/A2ML_Parser.affine index cbefa8ef..dec532ee 100644 --- a/a2ml/bindings/deno/src/A2ML_Parser.affine +++ b/a2ml/bindings/deno/src/A2ML_Parser.affine @@ -3,7 +3,7 @@ module A2ML_Parser; -// SPDX-License-Identifier: PMPL-1.0-or-later +// SPDX-License-Identifier: MPL-2.0 // Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) // // A2ML_Parser — Parser for A2ML (Attested Markup Language) documents. diff --git a/a2ml/bindings/deno/src/A2ML_Renderer.affine b/a2ml/bindings/deno/src/A2ML_Renderer.affine index f0e04c27..39cf01d7 100644 --- a/a2ml/bindings/deno/src/A2ML_Renderer.affine +++ b/a2ml/bindings/deno/src/A2ML_Renderer.affine @@ -3,7 +3,7 @@ module A2ML_Renderer; -// SPDX-License-Identifier: PMPL-1.0-or-later +// SPDX-License-Identifier: MPL-2.0 // Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) // // A2ML_Renderer — Render A2ML AST back to A2ML surface syntax. diff --git a/a2ml/bindings/deno/src/A2ML_Types.affine b/a2ml/bindings/deno/src/A2ML_Types.affine index 01665b17..9bcc7249 100644 --- a/a2ml/bindings/deno/src/A2ML_Types.affine +++ b/a2ml/bindings/deno/src/A2ML_Types.affine @@ -3,7 +3,7 @@ module A2ML_Types; -// SPDX-License-Identifier: PMPL-1.0-or-later +// SPDX-License-Identifier: MPL-2.0 // Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) // // A2ML_Types — Core data structs for A2ML (Attested Markup Language) documents. diff --git a/a2ml/prototype/wasm/src/WasmDemo.affine b/a2ml/prototype/wasm/src/WasmDemo.affine index e0583851..94228aea 100644 --- a/a2ml/prototype/wasm/src/WasmDemo.affine +++ b/a2ml/prototype/wasm/src/WasmDemo.affine @@ -3,7 +3,7 @@ module WasmDemo; -// SPDX-License-Identifier: PMPL-1.0-or-later +// SPDX-License-Identifier: MPL-2.0 // A2ML WASM protostruct using rescript-wasm-runtime. // This is a minimal demo intended for local testing only. diff --git a/axel-protocol/src/AxelApp.affine b/axel-protocol/src/AxelApp.affine index fba4909a..87180b6f 100644 --- a/axel-protocol/src/AxelApp.affine +++ b/axel-protocol/src/AxelApp.affine @@ -3,7 +3,7 @@ module AxelApp; -// SPDX-License-Identifier: PMPL-1.0-or-later +// SPDX-License-Identifier: MPL-2.0 // AXEL Protocol - DNS Label Checker // With proven formally verified URL/domain validation diff --git a/axel-protocol/src/AxelSts.affine b/axel-protocol/src/AxelSts.affine index eaa5d577..83fc9958 100644 --- a/axel-protocol/src/AxelSts.affine +++ b/axel-protocol/src/AxelSts.affine @@ -3,7 +3,7 @@ module AxelSts; -// SPDX-License-Identifier: PMPL-1.0-or-later +// SPDX-License-Identifier: MPL-2.0 // AXEL Protocol - DNS TXT Record Parser (Strict) // // Parses AXEL DNS TXT record payloads (RDATA only, not full RR lines). diff --git a/axel-protocol/src/ProvenResult.affine b/axel-protocol/src/ProvenResult.affine index 9f19968a..3113fc66 100644 --- a/axel-protocol/src/ProvenResult.affine +++ b/axel-protocol/src/ProvenResult.affine @@ -3,7 +3,7 @@ module ProvenResult; -// SPDX-License-Identifier: PMPL-1.0-or-later +// SPDX-License-Identifier: MPL-2.0 // SPDX-FileCopyrightText: 2025 Jonathan D.A. Jewell /** * Result struct for proven bindings diff --git a/axel-protocol/src/ProvenSafeUrl.affine b/axel-protocol/src/ProvenSafeUrl.affine index 2a18fa85..be06b5dd 100644 --- a/axel-protocol/src/ProvenSafeUrl.affine +++ b/axel-protocol/src/ProvenSafeUrl.affine @@ -3,7 +3,7 @@ module ProvenSafeUrl; -// SPDX-License-Identifier: PMPL-1.0-or-later +// SPDX-License-Identifier: MPL-2.0 // SPDX-FileCopyrightText: 2025 Jonathan D.A. Jewell /** * SafeUrl - URL parsing that cannot crash diff --git a/axel-protocol/src/Tea.affine b/axel-protocol/src/Tea.affine index 22922b0e..c94f8fbd 100644 --- a/axel-protocol/src/Tea.affine +++ b/axel-protocol/src/Tea.affine @@ -3,7 +3,7 @@ module Tea; -// SPDX-License-Identifier: PMPL-1.0-or-later +// SPDX-License-Identifier: MPL-2.0 // Minimal TEA implementation for STAMP // Compatible with full rescript-tea architecture diff --git a/docs/affinescript-testing-guide.adoc b/docs/affinescript-testing-guide.adoc index 87411483..9ef70125 100644 --- a/docs/affinescript-testing-guide.adoc +++ b/docs/affinescript-testing-guide.adoc @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: CC-BY-SA-4.0 + == AffineScript Testing Tools Guide *Version:* 1.0.0 *Date:* 2026-07-03 *Status:* Active (baseline — honest diff --git a/k9-svc/bindings/deno/src/K9.affine b/k9-svc/bindings/deno/src/K9.affine index 750d39ff..ede4c16c 100644 --- a/k9-svc/bindings/deno/src/K9.affine +++ b/k9-svc/bindings/deno/src/K9.affine @@ -3,7 +3,7 @@ module K9; -// SPDX-License-Identifier: PMPL-1.0-or-later +// SPDX-License-Identifier: MPL-2.0 // Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) // // K9 — Main module for the K9 (Self-Validating Components) parser library. diff --git a/k9-svc/bindings/deno/src/K9_Parser.affine b/k9-svc/bindings/deno/src/K9_Parser.affine index 0d5b17d2..c76a9b4c 100644 --- a/k9-svc/bindings/deno/src/K9_Parser.affine +++ b/k9-svc/bindings/deno/src/K9_Parser.affine @@ -3,7 +3,7 @@ module K9_Parser; -// SPDX-License-Identifier: PMPL-1.0-or-later +// SPDX-License-Identifier: MPL-2.0 // Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) // // K9_Parser — Parser for K9 self-validating component specifications. diff --git a/k9-svc/bindings/deno/src/K9_Renderer.affine b/k9-svc/bindings/deno/src/K9_Renderer.affine index 79852ee1..56377105 100644 --- a/k9-svc/bindings/deno/src/K9_Renderer.affine +++ b/k9-svc/bindings/deno/src/K9_Renderer.affine @@ -3,7 +3,7 @@ module K9_Renderer; -// SPDX-License-Identifier: PMPL-1.0-or-later +// SPDX-License-Identifier: MPL-2.0 // Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) // // K9_Renderer — Render K9 AST back to K9 surface syntax. diff --git a/k9-svc/bindings/deno/src/K9_Types.affine b/k9-svc/bindings/deno/src/K9_Types.affine index 86767d78..04b23986 100644 --- a/k9-svc/bindings/deno/src/K9_Types.affine +++ b/k9-svc/bindings/deno/src/K9_Types.affine @@ -3,7 +3,7 @@ module K9_Types; -// SPDX-License-Identifier: PMPL-1.0-or-later +// SPDX-License-Identifier: MPL-2.0 // Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) // // K9_Types — Core data structs for K9 (Self-Validating Components). diff --git a/lol/src/Lang1000.affine b/lol/src/Lang1000.affine index a1568bfa..1967396e 100644 --- a/lol/src/Lang1000.affine +++ b/lol/src/Lang1000.affine @@ -3,7 +3,7 @@ module Lang1000; -// SPDX-License-Identifier: PMPL-1.0-or-later +// SPDX-License-Identifier: MPL-2.0 // SPDX-FileCopyrightText: 2024-2026 Jonathan D.A. Jewell and Contributors /** diff --git a/lol/src/api/DigitalBiblePlatform.affine b/lol/src/api/DigitalBiblePlatform.affine index 0cdf3de9..5f9e6b77 100644 --- a/lol/src/api/DigitalBiblePlatform.affine +++ b/lol/src/api/DigitalBiblePlatform.affine @@ -3,7 +3,7 @@ module DigitalBiblePlatform; -// SPDX-License-Identifier: PMPL-1.0-or-later +// SPDX-License-Identifier: MPL-2.0 // SPDX-FileCopyrightText: 2024-2026 Jonathan D.A. Jewell and Contributors /** diff --git a/lol/src/crawlers/BibleCloud.affine b/lol/src/crawlers/BibleCloud.affine index 0e7072d5..f4be998c 100644 --- a/lol/src/crawlers/BibleCloud.affine +++ b/lol/src/crawlers/BibleCloud.affine @@ -3,7 +3,7 @@ module BibleCloud; -// SPDX-License-Identifier: PMPL-1.0-or-later +// SPDX-License-Identifier: MPL-2.0 // SPDX-FileCopyrightText: 2024-2026 Jonathan D.A. Jewell and Contributors /** diff --git a/lol/src/crawlers/BibleCom.affine b/lol/src/crawlers/BibleCom.affine index 312420bd..1df9ac62 100644 --- a/lol/src/crawlers/BibleCom.affine +++ b/lol/src/crawlers/BibleCom.affine @@ -3,7 +3,7 @@ module BibleCom; -// SPDX-License-Identifier: PMPL-1.0-or-later +// SPDX-License-Identifier: MPL-2.0 // SPDX-FileCopyrightText: 2024-2026 Jonathan D.A. Jewell and Contributors /** diff --git a/lol/src/crawlers/Crawler.affine b/lol/src/crawlers/Crawler.affine index ef03e860..3ab9679d 100644 --- a/lol/src/crawlers/Crawler.affine +++ b/lol/src/crawlers/Crawler.affine @@ -3,7 +3,7 @@ module Crawler; -// SPDX-License-Identifier: PMPL-1.0-or-later +// SPDX-License-Identifier: MPL-2.0 // SPDX-FileCopyrightText: 2024-2026 Jonathan D.A. Jewell and Contributors /** diff --git a/lol/src/crawlers/EBible.affine b/lol/src/crawlers/EBible.affine index 7c81cef5..3b1995f6 100644 --- a/lol/src/crawlers/EBible.affine +++ b/lol/src/crawlers/EBible.affine @@ -3,7 +3,7 @@ module EBible; -// SPDX-License-Identifier: PMPL-1.0-or-later +// SPDX-License-Identifier: MPL-2.0 // SPDX-FileCopyrightText: 2024-2026 Jonathan D.A. Jewell and Contributors /** diff --git a/lol/src/crawlers/FindBible.affine b/lol/src/crawlers/FindBible.affine index 1f022906..991ff141 100644 --- a/lol/src/crawlers/FindBible.affine +++ b/lol/src/crawlers/FindBible.affine @@ -3,7 +3,7 @@ module FindBible; -// SPDX-License-Identifier: PMPL-1.0-or-later +// SPDX-License-Identifier: MPL-2.0 // SPDX-FileCopyrightText: 2024-2026 Jonathan D.A. Jewell and Contributors /** diff --git a/lol/src/crawlers/PngScriptures.affine b/lol/src/crawlers/PngScriptures.affine index 70cc4ac6..f070568f 100644 --- a/lol/src/crawlers/PngScriptures.affine +++ b/lol/src/crawlers/PngScriptures.affine @@ -3,7 +3,7 @@ module PngScriptures; -// SPDX-License-Identifier: PMPL-1.0-or-later +// SPDX-License-Identifier: MPL-2.0 // SPDX-FileCopyrightText: 2024-2026 Jonathan D.A. Jewell and Contributors /** diff --git a/lol/src/cyc/OpenCyc.affine b/lol/src/cyc/OpenCyc.affine index 315dd926..2c79106b 100644 --- a/lol/src/cyc/OpenCyc.affine +++ b/lol/src/cyc/OpenCyc.affine @@ -3,7 +3,7 @@ module OpenCyc; -// SPDX-License-Identifier: PMPL-1.0-or-later +// SPDX-License-Identifier: MPL-2.0 // SPDX-FileCopyrightText: 2024-2026 Jonathan D.A. Jewell and Contributors /** diff --git a/lol/src/utils/Http.affine b/lol/src/utils/Http.affine index 2c911c52..ee99959c 100644 --- a/lol/src/utils/Http.affine +++ b/lol/src/utils/Http.affine @@ -3,7 +3,7 @@ module Http; -// SPDX-License-Identifier: PMPL-1.0-or-later +// SPDX-License-Identifier: MPL-2.0 // SPDX-FileCopyrightText: 2024-2026 Jonathan D.A. Jewell and Contributors /** diff --git a/lol/src/utils/Iso639.affine b/lol/src/utils/Iso639.affine index e73fb39d..2db47669 100644 --- a/lol/src/utils/Iso639.affine +++ b/lol/src/utils/Iso639.affine @@ -3,7 +3,7 @@ module Iso639; -// SPDX-License-Identifier: PMPL-1.0-or-later +// SPDX-License-Identifier: MPL-2.0 // SPDX-FileCopyrightText: 2024-2026 Jonathan D.A. Jewell and Contributors /** diff --git a/lol/src/utils/Statistics.affine b/lol/src/utils/Statistics.affine index 3cd9795e..53cf3f07 100644 --- a/lol/src/utils/Statistics.affine +++ b/lol/src/utils/Statistics.affine @@ -3,7 +3,7 @@ module Statistics; -// SPDX-License-Identifier: PMPL-1.0-or-later +// SPDX-License-Identifier: MPL-2.0 // SPDX-FileCopyrightText: 2024-2026 Jonathan D.A. Jewell and Contributors /** diff --git a/lol/src/verisimdb/CorpusAnalyzer.affine b/lol/src/verisimdb/CorpusAnalyzer.affine index dc125baf..a1c7bb16 100644 --- a/lol/src/verisimdb/CorpusAnalyzer.affine +++ b/lol/src/verisimdb/CorpusAnalyzer.affine @@ -3,7 +3,7 @@ module CorpusAnalyzer; -// SPDX-License-Identifier: PMPL-1.0-or-later +// SPDX-License-Identifier: MPL-2.0 // SPDX-FileCopyrightText: 2024-2026 Jonathan D.A. Jewell and Contributors /** diff --git a/lol/src/verisimdb/Export.affine b/lol/src/verisimdb/Export.affine index 32d4cc09..9b13e482 100644 --- a/lol/src/verisimdb/Export.affine +++ b/lol/src/verisimdb/Export.affine @@ -3,7 +3,7 @@ module Export; -// SPDX-License-Identifier: PMPL-1.0-or-later +// SPDX-License-Identifier: MPL-2.0 // SPDX-FileCopyrightText: 2024-2026 Jonathan D.A. Jewell and Contributors /** diff --git a/lol/src/verisimdb/VeriSimDB.affine b/lol/src/verisimdb/VeriSimDB.affine index 2da0790a..e3517c82 100644 --- a/lol/src/verisimdb/VeriSimDB.affine +++ b/lol/src/verisimdb/VeriSimDB.affine @@ -3,7 +3,7 @@ module VeriSimDB; -// SPDX-License-Identifier: PMPL-1.0-or-later +// SPDX-License-Identifier: MPL-2.0 // SPDX-FileCopyrightText: 2024-2026 Jonathan D.A. Jewell and Contributors /** diff --git a/lol/test/Lang1000_test.affine b/lol/test/Lang1000_test.affine index db504ba8..f00de6e8 100644 --- a/lol/test/Lang1000_test.affine +++ b/lol/test/Lang1000_test.affine @@ -3,7 +3,7 @@ module Lang1000_test; -// SPDX-License-Identifier: PMPL-1.0-or-later +// SPDX-License-Identifier: MPL-2.0 // SPDX-FileCopyrightText: 2024-2026 Jonathan D.A. Jewell and Contributors /** diff --git a/lol/test/Vitest.affine b/lol/test/Vitest.affine index 6b63c7de..fd85b87a 100644 --- a/lol/test/Vitest.affine +++ b/lol/test/Vitest.affine @@ -3,7 +3,7 @@ module Vitest; -// SPDX-License-Identifier: PMPL-1.0-or-later +// SPDX-License-Identifier: MPL-2.0 // SPDX-FileCopyrightText: 2024-2026 Jonathan D.A. Jewell and Contributors /** diff --git a/lol/test/crawlers/Crawler_test.affine b/lol/test/crawlers/Crawler_test.affine index 6d18ce30..fecda375 100644 --- a/lol/test/crawlers/Crawler_test.affine +++ b/lol/test/crawlers/Crawler_test.affine @@ -3,7 +3,7 @@ module Crawler_test; -// SPDX-License-Identifier: PMPL-1.0-or-later +// SPDX-License-Identifier: MPL-2.0 // SPDX-FileCopyrightText: 2024-2026 Jonathan D.A. Jewell and Contributors /** diff --git a/lol/test/utils/Iso639_test.affine b/lol/test/utils/Iso639_test.affine index e98ed236..802ff4eb 100644 --- a/lol/test/utils/Iso639_test.affine +++ b/lol/test/utils/Iso639_test.affine @@ -3,7 +3,7 @@ module Iso639_test; -// SPDX-License-Identifier: PMPL-1.0-or-later +// SPDX-License-Identifier: MPL-2.0 // SPDX-FileCopyrightText: 2024-2026 Jonathan D.A. Jewell and Contributors /** diff --git a/lol/test/utils/Statistics_test.affine b/lol/test/utils/Statistics_test.affine index 4e6b5964..aad517cf 100644 --- a/lol/test/utils/Statistics_test.affine +++ b/lol/test/utils/Statistics_test.affine @@ -3,7 +3,7 @@ module Statistics_test; -// SPDX-License-Identifier: PMPL-1.0-or-later +// SPDX-License-Identifier: MPL-2.0 // SPDX-FileCopyrightText: 2024-2026 Jonathan D.A. Jewell and Contributors /** diff --git a/panll-panels/src/ComplianceMonitor.affine b/panll-panels/src/ComplianceMonitor.affine index dfbba9eb..5d42557c 100644 --- a/panll-panels/src/ComplianceMonitor.affine +++ b/panll-panels/src/ComplianceMonitor.affine @@ -3,7 +3,7 @@ module ComplianceMonitor; -// SPDX-License-Identifier: PMPL-1.0-or-later +// SPDX-License-Identifier: MPL-2.0 // Compliance Monitor panel — Hypatia findings heatmap + trend. struct finding { { diff --git a/panll-panels/src/CrgDashboard.affine b/panll-panels/src/CrgDashboard.affine index 54c37ded..cc3cace1 100644 --- a/panll-panels/src/CrgDashboard.affine +++ b/panll-panels/src/CrgDashboard.affine @@ -3,7 +3,7 @@ module CrgDashboard; -// SPDX-License-Identifier: PMPL-1.0-or-later +// SPDX-License-Identifier: MPL-2.0 // CRG Dashboard panel — grade distribution, transitions, promotion queue. struct state { { diff --git a/panll-panels/src/ProofHub.affine b/panll-panels/src/ProofHub.affine index 9a19e59d..9fc90d15 100644 --- a/panll-panels/src/ProofHub.affine +++ b/panll-panels/src/ProofHub.affine @@ -3,7 +3,7 @@ module ProofHub; -// SPDX-License-Identifier: PMPL-1.0-or-later +// SPDX-License-Identifier: MPL-2.0 // Proof Verification Hub panel — proof table with trust level & staleness. struct proof { { diff --git a/panll-panels/src/VcldbClient.affine b/panll-panels/src/VcldbClient.affine index 7d97bc1a..36dedeeb 100644 --- a/panll-panels/src/VcldbClient.affine +++ b/panll-panels/src/VcldbClient.affine @@ -3,7 +3,7 @@ module VcldbClient; -// SPDX-License-Identifier: PMPL-1.0-or-later +// SPDX-License-Identifier: MPL-2.0 // VeriSimDB query client — executes VCL queries, returns octad rows. // // Thin wrapper over fetch(). Consumers (panels) call one of the diff --git a/scripts/build-registry.sh b/scripts/build-registry.sh index cb547e53..e21bc7a5 100755 --- a/scripts/build-registry.sh +++ b/scripts/build-registry.sh @@ -8,7 +8,7 @@ # This is the generator behind two artefacts that MUST NOT be hand-edited: # * .machine_readable/REGISTRY.a2ml — the machine index of every spec, # its canonical home, and a content-addressed `source_hash`. -# * TOPOLOGY.md — the human-readable map, derived +# * TOPOLOGY.adoc — the human-readable map, derived # from the registry + STATE.a2ml so it can never freeze again. # # The registry indexes two kinds of spec: @@ -47,7 +47,7 @@ MODE="write" [ "${1:-}" = "--check" ] && MODE="check" REGISTRY=".machine_readable/REGISTRY.a2ml" -TOPOLOGY="TOPOLOGY.md" +TOPOLOGY="TOPOLOGY.adoc" # Intentionally NO generation timestamp: a volatile date would make every # regeneration differ and defeat `--check`. The content (hashes + STATE) is the # only source of truth, so the output is a pure function of the committed tree. @@ -233,7 +233,7 @@ ENTRY } # --------------------------------------------------------------------------- -# Emit TOPOLOGY.md (DERIVED from the registry + STATE.a2ml) +# Emit TOPOLOGY.adoc (DERIVED from the registry + STATE.a2ml) # --------------------------------------------------------------------------- state_field() { # crude TOML-ish field reader for STATE.a2ml @@ -248,22 +248,24 @@ emit_topology() { phase="$(state_field phase)"; maturity="$(state_field maturity)" updated="$(state_field last-updated)" cat <
- - +// SPDX-License-Identifier: CC-BY-SA-4.0 +// TOPOLOGY.adoc — DERIVED architecture map (generated from REGISTRY.a2ml + STATE.a2ml) +// GENERATED FILE — DO NOT EDIT BY HAND. Run: just topology (scripts/build-registry.sh) -# Hyperpolymath Standards — Topology (derived) += Hyperpolymath Standards — Topology (derived) -> This file is **generated** from \`.machine_readable/REGISTRY.a2ml\` and -> \`.machine_readable/6a2/STATE.a2ml\` by \`scripts/build-registry.sh\`. -> It cannot freeze: every regeneration re-reads ground truth. Do not edit by hand. +____ +This file is *generated* from \`+.machine_readable/REGISTRY.a2ml+\` and +the canonical \`+STATE.a2ml+\` by \`+scripts/build-registry.sh+\`. +It cannot freeze: every regeneration re-reads ground truth. Do not edit by hand. +____ -- **Phase:** ${phase:-unknown}  |  **Maturity:** ${maturity:-unknown}  |  **STATE last-updated:** ${updated:-unknown} -- **Registry entries:** ${ENTRY_COUNT} specs across 6 streams -- **Front door:** human → [README.adoc](README.adoc); machine → [0-AI-MANIFEST.a2ml](0-AI-MANIFEST.a2ml) -- **Registry:** [.machine_readable/REGISTRY.a2ml](.machine_readable/REGISTRY.a2ml) (index + source hashes) · prose: [REGISTRY.adoc](REGISTRY.adoc) +* *Phase:* ${phase:-unknown} | *Maturity:* ${maturity:-unknown} | *STATE last-updated:* ${updated:-unknown} +* *Registry entries:* ${ENTRY_COUNT} specs across 6 streams +* *Front door:* human → link:README.adoc[README.adoc]; machine → link:0-AI-MANIFEST.a2ml[0-AI-MANIFEST.a2ml] +* *Registry:* link:.machine_readable/REGISTRY.a2ml[.machine_readable/REGISTRY.a2ml] (index + source hashes) · prose: link:REGISTRY.adoc[REGISTRY.adoc] -## Specs by stream +== Specs by stream HEADER @@ -279,37 +281,37 @@ HEADER esac # print the section if EITHER local or external specs populate this stream if grep -q "|${s}|" <<< "$SPECS" || grep -q "|${s}|" <<< "$EXTERNAL_SPECS"; then - printf '### %s\n\n' "$label" - printf '| Spec | Home | If you want… |\n|---|---|---|\n' + printf '=== %s\n\n' "$label" + printf '[cols="34%%,33%%,33%%",options="header"]\n|===\n| Spec | Home | If you want…\n' while IFS='|' read -r id stream home name route; do [ -z "$id" ] && continue [ "$stream" = "$s" ] || continue [ -d "$home" ] || continue - printf '| %s | [`%s`](%s) | %s |\n' "$name" "$home" "$home" "$route" + printf '| %s | link:%s[`+%s+`] | %s\n' "$name" "$home" "$home" "$route" done <<< "$SPECS" # external pointers in this stream (SSOT lives in another repo) while IFS='|' read -r id stream spec_kind owning_repo canonical_url version_pin format_version source_hash media_type lineage name route; do [ -z "$id" ] && continue [ "$stream" = "$s" ] || continue - printf '| %s | [`%s`](%s) `@ %s` ⇗ | %s |\n' "$name" "$owning_repo" "$canonical_url" "$version_pin" "$route" + printf '| %s | %s[`+%s+`] `+@ %s+` ⇗ | %s\n' "$name" "$canonical_url" "$owning_repo" "$version_pin" "$route" done <<< "$EXTERNAL_SPECS" - printf '\n' + printf '|===\n\n' fi done cat <<'FOOTER' -## How this map stays honest +== How this map stays honest -``` -file tree + STATE.a2ml ──► scripts/build-registry.sh ──► REGISTRY.a2ml ──► TOPOLOGY.md +.... +file tree + STATE.a2ml ──► scripts/build-registry.sh ──► REGISTRY.a2ml ──► TOPOLOGY.adoc ▲ │ │ ▼ just registry / CI HYP-S006 (registry-staleness) (registry-verify.yml) emits doc.drift on hash mismatch -``` +.... -Regenerate after any spec change: `just registry` (writes REGISTRY.a2ml + TOPOLOGY.md). -CI (`registry-verify.yml`) runs `--check` and fails the build if either is stale. +Regenerate after any spec change: `+just registry+` (writes REGISTRY.a2ml + TOPOLOGY.adoc). +CI (`+registry-verify.yml+`) runs `+--check+` and fails the build if either is stale. FOOTER } diff --git a/scripts/build-scorecards.sh b/scripts/build-scorecards.sh index aa637809..4f64216e 100644 --- a/scripts/build-scorecards.sh +++ b/scripts/build-scorecards.sh @@ -2,13 +2,13 @@ # SPDX-License-Identifier: MPL-2.0 # SPDX-FileCopyrightText: 2026 Jonathan D.A. Jewell (hyperpolymath) # -# build-scorecards.sh — regenerate COMPLIANCE-DASHBOARD.md from the per-spec +# build-scorecards.sh — regenerate COMPLIANCE-DASHBOARD.adoc from the per-spec # scorecards under .machine_readable/scorecards/. # # This mirrors scripts/build-registry.sh exactly in spirit: # * The SCORECARDS are the hand-authored source of truth (one per LOCAL spec # in REGISTRY.a2ml, keyed by spec_id, validated by scorecard.schema.json). -# * COMPLIANCE-DASHBOARD.md is DERIVED and MUST NOT be hand-edited. +# * COMPLIANCE-DASHBOARD.adoc is DERIVED and MUST NOT be hand-edited. # * Deterministic + idempotent (no timestamps in generated output — the # assessed_date lives in each source scorecard). Run twice → identical. # * Honest. A `pass` requires evidence; an `aspirational` requirement is NEVER @@ -22,7 +22,7 @@ # * every scorecard MUST key to a registered spec (orphan → hard error). # # Usage: -# bash scripts/build-scorecards.sh # write COMPLIANCE-DASHBOARD.md +# bash scripts/build-scorecards.sh # write COMPLIANCE-DASHBOARD.adoc # bash scripts/build-scorecards.sh --check # verify in sync; non-zero on drift # bash scripts/build-scorecards.sh --strict # also fail if any spec lacks a scorecard # bash scripts/build-scorecards.sh --verify # RUN every pass-row's `check`; @@ -44,7 +44,7 @@ done REGISTRY=".machine_readable/REGISTRY.a2ml" SCDIR=".machine_readable/scorecards" -DASHBOARD="COMPLIANCE-DASHBOARD.md" +DASHBOARD="COMPLIANCE-DASHBOARD.adoc" SCHEMA="$SCDIR/scorecard.schema.json" [ -f "$REGISTRY" ] || { echo "error: $REGISTRY not found (run: just registry)" >&2; exit 2; } @@ -273,30 +273,32 @@ emit_dashboard() { local g_must=0 g_must_pass=0 g_must_fail=0 g_reqs=0 g_reqs_sys=0 cat <<'HEADER' - - - - -# Standards Compliance Dashboard (derived) - -> Generated from `.machine_readable/scorecards/.scorecard.a2ml` by -> `scripts/build-scorecards.sh`. One scorecard per LOCAL spec in -> `.machine_readable/REGISTRY.a2ml`. Do not edit by hand — edit the scorecards. -> -> **How to read this.** Each spec is audited as MUST / SHOULD / COULD -> requirements. **MUST-status** is the compliance verdict: ✅ met (every MUST -> passes or is manual-only) or ❌ gap (some MUST fails). **Systems coverage** -> is the share of requirements with a real mechanical check (`system` ≠ `none`) -> — the honest measure of *enforcement vs. assertion*. **Aspirational** -> requirements (intentionally-unreachable reach targets) are never counted as -> passing. +// SPDX-License-Identifier: CC-BY-SA-4.0 +// COMPLIANCE-DASHBOARD.adoc — DERIVED from .machine_readable/scorecards/*.scorecard.a2ml +// GENERATED FILE — DO NOT EDIT BY HAND. Run: just scorecards (scripts/build-scorecards.sh) + += Standards Compliance Dashboard (derived) + +____ +Generated from `+.machine_readable/scorecards/.scorecard.a2ml+` by +`+scripts/build-scorecards.sh+`. One scorecard per LOCAL spec in +`+.machine_readable/REGISTRY.a2ml+`. Do not edit by hand — edit the scorecards. + +*How to read this.* Each spec is audited as MUST / SHOULD / COULD +requirements. *MUST-status* is the compliance verdict: ✅ met (every MUST +passes or is manual-only) or ❌ gap (some MUST fails). *Systems coverage* +is the share of requirements with a real mechanical check (`+system+` ≠ `+none+`) +— the honest measure of _enforcement vs. assertion_. *Aspirational* +requirements (intentionally-unreachable reach targets) are never counted as +passing. +____ HEADER # Per-spec table - printf '## Per-spec scorecards\n\n' - printf '| Spec | MUST status | MUST (pass/total) | SHOULD (pass/total) | COULD (pass/total) | Systems coverage | Grounded passes | Assessed |\n' - printf '|---|---|---|---|---|---|---|---|\n' + printf '== Per-spec scorecards\n\n' + printf '[cols="16%%,12%%,12%%,12%%,12%%,12%%,12%%,12%%",options="header"]\n|===\n' + printf '| Spec | MUST status | MUST (pass/total) | SHOULD (pass/total) | COULD (pass/total) | Systems coverage | Grounded passes | Assessed\n' local g_pass=0 g_pass_chk=0 local missing=() @@ -306,7 +308,7 @@ HEADER local file="$SCDIR/$id.scorecard.a2ml" if [ ! -f "$file" ]; then missing+=("$id") - printf '| `%s` | ⚠️ no scorecard | – | – | – | – | – | – |\n' "$id" + printf '| `+%s+` | ⚠️ no scorecard | – | – | – | – | – | –\n' "$id" continue fi scored_specs=$((scored_specs + 1)) @@ -334,7 +336,7 @@ HEADER [ "$p_all" -gt 0 ] && grounded="${p_chk}/${p_all}" local assessed; assessed="$(sc_field "$file" assessed_date)" - printf '| `%s` | %s | %d/%d | %d/%d | %d/%d | %s | %s | %s |\n' \ + printf '| `+%s+` | %s | %d/%d | %d/%d | %d/%d | %s | %s | %s\n' \ "$id" "$verdict" "$m_p" "$m_t" "$s_p" "$s_t" "$c_p" "$c_t" "$cov" "$grounded" "${assessed:-–}" g_must=$((g_must + m_t)); g_must_pass=$((g_must_pass + m_p)); g_must_fail=$((g_must_fail + m_f)) @@ -347,36 +349,36 @@ HEADER [ "$g_reqs" -gt 0 ] && est_cov="$(awk "BEGIN{printf \"%d%%\", ($g_reqs_sys/$g_reqs)*100}")" local est_grounded="n/a" [ "$g_pass" -gt 0 ] && est_grounded="$(awk "BEGIN{printf \"%d%%\", ($g_pass_chk/$g_pass)*100}")" - printf '\n## Estate rollup\n\n' - printf -- '- **Specs registered (local):** %d\n' "$total_specs" - printf -- '- **Specs with a scorecard:** %d / %d\n' "$scored_specs" "$total_specs" - printf -- '- **MUST requirements:** %d passing / %d total (%d failing)\n' "$g_must_pass" "$g_must" "$g_must_fail" - printf -- '- **Estate systems coverage:** %s of %d graded requirements have a mechanical check\n' "$est_cov" "$g_reqs" - printf -- '- **Grounded passes:** %d / %d (%s) pass rows carry an executable `check` run by `--verify`\n' "$g_pass_chk" "$g_pass" "$est_grounded" + printf '|===\n\n== Estate rollup\n\n' + printf -- '* *Specs registered (local):* %d\n' "$total_specs" + printf -- '* *Specs with a scorecard:* %d / %d\n' "$scored_specs" "$total_specs" + printf -- '* *MUST requirements:* %d passing / %d total (%d failing)\n' "$g_must_pass" "$g_must" "$g_must_fail" + printf -- '* *Estate systems coverage:* %s of %d graded requirements have a mechanical check\n' "$est_cov" "$g_reqs" + printf -- '* *Grounded passes:* %d / %d (%s) pass rows carry an executable `+check+` run by `+--verify+`\n' "$g_pass_chk" "$g_pass" "$est_grounded" if [ "${#missing[@]}" -gt 0 ]; then - printf -- '- **Specs still needing a scorecard (%d):** %s\n' "${#missing[@]}" "$(printf '`%s` ' "${missing[@]}")" + printf -- '* *Specs still needing a scorecard (%d):* %s\n' "${#missing[@]}" "$(printf '`+%s+` ' "${missing[@]}")" fi cat <<'FOOTER' -## How this dashboard stays honest +== How this dashboard stays honest -``` -scorecards/*.scorecard.a2ml ──► scripts/build-scorecards.sh ──► COMPLIANCE-DASHBOARD.md +.... +scorecards/*.scorecard.a2ml ──► scripts/build-scorecards.sh ──► COMPLIANCE-DASHBOARD.adoc (hand-authored) │ validated vs scorecard.schema.json ▼ just scorecards-check (CI) -``` +.... -- A `pass` requires cited `evidence`; the generator rejects a pass without it. -- `aspirational` requirements never count as passing (no intuition-plucked +* A `+pass+` requires cited `+evidence+`; the generator rejects a pass without it. +* `+aspirational+` requirements never count as passing (no intuition-plucked Grade-A gate can inflate a score — standards#446). -- `system = "none"` is legal but visible, and lowers systems coverage. -- A pass MAY carry an executable `check`; `--verify` RUNS every such check and - **fails loudly if a claimed pass does not hold right now** (DYADT applied to +* `+system = "none"+` is legal but visible, and lowers systems coverage. +* A pass MAY carry an executable `+check+`; `+--verify+` RUNS every such check and + *fails loudly if a claimed pass does not hold right now* (DYADT applied to the scorecards themselves). Passes without a check are reported as self-asserted — visible debt, tracked by the Grounded column. -- Regenerate after editing any scorecard: `just scorecards`. +* Regenerate after editing any scorecard: `+just scorecards+`. FOOTER } diff --git a/scripts/check-language-guide.sh b/scripts/check-language-guide.sh index 5827d193..9a825a7a 100755 --- a/scripts/check-language-guide.sh +++ b/scripts/check-language-guide.sh @@ -3,13 +3,13 @@ # # check-language-guide.sh — structural lint for per-language testing guides. # -# Every guide built from templates/language-testing-guide-TEMPLATE.md MUST carry +# Every guide built from templates/language-testing-guide-TEMPLATE.adoc MUST carry # the required sections and the R1–R9 requirement-mapping table. A guide that # silently omits a section (e.g. "Known gaps") is a false-completeness hole — # this fails loudly instead. # -# Usage: check-language-guide.sh [guide.md ...] -# With no args, checks every docs/*-testing-guide.md. +# Usage: check-language-guide.sh [guide.adoc ...] +# With no args, checks every docs/*-testing-guide.adoc. # Exit: 0 all valid · 1 a guide is missing a required section set -uo pipefail @@ -17,19 +17,19 @@ set -uo pipefail ROOT="$(git rev-parse --show-toplevel 2>/dev/null || pwd)" REQUIRED_SECTIONS=( - "## Requirement mapping" - "## Tools" - "## Recommended CI pipeline" - "## Best practices" - "## Known gaps" - "## Resources" + "Requirement mapping" + "Tools" + "Recommended CI pipeline" + "Best practices" + "Known gaps" + "Resources" ) check_one() { # file local f="$1" rc=0 sec if [ ! -f "$f" ]; then echo " ❌ $f: not found"; return 1; fi for sec in "${REQUIRED_SECTIONS[@]}"; do - grep -Fqx "$sec" "$f" || { echo " ❌ $(basename "$f"): missing section '$sec'"; rc=1; } + grep -Eq "^(#{2,4}|={2,4})[[:space:]]+${sec}$" "$f" || { echo " ❌ $(basename "$f"): missing section '$sec'"; rc=1; } done # The requirement mapping MUST reference the R1..R9 rows (at least R1 and R9). grep -Eq '\bR1\b' "$f" && grep -Eq '\bR9\b' "$f" || { echo " ❌ $(basename "$f"): requirement mapping does not reference R1..R9"; rc=1; } @@ -42,11 +42,11 @@ check_one() { # file if [ "$#" -gt 0 ]; then files=("$@") else - mapfile -t files < <(find "$ROOT/docs" -maxdepth 1 -type f -name '*-testing-guide.md' -print 2>/dev/null | LC_ALL=C sort) + mapfile -t files < <(find "$ROOT/docs" -maxdepth 1 -type f \( -name '*-testing-guide.adoc' -o -name '*-testing-guide.md' \) -print 2>/dev/null | LC_ALL=C sort) fi if [ "${#files[@]}" -eq 0 ]; then - echo "no language testing guides found (docs/*-testing-guide.md)"; exit 0 + echo "no language testing guides found (docs/*-testing-guide.{adoc,md})"; exit 0 fi rc=0 diff --git a/scripts/tests/wave3-scorecards-test.sh b/scripts/tests/wave3-scorecards-test.sh index a33a28b0..1c5f77d8 100755 --- a/scripts/tests/wave3-scorecards-test.sh +++ b/scripts/tests/wave3-scorecards-test.sh @@ -59,14 +59,14 @@ rm -f "$SCDIR/zzz-orphan.scorecard.a2ml" echo "== determinism + drift ==" # regenerate twice -> identical bash "$GEN" >/dev/null 2>&1 -h1="$(sha256sum "$ROOT/COMPLIANCE-DASHBOARD.md" | cut -d' ' -f1)" +h1="$(sha256sum "$ROOT/COMPLIANCE-DASHBOARD.adoc" | cut -d' ' -f1)" bash "$GEN" >/dev/null 2>&1 -h2="$(sha256sum "$ROOT/COMPLIANCE-DASHBOARD.md" | cut -d' ' -f1)" +h2="$(sha256sum "$ROOT/COMPLIANCE-DASHBOARD.adoc" | cut -d' ' -f1)" [ "$h1" = "$h2" ] && ok "regeneration is deterministic" || bad "regeneration not deterministic" # --check green when in sync bash "$GEN" --check >/dev/null 2>&1 && ok "--check passes when in sync" || bad "--check failed when in sync" # --check red when dashboard mutated -printf '\n\n' >> "$ROOT/COMPLIANCE-DASHBOARD.md" +printf '\n// drift\n' >> "$ROOT/COMPLIANCE-DASHBOARD.adoc" if bash "$GEN" --check >/dev/null 2>&1; then bad "--check missed injected drift"; else ok "--check detects injected drift"; fi bash "$GEN" >/dev/null 2>&1 # restore diff --git a/scripts/tests/wave5-language-guides-test.sh b/scripts/tests/wave5-language-guides-test.sh index 8a611353..df6e7532 100755 --- a/scripts/tests/wave5-language-guides-test.sh +++ b/scripts/tests/wave5-language-guides-test.sh @@ -15,12 +15,12 @@ bad() { echo " ❌ $1"; fail=$((fail + 1)); } echo "== real guides pass ==" guide_out="$(bash "$CHK" 2>&1)"; guide_rc=$? -if [ "$guide_rc" -eq 0 ] && printf '%s\n' "$guide_out" | grep -q 'affinescript-testing-guide.md'; then +if [ "$guide_rc" -eq 0 ] && printf '%s\n' "$guide_out" | grep -q 'affinescript-testing-guide.adoc'; then ok "estate guides are discovered and pass structural lint" else bad "estate guides were missed or failed lint" fi -bash "$CHK" "$ROOT/docs/affinescript-testing-guide.md" >/dev/null 2>&1 && ok "affinescript guide valid" || bad "affinescript guide invalid" +bash "$CHK" "$ROOT/docs/affinescript-testing-guide.adoc" >/dev/null 2>&1 && ok "affinescript guide valid" || bad "affinescript guide invalid" echo "== rejects incomplete guides ==" # missing a required section @@ -37,9 +37,9 @@ printf '\n# Baz\n## Requirement ma bash "$CHK" "$g3" >/dev/null 2>&1 && bad "missing R1..R9 not caught" || ok "missing R1..R9 rejected" echo "== the stale duplicate snapshot is gone ==" -[ ! -f "$ROOT/docs/language-testing-standards-v1.0.0-2024-04-14.md" ] && ok "duplicate snapshot removed" || bad "duplicate snapshot still present" +[ ! -f "$ROOT/docs/language-testing-standards-v1.0.0-2024-04-14.adoc" ] && ok "duplicate snapshot removed" || bad "duplicate snapshot still present" echo "== the standard is v2.0.0 with RFC-2119 ==" -grep -q 'Version:\*\* 2.0.0' "$ROOT/docs/language-testing-standards.md" && grep -qi 'RFC-2119' "$ROOT/docs/language-testing-standards.md" && ok "standard refreshed to v2.0.0 RFC-2119" || bad "standard not refreshed" +grep -q 'Version:\* 2.0.0' "$ROOT/docs/language-testing-standards.adoc" && grep -qi 'RFC-2119' "$ROOT/docs/language-testing-standards.adoc" && ok "standard refreshed to v2.0.0 RFC-2119" || bad "standard not refreshed" echo echo "Wave-5 language-guides regression: $pass passed, $fail failed"