From ed4f98a3c5bd0e73a7f195f7fca5ea21b2835723 Mon Sep 17 00:00:00 2001 From: "Jonathan D.A. Jewell" <6759885+hyperpolymath@users.noreply.github.com> Date: Fri, 9 Oct 2026 09:21:26 +0100 Subject: [PATCH] chore: retire the A2ML spec registry and its gates (#1161) A2ML is retired (D99, D269c, D312, D313); descriptive metadata now lives in deed clauses, k9 contracts and the k9 coordination protocol. The registry generator kept writing .machine_readable/REGISTRY.a2ml, and "Registry + topology in sync" went red whenever that output drifted. It is red on main today because build-registry.sh hashed tracked lockfiles inside spec homes. Retire the machinery instead of regenerating it (D222 pattern): - delete registry-verify.yml, REGISTRY.a2ml, build-registry.sh, build-scorecards.sh and their two tests; - retire Hypatia HYP-S006 (registry-staleness) and HYP-S009 (implementation-inside-canon, whose only input was the registry), with the 16 HYP-S009 baseline entries (205 -> 189; debts stay tracked in #687); - drop the registry/topology/scorecards Justfile recipes, the pre-commit drift guard, the registry checks in the Mustfile and MUST.contractile, the Adjustfile/Dustfile staleness blocks and the registry-verify actions.lock entry; - keep TOPOLOGY.adoc and COMPLIANCE-DASHBOARD.adoc as frozen snapshots, and turn REGISTRY.adoc into the retirement notice with permalinks to 6d19ce0e; - stop front doors, quickstarts, wikis and manifests routing readers to the registry (content deleted only in .a2ml files). registry-verify.yml also hosted two other gates. The Mustfile PR gate is unchanged: the required k9-contractile.yml runs the same two commands. The scorecard --verify (executing each pass row's check) is lost; the scorecards are frozen data pending R5 (#837), and REGISTRY.adoc says so. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_015bTuGfwCcvjrmNFejydTML --- .githooks/pre-commit | 5 +- .github/workflows/actions.lock | 2 - .github/workflows/registry-verify.yml | 103 ---- .github/workflows/self-test.yml | 7 +- .hypatia-baseline.json | 144 ------ .machine_readable/MUST.contractile | 5 +- .machine_readable/REGISTRY.a2ml | 385 --------------- .../contractiles/adjust/Adjustfile.a2ml | 6 - .../contractiles/dust/Dustfile.a2ml | 5 - .../contractiles/must/Mustfile.a2ml | 10 - 0-AI-MANIFEST.a2ml | 42 +- 0-canon/COMPLIANCE-DASHBOARD.adoc | 25 +- 1-formats/SATELLITES.a2ml | 4 +- .../form-fill-provenance/README.adoc | 3 +- 3-practice/CONTRIBUTING.adoc | 22 +- AGENTS.adoc | 23 +- CICD-WORKFLOW-CATALOG.md | 2 +- EXPLAINME.adoc | 12 +- Justfile | 40 +- QUICKSTART-DEV.adoc | 26 +- QUICKSTART-USER.adoc | 15 +- README.adoc | 29 +- REGISTRY.adoc | 217 ++++----- TOPOLOGY.adoc | 27 +- docs/AUDIT.adoc | 9 - docs/BADGE-CRITERIA-SPEC.adoc | 15 +- docs/INNERVATION.adoc | 2 +- .../migrations/pmpl-to-mpl-sweep-runbook.adoc | 3 +- docs/wikis/0.2-AI-MANIFEST.a2ml | 3 +- docs/wikis/README.adoc | 5 +- docs/wikis/developers/index.adoc | 4 +- docs/wikis/maintainers/index.adoc | 31 +- hooks/pre-commit | 17 - hypatia-rules/README.adoc | 28 +- .../implementation-inside-canon.a2ml | 110 ----- hypatia-rules/registry-staleness.a2ml | 155 ------ llm-warmup-dev.adoc | 16 +- llm-warmup-user.adoc | 8 +- scripts/build-registry.sh | 336 ------------- scripts/build-scorecards.sh | 451 ------------------ scripts/check-implementation-inside-canon.sh | 136 ------ scripts/check-workflow-staleness.sh | 14 +- scripts/tests/build-registry-test.sh | 150 ------ scripts/tests/build-scorecards-test.sh | 114 ----- scripts/tests/wave8-gates-test.sh | 4 +- standards-map.toml | 23 +- 46 files changed, 242 insertions(+), 2551 deletions(-) delete mode 100644 .github/workflows/registry-verify.yml delete mode 100644 .machine_readable/REGISTRY.a2ml delete mode 100644 hypatia-rules/implementation-inside-canon.a2ml delete mode 100644 hypatia-rules/registry-staleness.a2ml delete mode 100755 scripts/build-registry.sh delete mode 100644 scripts/build-scorecards.sh delete mode 100755 scripts/check-implementation-inside-canon.sh delete mode 100755 scripts/tests/build-registry-test.sh delete mode 100644 scripts/tests/build-scorecards-test.sh diff --git a/.githooks/pre-commit b/.githooks/pre-commit index 2d1b9da3e..3f689709a 100755 --- a/.githooks/pre-commit +++ b/.githooks/pre-commit @@ -124,9 +124,8 @@ run_validator "Bot directives" "validate-bot-directives.sh" "staged" # It demanded that every commit stage .machine_readable/REGISTRY.a2ml, a generated # TOML-shaped artefact -- i.e. a specimen of the record dialect the owner ruled # SUPERSEDED on 2026-09-08. Staging it then tripped the A2ML gate above, so the -# two gates deadlocked each other. The registry itself is UNCHANGED (R-H4); -# reshaping scripts/build-registry.sh is a separate, deliberate job. -# Drift is still caught in CI by .github/workflows/registry-verify.yml. +# two gates deadlocked each other. The registry, its generator and its CI +# check (registry-verify.yml) were retired on 2026-10-09; see REGISTRY.adoc. # Canonical names guard if [ -f "$REPO_ROOT/scripts/check-canonical-names.sh" ]; then diff --git a/.github/workflows/actions.lock b/.github/workflows/actions.lock index a31232556..03d1ba482 100644 --- a/.github/workflows/actions.lock +++ b/.github/workflows/actions.lock @@ -123,8 +123,6 @@ workflows: '.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@7e38f4b43b4db5c8dd498af069a4f6196df1d067' diff --git a/.github/workflows/registry-verify.yml b/.github/workflows/registry-verify.yml deleted file mode 100644 index 63bd57bde..000000000 --- a/.github/workflows/registry-verify.yml +++ /dev/null @@ -1,103 +0,0 @@ -# This workflow is managed by gh actions-lock. -# SPDX-License-Identifier: MPL-2.0 -# This workflow is managed by gh actions-lock. -# registry-verify — fail the build if the spec registry or the DERIVED -# topology map has drifted from the file tree. This is the in-repo half of -# the drift-detection loop (the estate half is Hypatia rule HYP-S006). -name: Registry Verify - -on: - push: - branches: [ main, master ] - pull_request: - branches: [ main, master ] - workflow_dispatch: - -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - -permissions: - actions: read - contents: read - -jobs: - verify: - name: Registry + topology in sync - runs-on: ubuntu-latest - timeout-minutes: 10 - steps: - - name: Checkout repository - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - with: - fetch-depth: 0 # full history so `git ls-files -s` hashes are stable - - # The scorecard `--verify` step below EXECUTES every pass-row's check. - # Those checks shell out to real tools; ubuntu-latest ships neither - # ripgrep nor xmllint. Without them `3-practice/release-pre-flight/v1-audit.sh` - # exits 2 ("v1-audit requires ripgrep") and the k9-svc MIME check exits - # 127 — which the verifier then reported as "claimed PASS but the pass - # is not real". That was a FALSE ACCUSATION: the passes were real, the - # checks simply never ran. A gate that cannot run its own checks must - # not be allowed to call the repo dishonest. - # - # NB this is a distinct fault from standards#381, which concerns - # REGISTRY.a2ml source_hash drift in the *first* step below and is - # not addressed here. - - name: Install check dependencies (ripgrep, xmllint) - run: | - set -euo pipefail - sudo apt-get update -qq - sudo apt-get install -y --no-install-recommends ripgrep libxml2-utils - rg --version | head -1 - xmllint --version 2>&1 | head -1 - - - name: Verify registry + derived topology are current - run: | - if ! bash scripts/build-registry.sh --check; then - { - echo "### Registry drift detected" - echo "" - echo "A tracked file under a spec home (or STATE.a2ml) changed without" - echo "regenerating the derived registry/topology. Fix locally:" - echo "" - echo '```sh' - echo "just registry # or: bash scripts/build-registry.sh" - echo "git add .machine_readable/REGISTRY.a2ml TOPOLOGY.adoc" - echo '```' - echo "" - echo "Install the pre-commit guard so this is caught before push:" - echo "" - echo '```sh' - echo "just hooks-install" - echo '```' - } >> "$GITHUB_STEP_SUMMARY" - exit 1 - fi - - - name: Mustfile enforcement (structural + execute invariants) - run: | - # Wave-8 gate promotion: the Mustfile's invariants previously executed - # only on push-to-main (boj-build.yml). PRs now gate on them too — - # a change that breaks a MUST invariant fails before merge, not after. - bash scripts/check-mustfile-structure.sh - bash scripts/run-mustfile.sh - - - name: Verify compliance dashboard is current (and pass-checks hold) - run: | - # --verify RUNS every pass-row's executable `check`: a claimed pass - # whose check does not hold fails this job (DYADT on the scorecards). - if ! bash scripts/build-scorecards.sh --check --strict --verify; then - { - echo "### Compliance dashboard drift" - echo "" - echo "0-canon/COMPLIANCE-DASHBOARD.adoc is stale, a scorecard is malformed/orphaned," - echo "or a registered spec has no scorecard. Fix locally:" - echo "" - echo '```sh' - echo "just scorecards # regenerate the dashboard" - echo "just scorecards-check-strict" - echo '```' - } >> "$GITHUB_STEP_SUMMARY" - exit 1 - fi diff --git a/.github/workflows/self-test.yml b/.github/workflows/self-test.yml index b05307e60..ea4288cdc 100644 --- a/.github/workflows/self-test.yml +++ b/.github/workflows/self-test.yml @@ -43,13 +43,12 @@ jobs: fetch-depth: 0 # The secret-scanner canary reads YAML with yq (preinstalled on the - # runner; YAML-POLICY Y-1) -- no Python. The scorecard - # grounding tests execute the same checks as registry-verify, including - # checks that require ripgrep and xmllint. + # runner; YAML-POLICY Y-1) -- no Python. Shell tests use ripgrep + # (wave9-session-detritus-test.sh); the Ruby tests need minitest. - name: Install test dependencies run: | sudo apt-get update -qq - sudo apt-get install -y --no-install-recommends ripgrep libxml2-utils ruby ruby-minitest + sudo apt-get install -y --no-install-recommends ripgrep ruby ruby-minitest # scripts/tests/check-ijson-jcs-test.sh needs the real tool; it exits 2 # without it. Same pin as ijson-jcs.yml (JSON-POLICY §3). diff --git a/.hypatia-baseline.json b/.hypatia-baseline.json index df6166ee4..c1927a9ad 100644 --- a/.hypatia-baseline.json +++ b/.hypatia-baseline.json @@ -851,150 +851,6 @@ "expires_at": "2026-11-29", "tracking_issue": "hyperpolymath/standards#687" }, - { - "severity": "medium", - "rule_module": "implementation_inside_canon", - "type": "HYP-S009", - "file": "2-protocols/axel/CNAME", - "note": "TEMPORARY ARCHITECTURE BASELINE (2026-08-29): decide extraction or an explicit co-location carve-out for AXEL deployment metadata.", - "expires_at": "2026-11-29", - "tracking_issue": "hyperpolymath/standards#687" - }, - { - "severity": "medium", - "rule_module": "implementation_inside_canon", - "type": "HYP-S009", - "file": "2-protocols/axel/Containerfile", - "note": "TEMPORARY ARCHITECTURE BASELINE (2026-08-29): decide extraction or an explicit co-location carve-out for the AXEL implementation.", - "expires_at": "2026-11-29", - "tracking_issue": "hyperpolymath/standards#687" - }, - { - "severity": "medium", - "rule_module": "implementation_inside_canon", - "type": "HYP-S009", - "file": "2-protocols/axel/ads.txt", - "note": "TEMPORARY ARCHITECTURE BASELINE (2026-08-29): decide extraction or an explicit co-location carve-out for AXEL deployment metadata.", - "expires_at": "2026-11-29", - "tracking_issue": "hyperpolymath/standards#687" - }, - { - "severity": "medium", - "rule_module": "implementation_inside_canon", - "type": "HYP-S009", - "file": "2-protocols/axel/docs/CNAME", - "note": "TEMPORARY ARCHITECTURE BASELINE (2026-08-29): decide extraction or an explicit co-location carve-out for AXEL documentation deployment metadata.", - "expires_at": "2026-11-29", - "tracking_issue": "hyperpolymath/standards#687" - }, - { - "severity": "medium", - "rule_module": "implementation_inside_canon", - "type": "HYP-S009", - "file": "2-protocols/axel/docs/ads.txt", - "note": "TEMPORARY ARCHITECTURE BASELINE (2026-08-29): decide extraction or an explicit co-location carve-out for AXEL documentation deployment metadata.", - "expires_at": "2026-11-29", - "tracking_issue": "hyperpolymath/standards#687" - }, - { - "severity": "medium", - "rule_module": "implementation_inside_canon", - "type": "HYP-S009", - "file": "2-protocols/axel/public/CNAME", - "note": "TEMPORARY ARCHITECTURE BASELINE (2026-08-29): decide extraction or an explicit co-location carve-out for AXEL public deployment metadata.", - "expires_at": "2026-11-29", - "tracking_issue": "hyperpolymath/standards#687" - }, - { - "severity": "medium", - "rule_module": "implementation_inside_canon", - "type": "HYP-S009", - "file": "2-protocols/axel/public/ads.txt", - "note": "TEMPORARY ARCHITECTURE BASELINE (2026-08-29): decide extraction or an explicit co-location carve-out for AXEL public deployment metadata.", - "expires_at": "2026-11-29", - "tracking_issue": "hyperpolymath/standards#687" - }, - { - "severity": "medium", - "rule_module": "implementation_inside_canon", - "type": "HYP-S009", - "file": "2-protocols/k9-coordination/tools/k9-init/Cargo.toml", - "note": "TEMPORARY ARCHITECTURE BASELINE (2026-08-29): decide whether k9-init belongs beside the protocol or must be extracted.", - "expires_at": "2026-11-29", - "tracking_issue": "hyperpolymath/standards#687" - }, - { - "severity": "medium", - "rule_module": "implementation_inside_canon", - "type": "HYP-S009", - "file": "rhodium-standard-repositories/satellites/cccp/satellites/nextgen-languages/7-tentacles/package.json", - "note": "TEMPORARY ARCHITECTURE BASELINE (2026-08-29): classify nested satellite implementation ownership before extraction or carve-out.", - "expires_at": "2026-11-29", - "tracking_issue": "hyperpolymath/standards#687" - }, - { - "severity": "medium", - "rule_module": "implementation_inside_canon", - "type": "HYP-S009", - "file": "rhodium-standard-repositories/satellites/palimpsest-license/Containerfile", - "note": "TEMPORARY ARCHITECTURE BASELINE (2026-08-29): classify satellite implementation ownership before extraction or carve-out.", - "expires_at": "2026-11-29", - "tracking_issue": "hyperpolymath/standards#687" - }, - { - "severity": "medium", - "rule_module": "implementation_inside_canon", - "type": "HYP-S009", - "file": "rhodium-standard-repositories/satellites/rsr-certifier/Cargo.toml", - "note": "TEMPORARY ARCHITECTURE BASELINE (2026-08-29): review the RSR certifier workspace's placement under the canonical home.", - "expires_at": "2026-11-29", - "tracking_issue": "hyperpolymath/standards#687" - }, - { - "severity": "medium", - "rule_module": "implementation_inside_canon", - "type": "HYP-S009", - "file": "rhodium-standard-repositories/satellites/rsr-certifier/container/Containerfile", - "note": "TEMPORARY ARCHITECTURE BASELINE (2026-08-29): review the RSR certifier container's placement under the canonical home.", - "expires_at": "2026-11-29", - "tracking_issue": "hyperpolymath/standards#687" - }, - { - "severity": "medium", - "rule_module": "implementation_inside_canon", - "type": "HYP-S009", - "file": "rhodium-standard-repositories/satellites/rsr-certifier/engine/Cargo.toml", - "note": "TEMPORARY ARCHITECTURE BASELINE (2026-08-29): review the RSR certifier engine's placement under the canonical home.", - "expires_at": "2026-11-29", - "tracking_issue": "hyperpolymath/standards#687" - }, - { - "severity": "medium", - "rule_module": "implementation_inside_canon", - "type": "HYP-S009", - "file": "rhodium-standard-repositories/satellites/rsr-certifier/extensions/vscode/package.json", - "note": "TEMPORARY ARCHITECTURE BASELINE (2026-08-29): review the RSR certifier editor extension's placement under the canonical home.", - "expires_at": "2026-11-29", - "tracking_issue": "hyperpolymath/standards#687" - }, - { - "severity": "medium", - "rule_module": "implementation_inside_canon", - "type": "HYP-S009", - "file": "rhodium-standard-repositories/satellites/rsr-certifier/lsp/Cargo.toml", - "note": "TEMPORARY ARCHITECTURE BASELINE (2026-08-29): review the RSR certifier LSP's placement under the canonical home.", - "expires_at": "2026-11-29", - "tracking_issue": "hyperpolymath/standards#687" - }, - { - "severity": "medium", - "rule_module": "implementation_inside_canon", - "type": "HYP-S009", - "file": "rhodium-standard-repositories/satellites/state.scm/Containerfile", - "note": "TEMPORARY ARCHITECTURE BASELINE (2026-08-29): classify satellite implementation ownership before extraction or carve-out.", - "expires_at": "2026-11-29", - "tracking_issue": "hyperpolymath/standards#687" - }, { "severity": "critical", "rule_module": "cicd_rules", diff --git a/.machine_readable/MUST.contractile b/.machine_readable/MUST.contractile index d50d6ab0e..d58f614f2 100644 --- a/.machine_readable/MUST.contractile +++ b/.machine_readable/MUST.contractile @@ -100,10 +100,7 @@ ; --- CI / workflow hardening --- (must "every workflow job declares timeout-minutes, EXCEPT reusable-workflow caller jobs (uses: ./...)") (must "secret-consuming action steps are gated with `if: secrets.X != ''`") - (must "any ossf/scorecard-action publish job contains only `uses:` steps — no `run:` in the publish job") - - ; --- Registry --- - (must "REGISTRY.a2ml is GENERATED — regenerate with scripts/build-registry.sh; never hand-edit")) + (must "any ossf/scorecard-action publish job contains only `uses:` steps — no `run:` in the publish job")) ; === Cross-Repo Musts (owned elsewhere — listed for traceability only) === ; These were established this session but belong in the named repo's own diff --git a/.machine_readable/REGISTRY.a2ml b/.machine_readable/REGISTRY.a2ml deleted file mode 100644 index ae29f59de..000000000 --- a/.machine_readable/REGISTRY.a2ml +++ /dev/null @@ -1,385 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -# SPDX-FileCopyrightText: 2026 Jonathan D.A. Jewell (hyperpolymath) -# -# REGISTRY.a2ml — the verifiable index of every spec/standard in this monorepo. -# -# GENERATED FILE — DO NOT EDIT BY HAND. -# Regenerate with: bash scripts/build-registry.sh (or: just registry) -# Source of truth: the SPECS table in scripts/build-registry.sh + the file tree. -# -# LOCAL entries: `source_hash` is a sha256 over `git ls-files -s `, so it -# changes whenever any tracked file under the spec's home changes. -# EXTERNAL entries (kind = "external"): a verified POINTER to a spec whose SSOT -# lives in another repo. `source_hash` is RECORDED (sentinel PENDING-FIRST-SYNC -# until upstream lands), not computed locally — the offline generator emits it -# verbatim. Hypatia rule HYP-S006 (hypatia-rules/registry-staleness.a2ml) -# recomputes LOCAL hashes and re-fetches EXTERNAL canonical_urls, emitting a -# `doc.drift` finding (strategy :review) when a recorded hash goes stale. - -[registry] -version = "1.0.0" -generator = "scripts/build-registry.sh" -hash_algorithm = "sha256(git ls-files -s ) # local; external: recorded pin" -entry_count = 34 - -[registry.streams] -foundation = "A2ML format family + K9 + contractiles (Stream 1)" -language = "AffineScript and language-policy specs (Stream 2)" -protocol = "Inter-service / agent protocols" -governance = "RSR, readiness grading, pre-flight gates, session standards" -readiness = "ARG / FRG / CRG / TRG maturity-grading frameworks" -integration = "Registry, hypatia rules, templates — the wiring (Stream 3)" - -[[spec]] -id = "estate-constitution" -name = "Hyperpolymath Estate Constitution" -stream = "governance" -home = "0-canon/constitution/" -canonical_doc = "0-canon/constitution/README.adoc" -source_hash = "sha256:be48496f7f786d9aca12271afeb063c10b8ea6ce6bec2efad4f2401d0186ccef" -route = "the highest estate-level rules, authority precedence, assurance, contribution, exceptions, and known tensions" - -[[spec]] -id = "k9-svc" -name = "K9 Self-Validating Components" -stream = "foundation" -home = "1-formats/k9/" -canonical_doc = "1-formats/k9/README.adoc" -source_hash = "sha256:dbf336e383f49c098a9cc7a3126fe817b824f41c054a7d2977ff47150db59281" -route = "the K9 specification, security analysis and adoption guidance (implementations live in hyperpolymath/k9-ecosystem)" - -[[spec]] -id = "contractiles" -name = "Contractiles (Must/Trust/Dust/Intend)" -stream = "foundation" -home = "1-formats/contractiles/" -canonical_doc = "1-formats/contractiles/README.adoc" -source_hash = "sha256:d82e0007277aeea794555bd2f0d2b83e8235def2771ff0d9c8dc23f9fdfc300e" -route = "policy-enforcement primitives the K9 layer is built from" - -[[spec]] -id = "meta-a2ml" -name = "META.a2ml spec" -stream = "foundation" -home = "1-formats/a2ml/meta/" -canonical_doc = "1-formats/a2ml/meta/README.adoc" -source_hash = "sha256:16ff64a7aeca0f213fa4e98dbe9e43e579259c93b8ab98a60e228c49aaab31e2" -route = "architecture decisions / governance metadata format" - -[[spec]] -id = "state-a2ml" -name = "STATE.a2ml spec" -stream = "foundation" -home = "1-formats/a2ml/state/" -canonical_doc = "1-formats/a2ml/state/README.adoc" -source_hash = "sha256:90de2e78ee3875bf7ca9b1e239a4bfd56b465ce5f07b3ca691d720704a8eb4ee" -route = "project-state metadata format (drives this registry's topology)" - -[[spec]] -id = "ecosystem-a2ml" -name = "ECOSYSTEM.a2ml spec" -stream = "foundation" -home = "1-formats/a2ml/ecosystem/" -canonical_doc = "1-formats/a2ml/ecosystem/README.adoc" -source_hash = "sha256:599daba5759987a132568e27eabe7596d4b6f29baa2a33556198e21c47ffbc1f" -route = "ecosystem-positioning metadata format" - -[[spec]] -id = "agentic-a2ml" -name = "AGENTIC.a2ml spec" -stream = "foundation" -home = "1-formats/a2ml/agentic/" -canonical_doc = "1-formats/a2ml/agentic/README.adoc" -source_hash = "sha256:f118e927f79664c0c79e249e2538a52563f9d63b828eba65611c379d37253175" -route = "AI-agent operational gating / entropy budgets" - -[[spec]] -id = "neurosym-a2ml" -name = "NEUROSYM.a2ml spec" -stream = "foundation" -home = "1-formats/a2ml/neurosym/" -canonical_doc = "1-formats/a2ml/neurosym/README.adoc" -source_hash = "sha256:9bfe5e975ccb49ee2a78c8baf6c3bbe962756f2946f0795af2cab7b76a51c5a9" -route = "symbolic semantics / proof obligations" - -[[spec]] -id = "playbook-a2ml" -name = "PLAYBOOK.a2ml spec" -stream = "foundation" -home = "1-formats/a2ml/playbook/" -canonical_doc = "1-formats/a2ml/playbook/README.adoc" -source_hash = "sha256:13956749d0074922bdcc7e7fc4ba3708a6cf24052612be6408533741a0b4215e" -route = "executable operational runbooks" - -[[spec]] -id = "anchor-a2ml" -name = "ANCHOR.a2ml spec" -stream = "foundation" -home = "1-formats/a2ml/anchor/" -canonical_doc = "1-formats/a2ml/anchor/README.adoc" -source_hash = "sha256:52b6aaa64eb11858abff115f21268f97bb862a9b169a171504c08b0170684e46" -route = "project-recalibration intervention format" - -[[spec]] -id = "0-ai-gatekeeper-protocol" -name = "0-AI Gatekeeper Protocol" -stream = "protocol" -home = "2-protocols/0-ai-gatekeeper/" -canonical_doc = "2-protocols/0-ai-gatekeeper/README.adoc" -source_hash = "sha256:09632266a1822b2583b3b96f831a540d41e3827cb93f5acb213585f90d8275e8" -route = "the AI-agent entry/gating protocol behind 0-AI-MANIFEST" - -[[spec]] -id = "k9-coordination-protocol" -name = "K9 Coordination Protocol" -stream = "protocol" -home = "2-protocols/k9-coordination/" -canonical_doc = "2-protocols/k9-coordination/README.adoc" -source_hash = "sha256:7481a72434e1961c002f6e6a69955034cb219cf5357756d59a15a5d4595b2905" -route = "multi-agent coordination on top of K9" - -[[spec]] -id = "avow-protocol" -name = "AVOW Protocol" -stream = "protocol" -home = "2-protocols/avow/" -canonical_doc = "2-protocols/avow/BINDING.adoc" -source_hash = "sha256:41c7f3653ab96f56f72a02c9c3a99e34007915912f03ff3f5e0eced689382045" -route = "consent-attested messaging / origin attribution" - -[[spec]] -id = "axel-protocol" -name = "AXEL Protocol" -stream = "protocol" -home = "2-protocols/axel/" -canonical_doc = "2-protocols/axel/README.adoc" -source_hash = "sha256:960ac958d74d0ec8b18afcf6cc7f336491fab6becce87ce25a62e2f804f660a6" -route = "age-gating + explicit-content enforcement" - -[[spec]] -id = "overlay-protocol" -name = "Overlay Protocol" -stream = "protocol" -home = "2-protocols/overlay/" -canonical_doc = "2-protocols/overlay/.machine_readable/descriptiles/ECOSYSTEM.a2ml" -source_hash = "sha256:ca720852bf060e6879c04b547af262874a0f1cbeedf4cfeeeb48b8e1b16f252e" -route = "layered overlay composition spec" - -[[spec]] -id = "adoption-readiness-grades" -name = "ARG — Adoption Readiness Grades" -stream = "readiness" -home = "adoption-readiness-grades/" -canonical_doc = "adoption-readiness-grades/README.adoc" -source_hash = "sha256:2550506e1c8836a1a7045b91196b92a8b28e222fdedab6003c2f34b2e3eec695" -route = "per-language adoption-maturity profile templates" - -[[spec]] -id = "foundations-readiness-grades" -name = "FRG — Foundations Readiness Grades" -stream = "readiness" -home = "foundations-readiness-grades/" -canonical_doc = "foundations-readiness-grades/README.adoc" -source_hash = "sha256:e8cd80df1620ee6cb95a68758c7c51a6406ebbd46cb60e4c8e83cc5d771fa83e" -route = "per-language foundational-maturity profile templates" - -[[spec]] -id = "component-readiness-grades" -name = "CRG — Component Readiness Grades" -stream = "readiness" -home = "component-readiness-grades/" -canonical_doc = "component-readiness-grades/README.adoc" -source_hash = "sha256:fd47af106dddd99a9424e1ecbe5888e6e707cc46e0ddd88ea8228785b4e19ebe" -route = "the X..A grading system for components" - -[[spec]] -id = "toolchain-readiness-grades" -name = "TRG — Toolchain Readiness Grades" -stream = "readiness" -home = "toolchain-readiness-grades/" -canonical_doc = "toolchain-readiness-grades/README.adoc" -source_hash = "sha256:c3d9161a193c3a588559ecf990555bf0c79a72f6fccff6143c5ec2a25f3fb2e9" -route = "per-toolchain readiness profile templates" - -[[spec]] -id = "rhodium-standard-repositories" -name = "RSR — Rhodium Standard Repositories" -stream = "governance" -home = "rhodium-standard-repositories/" -canonical_doc = "rhodium-standard-repositories/README.adoc" -source_hash = "sha256:3573484240d781ed5817364004b28a3a4da78946cf457069a3c857b540a1c394" -route = "the repository-compliance standard every repo is graded against" - -[[spec]] -id = "session-management-standards" -name = "Session Management Standards" -stream = "governance" -home = "3-practice/session-management-standards/" -canonical_doc = "3-practice/session-management-standards/README.adoc" -source_hash = "sha256:19cf6a748c8698a1664097b90af098d85b6e06542fd0ed7b4c4df348d473fc09" -route = "continuity / verify / handover protocols" - -[[spec]] -id = "did-you-actually-do-that" -name = "DYADT — Did-You-Actually-Do-That" -stream = "governance" -home = "1-formats/sub-specs/did-you-actually-do-that/" -canonical_doc = "1-formats/sub-specs/did-you-actually-do-that/README.adoc" -source_hash = "sha256:66930b4a3aec27a03a2e62bee3263f602ebadda9e0185043d133a59bce08c45d" -route = "post-action agent-claim verification (Tier 4 accountability)" - -[[spec]] -id = "ensaid-config" -name = "ENSAID Config" -stream = "governance" -home = "1-formats/sub-specs/ensaid-config/" -canonical_doc = "1-formats/sub-specs/ensaid-config/README.adoc" -source_hash = "sha256:9941b04a8a96dd1414c28c9dc9ba50fe4178aa6feb057675ea8a6d5615d85131" -route = "the ensaid configuration standard" - -[[spec]] -id = "accessibility" -name = "Accessibility Standard" -stream = "governance" -home = "3-practice/accessibility/" -canonical_doc = "3-practice/accessibility/STANDARD.a2ml" -source_hash = "sha256:849090c4b436106e300e3ad4c77e74cdc0d2ac3ea51c111a3bce8288bca84eed" -route = "estate accessibility requirements" - -[[spec]] -id = "publication-pre-flight" -name = "Publication Pre-Flight" -stream = "governance" -home = "3-practice/publication-pre-flight/" -canonical_doc = "3-practice/publication-pre-flight/HOL-SUITABILITY-CHECKLIST.adoc" -source_hash = "sha256:05abe62e69eb2dd6eb85a4f362d90d8e178bd7adbef1b3617e01b4c792ccdb3c" -route = "submission gate (HOL + Zenodo checklists)" - -[[spec]] -id = "release-pre-flight" -name = "Release Pre-Flight (V1 Gate)" -stream = "governance" -home = "3-practice/release-pre-flight/" -canonical_doc = "3-practice/release-pre-flight/V1-GATE.adoc" -source_hash = "sha256:5ddef2b20cb2c6fccfb2174893db316e7cb3b8f94f12e0e48294c76c6d6417aa" -route = "hard v1.0.0 audit requirements" - -[[spec]] -id = "hypatia-rules" -name = "Standards Hypatia Rules" -stream = "integration" -home = "hypatia-rules/" -canonical_doc = "hypatia-rules/README.adoc" -source_hash = "sha256:60a367489822dda378a6f0049add96a52f511777e08868c31f9b6a062134264d" -route = "the dogfooding rules that scan THIS repo (incl. drift detection)" - -[[spec]] -id = "a2ml-templates" -name = "A2ML Templates" -stream = "integration" -home = "1-formats/templates/" -canonical_doc = "1-formats/templates/STATE.a2ml.v2.spec.adoc" -source_hash = "sha256:5dbe5d5bef5e084631af8523ba210980b8a21e3969f382b6f0a52ca791609a6a" -route = "copy-in templates for the 7 A2ML files" - -[[spec]] -id = "form-fill-provenance" -name = "FFP — Form-Fill Provenance" -stream = "foundation" -home = "1-formats/sub-specs/form-fill-provenance/" -canonical_doc = "1-formats/sub-specs/form-fill-provenance/README.adoc" -source_hash = "sha256:d6e979cdf67dc045e0cf7fefc77e72fa1f2bc4424dd142f68e2f772875449124" -route = "whether a PDF form was machine-filled or printed blank for hand completion, and what a print path must record" - -[[spec]] -id = "affine-spec" -name = "AffineScript .affine (faces / source documents)" -stream = "language" -kind = "external" -spec_kind = "language-coupled" -owning_repo = "hyperpolymath/affinescript" -canonical_url = "https://github.com/hyperpolymath/affinescript/blob/main/spec/affine.adoc" -version_pin = "v2.0.0" -source_hash = "PENDING-FIRST-SYNC" -source_hash_algo = "sha256" -conformance_level = "draft" -last_synced = "never" -sync_status = "awaiting-upstream" -media_type = "application/vnd.affinescript.affine" -lineage = "affinescript:affine@2" -route = "faces, canonical-lowering invariant, canonical islands, idiom packs, mimicry bindings, project face policy" - -[[spec]] -id = "affex-manifest" -name = "AffineScript .affex (face-interop manifest)" -stream = "language" -kind = "external" -spec_kind = "language-coupled" -owning_repo = "hyperpolymath/affinescript" -canonical_url = "https://github.com/hyperpolymath/affinescript/blob/main/spec/affex.adoc" -version_pin = "v2.0.0" -source_hash = "PENDING-FIRST-SYNC" -source_hash_algo = "sha256" -conformance_level = "draft" -last_synced = "never" -sync_status = "awaiting-upstream" -media_type = "application/vnd.affinescript.affex" -lineage = "affinescript:affex@2" -route = "derived regenerable manifest; declaration heads not full bodies; format_version bumps independently" -format_version = "2" # tracked independently of version_pin - -[[spec]] -id = "affmap-provenance" -name = "AffineScript .affmap (provenance)" -stream = "language" -kind = "external" -spec_kind = "language-coupled" -owning_repo = "hyperpolymath/affinescript" -canonical_url = "https://github.com/hyperpolymath/affinescript/blob/main/spec/affmap.adoc" -version_pin = "v2.0.0" -source_hash = "PENDING-FIRST-SYNC" -source_hash_algo = "sha256" -conformance_level = "draft" -last_synced = "never" -sync_status = "awaiting-upstream" -media_type = "application/vnd.affinescript.affmap" -lineage = "affinescript:affmap@2" -route = "provenance format; own pointer for independent staleness tracking" - -[[spec]] -id = "a2ml" -name = "A2ML — Attested Markup Language" -stream = "foundation" -kind = "external" -spec_kind = "format-coupled" -owning_repo = "hyperpolymath/a2ml" -canonical_url = "https://github.com/hyperpolymath/a2ml/blob/main/README.adoc" -version_pin = "v1.0.0" -source_hash = "PENDING-FIRST-SYNC" -source_hash_algo = "sha256" -conformance_level = "draft" -last_synced = "never" -sync_status = "awaiting-upstream" -media_type = "application/vnd.a2ml" -lineage = "a2ml:a2ml@1" -route = "the typed/verified machine-readable document format; evicted from standards 2026-08-28 per #490" - -[[spec]] -id = "consent-aware-web" -name = "Consent-Aware Web (AIBDP + HTTP 430)" -stream = "protocol" -kind = "external" -spec_kind = "service-coupled" -owning_repo = "metadatastician/consent-aware-web" -canonical_url = "https://github.com/metadatastician/consent-aware-web/blob/main/README.adoc" -version_pin = "v0.2.0" -source_hash = "PENDING-FIRST-SYNC" -source_hash_algo = "sha256" -conformance_level = "draft" -last_synced = "never" -sync_status = "awaiting-upstream" -media_type = "application/aibdp+json" -lineage = "ietf:aibdp@0.2" -route = "consent headers / AI-usage boundaries for HTTP; extracted from this repo 2026-08-07" - -### End of REGISTRY.a2ml diff --git a/.machine_readable/contractiles/adjust/Adjustfile.a2ml b/.machine_readable/contractiles/adjust/Adjustfile.a2ml index 41c9177cd..cb2b6bd93 100644 --- a/.machine_readable/contractiles/adjust/Adjustfile.a2ml +++ b/.machine_readable/contractiles/adjust/Adjustfile.a2ml @@ -36,12 +36,6 @@ proposes corrective actions. Advisory — it warns and trends, it does not block - corrective: convert *.md → *.adoc (no duplicate formats) - severity: advisory -### registry-staleness -- description: REGISTRY.a2ml reflects the current spec tree -- tolerance: regenerate when specs are added/moved -- corrective: run `bash scripts/build-registry.sh` (or `just registry`) -- severity: advisory - ## Structural Drift ### contractile-trident-completeness diff --git a/.machine_readable/contractiles/dust/Dustfile.a2ml b/.machine_readable/contractiles/dust/Dustfile.a2ml index 786d9159e..0f6cca3f0 100644 --- a/.machine_readable/contractiles/dust/Dustfile.a2ml +++ b/.machine_readable/contractiles/dust/Dustfile.a2ml @@ -61,8 +61,3 @@ dry-run by default and gated behind --apply. - description: no Deno cache tracked in git - run: test -z "$(git ls-files '**/.deno/**' 2>/dev/null)" - severity: warning - -### registry-not-stale -- description: REGISTRY.a2ml regenerated after spec changes (run: just registry) -- verification: re-run scripts/build-registry.sh and diff; non-empty diff means stale -- severity: info diff --git a/.machine_readable/contractiles/must/Mustfile.a2ml b/.machine_readable/contractiles/must/Mustfile.a2ml index 4d018d81a..342002f0f 100644 --- a/.machine_readable/contractiles/must/Mustfile.a2ml +++ b/.machine_readable/contractiles/must/Mustfile.a2ml @@ -86,11 +86,6 @@ requirements — CI and pre-commit hooks fail if any check fails. - run: test -z "$(ls *.contractile 2>/dev/null)" - severity: warning -### registry-machine-readable -- description: REGISTRY.a2ml lives under .machine_readable/ (generated index) -- run: test -f .machine_readable/REGISTRY.a2ml -- severity: warning - ## CI / Workflow Hardening ### actions-sha-pinned @@ -104,8 +99,3 @@ requirements — CI and pre-commit hooks fail if any check fails. - verification: governance check — reusable-workflow caller jobs (uses: ./...) are exempt - severity: high - notes: Reusable callers cannot carry timeout-minutes; the timeout lives in the reusable. - -### registry-generated-not-hand-edited -- description: REGISTRY.a2ml is regenerated via scripts/build-registry.sh, never hand-edited -- run: test -f scripts/build-registry.sh -- severity: high diff --git a/0-AI-MANIFEST.a2ml b/0-AI-MANIFEST.a2ml index 4aa2156b4..db71a6bbd 100644 --- a/0-AI-MANIFEST.a2ml +++ b/0-AI-MANIFEST.a2ml @@ -14,21 +14,16 @@ RSR compliance, and the enforcement/CI that makes them stick. ## ROUTING — where to go for X (machine index) -The authoritative, verifiable index is **`.machine_readable/REGISTRY.a2ml`**: -one `[[spec]]` block per standard, each with its `home`, `canonical_doc`, and a -content-addressed `source_hash`. Prose explanation: `REGISTRY.adoc`. - | If you want… | Go to | |---|---| -| Every spec + home + source hash | `.machine_readable/REGISTRY.a2ml` | | A2ML / K9 foundation (Stream 1) | `a2ml/`, `1-formats/k9/`, `1-formats/contractiles/`, `*-a2ml/` | | Language policy (Stream 2) | `.claude/CLAUDE.md` | -| Protocols | `*-protocol/` (registry stream `protocol`) | +| Protocols | `*-protocol/` | | Readiness grades | `adoption-readiness-grades/`, `foundations-readiness-grades/`, `component-readiness-grades/`, `toolchain-readiness-grades/` | | Multi-repository task scope | `docs/MULTI-REPOSITORY-SCOPE-STANDARD.adoc`; illustrative declaration: `docs/repo-scope.example.toml` | | Enforcement / CI | `.github/workflows/`, `hooks/` | -| Drift / staleness automation | `REGISTRY.adoc`, `hypatia-rules/` (HYP-S006); reusable-pin freshness: `docs/decisions/ADR-003-workflow-pin-staleness-window.adoc`, `scripts/check-workflow-staleness.sh`, `scripts/propagate-workflow-pins.sh` | -| Derived architecture map | `TOPOLOGY.adoc` (generated — do not edit) | +| Drift / staleness automation | `hypatia-rules/`; reusable-pin freshness: `docs/decisions/ADR-003-workflow-pin-staleness-window.adoc`, `scripts/check-workflow-staleness.sh`, `scripts/propagate-workflow-pins.sh` | +| Derived architecture map | `TOPOLOGY.adoc` (do not edit) | | Current project state | `.machine_readable/descriptiles/STATE.a2ml` | | Education layer (deep docs, by audience) | `docs/wikis/` (Users / Developers / Maintainers); machine mirror `docs/wikis/0.2-AI-MANIFEST.a2ml` | @@ -49,51 +44,28 @@ absorbed-satellite layout), never in the repo root: **CRITICAL:** if any of these appear in the repo root, that is an ERROR. -### Generated files — DO NOT EDIT BY HAND - -- `.machine_readable/REGISTRY.a2ml` — regenerate with `just registry` -- `TOPOLOGY.adoc` — regenerated by the same generator (`scripts/build-registry.sh`) - -CI (`registry-verify.yml`) fails the build if either drifts from the file tree. - ## CORE INVARIANTS 1. **No A2ML duplication** — root must NOT contain STATE.a2ml, META.a2ml, etc. 2. **Single source of truth** — `.machine_readable/descriptiles/` is authoritative for state. -3. **Registry is generated, not authored** — edit the `SPECS` table in - `scripts/build-registry.sh`, then run `just registry`; never hand-edit - `REGISTRY.a2ml` or `TOPOLOGY.adoc`. -4. **Licence is Manual-Only for agents** — every file's licence/SPDX is set by +3. **Licence is Manual-Only for agents** — every file's licence/SPDX is set by the owner. Agents NEVER edit, sweep, or relicense `LICENSE` files or SPDX headers; licence drift is FLAG-ONLY (`:review`). See `LICENSE`, `.machine_readable/licensing-policy.toml`, and `.claude/CLAUDE.md`. -5. **Author attribution** — "Jonathan D.A. Jewell ". +4. **Author attribution** — "Jonathan D.A. Jewell ". ## SESSION STARTUP CHECKLIST - Read THIS file, then `README.adoc`. -- Read `.machine_readable/REGISTRY.a2ml` to locate the spec you need. - Read `.machine_readable/descriptiles/STATE.a2ml` for current status + blockers. - Read `.machine_readable/descriptiles/AGENTIC.a2ml` for interaction patterns. - Read `.claude/CLAUDE.md` for the language + licence policy (binding). -## DRIFT AUTOMATION (how this repo stays honest) - -``` -file tree + STATE.a2ml ──► scripts/build-registry.sh ──► REGISTRY.a2ml ──► TOPOLOGY.adoc - ▲ │ - │ ▼ - just registry / registry-verify.yml HYP-S006 (registry-staleness) - (fails build on drift) emits doc.drift → router (:review-capped on licence) -``` - ## ATTESTATION After reading, state: **"I have read the standards manifest. The human front -door is README.adoc and the machine index is .machine_readable/REGISTRY.a2ml. -A2ML state lives in .machine_readable/descriptiles/ only. REGISTRY.a2ml and TOPOLOGY.adoc -are generated — I will not hand-edit them. Licence/SPDX is Manual-Only — I will -flag, never edit."** +door is README.adoc. A2ML state lives in .machine_readable/descriptiles/ only. +Licence/SPDX is Manual-Only — I will flag, never edit."** ## META diff --git a/0-canon/COMPLIANCE-DASHBOARD.adoc b/0-canon/COMPLIANCE-DASHBOARD.adoc index 5aed164be..3787952ee 100644 --- a/0-canon/COMPLIANCE-DASHBOARD.adoc +++ b/0-canon/COMPLIANCE-DASHBOARD.adoc @@ -1,14 +1,21 @@ // SPDX-License-Identifier: CC-BY-SA-4.0 -// 0-canon/COMPLIANCE-DASHBOARD.adoc — DERIVED from .machine_readable/scorecards/*.scorecard.a2ml -// GENERATED FILE — DO NOT EDIT BY HAND. Run: just scorecards (scripts/build-scorecards.sh) +// 0-canon/COMPLIANCE-DASHBOARD.adoc — FROZEN snapshot. Its generator was retired on 2026-10-09 (see REGISTRY.adoc). -= Standards Compliance Dashboard (derived) += Standards Compliance Dashboard (frozen 2026-10-09) -____ -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. +[IMPORTANT] +==== +*Frozen.* This dashboard was generated from +`+.machine_readable/scorecards/.scorecard.a2ml+` by +`+scripts/build-scorecards.sh+`, one scorecard per local spec in the +registry. The generator and the registry were retired on 2026-10-09 +(link:../REGISTRY.adoc[REGISTRY.adoc]). What follows is their last output, +kept as a snapshot: nothing regenerates it, and editing a scorecard no longer +changes it. The scorecards' own fate is ruling R5 on +https://github.com/hyperpolymath/standards/issues/837[#837]. +==== +____ *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* @@ -62,7 +69,7 @@ ____ * *Estate systems coverage:* 67% of 324 graded requirements have a mechanical check * *Grounded passes:* 70 / 70 (100%) pass rows carry an executable `+check+` run by `+--verify+` -== How this dashboard stays honest +== How this dashboard was kept current (retired 2026-10-09) .... scorecards/*.scorecard.a2ml ──► scripts/build-scorecards.sh ──► 0-canon/COMPLIANCE-DASHBOARD.adoc @@ -79,4 +86,4 @@ scorecards/*.scorecard.a2ml ──► scripts/build-scorecards.sh ──► 0-ca *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+`. +* Until 2026-10-09, `+just scorecards+` regenerated this dashboard after a scorecard edit. The generator is retired; see link:../REGISTRY.adoc[REGISTRY.adoc]. diff --git a/1-formats/SATELLITES.a2ml b/1-formats/SATELLITES.a2ml index e025780cd..43d2b47f8 100644 --- a/1-formats/SATELLITES.a2ml +++ b/1-formats/SATELLITES.a2ml @@ -3,8 +3,6 @@ # DEPRECATED - Retired per Issue #495 / #479 -This file has been retired. Satellite registry information is now maintained in the -generated REGISTRY.a2ml (from scripts/build-registry.sh) which provides hash-verified -pointers. See .machine_readable/REGISTRY.a2ml for the authoritative source. +This file has been retired. This file is kept for historical reference only and will be removed in a future cleanup. diff --git a/1-formats/sub-specs/form-fill-provenance/README.adoc b/1-formats/sub-specs/form-fill-provenance/README.adoc index 4f8379d26..451c9ac28 100644 --- a/1-formats/sub-specs/form-fill-provenance/README.adoc +++ b/1-formats/sub-specs/form-fill-provenance/README.adoc @@ -220,8 +220,7 @@ A consumer MUST NOT report a provenance the evidence does not support. content provenance: a print path may *report* that appearances are missing, but it may not silently regenerate them. * link:../../../docs/decisions/[ADR-004] (README discipline) is why this spec - is one README plus normative parts, and why the registry entry is a - `scripts/build-registry.sh` row rather than a hand-kept index. + is one README plus normative parts. == Versioning diff --git a/3-practice/CONTRIBUTING.adoc b/3-practice/CONTRIBUTING.adoc index a60ff4b3c..5b07def83 100644 --- a/3-practice/CONTRIBUTING.adoc +++ b/3-practice/CONTRIBUTING.adoc @@ -92,23 +92,11 @@ Look for issues labelled: just hooks-install .... -This installs `+hooks/pre-commit+`, which catches the most common CI -failure before it leaves your machine: *registry drift*. The spec -registry (`+.machine_readable/REGISTRY.a2ml+`) records a content hash of -every tracked file under a spec home, so _any_ edit under one (including -`+.machine_readable/+` itself) must be followed by: - -[source,sh] ----- -just registry # regenerates REGISTRY.a2ml + TOPOLOGY.adoc -git add .machine_readable/REGISTRY.a2ml TOPOLOGY.adoc ----- - -If you skip this, the required "`Registry + topology in sync`" check -fails — and because it is a required check, stale registry hashes on -`+main+` block _every_ open PR, not just yours (see #381). The hook -fails the commit with the exact fix commands whenever the registry is -stale. +This installs `+hooks/pre-commit+`, which checks your staged files before +the commit leaves your machine. It blocks banned languages and Makefiles, +warns about source files without an SPDX header, and blocks any +reintroduction of the deprecated names listed in +`+0-canon/CANONICAL-NAMES.adoc+`. === Branch Naming diff --git a/AGENTS.adoc b/AGENTS.adoc index 5c53f141d..6b5ba6115 100644 --- a/AGENTS.adoc +++ b/AGENTS.adoc @@ -1,9 +1,9 @@ == Repository instructions This repository is the canonical general standards authority for the -Hyperpolymath estate. Read `+0-AI-MANIFEST.a2ml+`, `+README.adoc+`, -`+0-canon/constitution/README.adoc+`, and `+.machine_readable/REGISTRY.a2ml+` in -that order before changing normative material. +Hyperpolymath estate. Read `+0-AI-MANIFEST.a2ml+`, `+README.adoc+`, and +`+0-canon/constitution/README.adoc+` in that order before changing +normative material. Constitutional, normative, profile, local-policy, guidance, template, implementation, generated, and historical material are distinct @@ -13,14 +13,11 @@ currently holds; it does not gain authority merely by being generated or machine-readable. Canonical sources include `+0-canon/constitution/+`, domain standard sources, -profile sources, and the registry source consumed by -`+scripts/build-registry.sh+`. `+.machine_readable/REGISTRY.a2ml+` and -`+TOPOLOGY.adoc+` are generated: never edit them directly. Preserve -licences, coined names, MAA’s independent authority, and current -language/build conventions. Do not add TypeScript or Deno, weaken -validation, or describe draft/tested work as proven. +and profile sources. `+TOPOLOGY.adoc+` is a frozen snapshot: never edit it +directly. Preserve licences, coined names, MAA’s independent authority, +and current language/build conventions. Do not add TypeScript or Deno, +weaken validation, or describe draft/tested work as proven. -Run the relevant `+just+`/`+must+` targets, registry and topology -generators/checks, A2ML/Nickel/K9 validation where applicable, -link/canonical-name checks, and `+git diff --check+`. Regenerate twice -and require a clean second pass for generated outputs. +Run the relevant `+just+`/`+must+` targets, A2ML/Nickel/K9 validation +where applicable, link/canonical-name checks, and `+git diff --check+`. +Regenerate twice and require a clean second pass for generated outputs. diff --git a/CICD-WORKFLOW-CATALOG.md b/CICD-WORKFLOW-CATALOG.md index bba000288..e112f67f1 100644 --- a/CICD-WORKFLOW-CATALOG.md +++ b/CICD-WORKFLOW-CATALOG.md @@ -176,7 +176,7 @@ git config core.hooksPath .githooks | Hook | Trigger | Description | Blocking? | |------|---------|-------------|-----------| -| `pre-commit` | Before commit | Language policy, SPDX headers, K9 validation, workflow validation, registry drift, canonical names, bot directives (the A2ML manifests gate was removed 2026-09-15, owner ruling R-H3: A2ML is retired — DEED is the grammar; a grammar-faithful .deed validator returns per R-H2) | Yes | +| `pre-commit` | Before commit | Language policy, SPDX headers, K9 validation, workflow validation, canonical names, bot directives (the A2ML manifests gate was removed 2026-09-15, owner ruling R-H3: A2ML is retired — DEED is the grammar; a grammar-faithful .deed validator returns per R-H2) | Yes | | `pre-push` | Before push | Local Dogfood Gate (full validation: K9, SPDX, workflows, secrets scan — A2ML gate removed per R-H3) | Yes | | `commit-msg` | Before commit message saved | Conventional commits format, issue references, subject length, body presence | Yes | | `post-merge` | After merge/pull | Auto-deployment, submodule init, environment reminders (virtualenv, node_modules, Cargo.lock) | No | diff --git a/EXPLAINME.adoc b/EXPLAINME.adoc index 5dd57009d..7825a7a81 100644 --- a/EXPLAINME.adoc +++ b/EXPLAINME.adoc @@ -9,13 +9,13 @@ * *Humans* → link:README.adoc[README.adoc] (overview + "if you want X, go here" routing) * *Agents* → link:0-AI-MANIFEST.a2ml[0-AI-MANIFEST.a2ml] (machine routing) -* *The spec index* → link:.machine_readable/REGISTRY.a2ml[REGISTRY.a2ml] (every spec + home + source hash) · prose in link:REGISTRY.adoc[REGISTRY.adoc] This file used to carry its own hand-maintained spec inventory, which drifted (it listed ReScript as a primary language — banned 2026-04-30 in favour of AffineScript — and referenced `2-protocols/groove/` and `palimpsest-license/` as -local directories that do not exist in this monorepo). That inventory now lives -in the generated, CI-verified registry instead, so it can no longer go stale. +local directories that do not exist in this monorepo). That inventory then moved +into a generated registry, which was itself retired on 2026-10-09; see +link:REGISTRY.adoc[REGISTRY.adoc]. ==== == What this repo is @@ -25,10 +25,6 @@ self-validating components, the protocols, the readiness-grading frameworks (ARG/FRG/CRG/TRG), RSR compliance, and the enforcement/CI that makes them stick. Former satellite repos were absorbed as subdirectories on 2026-02-08. -For the full, verifiable list of specs and where each one lives, read -link:.machine_readable/REGISTRY.a2ml[REGISTRY.a2ml] (or the human prose in -link:REGISTRY.adoc[REGISTRY.adoc]). - == Architecture decisions (the durable ones) [cols="1,3", options="header"] @@ -59,7 +55,7 @@ link:REGISTRY.adoc[REGISTRY.adoc]). == How to use this repo . *New project?* See link:1-formats/A2ML-REPO-TEMPLATE.adoc[1-formats/A2ML-REPO-TEMPLATE.adoc] and the *Usage* section of link:README.adoc[README.adoc]. -. *Looking for a specific spec?* link:.machine_readable/REGISTRY.a2ml[REGISTRY.a2ml]. +. *Looking for a specific spec?* Start from the routing table in link:README.adoc[README.adoc]. . *Language question?* link:.claude/CLAUDE.md[.claude/CLAUDE.md]. . *CI / enforcement?* link:.github/workflows/[.github/workflows/] + link:hooks/[hooks/]. . *Build / test?* `just build`, `just test` (see link:Justfile[Justfile]). diff --git a/Justfile b/Justfile index 2dffd72b5..147529df4 100644 --- a/Justfile +++ b/Justfile @@ -10,17 +10,6 @@ default: @just --list -# Regenerate the verifiable spec registry + DERIVED topology from the file tree -registry: - @bash scripts/build-registry.sh - -# Alias: same generator also (re)writes TOPOLOGY.adoc -topology: registry - -# Fail if REGISTRY.a2ml or TOPOLOGY.adoc has drifted from the file tree -registry-check: - @bash scripts/build-registry.sh --check - # Run the workflow-staleness gate against a repo (default: this one) staleness-check path=".": @bash scripts/check-workflow-staleness.sh "{{path}}" @@ -103,23 +92,6 @@ debt-ratchet-down path=".machine_readable/Debtfile.a2ml": hooks-install: @bash hooks/install.sh -# Regenerate the compliance dashboard from the per-spec scorecards -scorecards: - @bash scripts/build-scorecards.sh - -# Fail if 0-canon/COMPLIANCE-DASHBOARD.adoc has drifted from the scorecards -scorecards-check: - @bash scripts/build-scorecards.sh --check - -# Strict: also fail if any registered local spec lacks a scorecard -scorecards-check-strict: - @bash scripts/build-scorecards.sh --check --strict - -# Ground-truth the dashboard: RUN every pass-row's executable `check` -# (a claimed pass whose check fails is a hard error — DYADT on the scorecards) -scorecards-verify: - @bash scripts/build-scorecards.sh --check --strict --verify - # DYADT: verify a CLAIMS.a2ml against primary evidence (default: root CLAIMS.a2ml) verify-claims path="CLAIMS.a2ml": @bash scripts/verify-claims.sh "{{path}}" @@ -145,12 +117,11 @@ language-guides-check: canonical-names-check base="origin/main": @bash scripts/check-canonical-names.sh "{{base}}" -# Aggregate compliance gate: registry drift is the HARD gate (registry-check, -# a hard dep). The RSR self-audit is INFORMATIONAL — a monorepo is not expected -# to score Gold — but a *broken* audit (exit 4 / unexpected) must fail loudly -# rather than pass silently under a blanket `|| true` (Wave-0 false-green fix). -validate: registry-check - @echo "=== validate: registry drift (HARD GATE) — passed as a dependency above ===" +# Aggregate compliance gate. The RSR self-audit is INFORMATIONAL — a monorepo +# is not expected to score Gold — but a *broken* audit (exit 4 / unexpected) +# must fail loudly rather than pass silently under a blanket `|| true` +# (Wave-0 false-green fix). +validate: @echo "=== validate: per-language testing guides (structural, HARD GATE) ===" @bash scripts/check-language-guide.sh @echo "=== validate: canonical-names reintroduction guard (vs origin/main) ===" @@ -162,7 +133,6 @@ validate: registry-check # Print role-appropriate LLM warm-up context (machine front door) llm-context role="dev": @echo "# Front door: 0-AI-MANIFEST.a2ml (machine) + README.adoc (human)" - @echo "# Registry: .machine_readable/REGISTRY.a2ml · prose: REGISTRY.adoc" @cat "llm-warmup-{{role}}.md" 2>/dev/null || cat 0-AI-MANIFEST.a2ml # Build all sub-project artefacts diff --git a/QUICKSTART-DEV.adoc b/QUICKSTART-DEV.adoc index 543a76c4e..57202f12f 100644 --- a/QUICKSTART-DEV.adoc +++ b/QUICKSTART-DEV.adoc @@ -6,8 +6,8 @@ [NOTE] Working *on* the standards themselves. Canonical entry points: -link:README.adoc[README.adoc] (human), link:0-AI-MANIFEST.a2ml[0-AI-MANIFEST.a2ml] -(agent), link:.machine_readable/REGISTRY.a2ml[REGISTRY.a2ml] (spec index). +link:README.adoc[README.adoc] (human) and +link:0-AI-MANIFEST.a2ml[0-AI-MANIFEST.a2ml] (agent). == Tech Stack @@ -60,28 +60,15 @@ just test # runs every sub-project test suite standards/ ├── README.adoc # Human front door (routing table) ├── 0-AI-MANIFEST.a2ml # Machine front door (agent entry) -├── REGISTRY.adoc # Prose: the registry + drift automation +├── REGISTRY.adoc # Notice: registry machinery retired 2026-10-09 ├── a2ml/ 1-formats/k9/ *-a2ml/ # Foundation specs (Stream 1) ├── *-protocol/ # Protocol specs ├── *-readiness-grades/ # ARG / FRG / CRG / TRG frameworks -├── hypatia-rules/ # Dogfooding rules incl. HYP-S006 (drift) -├── scripts/build-registry.sh # Generator for REGISTRY.a2ml + TOPOLOGY.adoc -├── .machine_readable/ # State (descriptiles/), REGISTRY.a2ml, contractiles +├── hypatia-rules/ # Dogfooding rules +├── .machine_readable/ # State (descriptiles/), contractiles ├── Justfile # Task runner recipes ├── guix.scm # Guix reproducible environment -└── .github/workflows/ # Enforcement + registry-verify CI ----- - -== Registry workflow (important) - -`.machine_readable/REGISTRY.a2ml` and `TOPOLOGY.adoc` are *generated*. To add or -move a spec, edit the `SPECS` table in -link:scripts/build-registry.sh[`scripts/build-registry.sh`], then: - -[source,bash] ----- -just registry # regenerate REGISTRY.a2ml + TOPOLOGY.adoc -just registry-check # what CI enforces — fails on drift +└── .github/workflows/ # Enforcement CI ---- == Key Recipes @@ -111,7 +98,6 @@ Read `.machine_readable/MUST.contractile` before making changes. Key invariants that must never be violated: * A2ML state files live in `.machine_readable/descriptiles/` only — never the repo root. -* `REGISTRY.a2ml` + `TOPOLOGY.adoc` are generated — regenerate, never hand-edit. * No Makefiles (use Justfile); SPDX header on every source file. * Licence/SPDX is Manual-Only for agents — flag drift, never edit it. diff --git a/QUICKSTART-USER.adoc b/QUICKSTART-USER.adoc index e2160fdae..647578450 100644 --- a/QUICKSTART-USER.adoc +++ b/QUICKSTART-USER.adoc @@ -7,8 +7,7 @@ [NOTE] This is a *specs* monorepo, not an application to install and run. "Using" it means *applying* the standards to your own repository. The canonical front door -is link:README.adoc[README.adoc]; the machine index is -link:.machine_readable/REGISTRY.a2ml[REGISTRY.a2ml]. +is link:README.adoc[README.adoc]. == What is standards? @@ -30,19 +29,17 @@ git clone https://github.com/hyperpolymath/standards.git . *Add the 7 A2ML files:* copy from link:1-formats/templates/[`1-formats/templates/`] into your repo's `.machine_readable/`. . *Adopt enforcement:* copy the relevant link:.github/workflows/[workflows] and - link:hooks/[hooks] (language policy, doc-format, Makefile blocker, registry-verify). + link:hooks/[hooks] (language policy, doc-format, Makefile blocker). . *Follow the language + licence policy:* link:.claude/CLAUDE.md[.claude/CLAUDE.md]. == Find a specific spec -Use the registry — it routes you from a spec `id` to its `home` and the one doc -to read first: - -* Machine index: link:.machine_readable/REGISTRY.a2ml[`.machine_readable/REGISTRY.a2ml`] -* Prose + drift automation: link:REGISTRY.adoc[REGISTRY.adoc] +Start from the "if you want X, go here" routing table in +link:README.adoc[README.adoc]. The generated spec registry was retired on +2026-10-09; see link:REGISTRY.adoc[REGISTRY.adoc]. == Get help * *Routing:* the table at the top of link:README.adoc[README.adoc] * *Report a problem:* https://github.com/hyperpolymath/standards/issues -* *Architecture map (derived):* link:TOPOLOGY.adoc[TOPOLOGY.adoc] +* *Architecture map (frozen snapshot):* link:TOPOLOGY.adoc[TOPOLOGY.adoc] diff --git a/README.adoc b/README.adoc index 6a0678d0a..902d65c91 100644 --- a/README.adoc +++ b/README.adoc @@ -23,7 +23,7 @@ routes off them: | You are… | Start at | Then | A **human** | this file (link:README.adoc[README.adoc]) | follow the routing table below -| An **AI agent** | link:0-AI-MANIFEST.a2ml[0-AI-MANIFEST.a2ml] | then link:.machine_readable/REGISTRY.a2ml[REGISTRY.a2ml] for the machine index +| An **AI agent** | link:0-AI-MANIFEST.a2ml[0-AI-MANIFEST.a2ml] | then follow its routing table |=== Every other "what is this repo" doc is now a thin pointer back to these two @@ -39,9 +39,6 @@ Every other "what is this repo" doc is now a thin pointer back to these two | The estate's highest rules, authority precedence, assurance constitution, and tension register | link:0-canon/constitution/[Constitutional district] -| The complete, verifiable index of every spec + its home + source hash -| link:.machine_readable/REGISTRY.a2ml[REGISTRY.a2ml] (machine) · link:REGISTRY.adoc[REGISTRY.adoc] (prose) - | The **A2ML / K9 foundation** (Stream 1) — the 7-format family, K9, contractiles | link:a2ml/[a2ml/], link:1-formats/k9/[1-formats/k9/], link:1-formats/contractiles/[1-formats/contractiles/] and the `*-a2ml/` spec dirs @@ -49,7 +46,7 @@ Every other "what is this repo" doc is now a thin pointer back to these two | link:.claude/CLAUDE.md[.claude/CLAUDE.md] (canonical) + the <> table below | The **protocols** — AVOW, AXEL, Overlay, K9-coordination, Consent-Aware-HTTP, 0-AI-gatekeeper -| the `*-protocol/` dirs (see link:.machine_readable/REGISTRY.a2ml[registry], stream `protocol`) +| the `*-protocol/` dirs | The **readiness grades** — ARG / FRG / CRG / TRG | link:adoption-readiness-grades/[ARG], link:foundations-readiness-grades/[FRG], link:component-readiness-grades/[CRG], link:toolchain-readiness-grades/[TRG] @@ -62,10 +59,10 @@ Every other "what is this repo" doc is now a thin pointer back to these two | link:.github/workflows/[.github/workflows/] + link:hooks/[hooks/] + <> | The **drift / staleness automation** — how this repo keeps itself honest -| link:REGISTRY.adoc[REGISTRY.adoc] + link:hypatia-rules/[hypatia-rules/] (HYP-S006); reusable-workflow pin freshness: link:docs/decisions/ADR-003-workflow-pin-staleness-window.adoc[ADR-003] (`scripts/check-workflow-staleness.sh` gate + `scripts/propagate-workflow-pins.sh` deliberate-bump) +| link:hypatia-rules/[hypatia-rules/]; reusable-workflow pin freshness: link:docs/decisions/ADR-003-workflow-pin-staleness-window.adoc[ADR-003] (`scripts/check-workflow-staleness.sh` gate + `scripts/propagate-workflow-pins.sh` deliberate-bump) -| The **architecture map** (derived, never frozen) -| link:TOPOLOGY.adoc[TOPOLOGY.adoc] (generated from STATE + registry) +| The **architecture map** (frozen snapshot) +| link:TOPOLOGY.adoc[TOPOLOGY.adoc] (frozen 2026-10-09; no longer regenerated) | To **stand up a new repo** to these standards | link:1-formats/A2ML-REPO-TEMPLATE.adoc[1-formats/A2ML-REPO-TEMPLATE.adoc] + <> @@ -74,10 +71,10 @@ Every other "what is this repo" doc is now a thin pointer back to these two | link:docs/wikis/[docs/wikis/] — link:docs/wikis/users/index.adoc[Users] · link:docs/wikis/developers/index.adoc[Developers] · link:docs/wikis/maintainers/index.adoc[Maintainers] |=== -NOTE: link:.machine_readable/REGISTRY.a2ml[REGISTRY.a2ml] and -link:TOPOLOGY.adoc[TOPOLOGY.adoc] are **generated** by -`scripts/build-registry.sh` (`just registry`) and verified in CI by -`registry-verify.yml`. Do not hand-edit them. +NOTE: The registry and scorecards generators and the `registry-verify` +gate were retired on 2026-10-09, because A2ML is retired. +link:TOPOLOGY.adoc[TOPOLOGY.adoc] and the compliance dashboard are now +frozen snapshots. See link:REGISTRY.adoc[REGISTRY.adoc] for details. == Overview @@ -143,8 +140,6 @@ RSR boilerplate (LICENSE, CODE_OF_CONDUCT, CONTRIBUTING, SECURITY, MAINTAINERS) |Standards update tooling and documentation |=== -Satellite registry is still machine-readable in link:1-formats/SATELLITES.a2ml[1-formats/SATELLITES.a2ml]. - For detailed repository structure requirements, see link:1-formats/A2ML-REPO-TEMPLATE.adoc[1-formats/A2ML-REPO-TEMPLATE.adoc]. === A2ML Format Family (7 Formats) @@ -423,7 +418,7 @@ standards/ | +-- docs/ +-- standards-update/ # Standards update tooling | +-- README.adoc -+-- 1-formats/SATELLITES.a2ml # Hub-satellite registry (machine-readable) ++-- 1-formats/SATELLITES.a2ml # Retired satellite registry (history only) +-- 1-formats/A2ML-REPO-TEMPLATE.adoc # Canonical structure for -a2ml repos +-- CODE_OF_CONDUCT.md # Template +-- CONTRIBUTING.md # Template @@ -455,7 +450,7 @@ standards/ **Standards Monorepo (this repository):** -* link:1-formats/SATELLITES.a2ml[1-formats/SATELLITES.a2ml] -- Machine-readable satellite registry +* link:1-formats/SATELLITES.a2ml[1-formats/SATELLITES.a2ml] -- Retired satellite registry (history only) * link:docs/UX-standards/[docs/UX-standards] -- UX standards and E-Grade launcher specification **A2ML Format Family (local subdirectories):** @@ -506,4 +501,4 @@ _Canonical standards for the Hyperpolymath ecosystem._ == Architecture -See link:TOPOLOGY.adoc[TOPOLOGY.adoc] for a visual architecture map and completion dashboard. +See link:TOPOLOGY.adoc[TOPOLOGY.adoc] for a visual architecture map and completion dashboard (a frozen snapshot, no longer regenerated). diff --git a/REGISTRY.adoc b/REGISTRY.adoc index b8e1ee0db..745d5617c 100644 --- a/REGISTRY.adoc +++ b/REGISTRY.adoc @@ -1,150 +1,99 @@ // SPDX-License-Identifier: CC-BY-SA-4.0 -= The Standards Registry — Verifiable Spec Index + Drift Automation -:toc: macro += The Standards Registry — Retired 2026-10-09 :icons: font -toc::[] +[IMPORTANT] +==== +The verifiable spec registry, the generators that wrote it and the gates that +checked it were *retired on 2026-10-09*. Nothing in this repository +generates, reads or checks a registry any more. This page stays at this path +so that existing links still resolve. +==== -This document explains the *verifiable registry* that indexes every spec in -this monorepo, and how it is wired into the live automation so that -documentation drift becomes a *detected, routed finding* instead of -something noticed sixty days later. +== Why it was retired -The registry is the machine half of the *front door*. If you are arriving -here: +The registry was a generated A2ML file, and A2ML is retired (owner rulings +D99, D269c, D312 and D313). Descriptive metadata now lives in deed clauses +(grammar: link:1-formats/deed/spec/abnf/deed.abnf[`deed.abnf`]), k9 contracts +and the k9 coordination protocol (grammar: +link:2-protocols/k9-coordination/spec/abnf/coordination-k9-grammar_v1.1.abnf[`coordination-k9-grammar_v1.1.abnf`]). +A generator that kept writing A2ML, and a required check that failed whenever +that output drifted, kept a retired format alive. They went together. -* *Human?* Start at link:README.adoc[README.adoc]. -* *Agent?* Start at link:0-AI-MANIFEST.a2ml[0-AI-MANIFEST.a2ml]. -* *Want the raw index?* Read link:.machine_readable/REGISTRY.a2ml[`.machine_readable/REGISTRY.a2ml`]. +== What was retired -== What the registry is - -link:.machine_readable/REGISTRY.a2ml[`.machine_readable/REGISTRY.a2ml`] is a -generated A2ML file with one `[[spec]]` block per standard. Each block records: - -[cols="1,3", options="header"] -|=== -| Field | Meaning - -| `id` | Stable short identifier. -| `name` | Human-readable name. -| `stream` | One of `foundation`, `language`, `protocol`, `governance`, `readiness`, `integration`. -| `home` | The canonical directory the spec lives in (verified to exist). -| `canonical_doc` | The single doc to read first for that spec. -| `source_hash` | `sha256` over `git ls-files -s ` — a content-addressed fingerprint of the whole home. -| `route` | One-line "go here if you want X". -|=== - -The registry is *honest by construction*: the generator only emits a spec -whose `home` directory actually exists, and reports a missing home to stderr -rather than inventing one. - -=== External pointers (specs whose SSOT lives in another repo) - -Some specs are *language/service-coupled*: their source-of-truth deliberately -lives in another repo whose release cadence this monorepo must not own. The -clearest example is the AffineScript v2 standards — `.affine` (faces / source -documents), `.affex` (face-interop manifest) and `.affmap` (provenance) — whose -SSOT is `hyperpolymath/affinescript`. For these the registry holds a *verified -pointer, never a copy*; duplicating the normative text would create two sources -of truth and guarantee drift. - -External entries carry `kind = "external"` and, in place of a local `home`: - -[cols="1,3", options="header"] -|=== -| Field | Meaning - -| `spec_kind` | `language-coupled` or `service-coupled`. -| `owning_repo` | The repo that authors + versions the spec. -| `canonical_url` | The upstream source-of-truth document (what HYP-S006 fetches). -| `version_pin` | The upstream version/tag this pointer is pinned to. -| `source_hash` | The *recorded* upstream hash, or the sentinel `PENDING-FIRST-SYNC` until upstream lands. NEVER fabricated; NEVER fetched at generation time. -| `source_hash_algo` | `sha256` (md5/sha1 are rejected as unverified). -| `media_type` / `lineage` | Provenance fields, consistent with the lineage convention. -| `format_version` | Only for regenerable artefacts (e.g. `.affex`) whose format version is tracked *independently* of `version_pin`. -|=== - -Because the generator is offline and deterministic, an external entry's -`source_hash` is *recorded* in the `EXTERNAL_SPECS` table in the generator and -emitted verbatim, so `--check` stays a pure function of the committed tree. The -network-side verification (re-fetching `canonical_url`) is HYP-S006's job, and -re-pinning a pointer is capped to `:review` — an owner decision, never an -auto-regen. (`.affcite.a2ml` is a CodeCite-profile A2ML artefact in the -AffineScript repo, not a separate registry pointer.) - -== How `source_hash` works (and why it catches drift) - -`git ls-files -s ` lists every tracked file under a home together with -its blob SHA and path. Hashing that listing yields a fingerprint that changes -whenever *any* tracked file under the spec changes — content, addition, or -removal. Recording it in the registry means a later recompute can prove -whether a spec has moved underneath its documentation. (For external pointers, -the recorded hash is instead checked against a fresh fetch of `canonical_url`.) - -== Regenerating (the generator) - -The registry and the *derived* topology map are produced by one generator: - -[source,bash] ----- -just registry # writes .machine_readable/REGISTRY.a2ml + TOPOLOGY.adoc -just registry-check # verify-only; non-zero exit on drift ----- - -Both `.machine_readable/REGISTRY.a2ml` and link:TOPOLOGY.adoc[TOPOLOGY.adoc] are -*generated files — do not edit by hand*. The single source of truth is the -`SPECS` table in link:scripts/build-registry.sh[`scripts/build-registry.sh`]. -Add a spec there and the hash, the registry entry, and the topology row all -follow automatically. link:TOPOLOGY.adoc[TOPOLOGY.adoc] can therefore never -freeze the way the old hand-maintained version did (it sat at `2026-04-04` -claiming 80% while the integration layer read 0%). - -== The drift-detection loop - -Drift is caught at two layers that share the same hash algorithm: - -[cols="1,3", options="header"] +[cols="2,3", options="header"] |=== -| Layer | What it does - -| *In-repo* — link:.github/workflows/registry-verify.yml[`registry-verify.yml`] -| Runs `build-registry.sh --check` on every push/PR and *fails the build* if the registry or topology is stale. - -| *Estate* — link:hypatia-rules/registry-staleness.a2ml[HYP-S006 `registry-staleness`] -| Hypatia recomputes the hashes fleet-wide and emits a `doc.drift` Groove signal when a recorded hash is stale or a derived doc was hand-edited. +| Retired | What it did + +| `.machine_readable/REGISTRY.a2ml` +| The generated spec index: one `[[spec]]` block per standard (id, stream, + home, canonical doc, `source_hash`, route), plus pointers to specs whose + source of truth lives in another repo. + +| `scripts/build-registry.sh` and its test +| Wrote the registry and `TOPOLOGY.adoc`. `--check` failed on drift. + +| `.github/workflows/registry-verify.yml` +| The "Registry + topology in sync" check. It also ran the Mustfile PR gate, + which the required "K9-SVC contractile validation" check + (`k9-contractile.yml`) still runs with the same two commands, and + `build-scorecards.sh --check --strict --verify`, which nothing runs now + (see below). + +| `scripts/build-scorecards.sh` and its test +| Wrote `0-canon/COMPLIANCE-DASHBOARD.adoc` from the per-spec scorecards. + `--verify` executed every scorecard pass row's `check`, so a claimed pass + that no longer held failed CI. That execution is retired with the + generator; the scorecards are frozen data until ruling R5 settles them. + +| `hypatia-rules/registry-staleness.a2ml` +| Hypatia rule HYP-S006: registry staleness, and re-fetching external pointers. + +| `hypatia-rules/implementation-inside-canon.a2ml`, + `scripts/check-implementation-inside-canon.sh`, and the 16 `HYP-S009` + entries in `.hypatia-baseline.json` +| Hypatia rule HYP-S009: flagged product/build manifests below a local spec + home, as listed in the registry. Without the registry it had no input and + only printed a warning. The carve-out debts it baselined stay tracked in + https://github.com/hyperpolymath/standards/issues/687[#687]. + +| Justfile `registry`, `topology`, `registry-check`, `scorecards*` +| Local entry points. `just validate` no longer depends on `registry-check`. + +| The registry block in `hooks/pre-commit`; the `registry-*` checks in the + Mustfile; the registry clause in `MUST.contractile`; the `registry-staleness` + entries in the Adjustfile and Dustfile +| Local and contractile enforcement of the above. |=== -[source] ----- -file tree + STATE.a2ml ──► scripts/build-registry.sh ──► REGISTRY.a2ml ──► TOPOLOGY.adoc - ▲ │ - │ ▼ - just registry / registry-verify.yml HYP-S006 (registry-staleness) - (fails the build on drift) emits doc.drift → router ----- - -== The hybrid automation router +== Where the old content is -When HYP-S006 fires, the *hybrid automation router* decides what happens to -the finding. Its strategy is declared in the rule's `@router` block: +The last tree that carried the registry is frozen at +https://github.com/hyperpolymath/standards/tree/6d19ce0ebae047027dcfd594c7810bf35c642faa[`6d19ce0e`]: -* *Default:* `auto_execute` — regenerating a derived file from the file tree - is mechanical and safe, so the router may run the `rebuild-registry` recipe. -* *Hard cap:* any drift whose content overlaps a licence/SPDX token - (`SPDX-License-Identifier`, `PMPL`, `MPL-2.0`, `AGPL`, `Palimpsest`, - `licen[cs]e`) is *demoted to `:review`* and never auto-applied. +* https://github.com/hyperpolymath/standards/blob/6d19ce0ebae047027dcfd594c7810bf35c642faa/.machine_readable/REGISTRY.a2ml[the registry itself]; +* https://github.com/hyperpolymath/standards/blob/6d19ce0ebae047027dcfd594c7810bf35c642faa/scripts/build-registry.sh[its generator], + including the `EXTERNAL_SPECS` table of external pointers (owning repo, + canonical URL, version pin); +* https://github.com/hyperpolymath/standards/blob/6d19ce0ebae047027dcfd594c7810bf35c642faa/REGISTRY.adoc[the previous version of this page], + which documents the fields and the drift automation. -This cap mirrors the estate Manual-Only licence guardrail -(link:.claude/CLAUDE.md[`.claude/CLAUDE.md`]) and Hypatia's own -`license_finding_strategy/0`: *agents flag licence drift, the owner edits it* -(the rule that closed neurophone#99). Downstream pipelines MUST honour the -cap. +== What stays, frozen -== Adding or moving a spec +* link:TOPOLOGY.adoc[`TOPOLOGY.adoc`] and + link:0-canon/COMPLIANCE-DASHBOARD.adoc[`0-canon/COMPLIANCE-DASHBOARD.adoc`] + are kept as *frozen snapshots* of their last generation. Nothing + regenerates them. Read them as history, not as current state. +* The per-spec scorecards under `.machine_readable/scorecards/` are not + touched by this retirement. Their fate is ruling R5 on + https://github.com/hyperpolymath/standards/issues/837[#837] (the mapping is + in https://github.com/hyperpolymath/standards/pull/845[#845]). -1. Edit the `SPECS` table in link:scripts/build-registry.sh[`scripts/build-registry.sh`]. -2. Run `just registry`. -3. Commit the regenerated `REGISTRY.a2ml` + `TOPOLOGY.adoc` alongside your change. +== What replaces it -CI will reject the PR if you change a spec's home without regenerating. +Nothing yet: there is no live spec index in this repository today. +link:standards-map.toml[`standards-map.toml`], checked by +`scripts/check-standards-map.sh`, maps every tracked path to its district and +gate, but it is not a spec catalogue. A deeds-era replacement is a separate +decision. diff --git a/TOPOLOGY.adoc b/TOPOLOGY.adoc index ab237c23c..8e42bf1c0 100644 --- a/TOPOLOGY.adoc +++ b/TOPOLOGY.adoc @@ -1,19 +1,22 @@ // 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) +// TOPOLOGY.adoc — FROZEN snapshot. Its generator was retired on 2026-10-09 (see REGISTRY.adoc). -= Hyperpolymath Standards — Topology (derived) += Hyperpolymath Standards — Topology (frozen 2026-10-09) -____ -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. -____ +[IMPORTANT] +==== +*Frozen.* This map was generated from `+.machine_readable/REGISTRY.a2ml+` and +`+STATE.a2ml+` by `+scripts/build-registry.sh+`. The registry and its +generator were retired on 2026-10-09 (link:REGISTRY.adoc[REGISTRY.adoc]). +What follows is their last output, kept as a snapshot: nothing regenerates +it, so it does not follow later changes to the tree. The tree it describes is +https://github.com/hyperpolymath/standards/tree/6d19ce0ebae047027dcfd594c7810bf35c642faa[`6d19ce0e`]. +==== * *Phase:* active | *Maturity:* experimental | *STATE last-updated:* 2026-09-07T00:00:00Z * *Registry entries:* 34 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] +* *Registry:* retired 2026-10-09 — link:REGISTRY.adoc[REGISTRY.adoc] == Specs by stream @@ -93,7 +96,7 @@ ____ | A2ML Templates | link:1-formats/templates/[`+1-formats/templates/+`] | copy-in templates for the 7 A2ML files |=== -== How this map stays honest +== How this map was kept current (retired 2026-10-09) .... file tree + STATE.a2ml ──► scripts/build-registry.sh ──► REGISTRY.a2ml ──► TOPOLOGY.adoc @@ -103,5 +106,5 @@ file tree + STATE.a2ml ──► scripts/build-registry.sh ──► REGISTRY.a2 (registry-verify.yml) emits doc.drift on hash mismatch .... -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. +Until 2026-10-09, `+just registry+` rewrote REGISTRY.a2ml and this file after a spec change, +and CI (`+registry-verify.yml+`) failed the build if either was stale. All of it is retired; see link:REGISTRY.adoc[REGISTRY.adoc]. diff --git a/docs/AUDIT.adoc b/docs/AUDIT.adoc index 49109c60b..3711c7ae0 100644 --- a/docs/AUDIT.adoc +++ b/docs/AUDIT.adoc @@ -36,9 +36,6 @@ conformance have to satisfy, and has it?* them.* Gate A assertion 4. See `canon.lock [canon.lockstep]`. . *Licence and SPDX are manual-only.* No agent edits, sweeps or relicenses `LICENSE` or any SPDX header. Licence drift is FLAG-ONLY (`:review`). -. *Generated files are never hand-edited.* `.machine_readable/REGISTRY.a2ml` - and `TOPOLOGY.adoc` are generated by `scripts/build-registry.sh`; CI - (`registry-verify.yml`) fails on drift. == Gate inventory @@ -59,11 +56,6 @@ The gates that apply to this repository, and where each lives. path is gone also fails. Every `canon_slot` resolves in `canon.lock`. | `scripts/check-standards-map.sh` -| *Registry freshness* -| `.machine_readable/REGISTRY.a2ml` and `TOPOLOGY.adoc` have not drifted from - the file tree. -| `scripts/build-registry.sh --check` (`registry-verify.yml`) - | *Self-conformance* | The canon's declared capabilities match the scaffold it actually carries. | `scripts/check-rsr-profile.sh .` @@ -171,7 +163,6 @@ Before this repository may be tagged `canon-v*`: . `docs/AFFIRMATION.adoc` **signed** by the owner. It is currently unsigned and therefore not citable. . `scripts/run-shell-test-suite.sh` green. -. `scripts/build-registry.sh --check` exits 0. . `standards-map.toml` green and `entry_count` current. == See also diff --git a/docs/BADGE-CRITERIA-SPEC.adoc b/docs/BADGE-CRITERIA-SPEC.adoc index 189f79f72..a95389c4a 100644 --- a/docs/BADGE-CRITERIA-SPEC.adoc +++ b/docs/BADGE-CRITERIA-SPEC.adoc @@ -159,15 +159,18 @@ Therefore: These are the load-bearing content of this spec. Each restates, in badge terms, a rule the estate already enforces somewhere else; the citation -is given so the rule is not a new invention. +is given so the rule is not a new invention. The scorecard generator +`scripts/build-scorecards.sh` was retired on 2026-10-09; citations to it in +this document refer to the file as it stood at +https://github.com/hyperpolymath/standards/tree/6d19ce0ebae047027dcfd594c7810bf35c642faa[commit `6d19ce0e`]. [[H1]] H1 — Evidence or silence:: Every criterion marked `pass` MUST carry a resolvable `evidence` pointer (file path with anchor, CI job name, or issue URL). A `pass` with empty evidence is a defect, not a pass. Source: `scorecard.schema.json` `evidence` — "Empty/absent evidence with -status=pass is a scorecard defect the generator rejects", enforced by -`scripts/build-scorecards.sh` `parse_scorecard()`. +status=pass is a scorecard defect the generator rejects", formerly enforced +by `scripts/build-scorecards.sh` `parse_scorecard()`. [[H2]] H2 — Grounded beats asserted:: A `pass` that carries an executable @@ -299,9 +302,9 @@ Rendering: == Criteria a badge must satisfy Written as MUST / SHOULD / COULD with an executable `check` per row, in -the vocabulary of `scorecard.schema.json`, so that a badge assertion can -be audited by the same generator that audits specs. `` is the subject -repository root; `` is the lowercase axis name. +the vocabulary of `scorecard.schema.json`, so that a badge assertion could +be audited by the same generator that audited specs (retired 2026-10-09). +`` is the subject repository root; `` is the lowercase axis name. === MUST diff --git a/docs/INNERVATION.adoc b/docs/INNERVATION.adoc index 0c64d86bc..68c7b8470 100644 --- a/docs/INNERVATION.adoc +++ b/docs/INNERVATION.adoc @@ -142,5 +142,5 @@ is migrated. - `coordination.k9` — nerve receptor for this repo - `ROADMAP.adoc` — phases A–D of the innervation build-out -- `TOPOLOGY.adoc` — architecture diagram +- `TOPOLOGY.adoc` — architecture diagram (frozen snapshot, no longer regenerated) - `component-readiness-grades/SELF-ASSESSMENT.adoc` — why this repo is B diff --git a/docs/migrations/pmpl-to-mpl-sweep-runbook.adoc b/docs/migrations/pmpl-to-mpl-sweep-runbook.adoc index 443713d01..3a70c732f 100644 --- a/docs/migrations/pmpl-to-mpl-sweep-runbook.adoc +++ b/docs/migrations/pmpl-to-mpl-sweep-runbook.adoc @@ -180,7 +180,8 @@ nextgen-databases — all four confirmed in §1/§3/§4): the §5 licence. . Re-run the repo's own CI locally where it has content-addressed gates (e.g. a registry/topology regen — `standards` needed `just registry` after a - tracked-file edit; expect similar in repos with `.machine_readable/REGISTRY`). + tracked-file edit until that registry was retired on 2026-10-09; expect + similar in repos that still carry `.machine_readable/REGISTRY`). . Commit per-repo with a clear `chore(licence):` message enumerating files + the keep-list. . Push `-u origin claude/`; open a **draft** PR; let CI run. diff --git a/docs/wikis/0.2-AI-MANIFEST.a2ml b/docs/wikis/0.2-AI-MANIFEST.a2ml index 748a7df36..c43fc02e3 100644 --- a/docs/wikis/0.2-AI-MANIFEST.a2ml +++ b/docs/wikis/0.2-AI-MANIFEST.a2ml @@ -22,7 +22,6 @@ format: front_doors: human: "README.adoc" machine: "0-AI-MANIFEST.a2ml" - verifiable_index: ".machine_readable/REGISTRY.a2ml" tracks: - audience: "users" @@ -36,7 +35,7 @@ tracks: - audience: "maintainers" home: "docs/wikis/maintainers/index.adoc" quickstart: "QUICKSTART-MAINTAINER.adoc" - for: "evolving the standards: registry generator, guardrails, drift automation" + for: "evolving the standards: guardrails, drift automation" todo: - "Flesh out per-track core-concept prose beyond the link spine" diff --git a/docs/wikis/README.adoc b/docs/wikis/README.adoc index c36664ff1..40f869d5d 100644 --- a/docs/wikis/README.adoc +++ b/docs/wikis/README.adoc @@ -25,7 +25,6 @@ The wiki does not replace the canonical front doors — it *teaches* them: * Human front door: `README.adoc` * Machine front door: `0-AI-MANIFEST.a2ml` -* Verifiable index of every spec: `.machine_readable/REGISTRY.a2ml` == Tracks by audience @@ -44,8 +43,8 @@ The wiki does not replace the canonical front doors — it *teaches* them: | link:../../QUICKSTART-DEV.adoc[QUICKSTART-DEV] | link:maintainers/index.adoc[Maintainers] -| People *evolving* this repo — the registry generator, the guardrails, the - licence policy, the drift/staleness automation, the innervation stack. +| People *evolving* this repo — the guardrails, the licence policy, the + drift/staleness automation, the innervation stack. | link:../../QUICKSTART-MAINTAINER.adoc[QUICKSTART-MAINTAINER] |=== diff --git a/docs/wikis/developers/index.adoc b/docs/wikis/developers/index.adoc index dae322d8a..9f24b0720 100644 --- a/docs/wikis/developers/index.adoc +++ b/docs/wikis/developers/index.adoc @@ -38,7 +38,7 @@ NOTE: Scaffold. The link spine is complete; the connective prose is `TODO`. === 5. Write & extend Hypatia rules -* `hypatia-rules/` (e.g. HYP-S006 `registry-staleness`) — the estate-side +* `hypatia-rules/` (e.g. HYP-S001 `crg-demotion-detector`) — the estate-side detection rules and the hybrid automation router (`:auto_execute` vs `:review`, with licence findings capped to `:review`). * TODO: "anatomy of a rule + how to add one". @@ -48,7 +48,7 @@ NOTE: Scaffold. The link spine is complete; the connective prose is `TODO`. * `.github/workflows/` + `hooks/`. * The workflow-pin staleness gate: `scripts/check-workflow-staleness.sh` (recency window — link:../../decisions/ADR-003-workflow-pin-staleness-window.adoc[ADR-003]). -* Registry/topology sync, language policy, no-JS, secret scanning, SPARK gate. +* Language policy, no-JS, secret scanning, SPARK gate. * TODO: "decode a red gate and the fastest green path". === 7. Reference diff --git a/docs/wikis/maintainers/index.adoc b/docs/wikis/maintainers/index.adoc index d49d10f11..b5e98e9f6 100644 --- a/docs/wikis/maintainers/index.adoc +++ b/docs/wikis/maintainers/index.adoc @@ -5,9 +5,9 @@ :toc-placement: preamble :status: Scaffold v0.1.0 (2026-06-21) -For maintainers of **this repo** — the people who change the standards, run -the generators, and uphold the guardrails. Highest blast radius; read the -guardrails before touching anything. +For maintainers of **this repo** — the people who change the standards and +uphold the guardrails. Highest blast radius; read the guardrails before +touching anything. NOTE: Scaffold. The link spine is complete; the connective prose is `TODO`. @@ -21,46 +21,39 @@ NOTE: Scaffold. The link spine is complete; the connective prose is `TODO`. classification. (Root cause: neurophone#99.) * TODO: the five-way classification cheat-sheet (MPL / ARR / AGPL / forks / PMPL). -=== Generated files are never hand-edited +=== Frozen snapshots are never hand-edited -* `.machine_readable/REGISTRY.a2ml` and `TOPOLOGY.adoc` are *generated* by - `scripts/build-registry.sh` (`just registry`); edit the `SPECS` table in the - generator, then regenerate. CI `registry-verify.yml` fails on drift. -* TODO: "add a new spec home end-to-end". +* `TOPOLOGY.adoc` and `0-canon/COMPLIANCE-DASHBOARD.adoc` are frozen snapshots. + Their generators and the `registry-verify` gate were retired on 2026-10-09; + see `REGISTRY.adoc`. == Learning path -=== 1. The registry + topology pipeline +=== 1. Drift / staleness automation -* `scripts/build-registry.sh`, `just registry` / `just registry-check`, - `REGISTRY.adoc`, `TOPOLOGY.adoc` (derived). - -=== 2. Drift / staleness automation - -* HYP-S006 `registry-staleness` (`hypatia-rules/`) — the time-window idiom. * Reusable-pin freshness: link:../../decisions/ADR-003-workflow-pin-staleness-window.adoc[ADR-003], `scripts/check-workflow-staleness.sh`, `scripts/propagate-workflow-pins.sh`. * Deferred cross-repo auto-bump: `docs/FUTURE-WORK.adoc` (#16). -=== 3. Readiness-grade governance +=== 2. Readiness-grade governance * `component-readiness-grades/` (+ ARG/FRG/TRG), `0-canon/CRG-SELF-ASSESSMENT.adoc`, the demotion/overclaim detectors in `hypatia-rules/`. -=== 4. Decision records & policy +=== 3. Decision records & policy * `docs/decisions/` (ADR process), the `*-POLICY.adoc` set (DEPENDABOT, TRUSTED-BASE, REMOTE-URL, CODEOWNERS, TOOLING-VERSION-INTEGRITY). * TODO: "when to write an ADR vs a policy". -=== 5. The innervation / contractile stack (descriptiles) +=== 4. The innervation / contractile stack (descriptiles) * `.machine_readable/descriptiles/` (STATE/META/…), `1-formats/contractiles/`, `contractile.just`, `coordination.k9`, `.verisimdb/`, and Hypatia as the estate-side analyser. * TODO: "how a contractile is registered and fires"; whether estate scripts (e.g. the staleness/propagation pair) should be registered as contractiles. -=== 6. Release & ownership +=== 5. Release & ownership * `3-practice/release-pre-flight/`, `3-practice/publication-pre-flight/`, `just v1-audit`, `3-practice/MAINTAINERS.adoc`, `3-practice/CODEOWNERS-POLICY.adoc`, `3-practice/SECURITY.md`. diff --git a/hooks/pre-commit b/hooks/pre-commit index 2ce2c13b2..d8a1929a7 100755 --- a/hooks/pre-commit +++ b/hooks/pre-commit @@ -74,23 +74,6 @@ for file in $SOURCE_FILES; do fi done -# Registry / topology drift guard (standards repo only — runs where the -# generator is present). The verifiable spec registry records a content -# hash per spec home; when a tracked file under a home changes without -# regenerating, the recorded source_hash goes stale and registry-verify.yml -# reds main. (It did, three times, when spec-home edits merged without a -# regenerate.) Catch it locally, before the commit, instead of in CI. -if [ -f scripts/build-registry.sh ]; then - if ! bash scripts/build-registry.sh --check >/dev/null 2>&1; then - echo -e "${RED}✗ REGISTRY.a2ml / TOPOLOGY.adoc are stale — regenerate before committing.${NC}" - echo " A tracked file under a spec home (or STATE.a2ml) changed without" - echo " regenerating the derived registry/topology." - echo " Fix: bash scripts/build-registry.sh" - echo " git add .machine_readable/REGISTRY.a2ml TOPOLOGY.adoc" - ERRORS=$((ERRORS + 1)) - fi -fi - # Canonical-names guard: block reintroduction of the deprecated names listed in # 0-canon/CANONICAL-NAMES.adoc within the staged diff. Only added lines are checked, so # not-yet-migrated existing occurrences do not trip it. diff --git a/hypatia-rules/README.adoc b/hypatia-rules/README.adoc index a3b2d0771..7cf87ac46 100644 --- a/hypatia-rules/README.adoc +++ b/hypatia-rules/README.adoc @@ -3,7 +3,7 @@ :status: Draft v0.3.0 :updated: 2026-08-24 -Ten Hypatia rules specific to the standards-repo dogfooding loop. +Eight Hypatia rules specific to the standards-repo dogfooding loop. Each rule is defined in A2ML, consumes VeriSimDB octads or the repo file tree, and emits Groove `compliance.finding.new` signals. @@ -16,10 +16,8 @@ tree, and emits Groove `compliance.finding.new` signals. | HYP-S003 | `proof-freshness` | Alert when a proof hasn't been re-verified in > 30 days | | HYP-S004 | `rsr-self-compliance` | Validate standards repo against its own RSR definition | | HYP-S005 | `crg-overclaim-detector` | Alert when a self-declared CRG grade lacks v2.0 evidence artefacts | -| HYP-S006 | `registry-staleness` | Alert when REGISTRY.a2ml source hashes go stale or a DERIVED doc (TOPOLOGY.adoc) drifts | | HYP-S007 | `profile-drift-detector` | Flag a descriptiles file whose content drifts from its declared A2ML `@profile` | | HYP-S008 | `workflow-allowlist-gap` | Flag a workflow `uses:` an action/reusable not permitted by the repo Actions allowlist (would `startup_failure`) | -| HYP-S009 | `implementation-inside-canon` | Flag product/build manifests below a local (non-external) canonical spec home | | HYP-UUID-001 | `uuid-v7-estate-conformance` | Reject non-v7 UUID literals and untracked legacy identifiers across both estates | The CRG rule pair (S001 + S005) together enforce grade-honesty: S001 @@ -27,15 +25,6 @@ catches backwards moves, S005 catches forwards-overshoots. Both read from `crg-grade` octads in VeriSimDB, but S005 also scans the repo file tree for evidence artefacts required by CRG v2.0 (STRICT). -S006 closes the documentation-drift loop: it recomputes each spec's -`source_hash` from the file tree (the same way `scripts/build-registry.sh` -does) and emits a `doc.drift` signal when the recorded hash is stale or a -generated file (TOPOLOGY.adoc) was hand-edited. Its `@router` block defaults -to `auto_execute` (regenerate), but **caps any licence/SPDX-overlapping -drift to `:review`** — honouring the Manual-Only licence guardrail in -`.claude/CLAUDE.md`. This is the estate-side mirror of the in-repo -`registry-verify.yml` workflow. - HYP-S007 closes the dogfooding loop for the A2ML profile mechanism: every descriptiles file declares an `@profile(id=…)` (a2ml/SPEC.adoc Section 8), and this rule flags any file that no longer satisfies its declared profile definition in @@ -52,14 +41,12 @@ so the gap is a legible finding, not a dark run. It is FLAG-ONLY workflow `GITHUB_TOKEN`; its recipe runs `scripts/check-allowed-actions.sh` and the paired `scripts/set-allowed-actions.sh` performs the admin fix. -HYP-S009 is the recurrence guard for the standards carve-out campaign. It uses -`.machine_readable/REGISTRY.a2ml` as the authoritative canon boundary and scans -only local entries (those not marked `kind = "external"`); it does not guess -from broad directory names or the mere presence of an A2ML file. Product/build -manifests below a local spec home emit review-tier findings. The rule is -deliberately flag-only: -moving an implementation can cross history, ownership, and licence boundaries -and therefore requires a reviewed carve-out rather than scanner autofix. +HYP-S009 (`implementation-inside-canon`) was the recurrence guard for the +standards carve-out campaign (#479/#498). It read +`.machine_readable/REGISTRY.a2ml` as its canon boundary and flagged +product/build manifests below a local spec home. It was retired on 2026-10-09 +with the registry (see link:../REGISTRY.adoc[REGISTRY.adoc]). Its baselined +carve-out debts stay tracked in standards#687. == Implementation @@ -87,7 +74,6 @@ Rules read from: - `a2ml/profiles/REGISTRY.a2ml` + `a2ml/profiles/*/PROFILE.a2ml` and the descriptiles files under `.machine_readable/` (HYP-S007) - `.github/workflows/*` and `rhodium-standard-repositories/actions-allowlist/allowed-actions.json` (HYP-S008) -- `.machine_readable/REGISTRY.a2ml` LOCAL homes and their product/build manifests (HYP-S009) And emit: - Groove `compliance.finding.new` signals with the rule's ID diff --git a/hypatia-rules/implementation-inside-canon.a2ml b/hypatia-rules/implementation-inside-canon.a2ml deleted file mode 100644 index 177a9ae8a..000000000 --- a/hypatia-rules/implementation-inside-canon.a2ml +++ /dev/null @@ -1,110 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -# HYP-S009 — Implementation Inside Canon -# -# A REGISTRY.a2ml entry whose home is LOCAL declares that the directory is the -# in-repository source of truth for a standard. Product/build manifests below -# that home are therefore architectural drift: an implementation has started -# growing inside the canon again. This is the recurrence guard for the -# standards carve-out campaign (#479 / #498). -# -# This rule deliberately does NOT infer canon from "contains an .a2ml file" or -# from a broad directory name such as docs/. Those heuristics made the earlier -# shell prototype flag legitimate examples, migrations, and documentation -# tooling. REGISTRY.a2ml is the authoritative boundary. - -@rule(version="1.0"): -id: HYP-S009 -name: "Implementation inside canon" -description: "Flag product/build manifests below a local (non-external) REGISTRY.a2ml spec home" -severity: medium -category: StandardsCompliance -auto_fixable: false -source: standards/hypatia-rules -@end - -@parameters: -registry: .machine_readable/REGISTRY.a2ml -implementation_basenames: - - Cargo.toml - - deno.json - - package.json - - Containerfile - - compose.yaml - - CNAME - - ads.txt -conditional_basenames: - - guix.scm -path_exemptions: - - "**/examples/**" - - "**/templates/**" - - "**/test/fixtures/**" - - "**/tests/fixtures/**" -@end - -@scanner(type="file-tree"): -find: - - glob: ".machine_readable/REGISTRY.a2ml" - - glob: "**/Cargo.toml" - - glob: "**/deno.json" - - glob: "**/package.json" - - glob: "**/Containerfile" - - glob: "**/compose.yaml" - - glob: "**/guix.scm" - - glob: "**/CNAME" - - glob: "**/ads.txt" -@end - -@logic(engine="built-in"): -steps: - - parse_registry: ".machine_readable/REGISTRY.a2ml" - extract: - - key: "id" - as: spec_id - - key: "home" - as: home - - key: "kind" - as: kind - # Local entries omit `kind`; external pointers explicitly use - # `kind = external`. This matches the registry generator contract. - - for_each_spec where "kind != external": - require: "home is a normalized repository-relative directory" - reject_if: "home is absolute or contains a '..' path component" - scan_descendants: home - emit_if: "path not in path_exemptions && basename in implementation_basenames" - finding_kind: implementation-inside-canon - emit_if: "path not in path_exemptions && basename == guix.scm && file is not a documented non-building stub" - finding_kind: implementation-inside-canon - - deduplicate_by: "spec_id, normalized_path" -@end - -@router: -default_strategy: review -# Moving an implementation changes repository ownership/topology and may cross -# licence boundaries. It is never safe for a scanner to perform that move. -strategy_caps: - - when: "finding_kind == implementation-inside-canon" - cap: review - reason: "Carve-out requires history, ownership, licence, and destination-repo review" -@end - -@action: -emit_signal: compliance.finding.new -message_template: >- - Implementation manifest {normalized_path} is inside LOCAL canonical spec - home '{home}' ({spec_id}). Move the product/build surface to its owning repo - and leave only normative spec, policy, registry, or template-as-spec content. -recipe: review-canon-carve-out -halt_on_violation: false -dedupe_window_days: 7 -@end - -@recipe(id="review-canon-carve-out"): -description: "Produce an audit-only carve-out report; never move or delete files automatically" -command: "bash scripts/check-implementation-inside-canon.sh ." -auto_applicable: false -@end - -@sibling_rules: -- HYP-S006 registry-staleness — verifies registry pointers and derived docs -- HYP-S008 workflow-allowlist-gap — reifies zero-job Actions failures -@end diff --git a/hypatia-rules/registry-staleness.a2ml b/hypatia-rules/registry-staleness.a2ml deleted file mode 100644 index 8804ef3cb..000000000 --- a/hypatia-rules/registry-staleness.a2ml +++ /dev/null @@ -1,155 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -# HYP-S006 — Registry Staleness / Doc Drift -# Detects when the verifiable spec registry (.machine_readable/REGISTRY.a2ml) -# no longer matches ground truth, or when DERIVED docs (TOPOLOGY.adoc) were -# hand-edited away from their generated form. Drift becomes a routed finding -# the moment it lands — not something noticed 60 days later. -# -# Covers BOTH registry entry shapes: -# * LOCAL specs — recorded source_hash vs a fresh git-ls-files compute. -# * EXTERNAL specs (kind="external") — verified pointers to specs whose SSOT -# lives in another repo (e.g. AffineScript .affine/.affex/.affmap). The -# recorded source_hash is checked against a fresh fetch of canonical_url; -# re-pinning is capped to :review (owner decision, not an auto-regen). -# -# Companion to scripts/build-registry.sh (the generator) and -# .github/workflows/registry-verify.yml (the in-repo --check gate). This rule -# is the estate-side half: it lets Hypatia surface the same drift across the -# fleet and route it through the hybrid automation router. - -@rule(version="1.0"): -id: HYP-S006 -name: "Registry staleness / doc drift" -description: "Alert when a spec's recorded source_hash in REGISTRY.a2ml no longer matches a fresh compute (local) or a fresh fetch of canonical_url (external pointer), or a DERIVED doc (TOPOLOGY.adoc) drifted from its generator" -severity: medium -category: StandardsCompliance -auto_fixable: true -source: standards/hypatia-rules - -@parameters: -# How long a hash mismatch may persist before the finding escalates. -stale_after_days: 14 -critical_after_days: 60 -@end - -@scanner(type="file-tree"): -find: - - glob: ".machine_readable/REGISTRY.a2ml" - - glob: "TOPOLOGY.adoc" - - glob: "scripts/build-registry.sh" -@end - -@logic(engine="built-in"): -# Two entry shapes share one registry: -# * LOCAL (no `kind`) — recompute sha256 over `git ls-files -s ` -# exactly as the generator does, compare to the -# recorded value. -# * EXTERNAL (kind="external")— a verified pointer to a spec whose SSOT is -# another repo. Re-fetch canonical_url and -# recompute with source_hash_algo (sha256+; -# md5/sha1 are rejected as UNVERIFIED), compare -# to the recorded source_hash. This is the -# network-side check the offline generator and -# the in-repo registry-verify.yml cannot do. -steps: - - parse_registry: ".machine_readable/REGISTRY.a2ml" - extract: - - key: "home" - as: home - - key: "kind" - as: kind - - key: "canonical_url" - as: canonical_url - - key: "source_hash_algo" - as: algo - - key: "sync_status" - as: sync_status - - key: "source_hash" - as: recorded_hash - # --- LOCAL specs ------------------------------------------------------- - - for_each_spec where "kind != external": - recompute: "sha256(git ls-files -s ${home})" - compare_to: recorded_hash - emit_if: "recompute != recorded_hash" - finding_kind: registry-hash-stale - - check_home_exists where "kind != external": - emit_if: "home directory absent" - finding_kind: registry-dead-home - # --- EXTERNAL specs (verified pointers; SSOT in another repo) ---------- - - reject_weak_algo where "kind == external": - emit_if: "algo in [md5, sha1]" # security policy: no MD5/SHA1 - finding_kind: registry-weak-algo - - for_each_spec where "kind == external && recorded_hash != 'PENDING-FIRST-SYNC'": - fetch: canonical_url - recompute: "${algo}(fetched_content)" - compare_to: recorded_hash - emit_if: "recompute != recorded_hash" - finding_kind: registry-pointer-stale - - for_each_spec where "kind == external && recorded_hash == 'PENDING-FIRST-SYNC'": - # Not drift — upstream has not landed yet. Surface as info, and as a - # low finding only once it has sat unsynced beyond the grace window. - fetch: canonical_url - emit_if: "fetch succeeds" - finding_kind: registry-pointer-ready # ready for first sync (info) - emit_if: "still PENDING beyond ${stale_after_days}d" - finding_kind: registry-pointer-unsynced # low - # --- DERIVED docs ------------------------------------------------------ - - check_derived_docs: - command: "bash scripts/build-registry.sh --check" - emit_if: "non-zero exit" - finding_kind: derived-doc-stale -@end - -# --------------------------------------------------------------------------- -# Hybrid automation router strategy. -# The router decides whether a finding is auto-executed or held for review. -# Doc/registry drift is mechanical and safe to regenerate, EXCEPT where the -# drifted content touches licence/SPDX — those are FLAG-ONLY per the estate -# Manual-Only licence guardrail (.claude/CLAUDE.md) and hypatia -# license_finding_strategy/0. The router MUST honour the cap below. -# --------------------------------------------------------------------------- -@router: -default_strategy: auto_execute # regenerate REGISTRY.a2ml + TOPOLOGY.adoc -recipe: rebuild-registry -# Hard cap: any finding whose drift overlaps a licence/SPDX token is demoted -# to :review and never auto-applied, mirroring license_finding_strategy/0. -strategy_caps: - - when: "finding touches /SPDX-License-Identifier|PMPL|MPL-2\\.0|AGPL|Palimpsest|licen[cs]e/i" - cap: review - reason: "Manual-Only licence guardrail — agents flag, owner edits (neurophone#99)" - - when: "finding_kind == registry-dead-home" - cap: review - reason: "A missing home is a structural change, not a regen — needs human triage" - - when: "finding_kind in [registry-pointer-stale, registry-pointer-unsynced, registry-weak-algo]" - cap: review - reason: "External pointers reference another repo's SSOT — re-pinning version_pin/source_hash is an owner decision, never an auto-regen (rebuild-registry cannot recompute a cross-repo hash offline)." -@end - -@action: -emit_signal: doc.drift -message_template: >- - Registry drift: {finding_kind} for spec '{id}' (home={home} url={canonical_url}). - Recorded {recorded_hash}, fresh compute/fetch differs. For LOCAL drift run - 'just registry' to regenerate; for EXTERNAL pointers re-pin is an owner - decision (capped :review). ({age_days}d since generated) -recipe: rebuild-registry -severity_escalates_at: 60 -halt_on_violation: false -dedupe_window_days: 7 -@end - -@recipe(id="rebuild-registry"): -description: "Regenerate the registry + derived topology from the file tree" -command: "bash scripts/build-registry.sh" -auto_applicable: true -# NOTE: auto_applicable is gated by @router strategy_caps above — a licence- -# overlapping drift is capped to :review and will NOT auto-run this recipe. -@end - -@sibling_rules: -- HYP-S003 proof-freshness — same staleness shape, for proof artefacts -- HYP-S004 rsr-self-compliance — structural self-dogfooding gate -- HYP-S005 crg-overclaim-detector — grade-honesty gate -@end - -@end diff --git a/llm-warmup-dev.adoc b/llm-warmup-dev.adoc index f064346b3..ade783105 100644 --- a/llm-warmup-dev.adoc +++ b/llm-warmup-dev.adoc @@ -2,26 +2,18 @@ ____ Thin stub. Canonical machine entry: *`+0-AI-MANIFEST.a2ml+`*. Canonical -human entry: *`+README.adoc+`*. Spec index: -*`+.machine_readable/REGISTRY.a2ml+`*. +human entry: *`+README.adoc+`*. ____ === You are working _on_ the standards themselves -* *Find a spec:* `+.machine_readable/REGISTRY.a2ml+` (id → home → -source_hash). -* *Add/move a spec:* edit the `+SPECS+` table in -`+scripts/build-registry.sh+`, then `+just registry+` (regenerates -`+REGISTRY.a2ml+` + `+TOPOLOGY.adoc+`). CI rejects a spec change that -forgets to regenerate (`+registry-verify.yml+`). +* *Find a spec:* the routing table at the top of `+README.adoc+`. * *Language + licence policy (binding):* `+.claude/CLAUDE.md+`. Licence/SPDX is *Manual-Only* — flag drift, never edit it. * *State you must keep current:* `+.machine_readable/descriptiles/STATE.a2ml+`. === Key commands -* `+just registry+` — regenerate the spec registry + derived topology -* `+just registry-check+` — fail on drift (what CI runs) * `+just build+` / `+just test+` — build + run the sub-project test suites * `+just doctor+` / `+just heal+` — diagnose / auto-repair @@ -30,5 +22,5 @@ suites * Licence: see `+LICENSE+` (Manual-Only for agents). * Part of the Hyperpolymath ecosystem. -* Architecture map (derived): `+TOPOLOGY.adoc+`. Drift automation: -`+REGISTRY.adoc+`. +* Architecture map (frozen snapshot): `+TOPOLOGY.adoc+`. Registry +retirement notice: `+REGISTRY.adoc+`. diff --git a/llm-warmup-user.adoc b/llm-warmup-user.adoc index 2eba7fde4..bbb456a5e 100644 --- a/llm-warmup-user.adoc +++ b/llm-warmup-user.adoc @@ -2,8 +2,7 @@ ____ Thin stub. Canonical machine entry: *`+0-AI-MANIFEST.a2ml+`*. Canonical -human entry: *`+README.adoc+`*. Spec index: -*`+.machine_readable/REGISTRY.a2ml+`*. +human entry: *`+README.adoc+`*. ____ === You are _applying_ these standards to another repo @@ -14,9 +13,8 @@ path: * *Stand up a compliant repo:* `+1-formats/A2ML-REPO-TEMPLATE.adoc+` + the _Usage_ section of `+README.adoc+`; copy the 7 A2ML files from `+1-formats/templates/+`. -* *Pick the spec you need:* `+.machine_readable/REGISTRY.a2ml+` routes -you by `+id+` → `+home+` → `+canonical_doc+` (A2ML family, K9, -protocols, readiness grades, RSR, pre-flight gates). +* *Pick the spec you need:* `+README.adoc+` routes you to each area +(A2ML family, K9, protocols, readiness grades, RSR, pre-flight gates). * *Adopt the enforcement:* copy the relevant `+.github/workflows/+` + `+hooks/+`. * *Language rules you must follow:* `+.claude/CLAUDE.md+`. diff --git a/scripts/build-registry.sh b/scripts/build-registry.sh deleted file mode 100755 index 71754b44f..000000000 --- a/scripts/build-registry.sh +++ /dev/null @@ -1,336 +0,0 @@ -#!/usr/bin/env bash -# SPDX-License-Identifier: MPL-2.0 -# SPDX-FileCopyrightText: 2026 Jonathan D.A. Jewell (hyperpolymath) -# -# build-registry.sh — regenerate the verifiable spec registry and the -# DERIVED topology map from ground truth (the file tree + STATE.a2ml). -# -# 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.adoc — the human-readable map, derived -# from the registry + STATE.a2ml so it can never freeze again. -# -# The registry indexes two kinds of spec: -# * LOCAL specs — homed in this monorepo. `source_hash` is computed from -# `git ls-files -s `: that listing already pins every tracked -# file's blob SHA + path, so any content change under a home changes -# its hash. -# * EXTERNAL specs — language/service-coupled specs whose source-of-truth -# deliberately lives in ANOTHER repo (e.g. the AffineScript .affine / -# .affex / .affmap standards, SSOT = hyperpolymath/affinescript). We -# record a verified POINTER (canonical_url + version_pin + a recorded -# source_hash), never a copy — duplicating the normative text would -# create two sources of truth. The recorded source_hash is PINNED in -# the EXTERNAL_SPECS table below (sentinel until upstream lands); the -# OFFLINE generator emits it verbatim so `--check` stays deterministic. -# -# Hypatia rule HYP-S006 (hypatia-rules/registry-staleness.a2ml) recomputes -# LOCAL hashes from the tree and (network-capable, estate-side) re-fetches -# EXTERNAL canonical_urls, emitting a `doc.drift` finding when a recorded -# hash goes stale. -# -# Principles (do not violate): -# * Honest. Only specs whose home directory exists are listed. A missing -# home is reported to stderr, never silently invented. -# * Deterministic + idempotent. Run twice → byte-identical output. -# * No network, no commit, no push. Run on a branch; review the diff. -# (External source_hashes are RECORDED here, never fetched at gen time.) -# -# Usage: bash scripts/build-registry.sh # write artefacts -# bash scripts/build-registry.sh --check # verify, non-zero on drift -set -euo pipefail - -cd "$(git rev-parse --show-toplevel)" - -MODE="write" -[ "${1:-}" = "--check" ] && MODE="check" - -REGISTRY=".machine_readable/REGISTRY.a2ml" -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. - -# --------------------------------------------------------------------------- -# Spec table — the single source of truth for what this monorepo standardises. -# Columns: id | stream | home | name | route (one-line "go here if you want X") -# stream ∈ foundation | language | protocol | governance | readiness | integration -# Add a row here when a new spec lands; the hash + topology follow automatically. -# --------------------------------------------------------------------------- -read -r -d '' SPECS <<'TSV' || true -estate-constitution|governance|0-canon/constitution/|Hyperpolymath Estate Constitution|the highest estate-level rules, authority precedence, assurance, contribution, exceptions, and known tensions -k9-svc|foundation|1-formats/k9/|K9 Self-Validating Components|the K9 specification, security analysis and adoption guidance (implementations live in hyperpolymath/k9-ecosystem) -contractiles|foundation|1-formats/contractiles/|Contractiles (Must/Trust/Dust/Intend)|policy-enforcement primitives the K9 layer is built from -meta-a2ml|foundation|1-formats/a2ml/meta/|META.a2ml spec|architecture decisions / governance metadata format -state-a2ml|foundation|1-formats/a2ml/state/|STATE.a2ml spec|project-state metadata format (drives this registry's topology) -ecosystem-a2ml|foundation|1-formats/a2ml/ecosystem/|ECOSYSTEM.a2ml spec|ecosystem-positioning metadata format -agentic-a2ml|foundation|1-formats/a2ml/agentic/|AGENTIC.a2ml spec|AI-agent operational gating / entropy budgets -neurosym-a2ml|foundation|1-formats/a2ml/neurosym/|NEUROSYM.a2ml spec|symbolic semantics / proof obligations -playbook-a2ml|foundation|1-formats/a2ml/playbook/|PLAYBOOK.a2ml spec|executable operational runbooks -anchor-a2ml|foundation|1-formats/a2ml/anchor/|ANCHOR.a2ml spec|project-recalibration intervention format -0-ai-gatekeeper-protocol|protocol|2-protocols/0-ai-gatekeeper/|0-AI Gatekeeper Protocol|the AI-agent entry/gating protocol behind 0-AI-MANIFEST -k9-coordination-protocol|protocol|2-protocols/k9-coordination/|K9 Coordination Protocol|multi-agent coordination on top of K9 -avow-protocol|protocol|2-protocols/avow/|AVOW Protocol|consent-attested messaging / origin attribution -axel-protocol|protocol|2-protocols/axel/|AXEL Protocol|age-gating + explicit-content enforcement -overlay-protocol|protocol|2-protocols/overlay/|Overlay Protocol|layered overlay composition spec -adoption-readiness-grades|readiness|adoption-readiness-grades/|ARG — Adoption Readiness Grades|per-language adoption-maturity profile templates -foundations-readiness-grades|readiness|foundations-readiness-grades/|FRG — Foundations Readiness Grades|per-language foundational-maturity profile templates -component-readiness-grades|readiness|component-readiness-grades/|CRG — Component Readiness Grades|the X..A grading system for components -toolchain-readiness-grades|readiness|toolchain-readiness-grades/|TRG — Toolchain Readiness Grades|per-toolchain readiness profile templates -rhodium-standard-repositories|governance|rhodium-standard-repositories/|RSR — Rhodium Standard Repositories|the repository-compliance standard every repo is graded against -session-management-standards|governance|3-practice/session-management-standards/|Session Management Standards|continuity / verify / handover protocols -did-you-actually-do-that|governance|1-formats/sub-specs/did-you-actually-do-that/|DYADT — Did-You-Actually-Do-That|post-action agent-claim verification (Tier 4 accountability) -ensaid-config|governance|1-formats/sub-specs/ensaid-config/|ENSAID Config|the ensaid configuration standard -accessibility|governance|3-practice/accessibility/|Accessibility Standard|estate accessibility requirements -publication-pre-flight|governance|3-practice/publication-pre-flight/|Publication Pre-Flight|submission gate (HOL + Zenodo checklists) -release-pre-flight|governance|3-practice/release-pre-flight/|Release Pre-Flight (V1 Gate)|hard v1.0.0 audit requirements -hypatia-rules|integration|hypatia-rules/|Standards Hypatia Rules|the dogfooding rules that scan THIS repo (incl. drift detection) -a2ml-templates|integration|1-formats/templates/|A2ML Templates|copy-in templates for the 7 A2ML files -form-fill-provenance|foundation|1-formats/sub-specs/form-fill-provenance/|FFP — Form-Fill Provenance|whether a PDF form was machine-filled or printed blank for hand completion, and what a print path must record -TSV - -# --------------------------------------------------------------------------- -# External spec table — language/service-coupled specs whose SSOT lives in -# ANOTHER repo. The registry holds a verified POINTER, never a copy. -# Columns: id | stream | spec_kind | owning_repo | canonical_url | version_pin | -# format_version | source_hash | media_type | lineage | name | route -# * spec_kind ∈ language-coupled | service-coupled -# * format_version: only for regenerable artefacts whose format version is -# tracked INDEPENDENTLY of the language version_pin (e.g. .affex). Empty -# otherwise. (owner directive 2026-06-03) -# * source_hash : RECORDED here (sentinel `PENDING-FIRST-SYNC` until the -# upstream spec lands). NEVER fetched at generation time — HYP-S006 does -# the network-side verification. NEVER fabricate a hash. -# Field set ratified by owner 2026-06-03: 7 base (name/canonical_url/owning_repo/ -# version_pin/source_hash/conformance_level/last_synced) + provenance -# (source_hash_algo/spec_kind/media_type/lineage). conformance_level is "draft" -# and last_synced "never" until first sync, so they are emitted by the writer, -# not carried per-row. source_hash_algo is sha256 (md5/sha1 are banned). -# --------------------------------------------------------------------------- -read -r -d '' EXTERNAL_SPECS <<'TSV' || true -affine-spec|language|language-coupled|hyperpolymath/affinescript|https://github.com/hyperpolymath/affinescript/blob/main/spec/affine.adoc|v2.0.0||PENDING-FIRST-SYNC|application/vnd.affinescript.affine|affinescript:affine@2|AffineScript .affine (faces / source documents)|faces, canonical-lowering invariant, canonical islands, idiom packs, mimicry bindings, project face policy -affex-manifest|language|language-coupled|hyperpolymath/affinescript|https://github.com/hyperpolymath/affinescript/blob/main/spec/affex.adoc|v2.0.0|2|PENDING-FIRST-SYNC|application/vnd.affinescript.affex|affinescript:affex@2|AffineScript .affex (face-interop manifest)|derived regenerable manifest; declaration heads not full bodies; format_version bumps independently -affmap-provenance|language|language-coupled|hyperpolymath/affinescript|https://github.com/hyperpolymath/affinescript/blob/main/spec/affmap.adoc|v2.0.0||PENDING-FIRST-SYNC|application/vnd.affinescript.affmap|affinescript:affmap@2|AffineScript .affmap (provenance)|provenance format; own pointer for independent staleness tracking -a2ml|foundation|format-coupled|hyperpolymath/a2ml|https://github.com/hyperpolymath/a2ml/blob/main/README.adoc|v1.0.0||PENDING-FIRST-SYNC|application/vnd.a2ml|a2ml:a2ml@1|A2ML — Attested Markup Language|the typed/verified machine-readable document format; evicted from standards 2026-08-28 per #490 -consent-aware-web|protocol|service-coupled|metadatastician/consent-aware-web|https://github.com/metadatastician/consent-aware-web/blob/main/README.adoc|v0.2.0||PENDING-FIRST-SYNC|application/aibdp+json|ietf:aibdp@0.2|Consent-Aware Web (AIBDP + HTTP 430)|consent headers / AI-usage boundaries for HTTP; extracted from this repo 2026-08-07 -TSV - -# Pick the canonical human doc for a home: README.adoc > README.md > first *.adoc spec. -canonical_doc() { - local home="$1" - for c in "${home}README.adoc" "${home}README.md"; do - [ -f "$c" ] && { printf '%s' "$c"; return; } - done - local first - first="$(git ls-files -- "${home}" | grep -iE '\.(adoc|a2ml)$' | head -1 || true)" - printf '%s' "${first:-${home}}" -} - -# Content-addressed hash of everything tracked under a home path. -home_hash() { - local home="$1" - git ls-files -s -- "$home" | sha256sum | cut -d' ' -f1 -} - -# --------------------------------------------------------------------------- -# Emit REGISTRY.a2ml -# --------------------------------------------------------------------------- -emit_registry() { - cat <
-# -# REGISTRY.a2ml — the verifiable index of every spec/standard in this monorepo. -# -# GENERATED FILE — DO NOT EDIT BY HAND. -# Regenerate with: bash scripts/build-registry.sh (or: just registry) -# Source of truth: the SPECS table in scripts/build-registry.sh + the file tree. -# -# LOCAL entries: \`source_hash\` is a sha256 over \`git ls-files -s \`, so it -# changes whenever any tracked file under the spec's home changes. -# EXTERNAL entries (kind = "external"): a verified POINTER to a spec whose SSOT -# lives in another repo. \`source_hash\` is RECORDED (sentinel PENDING-FIRST-SYNC -# until upstream lands), not computed locally — the offline generator emits it -# verbatim. Hypatia rule HYP-S006 (hypatia-rules/registry-staleness.a2ml) -# recomputes LOCAL hashes and re-fetches EXTERNAL canonical_urls, emitting a -# \`doc.drift\` finding (strategy :review) when a recorded hash goes stale. - -[registry] -version = "1.0.0" -generator = "scripts/build-registry.sh" -hash_algorithm = "sha256(git ls-files -s ) # local; external: recorded pin" -entry_count = ${ENTRY_COUNT} - -[registry.streams] -foundation = "A2ML format family + K9 + contractiles (Stream 1)" -language = "AffineScript and language-policy specs (Stream 2)" -protocol = "Inter-service / agent protocols" -governance = "RSR, readiness grading, pre-flight gates, session standards" -readiness = "ARG / FRG / CRG / TRG maturity-grading frameworks" -integration = "Registry, hypatia rules, templates — the wiring (Stream 3)" -HEADER - - while IFS='|' read -r id stream home name route; do - [ -z "$id" ] && continue - if [ ! -d "$home" ]; then - echo "WARN: home missing for '$id' ($home) — skipped" >&2 - continue - fi - local doc hash - doc="$(canonical_doc "$home")" - hash="$(home_hash "$home")" - cat </dev/null | head -1 \ - | sed -E 's/^[^=]*=[[:space:]]*//; s/[[:space:]]*#.*$//; s/[[:space:]]+$//; s/^"//; s/"$//' -} - -emit_topology() { - local phase maturity updated - phase="$(state_field phase)"; maturity="$(state_field maturity)" - updated="$(state_field last-updated)" - cat <
"$tmp_r"; emit_topology > "$tmp_t" - rc=0 - if ! diff -q "$tmp_r" "$REGISTRY" >/dev/null 2>&1; then - echo "DRIFT: $REGISTRY is stale — run 'just registry'"; rc=1; fi - if ! diff -q "$tmp_t" "$TOPOLOGY" >/dev/null 2>&1; then - echo "DRIFT: $TOPOLOGY is stale — run 'just registry'"; rc=1; fi - rm -f "$tmp_r" "$tmp_t" - [ "$rc" -eq 0 ] && echo "OK: registry + topology are in sync with the file tree." - exit "$rc" -fi - -emit_registry > "$REGISTRY" -emit_topology > "$TOPOLOGY" -echo "Wrote $REGISTRY and $TOPOLOGY ($ENTRY_COUNT specs)." diff --git a/scripts/build-scorecards.sh b/scripts/build-scorecards.sh deleted file mode 100644 index 996f972d7..000000000 --- a/scripts/build-scorecards.sh +++ /dev/null @@ -1,451 +0,0 @@ -#!/usr/bin/env bash -# SPDX-License-Identifier: MPL-2.0 -# SPDX-FileCopyrightText: 2026 Jonathan D.A. Jewell (hyperpolymath) -# -# build-scorecards.sh — regenerate 0-canon/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). -# * 0-canon/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 -# counted as pass; a requirement with system="none" is counted as -# un-automated, which lowers the spec's systems-coverage %. The dashboard -# measures enforcement-vs-theatre, not aspiration. -# -# The generator also enforces the registry↔scorecard correspondence: -# * every LOCAL registered spec SHOULD have a scorecard (missing → reported; -# fails only in --strict), -# * every scorecard MUST key to a registered spec (orphan → hard error). -# -# Usage: -# bash scripts/build-scorecards.sh # write 0-canon/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`; -# # a claimed pass whose check fails is a hard error -# (flags may combine, e.g. --check --strict --verify) -set -euo pipefail - -cd "$(git rev-parse --show-toplevel)" - -MODE="write"; STRICT=0; VERIFY=0 -for arg in "$@"; do - case "$arg" in - --check) MODE="check" ;; - --strict) STRICT=1 ;; - --verify) VERIFY=1 ;; - *) echo "error: unknown option: $arg" >&2; exit 2 ;; - esac -done - -REGISTRY=".machine_readable/REGISTRY.a2ml" -SCDIR=".machine_readable/scorecards" -DASHBOARD="0-canon/COMPLIANCE-DASHBOARD.adoc" -SCHEMA="$SCDIR/scorecard.schema.json" - -[ -f "$REGISTRY" ] || { echo "error: $REGISTRY not found (run: just registry)" >&2; exit 2; } - -# --------------------------------------------------------------------------- -# Local spec inventory from REGISTRY.a2ml: emit "idname" per LOCAL [[spec]] -# (external pointers — kind="external" — are excluded: their SSOT lives in -# another repo and cannot be self-assessed here). -# --------------------------------------------------------------------------- -local_specs() { - awk ' - /^\[\[spec\]\]/ { in_spec=1; id=""; name=""; ext=0; next } - in_spec && /^id = "/ { id=$0; sub(/^id = "/,"",id); sub(/".*$/,"",id) } - in_spec && /^name = "/ { name=$0; sub(/^name = "/,"",name); sub(/".*$/,"",name) } - in_spec && /^kind = "external"/ { ext=1 } - in_spec && /^route = "/ { if (id!="" && ext==0) printf "%s\t%s\n", id, name; in_spec=0 } - ' "$REGISTRY" -} - -# --------------------------------------------------------------------------- -# Parse one scorecard file. Emits TSV lines: tierstatushas_systemhas_check -# tier ∈ must|should|could ; status ∈ pass|fail|aspirational|manual-only -# has_system ∈ 1 (system present and != "none") | 0 -# has_check ∈ 1 (an executable `check` is present) | 0 -# Also validates: pass requires non-empty evidence; status is from the enum. -# Exits non-zero (message on stderr) on a malformed scorecard. -# --------------------------------------------------------------------------- -parse_scorecard() { - awk -v file="$1" ' - function fail(msg) { printf "SCORECARD ERROR [%s]: %s\n", file, msg > "/dev/stderr"; errors++ } - function flush() { - if (tier=="") return - if (id=="") fail("a [[" tier "]] block has no id") - if (status=="") { fail((id==""?"(unnamed)":id) ": missing status"); return } - if (status!="pass" && status!="fail" && status!="aspirational" && status!="manual-only") - fail(id ": invalid status \"" status "\"") - if (status=="pass" && evidence=="") - fail(id ": status=pass requires evidence") - printf "%s\t%s\t%s\t%s\n", tier, status, (sys!="" && sys!="none") ? 1 : 0, (chk!="") ? 1 : 0 - } - /^\[\[(must|should|could)\]\]/ { - flush() - tier=$0; sub(/^\[\[/,"",tier); sub(/\]\].*$/,"",tier) - id=""; status=""; sys=""; evidence=""; chk=""; next - } - /^\[scorecard\]/ { flush(); tier=""; next } - tier!="" && /^id = "/ { id=$0; sub(/^id = "/,"",id); sub(/".*$/,"",id) } - tier!="" && /^status = "/ { status=$0; sub(/^status = "/,"",status); sub(/".*$/,"",status) } - tier!="" && /^system = "/ { sys=$0; sub(/^system = "/,"",sys); sub(/".*$/,"",sys) } - tier!="" && /^evidence = "/ { evidence=$0; sub(/^evidence = "/,"",evidence); sub(/".*$/,"",evidence) } - tier!="" && /^check = "/ { chk=$0; sub(/^check = "/,"",chk); sub(/".*$/,"",chk) } - END { flush(); if (errors>0) exit 1 } - ' "$1" -} - -# --------------------------------------------------------------------------- -# Extract executable checks from one scorecard, one record per row that HAS a -# `check`. Record format (US-delimited, \x1f — never appears in shell text): -# id US status US check -# The check VALUE may contain TOML-escaped quotes (\") and backslashes (\\): -# strip only the TRAILING quote (not the first embedded one) and unescape, -# otherwise any check containing a quoted argument is silently truncated into -# a different (broken) command. -# --------------------------------------------------------------------------- -extract_checks() { - awk ' - function unescape(s) { - gsub(/\\\\/, "\x01", s) # protect literal backslashes first - gsub(/\\"/, "\"", s) # \" -> " - gsub(/\x01/, "\\", s) # restore backslashes - return s - } - function flush() { - if (tier=="" || chk=="") return - printf "%s\x1f%s\x1f%s\n", id, status, unescape(chk) - } - /^\[\[(must|should|could)\]\]/ { - flush() - tier=$0; sub(/^\[\[/,"",tier); sub(/\]\].*$/,"",tier) - id=""; status=""; chk=""; next - } - /^\[scorecard\]/ { flush(); tier=""; next } - tier!="" && /^id = "/ { id=$0; sub(/^id = "/,"",id); sub(/".*$/,"",id) } - tier!="" && /^status = "/ { status=$0; sub(/^status = "/,"",status); sub(/".*$/,"",status) } - tier!="" && /^check = "/ { chk=$0; sub(/^check = "/,"",chk); sub(/"[[:space:]]*$/,"",chk) } - END { flush() } - ' "$1" -} - -# --------------------------------------------------------------------------- -# --verify: RUN every pass-row check. DYADT applied to the scorecards — -# a `pass` is only as good as a check that exits 0 right now. -# * pass + check exits 0 -> grounded pass (good) -# * pass + check exits !=0 -> HARD ERROR (the claimed pass is not real) -# * pass + no check -> self-asserted (reported; visible debt) -# * fail/other + check exits 0 -> stale-fail (advisory: re-grade candidate) -# --------------------------------------------------------------------------- -# Tools the checks shell out to that are NOT present on a bare runner. -# -# Why this exists: a check whose tool is absent is indistinguishable from a -# check that ran and failed, so the verifier accused the repo of claiming a -# fake pass. `xmllint` missing surfaced as exit 127; ripgrep missing made -# 3-practice/release-pre-flight/v1-audit.sh exit 2, so its greps matched nothing and -# returned 1. All seven were reported as "the pass is not real" — and all -# seven passes were in fact real. -# -# Newly diagnosed; this is NOT standards#381. That issue is REGISTRY.a2ml -# source_hash drift in build-registry.sh — the *first* step of the same CI -# job, a different script and a different mechanism, still unaddressed. -# -# Declared explicitly rather than inferred: splitting a check string to guess -# its commands is unreliable (a quoted regex like "a\|b\|c", or `[ $(…) -ge -# 25 ]`, both misparse) and a mis-parse would invent failures — the very sin -# this guard exists to prevent. -# -# Add a tool here only if a check genuinely needs it AND it is absent from a -# default ubuntu-latest image. CI installs these in registry-verify.yml. -# Measured against the current scorecards: `xmllint` is named by 4 checks and -# `jq` by 1; `rg` is named by none but is required *transitively* — the six -# release-pre-flight checks invoke v1-audit.sh, which hard-exits 2 without it. -# (`python3` and `cargo` are also referenced but ship on ubuntu-latest.) -VERIFY_OPTIONAL_TOOLS="rg xmllint jq" - -check_missing_tools() { - local chk="$1" t out="" - for t in $VERIFY_OPTIONAL_TOOLS; do - # Word-boundary containment test, no tokenising: only reports a tool that - # the check actually names and that is actually not installed. - case " $chk " in - *[!A-Za-z0-9_-]"$t"[!A-Za-z0-9_-]*) - command -v "$t" >/dev/null 2>&1 || out="$out$t " ;; - esac - done - printf '%s' "$out" -} - -run_verify() { - local rc=0 grounded=0 selfasserted=0 broken=0 stale=0 unrunnable=0 - local f base id status chk crc miss t absent="" - echo "== scorecard --verify: running pass-row checks ==" - - # ---- environment preflight ------------------------------------------- - # Per-check tool detection cannot be complete: a check may invoke a repo - # script that needs a tool the check string never names. release-pre-flight - # checks call v1-audit.sh, which exits 2 when ripgrep is missing; its greps - # then match nothing and the verifier concluded SIX claimed passes were - # "not real". They were real. Rather than risk that class of false - # accusation, refuse to verify at all in an incomplete environment. - for t in $VERIFY_OPTIONAL_TOOLS; do - command -v "$t" >/dev/null 2>&1 || absent="$absent$t " - done - if [ -n "$absent" ]; then - echo "⛔ verify environment incomplete — missing: ${absent% }" >&2 - echo " Checks (and the scripts they invoke) could fail for lack of" >&2 - echo " tooling rather than because a claim is false, so pass-rows will" >&2 - echo " NOT be judged. Install the tools and re-run:" >&2 - echo " sudo apt-get install -y ripgrep libxml2-utils jq" >&2 - return 1 - fi - shopt -s nullglob - for f in "$SCDIR"/*.scorecard.a2ml; do - base="$(basename "$f" .scorecard.a2ml)" - # count self-asserted passes (pass rows minus pass rows with checks) - local p_total p_chk - p_total="$(parse_scorecard "$f" | awk -F'\t' '$2=="pass"' | wc -l)" - p_chk="$(parse_scorecard "$f" | awk -F'\t' '$2=="pass" && $4==1' | wc -l)" - selfasserted=$((selfasserted + p_total - p_chk)) - while IFS=$'\x1f' read -r id status chk; do - [ -z "$chk" ] && continue - # A check whose tooling is absent did not run, so it can neither ground - # nor refute the claimed status. Report it as unrunnable — still a - # failure (an unverifiable pass must never go green), but described - # accurately so the fix is "install the tool", not "the claim is a lie". - miss="$(check_missing_tools "$chk")" - if [ -n "$miss" ]; then - echo " ⛔ $base/$id: check CANNOT RUN — missing tool(s): ${miss% }" - echo " check: $chk" - unrunnable=$((unrunnable + 1)); rc=1 - continue - fi - # Checks run read-only from the repo root; they must not mutate. - ( cd "$(git rev-parse --show-toplevel)" && bash -c "$chk" ) >/dev/null 2>&1; crc=$? - if [ "$status" = "pass" ]; then - if [ "$crc" -eq 0 ]; then - grounded=$((grounded + 1)) - elif [ "$crc" -eq 127 ]; then - echo " ⛔ $base/$id: check CANNOT RUN — command not found (exit 127)" - echo " check: $chk" - unrunnable=$((unrunnable + 1)); rc=1 - else - echo " ❌ $base/$id: claimed PASS but check exited $crc — the pass is not real" - echo " check: $chk" - broken=$((broken + 1)); rc=1 - fi - else - if [ "$crc" -eq 0 ]; then - echo " ℹ️ $base/$id: status=$status but its check now passes — re-grade candidate (stale-fail)" - stale=$((stale + 1)) - fi - fi - done < <(extract_checks "$f") - done - shopt -u nullglob - echo " ── verify: $grounded grounded pass · $broken broken pass · $unrunnable unrunnable · $selfasserted self-asserted pass · $stale stale-fail" - if [ "$broken" -gt 0 ]; then - echo "❌ --verify FAILED: $broken claimed pass(es) whose check does not hold" >&2 - fi - if [ "$unrunnable" -gt 0 ]; then - echo "⛔ --verify FAILED: $unrunnable check(s) could not run (missing tooling)." >&2 - echo " These are NOT fake passes — the checks never executed. Install the" >&2 - echo " listed tools and re-run. CI installs them in registry-verify.yml." >&2 - fi - return $rc -} - -# Read a [scorecard] header field. -sc_field() { # file key - grep -E "^$2 = \"" "$1" 2>/dev/null | head -1 | sed -E "s/^$2 = \"//; s/\".*$//" -} - -# --------------------------------------------------------------------------- -# Emit the dashboard to stdout. -# --------------------------------------------------------------------------- -emit_dashboard() { - local total_specs=0 scored_specs=0 - local g_must=0 g_must_pass=0 g_must_fail=0 g_reqs=0 g_reqs_sys=0 - - cat <<'HEADER' -// SPDX-License-Identifier: CC-BY-SA-4.0 -// 0-canon/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 '[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=() - while IFS=$'\t' read -r id name; do - [ -z "$id" ] && continue - total_specs=$((total_specs + 1)) - local file="$SCDIR/$id.scorecard.a2ml" - if [ ! -f "$file" ]; then - missing+=("$id") - printf '| `+%s+` | ⚠️ no scorecard | – | – | – | – | – | –\n' "$id" - continue - fi - scored_specs=$((scored_specs + 1)) - - # tallies - local m_t=0 m_p=0 m_f=0 s_t=0 s_p=0 c_t=0 c_p=0 reqs=0 reqs_sys=0 p_all=0 p_chk=0 - local parsed; parsed="$(parse_scorecard "$file")" - while IFS=$'\t' read -r tier status has_sys has_chk; do - [ -z "$tier" ] && continue - reqs=$((reqs + 1)); [ "$has_sys" = "1" ] && reqs_sys=$((reqs_sys + 1)) - if [ "$status" = pass ]; then - p_all=$((p_all + 1)); [ "$has_chk" = "1" ] && p_chk=$((p_chk + 1)) - fi - case "$tier" in - must) m_t=$((m_t+1)); [ "$status" = pass ] && m_p=$((m_p+1)); [ "$status" = fail ] && m_f=$((m_f+1)) ;; - should) s_t=$((s_t+1)); [ "$status" = pass ] && s_p=$((s_p+1)) ;; - could) c_t=$((c_t+1)); [ "$status" = pass ] && c_p=$((c_p+1)) ;; - esac - done <<< "$parsed" - - local verdict; if [ "$m_f" -gt 0 ]; then verdict="❌ gap"; else verdict="✅ met"; fi - local cov="n/a" - [ "$reqs" -gt 0 ] && cov="$(awk "BEGIN{printf \"%d%%\", ($reqs_sys/$reqs)*100}")" - local grounded="–" - [ "$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' \ - "$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)) - g_reqs=$((g_reqs + reqs)); g_reqs_sys=$((g_reqs_sys + reqs_sys)) - g_pass=$((g_pass + p_all)); g_pass_chk=$((g_pass_chk + p_chk)) - done < <(local_specs) - - # Rollup - local est_cov="n/a" - [ "$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\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[@]}")" - fi - - cat <<'FOOTER' - -== How this dashboard stays honest - -.... -scorecards/*.scorecard.a2ml ──► scripts/build-scorecards.sh ──► 0-canon/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). -* `+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+`. -FOOTER -} - -# --------------------------------------------------------------------------- -# Orphan check: every scorecard must key to a LOCAL registered spec. -# --------------------------------------------------------------------------- -check_orphans() { - local ids; ids="$(local_specs | cut -f1)" - local rc=0 f base id - shopt -s nullglob - for f in "$SCDIR"/*.scorecard.a2ml; do - base="$(basename "$f" .scorecard.a2ml)" - id="$(sc_field "$f" spec_id)" - if [ "$base" != "$id" ]; then - echo "ORPHAN: $f — filename '$base' != spec_id '$id'" >&2; rc=1; fi - if ! grep -qx "$id" <<< "$ids"; then - echo "ORPHAN: $f — spec_id '$id' is not a LOCAL spec in $REGISTRY" >&2; rc=1; fi - done - shopt -u nullglob - return $rc -} - -# --------------------------------------------------------------------------- -# Optional JSON-schema validation of every scorecard, if a validator is present. -# (Best-effort: the format is TOML-ish, so we validate the parsed logical form -# via parse_scorecard, which enforces the schema's load-bearing rules. A real -# JSON-schema check runs estate-side; here we ensure parseability + rules.) -# --------------------------------------------------------------------------- -validate_all() { - local rc=0 f - shopt -s nullglob - for f in "$SCDIR"/*.scorecard.a2ml; do - parse_scorecard "$f" >/dev/null || rc=1 - done - shopt -u nullglob - return $rc -} - -# --- run --------------------------------------------------------------------- -validate_all || { echo "error: one or more scorecards are malformed (see above)" >&2; exit 1; } -check_orphans || { echo "error: orphan scorecard(s) (see above)" >&2; exit 1; } - -# Missing-scorecard gate (strict only). -if [ "$STRICT" = "1" ]; then - miss="$(comm -23 <(local_specs | cut -f1 | sort) <(ls "$SCDIR"/*.scorecard.a2ml 2>/dev/null | xargs -n1 basename 2>/dev/null | sed 's/\.scorecard\.a2ml$//' | sort) || true)" - if [ -n "$miss" ]; then - echo "STRICT: the following LOCAL specs have no scorecard:" >&2 - echo "$miss" | sed 's/^/ - /' >&2 - exit 1 - fi -fi - -# Executable grounding gate (--verify): run every pass-row check. -if [ "$VERIFY" = "1" ]; then - run_verify || exit 1 -fi - -if [ "$MODE" = "check" ]; then - tmp="$(mktemp)" - emit_dashboard > "$tmp" - if ! diff -q "$tmp" "$DASHBOARD" >/dev/null 2>&1; then - echo "DRIFT: $DASHBOARD is stale — run 'just scorecards'"; rm -f "$tmp"; exit 1 - fi - rm -f "$tmp" - echo "OK: $DASHBOARD is in sync with the scorecards." - exit 0 -fi - -emit_dashboard > "$DASHBOARD" -echo "Wrote $DASHBOARD." diff --git a/scripts/check-implementation-inside-canon.sh b/scripts/check-implementation-inside-canon.sh deleted file mode 100755 index 6754c94d5..000000000 --- a/scripts/check-implementation-inside-canon.sh +++ /dev/null @@ -1,136 +0,0 @@ -#!/usr/bin/env bash -# SPDX-License-Identifier: MPL-2.0 -# check-implementation-inside-canon.sh — executable reference for HYP-S009. -# -# A directory is canonical only when .machine_readable/REGISTRY.a2ml names it -# as a local spec home. Local entries omit `kind`; external pointers explicitly -# set `kind = "external"`. Only tracked files are inspected, matching what a -# clean CI checkout and a pull-request scanner can observe. -# -# Usage: check-implementation-inside-canon.sh [REPOSITORY] -# Exit 0: no findings; 1: implementation manifests found; 2: bad input/schema. - -set -euo pipefail - -repo=${1:-.} -registry="$repo/.machine_readable/REGISTRY.a2ml" - -if ! git -C "$repo" rev-parse --git-dir >/dev/null 2>&1; then - echo "implementation-inside-canon: not a git repository: $repo" >&2 - exit 2 -fi - -if [ ! -f "$registry" ]; then - echo "implementation-inside-canon: missing registry: $registry" >&2 - exit 2 -fi - -is_product_manifest() { - case "$1" in - Cargo.toml|deno.json|package.json|Containerfile|compose.yaml|CNAME|ads.txt) - return 0 - ;; - *) - return 1 - ;; - esac -} - -is_template_or_fixture() { - case "/$1/" in - */examples/*|*/templates/*|*/test/fixtures/*|*/tests/fixtures/*) - return 0 - ;; - *) - return 1 - ;; - esac -} - -guix_is_non_stub() { - # A comment/whitespace-only guix.scm is a documented placeholder, not a - # build surface. Any executable Scheme form makes it a product manifest. - awk ' - /^[[:space:]]*($|;)/ { next } - { substantive = 1 } - END { exit(substantive ? 0 : 1) } - ' "$1" -} - -findings=0 - -while IFS=$'\t' read -r spec_id home; do - [ -n "$home" ] || continue - - case "/$home/" in - //*|*/../*|*/./*) - echo "implementation-inside-canon: unsafe registry home for $spec_id: $home" >&2 - exit 2 - ;; - esac - - while IFS= read -r -d '' tracked; do - base=${tracked##*/} - report=false - - if is_template_or_fixture "$tracked"; then - continue - fi - - if is_product_manifest "$base"; then - report=true - elif [ "$base" = guix.scm ] && guix_is_non_stub "$repo/$tracked"; then - report=true - fi - - if [ "$report" = true ]; then - printf 'HYP-S009\t%s\t%s\n' "$spec_id" "$tracked" - findings=$((findings + 1)) - fi - done < <(git -C "$repo" ls-files -z -- "$home") -done < <( - awk ' - function unquote(value) { - sub(/^[[:space:]]*"/, "", value) - sub(/"[[:space:]]*$/, "", value) - return value - } - function emit() { - if (in_spec && id != "" && home != "" && tolower(kind) != "external") { - print id "\t" home - } - } - /^\[\[spec\]\][[:space:]]*$/ { - emit() - in_spec = 1 - id = home = kind = "" - next - } - in_spec && /^[[:space:]]*id[[:space:]]*=/ { - value = $0 - sub(/^[^=]*=[[:space:]]*/, "", value) - id = unquote(value) - next - } - in_spec && /^[[:space:]]*home[[:space:]]*=/ { - value = $0 - sub(/^[^=]*=[[:space:]]*/, "", value) - home = unquote(value) - next - } - in_spec && /^[[:space:]]*kind[[:space:]]*=/ { - value = $0 - sub(/^[^=]*=[[:space:]]*/, "", value) - kind = unquote(value) - next - } - END { emit() } - ' "$registry" -) - -if [ "$findings" -gt 0 ]; then - echo "implementation-inside-canon: $findings tracked product/build manifest(s) in local canonical homes" >&2 - exit 1 -fi - -echo "implementation-inside-canon: clean" diff --git a/scripts/check-workflow-staleness.sh b/scripts/check-workflow-staleness.sh index e46ebbb1a..fcff1f39c 100755 --- a/scripts/check-workflow-staleness.sh +++ b/scripts/check-workflow-staleness.sh @@ -16,12 +16,12 @@ set -eo pipefail # (observed live in stapeln — 5a93d9d→d72fe5a→4ddc926 in ~30 min, three # forced 3-file bumps). The gate became a treadmill instead of a guard. # -# The fix mirrors the estate's existing staleness idiom (Hypatia HYP-S006 -# `registry-staleness`, which tolerates drift for `stale_after_days` before it -# escalates): a pin PASSES if it is a genuine ancestor of standards HEAD that -# is *within a recency window* — at most STALENESS_WINDOW_COMMITS commits -# behind HEAD, OR at most STALENESS_WINDOW_DAYS days old (union; either -# qualifies). +# The fix mirrored the staleness idiom of Hypatia HYP-S006 +# `registry-staleness` (retired 2026-10-09), which tolerated drift for +# `stale_after_days` before it escalated. A pin PASSES if it is a genuine +# ancestor of standards HEAD that is *within a recency window* — at most +# STALENESS_WINDOW_COMMITS commits behind HEAD, OR at most +# STALENESS_WINDOW_DAYS days old (union; either qualifies). # # ── Why age alone no longer FAILS (2026-07-21) ────────────────────────────── # The window was still a clock, just a slower one. standards moves ~2.6 @@ -61,7 +61,7 @@ set -eo pipefail # is available for ancestry/age math). # STALENESS_WINDOW_COMMITS — max commits-behind-HEAD a pin may be (default 50). # STALENESS_WINDOW_DAYS — max age in days a pin may be (default 14, matching -# HYP-S006 stale_after_days). Advisory since +# the retired HYP-S006 stale_after_days). Advisory since # 2026-07-21: exceeding it emits a notice, not an # error. # STALENESS_STANDARDS_NWO — owner/repo a pin must belong to, used for the diff --git a/scripts/tests/build-registry-test.sh b/scripts/tests/build-registry-test.sh deleted file mode 100755 index 96b4fea3c..000000000 --- a/scripts/tests/build-registry-test.sh +++ /dev/null @@ -1,150 +0,0 @@ -#!/usr/bin/env bash -# SPDX-License-Identifier: MPL-2.0 -# SPDX-FileCopyrightText: 2026 Jonathan D.A. Jewell (hyperpolymath) -set -uo pipefail -# -# Regression cover for scripts/build-registry.sh. -# -# REGISTRY.a2ml and TOPOLOGY.adoc are generated artefacts, and `--check` is the -# gate behind the required context "Registry + topology in sync". A stale -# registry does not fail quietly in one place: four scorecard rows ground their -# `status = "pass"` on `build-registry.sh --check`, so one stale file also fails -# `build-scorecards.sh --verify` and surfaces as unrelated-looking assertion -# failures in the wave-3 suite, a long way from the cause. -# -# Everything runs inside a throwaway CLONE of the repository. build-registry.sh -# cd's to the git toplevel and reads the INDEX (`git ls-files -s`), so it needs -# a real repo; and planting drift in the developer's own worktree would risk -# destroying uncommitted registry work during cleanup. - -ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)" -TMP="$(mktemp -d)" -trap 'rm -rf "$TMP"' EXIT - -pass=0 fail=0 -ok() { echo " ✅ $1"; pass=$((pass + 1)); } -bad() { echo " ❌ $1"; fail=$((fail + 1)); } - -REPO="$TMP/repo" -if ! git clone -q "$ROOT" "$REPO" 2>/dev/null; then - echo " ❌ could not clone the repository under test"; exit 1 -fi -cd "$REPO" || exit 1 -git config user.name "Standards regression test" -git config user.email "standards-regression@example.invalid" - -# The clone carries the COMMITTED generator. Overlay the working-tree copy so -# this suite exercises the script UNDER REVIEW — without this, a break -# introduced in a pull request is invisible here and the tests pass for the -# wrong reason. -cp "$ROOT/scripts/build-registry.sh" scripts/build-registry.sh - -REG=".machine_readable/REGISTRY.a2ml" -TOP="TOPOLOGY.adoc" -# Carry the proposed artefacts too: a local regeneration must be testable -# before committing. Stage only in this throwaway clone so the mutation -# controls below restore these exact inputs with git checkout. -cp "$ROOT/$REG" "$REG" -cp "$ROOT/$TOP" "$TOP" -git add -- "$REG" "$TOP" - -echo "== the proposed artefacts are in sync with the committed source tree ==" -out="$(bash scripts/build-registry.sh --check 2>&1)"; rc=$? -if [ "$rc" -eq 0 ] && printf '%s' "$out" | grep -qF "OK:"; then - ok "--check reports OK on a clean checkout" -else - bad "--check on a clean checkout (rc=$rc)"; printf '%s\n' "$out" | sed 's/^/ | /' -fi - -echo -echo "== --check detects a mutated artefact ==" -printf '\n# planted drift\n' >> "$REG" -out="$(bash scripts/build-registry.sh --check 2>&1)"; rc=$? -if [ "$rc" -eq 1 ] && printf '%s' "$out" | grep -qF "DRIFT: $REG"; then - ok "a mutated REGISTRY.a2ml is reported as DRIFT" -else - bad "mutated registry not caught (rc=$rc)"; printf '%s\n' "$out" | sed 's/^/ | /' -fi -git checkout -- "$REG" - -printf '\n// planted drift\n' >> "$TOP" -out="$(bash scripts/build-registry.sh --check 2>&1)"; rc=$? -if [ "$rc" -eq 1 ] && printf '%s' "$out" | grep -qF "DRIFT: $TOP"; then - ok "a mutated TOPOLOGY.adoc is reported as DRIFT" -else - bad "mutated topology not caught (rc=$rc)"; printf '%s\n' "$out" | sed 's/^/ | /' -fi -git checkout -- "$TOP" - - -echo -echo "== --check detects a tree change the artefacts do not yet record ==" -# The real-world fault: someone adds a tracked file under a spec's home and -# forgets `just registry`. source_hash is sha256 over `git ls-files -s `, -# which reads the INDEX — so the file must be STAGED for this to bite, which is -# also why --check belongs after `git add`, never on a dirty worktree. -printf 'planted registry probe\n' > 0-canon/constitution/zzz-registry-probe.adoc -git add 0-canon/constitution/zzz-registry-probe.adoc -out="$(bash scripts/build-registry.sh --check 2>&1)"; rc=$? -if [ "$rc" -eq 1 ] && printf '%s' "$out" | grep -qF "DRIFT:"; then - ok "a newly-tracked file under a spec home makes the artefacts stale" -else - bad "new tracked file under a spec home did not drift (rc=$rc)"; printf '%s\n' "$out" | sed 's/^/ | /' -fi - -echo -echo "== the gate's scope is the spec homes, not the whole tree ==" -# Worth pinning down so nobody later mistakes this gate for whole-tree coverage: -# a tracked file outside every declared home legitimately does NOT drift the -# registry, because no source_hash covers it. -git rm -q --cached 0-canon/constitution/zzz-registry-probe.adoc >/dev/null 2>&1 -rm -f 0-canon/constitution/zzz-registry-probe.adoc -mkdir -p .machine_readable/scorecards -printf '[metadata]\nname = "zzz-probe"\n' > .machine_readable/scorecards/zzz-registry-probe.scorecard.a2ml -git add .machine_readable/scorecards/zzz-registry-probe.scorecard.a2ml -out="$(bash scripts/build-registry.sh --check 2>&1)"; rc=$? -if [ "$rc" -eq 0 ]; then - ok "a tracked file outside every spec home does not drift the registry" -else - bad "a file outside every spec home unexpectedly drifted the registry (rc=$rc)" - printf '%s\n' "$out" | sed 's/^/ | /' -fi -git rm -q --cached .machine_readable/scorecards/zzz-registry-probe.scorecard.a2ml >/dev/null 2>&1 -rm -f .machine_readable/scorecards/zzz-registry-probe.scorecard.a2ml - -echo -echo "== regenerating clears the drift ==" -# Re-plant the in-scope drift, then prove the generator resolves it. -printf 'planted registry probe\n' > 0-canon/constitution/zzz-registry-probe.adoc -git add 0-canon/constitution/zzz-registry-probe.adoc -bash scripts/build-registry.sh >/dev/null 2>&1 -out="$(bash scripts/build-registry.sh --check 2>&1)"; rc=$? -if [ "$rc" -eq 0 ] && printf '%s' "$out" | grep -qF "OK:"; then - ok "a regenerated registry is back in sync" -else - bad "regeneration did not clear the drift (rc=$rc)"; printf '%s\n' "$out" | sed 's/^/ | /' -fi - -echo -echo "== the generator is deterministic ==" -# The header promises "Run twice -> byte-identical output" and "intentionally NO -# generation timestamp". If that ever stops holding, the gate becomes a coin -# toss that reddens unrelated pull requests. -bash scripts/build-registry.sh >/dev/null 2>&1 -r1="$(sha256sum "$REG" | cut -d' ' -f1)"; t1="$(sha256sum "$TOP" | cut -d' ' -f1)" -bash scripts/build-registry.sh >/dev/null 2>&1 -r2="$(sha256sum "$REG" | cut -d' ' -f1)"; t2="$(sha256sum "$TOP" | cut -d' ' -f1)" -[ "$r1" = "$r2" ] && ok "two REGISTRY.a2ml generations are byte-identical" \ - || bad "REGISTRY.a2ml is not deterministic" -[ "$t1" = "$t2" ] && ok "two TOPOLOGY.adoc generations are byte-identical" \ - || bad "TOPOLOGY.adoc is not deterministic" - -if grep -q 'generated' "$REG" && grep -qiE '^[[:space:]]*generated(_at)?[[:space:]]*=' "$REG"; then - bad "REGISTRY.a2ml carries a generation timestamp — that would defeat --check" -else - ok "REGISTRY.a2ml carries no generation timestamp" -fi - -echo -echo "build-registry regression: $pass passed, $fail failed" -[ "$fail" -eq 0 ] diff --git a/scripts/tests/build-scorecards-test.sh b/scripts/tests/build-scorecards-test.sh deleted file mode 100644 index eb1f965a9..000000000 --- a/scripts/tests/build-scorecards-test.sh +++ /dev/null @@ -1,114 +0,0 @@ -#!/usr/bin/env bash -# SPDX-License-Identifier: MPL-2.0 -set -uo pipefail -# -# Wave-3 scorecard/dashboard regression test. -# -# The generator must be honest and deterministic: -# * a `pass` without evidence is rejected, -# * an orphan scorecard (spec_id not in the registry) is rejected, -# * `aspirational` never counts as a MUST pass, -# * regeneration is idempotent, and --check detects drift. - -ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)" -GEN="$ROOT/scripts/build-scorecards.sh" -SCDIR="$ROOT/.machine_readable/scorecards" -TMP="$(mktemp -d)"; trap 'rm -rf "$TMP"; rm -f "$SCDIR"/zzz-*.scorecard.a2ml' EXIT - -pass=0 fail=0 -ok() { echo " ✅ $1"; pass=$((pass + 1)); } -bad() { echo " ❌ $1"; fail=$((fail + 1)); } - -echo "== generator honesty ==" -# pass without evidence -> rejected -cat > "$SCDIR/zzz-a.scorecard.a2ml" <<'EOF' -[scorecard] -spec_id = "a2ml" -version = "1.0.0" -assessed_date = "2026-07-03" -assessor = "x" - -[[must]] -id = "M1" -text = "x" -system = "none" -status = "pass" -effects = "y" -EOF -if bash "$GEN" >/dev/null 2>&1; then bad "pass-without-evidence was NOT rejected"; else ok "pass-without-evidence rejected"; fi -rm -f "$SCDIR/zzz-a.scorecard.a2ml" - -# orphan spec_id -> rejected -cat > "$SCDIR/zzz-orphan.scorecard.a2ml" <<'EOF' -[scorecard] -spec_id = "definitely-not-a-registered-spec" -version = "1.0.0" -assessed_date = "2026-07-03" -assessor = "x" - -[[must]] -id = "M1" -text = "x" -system = "none" -status = "fail" -effects = "y" -EOF -if bash "$GEN" >/dev/null 2>&1; then bad "orphan scorecard was NOT rejected"; else ok "orphan scorecard rejected"; fi -rm -f "$SCDIR/zzz-orphan.scorecard.a2ml" - -echo "== determinism + drift ==" -# regenerate twice -> identical -bash "$GEN" >/dev/null 2>&1 -h1="$(sha256sum "$ROOT/0-canon/COMPLIANCE-DASHBOARD.adoc" | cut -d' ' -f1)" -bash "$GEN" >/dev/null 2>&1 -h2="$(sha256sum "$ROOT/0-canon/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// drift\n' >> "$ROOT/0-canon/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 - -echo "== --verify (executable grounding; Wave 7) ==" -# pick any real scorecard to mutate, restore after -TGT="$(ls "$SCDIR"/*.scorecard.a2ml | head -1)" -cp "$TGT" "$TMP/orig.a2ml" -# (a) a pass row with a FAILING check must fail --verify (broken pass). -# Pass rows are now fully grounded (each already carries a check), so REPLACE -# every existing check with `false` rather than inserting a duplicate line -# (the parser takes the last check line in a block). -sed 's/^check = ".*"$/check = "false"/' "$TMP/orig.a2ml" > "$TGT" -if bash "$GEN" --verify >/dev/null 2>&1; then bad "--verify missed a broken pass-check"; else ok "--verify fails on a broken pass-check"; fi -cp "$TMP/orig.a2ml" "$TGT" -# (b) pass rows with HOLDING checks keep --verify green (replace all with `true`) -sed 's/^check = ".*"$/check = "true"/' "$TMP/orig.a2ml" > "$TGT" -bout="$(bash "$GEN" --verify 2>&1)"; brc=$? -if [ "$brc" -eq 0 ]; then ok "--verify green with holding pass-checks"; else - # Print WHY this failed. A bare `>/dev/null 2>&1` here once cost two CI - # round-trips to diagnose: a stale generated file (REGISTRY.a2ml) broke a - # real pass-check in a DIFFERENT scorecard, and all this assertion could - # say was "it failed". Only pass rows in other scorecards can do this — - # every check in the mutated fixture is `true`. - printf ' --- offending --verify output ---\n%s\n ---------------------------------\n' \ - "$(printf '%s\n' "$bout" | grep -Ei 'FAILED|broken|could not run|not hold|✗|❌' | head -10)" >&2 - bad "--verify failed on holding checks" -fi -# (c) grounded count appears in verify output (capture first: `grep -q` closing -# the pipe early can SIGPIPE the still-writing generator under pipefail) -cout="$(bash "$GEN" --verify 2>&1 || true)" -if grep -qE '[1-9][0-9]* grounded pass' <<< "$cout"; then ok "grounded passes counted"; else bad "grounded count missing"; fi -cp "$TMP/orig.a2ml" "$TGT" -# (d) a FAIL row whose check passes is a stale-fail ADVISORY (not fatal) -awk '1; /^status = "fail"$/ && !done {print "check = \"true\""; done=1}' "$TMP/orig.a2ml" > "$TGT" -vout="$(bash "$GEN" --verify 2>&1)"; vrc=$? -if [ "$vrc" -eq 0 ] && grep -q 'stale-fail' <<< "$vout"; then ok "stale-fail is advisory, reported, non-fatal"; else - # some scorecards may have no fail rows; treat absence of any fail row as skip-ok - grep -q '^status = "fail"$' "$TMP/orig.a2ml" && { printf ' --- verify output ---\n%s\n ---\n' "$(printf '%s\n' "$vout" | tail -10)" >&2; bad "stale-fail not handled (rc=$vrc)"; } || ok "no fail rows in fixture (skip)" -fi -cp "$TMP/orig.a2ml" "$TGT" -bash "$GEN" >/dev/null 2>&1 # restore dashboard - -echo -echo "Wave-3 scorecard regression: $pass passed, $fail failed" -[ "$fail" -eq 0 ] diff --git a/scripts/tests/wave8-gates-test.sh b/scripts/tests/wave8-gates-test.sh index 8cf0a4ec4..6ad96d9a5 100755 --- a/scripts/tests/wave8-gates-test.sh +++ b/scripts/tests/wave8-gates-test.sh @@ -7,7 +7,7 @@ set -uo pipefail # Every promoted gate must demonstrably BLOCK on bad input and PASS on good: # * apply-baseline.sh blocking mode: unbaselined high/critical finding fails; # baselined finding passes; EXPIRED baseline entry no longer suppresses. -# * Mustfile PR gate: the exact commands registry-verify.yml runs succeed on +# * Mustfile PR gate: the exact commands k9-contractile.yml runs succeed on # this repo, and a broken Mustfile fails them (via the wave-1 runner). ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)" @@ -54,7 +54,7 @@ EOF bash "$AB" "$TMP/low.json" "$TMP/empty-baseline.json" blocking >/dev/null 2>&1 expect 0 $? "low-severity finding stays below blocking threshold" -echo "== Mustfile PR gate (exact registry-verify.yml commands) ==" +echo "== Mustfile PR gate (exact k9-contractile.yml commands) ==" ( cd "$ROOT" && bash scripts/check-mustfile-structure.sh >/dev/null 2>&1 ) expect 0 $? "structural check passes on this repo" ( cd "$ROOT" && bash scripts/run-mustfile.sh >/dev/null 2>&1 ) diff --git a/standards-map.toml b/standards-map.toml index 699a3802b..e5a5d4eeb 100644 --- a/standards-map.toml +++ b/standards-map.toml @@ -4,9 +4,10 @@ # standards-map.toml - the machine-readable map of hyperpolymath/standards. # # WHY THIS EXISTS -# .machine_readable/REGISTRY.a2ml indexes 33 SPECS. This repo has 118 top-level -# entries. The other 85 have no declared domain, kind, lifecycle or gate, and -# THAT absence is what makes the repo unreadable by machine and by human. +# The spec registry (retired 2026-10-09, see REGISTRY.adoc) indexed 33 SPECS. +# This repo had 118 top-level entries. The other 85 had no declared domain, +# kind, lifecycle or gate, and THAT absence is what made the repo unreadable +# by machine and by human. # # BIDIRECTIONAL, LIKE THE SPINE'S root-allow.txt # An entry here MUST exist. A path that exists MUST be listed here. @@ -227,7 +228,7 @@ lifecycle = "deprecated" canonical = false canon_slot = "" canonical_doc = "1-formats/a2ml//index.adoc" -gate = "registry-verify" +gate = "" note = "a2ml/ evicted 2026-08-28 by 24a12d6f; these 7 profile dirs (191 files) stayed behind. Finish the eviction or revert it. [1-formats district move: relocated to 1-formats/a2ml/meta/; this path keeps a POINTER.adoc stub]" [[entry]] @@ -240,7 +241,7 @@ lifecycle = "deprecated" canonical = false canon_slot = "" canonical_doc = "1-formats/a2ml//index.adoc" -gate = "registry-verify" +gate = "" note = "a2ml/ evicted 2026-08-28 by 24a12d6f; these 7 profile dirs (191 files) stayed behind. Finish the eviction or revert it. [1-formats district move: relocated to 1-formats/a2ml/agentic/; this path keeps a POINTER.adoc stub]" [[entry]] @@ -253,7 +254,7 @@ lifecycle = "deprecated" canonical = false canon_slot = "" canonical_doc = "1-formats/a2ml//index.adoc" -gate = "registry-verify" +gate = "" note = "a2ml/ evicted 2026-08-28 by 24a12d6f; these 7 profile dirs (191 files) stayed behind. Finish the eviction or revert it. [1-formats district move: relocated to 1-formats/a2ml/state/; this path keeps a POINTER.adoc stub]" [[entry]] @@ -279,7 +280,7 @@ lifecycle = "deprecated" canonical = false canon_slot = "" canonical_doc = "1-formats/a2ml//index.adoc" -gate = "registry-verify" +gate = "" note = "a2ml/ evicted 2026-08-28 by 24a12d6f; these 7 profile dirs (191 files) stayed behind. Finish the eviction or revert it. [1-formats district move: relocated to 1-formats/a2ml/anchor/; this path keeps a POINTER.adoc stub]" [[entry]] @@ -292,7 +293,7 @@ lifecycle = "deprecated" canonical = false canon_slot = "" canonical_doc = "1-formats/a2ml//index.adoc" -gate = "registry-verify" +gate = "" note = "a2ml/ evicted 2026-08-28 by 24a12d6f; these 7 profile dirs (191 files) stayed behind. Finish the eviction or revert it. [1-formats district move: relocated to 1-formats/a2ml/ecosystem/; this path keeps a POINTER.adoc stub]" [[entry]] @@ -305,7 +306,7 @@ lifecycle = "deprecated" canonical = false canon_slot = "" canonical_doc = "1-formats/a2ml//index.adoc" -gate = "registry-verify" +gate = "" note = "a2ml/ evicted 2026-08-28 by 24a12d6f; these 7 profile dirs (191 files) stayed behind. Finish the eviction or revert it. [1-formats district move: relocated to 1-formats/a2ml/neurosym/; this path keeps a POINTER.adoc stub]" [[entry]] @@ -318,7 +319,7 @@ lifecycle = "deprecated" canonical = false canon_slot = "" canonical_doc = "1-formats/a2ml//index.adoc" -gate = "registry-verify" +gate = "" note = "a2ml/ evicted 2026-08-28 by 24a12d6f; these 7 profile dirs (191 files) stayed behind. Finish the eviction or revert it. [1-formats district move: relocated to 1-formats/a2ml/playbook/; this path keeps a POINTER.adoc stub]" [[entry]] @@ -952,7 +953,7 @@ lifecycle = "generated" canonical = true canon_slot = "" canonical_doc = ".machine_readable/index.adoc" -gate = "registry-verify" +gate = "k9-contractile" note = "F2 CLOSED — MIGRATION CANCELLED. This entry used to point at machine-readable/: the spine un-hid its tree in 2026-08 and its root-allow.txt called the hyphenated form canonical, so this repo was to adopt it. The owner ruling of 2026-09-17 settles R-A the other way, and the census backs it: rsr-template-repo's docs/governance/TEMPLATE-LINEAGE-AUDIT.adoc records 48 repos on the dotted form against 9 hyphenated at the divergence. The spine was the minority; this repo's spelling was always the majority. target is now the identity path: the canon does NOT move." [[entry]]