diff --git a/.machine_readable/template-capability-gates.toml b/.machine_readable/template-capability-gates.toml index edab5836f..5125ba98a 100644 --- a/.machine_readable/template-capability-gates.toml +++ b/.machine_readable/template-capability-gates.toml @@ -31,7 +31,7 @@ known = ["rust", "zig", "agda", "idris2", "haskell", "gleam", "elixir", "affines # GitHub resolves community-health files from .github/ as readily as the root, # and the estate's canonical location for them IS .github/ - naming only the # root form marked every conforming repo as missing them. -paths = ["README.adoc", "EXPLAINME.adoc|docs/EXPLAINME.adoc", "LICENSE", "SECURITY.md|.github/SECURITY.md", "CONTRIBUTING.md|.github/CONTRIBUTING.md", "CODE_OF_CONDUCT.md|.github/CODE_OF_CONDUCT.md", "CHANGELOG.adoc|CHANGELOG.md", "0-AI-MANIFEST.a2ml", "machine-readable/descriptiles/|.machine_readable/descriptiles/", "machine-readable/rsr-profile.a2ml|.machine_readable/rsr-profile.a2ml", ".well-known/", ".gitignore", "Justfile"] +paths = ["README.adoc", "EXPLAINME.adoc|docs/EXPLAINME.adoc", "LICENSE", "SECURITY.md|.github/SECURITY.md", "CONTRIBUTING.md|.github/CONTRIBUTING.md", "CODE_OF_CONDUCT.md|.github/CODE_OF_CONDUCT.md", "CHANGELOG.adoc|CHANGELOG.md", "0-AI-MANIFEST.a2ml", ".machine_readable/descriptiles/|machine-readable/descriptiles/", ".machine_readable/rsr-profile.a2ml|machine-readable/rsr-profile.a2ml", ".well-known/", ".gitignore", "Justfile"] [gates] # "module path (file, dir/, or glob)" = "gating capability" @@ -98,8 +98,9 @@ paths = [".github/workflows/rust-ci.yml", ".github/workflows/release.yml", ".git # and the canon SERVES, which no capability describes. # # Applies ONLY where the profile declares role = "canon" -# (.machine_readable/rsr-profile.a2ml here; machine-readable/rsr-profile.a2ml -# once the root rename lands). +# (.machine_readable/rsr-profile.a2ml here and in the spine — the root rename +# landed 2026-09-17; machine-readable/rsr-profile.a2ml is the minority spelling +# and is still resolved). # # A minted repo declaring role = "canon" to evade a gate is still drift, which # is the behaviour that matters for the other ~441 repos. diff --git a/0-canon/rsr/RSR-SPEC-v2.adoc b/0-canon/rsr/RSR-SPEC-v2.adoc index 134d6daa0..9d2157d97 100644 --- a/0-canon/rsr/RSR-SPEC-v2.adoc +++ b/0-canon/rsr/RSR-SPEC-v2.adoc @@ -269,5 +269,27 @@ per the estate's manual-only licence guardrail. *Version*: 2.0.0-draft + *Status*: Draft (see <>) + *Era*: v2 + -*SSOT*: `spec/rsr-criteria-v2.a2ml` + +*SSOT*: `0-canon/rsr/rsr-criteria-v2.a2ml` + *Date*: 2026-07-03 + +== Appendix E: Errata + +Corrections that do not change criteria semantics, shipped as PATCH bumps per +`rsr-criteria-v2.a2ml` `[versioning].errata`. This appendix is named by that +rule and did not exist before 2.0.2 - the rule pointed at a section that had +never been written. + +=== 2.0.2 — 2026-09-17 + +* *The machine tree's spelling is `.machine_readable/`.* Ruling R-A settles the + question the law had left open. Criteria `3.1.1` (`descriptiles-dir`) and + `3.2.2` (`rsr-profile`), plus the `[versioning]` freeze-mechanism and the + `[scoring]`/`[oracle]` report prose, named `machine-readable/` as if it were + the only spelling. They now name the canonical one. +* *No semantics change.* The gates' `paths` alternatives have always accepted + either spelling (`machine-readable/descriptiles/|.machine_readable/descriptiles/`), + so no repository's conformance moved. Only the canonical form's position in + each alternative list changed. +* *`machine-readable-substrate` is not a path.* The criterion key keeps its name; + it is an identifier and renaming it would be a criteria-set change, not + erratum. diff --git a/0-canon/rsr/rsr-criteria-v2.a2ml b/0-canon/rsr/rsr-criteria-v2.a2ml index 55cac8333..e728ac263 100644 --- a/0-canon/rsr/rsr-criteria-v2.a2ml +++ b/0-canon/rsr/rsr-criteria-v2.a2ml @@ -32,7 +32,7 @@ model = "semver-with-errata" rule-major = "A MAJOR bump is an era change: it MAY remove or redefine criteria and MAY move a criterion between tiers. Cutting a major freezes the prior major's rsr-criteria as an immutable, hash-pinned artefact under archive/." rule-minor = "A MINOR bump MAY ADD criteria or ADD a capability gate, but MUST NOT make a previously-conforming repo non-conforming at the same tier. Additive only." rule-patch = "A PATCH bump is editorial (wording, detection-rule id corrections, template_ref fixes) with no criteria-set change." -freeze-mechanism = "A released major is frozen by pinning this file's byte-hash in machine-readable/REGISTRY.a2ml (or the spec's own VERSIONS ledger), NOT by a prose 'FROZEN' banner. A freeze guard in CI (see [oracle].freeze-guard) fails any PR that mutates a frozen major's criteria file." +freeze-mechanism = "A released major is frozen by pinning this file's byte-hash in .machine_readable/REGISTRY.a2ml (or the spec's own VERSIONS ledger), NOT by a prose 'FROZEN' banner. A freeze guard in CI (see [oracle].freeze-guard) fails any PR that mutates a frozen major's criteria file." errata = "Corrections that do not change criteria semantics are recorded in RSR-SPEC-v2.adoc Appendix E (Errata) and shipped as PATCH bumps." [tiers] @@ -46,12 +46,12 @@ scale = "X F E D C B A maps onto the readiness-grade scale; RSR tiers are the re [scoring] # The capability-gated model (replaces v1.0's flat 'every repo needs all 11 categories'). -applicable-set = "A criterion is APPLICABLE to a repo iff its `gate` is `universal` OR the repo's machine-readable/rsr-profile.a2ml declares the gating capability (per TEMPLATE-APPLICABILITY-POLICY.adoc). Non-applicable criteria are scored `na` and excluded from the denominator." +applicable-set = "A criterion is APPLICABLE to a repo iff its `gate` is `universal` OR the repo's .machine_readable/rsr-profile.a2ml declares the gating capability (per TEMPLATE-APPLICABILITY-POLICY.adoc). Non-applicable criteria are scored `na` and excluded from the denominator." denominator = "sum of weights of APPLICABLE criteria" numerator = "sum of weights of APPLICABLE criteria whose `detect` returns pass" partial = "A criterion MAY return `partial` (e.g. some but not all files present); partial contributes half its weight and is reported explicitly." na-honesty = "A repo MUST NOT reach a tier by declaring away (via rsr-profile) a capability it actually has. hypatia cross-checks declared capabilities against detected ones (structural_drift) and flags under-declaration as :review." -report = "The oracle writes a per-repo scorecard to verisim-data (machine-readable/scorecards/.scorecard.a2ml shape) with per-criterion verdicts, the applicable set, and the resulting tier." +report = "The oracle writes a per-repo scorecard to verisim-data (.machine_readable/scorecards/.scorecard.a2ml shape) with per-criterion verdicts, the applicable set, and the resulting tier." [oracle] # ONE normative checker. RSR v1.0 shipped five divergent checkers; v2.0 designates @@ -122,17 +122,17 @@ key = "machine-readable-substrate" name = "Machine-Readable Substrate (Descriptiles)" weight = 14 criteria = [ - { id = "3.1.1", name = "descriptiles-dir", desc = "machine-readable/descriptiles/ present (NOT 6a2/, which is deprecated 2026-06-30)", tier = "gold", gate = "universal", detect = "structural_drift/SD003", template_ref = "machine-readable/descriptiles/" }, - { id = "3.1.2", name = "state", desc = "STATE.a2ml — current state/progress (valid record dialect)", tier = "gold", gate = "universal", detect = "structural_drift/SD004", template_ref = "machine-readable/descriptiles/STATE.a2ml" }, - { id = "3.1.3", name = "meta", desc = "META.a2ml — ADRs / constitutional authority", tier = "gold", gate = "universal", detect = "structural_drift/SD005", template_ref = "machine-readable/descriptiles/META.a2ml" }, - { id = "3.1.4", name = "ecosystem", desc = "ECOSYSTEM.a2ml — estate position + what-this-is-not", tier = "gold", gate = "universal", detect = "structural_drift/SD006", template_ref = "machine-readable/descriptiles/ECOSYSTEM.a2ml" }, - { id = "3.1.5", name = "agentic", desc = "AGENTIC.a2ml — agent permissions / risk gating", tier = "gold", gate = "universal", detect = "structural_drift/SD007", template_ref = "machine-readable/descriptiles/AGENTIC.a2ml" }, - { id = "3.1.6", name = "neurosym", desc = "NEUROSYM.a2ml — proof obligations / meaning of ops", tier = "gold", gate = "universal", detect = "structural_drift/SD008", template_ref = "machine-readable/descriptiles/NEUROSYM.a2ml" }, - { id = "3.1.7", name = "playbook", desc = "PLAYBOOK.a2ml — operational runbook", tier = "gold", gate = "universal", detect = "structural_drift/SD009", template_ref = "machine-readable/descriptiles/PLAYBOOK.a2ml" }, - { id = "3.1.8", name = "anchor", desc = "ANCHOR.a2ml — semantic authority + golden path", tier = "gold", gate = "universal", detect = "structural_drift/SD010", template_ref = "machine-readable/descriptiles/anchors/ANCHOR.a2ml" }, - { id = "3.1.9", name = "clade", desc = "CLADE.a2ml — identity/lineage (registers into gv-clade-index)", tier = "gold", gate = "governance-tier", detect = "structural_drift/SD011", template_ref = "machine-readable/descriptiles/CLADE.a2ml" }, + { id = "3.1.1", name = "descriptiles-dir", desc = ".machine_readable/descriptiles/ present (NOT 6a2/, which is deprecated 2026-06-30)", tier = "gold", gate = "universal", detect = "structural_drift/SD003", template_ref = ".machine_readable/descriptiles/" }, + { id = "3.1.2", name = "state", desc = "STATE.a2ml — current state/progress (valid record dialect)", tier = "gold", gate = "universal", detect = "structural_drift/SD004", template_ref = ".machine_readable/descriptiles/STATE.a2ml" }, + { id = "3.1.3", name = "meta", desc = "META.a2ml — ADRs / constitutional authority", tier = "gold", gate = "universal", detect = "structural_drift/SD005", template_ref = ".machine_readable/descriptiles/META.a2ml" }, + { id = "3.1.4", name = "ecosystem", desc = "ECOSYSTEM.a2ml — estate position + what-this-is-not", tier = "gold", gate = "universal", detect = "structural_drift/SD006", template_ref = ".machine_readable/descriptiles/ECOSYSTEM.a2ml" }, + { id = "3.1.5", name = "agentic", desc = "AGENTIC.a2ml — agent permissions / risk gating", tier = "gold", gate = "universal", detect = "structural_drift/SD007", template_ref = ".machine_readable/descriptiles/AGENTIC.a2ml" }, + { id = "3.1.6", name = "neurosym", desc = "NEUROSYM.a2ml — proof obligations / meaning of ops", tier = "gold", gate = "universal", detect = "structural_drift/SD008", template_ref = ".machine_readable/descriptiles/NEUROSYM.a2ml" }, + { id = "3.1.7", name = "playbook", desc = "PLAYBOOK.a2ml — operational runbook", tier = "gold", gate = "universal", detect = "structural_drift/SD009", template_ref = ".machine_readable/descriptiles/PLAYBOOK.a2ml" }, + { id = "3.1.8", name = "anchor", desc = "ANCHOR.a2ml — semantic authority + golden path", tier = "gold", gate = "universal", detect = "structural_drift/SD010", template_ref = ".machine_readable/descriptiles/anchors/ANCHOR.a2ml" }, + { id = "3.1.9", name = "clade", desc = "CLADE.a2ml — identity/lineage (registers into gv-clade-index)", tier = "gold", gate = "governance-tier", detect = "structural_drift/SD011", template_ref = ".machine_readable/descriptiles/CLADE.a2ml" }, { id = "3.2.1", name = "a2ml-valid", desc = "All .a2ml files parse + validate against their record-dialect profile", tier = "gold", gate = "universal", detect = "rsr-conformance/a2ml_valid", template_ref = "-" }, - { id = "3.2.2", name = "rsr-profile", desc = "machine-readable/rsr-profile.a2ml declares capabilities (drives applicable set)", tier = "silver", gate = "universal", detect = "rsr-conformance/profile_present", template_ref = "machine-readable/rsr-profile.a2ml" }, + { id = "3.2.2", name = "rsr-profile", desc = ".machine_readable/rsr-profile.a2ml declares capabilities (drives applicable set)", tier = "silver", gate = "universal", detect = "rsr-conformance/profile_present", template_ref = ".machine_readable/rsr-profile.a2ml" }, ] [[category]] diff --git a/canon.lock b/canon.lock index c894605e9..b3a5beaeb 100644 --- a/canon.lock +++ b/canon.lock @@ -88,12 +88,36 @@ # change) - not MINOR, which is additive. # # --------------------------------------------------------------------------- +# +# 2026-09-17 - PATCH 2.0.1 -> 2.0.2. THE MACHINE TREE'S SPELLING. +# +# Ruling R-A settles the spelling as `.machine_readable/`, so the normative +# artefacts stop naming the hyphenated path. This IS a change to files named in +# [canon.artifacts], so the bump obligation above applies - and PATCH is the +# category the rule itself gives it: rsr-criteria [versioning].rule-patch reads +# "editorial (wording, detection-rule id corrections, template_ref fixes) with +# no criteria-set change". There is no criteria-set change here. +# +# Why not MINOR, and not a MAJOR era change: +# * the gates file's paths array uses '|' alternatives that ALREADY resolve +# both spellings, so no repository's conformance changes at any tier. The +# edit only puts the canonical form first in the list, which is why it is +# cosmetic in effect as well as in intent; +# * no criterion is added, removed, re-tiered or re-gated; +# * `key = "machine-readable-substrate"` in the criteria is an IDENTIFIER, not +# a path, and is deliberately untouched - the same trap that corrupted six +# files on the spine side of this rename. +# +# Sequence, per [canon].order: the SPINE re-adopts these two hashes first, then +# this releases. Gate A enforces the order. +# +# --------------------------------------------------------------------------- [canon] # A released major is immutable. Bumping `version` to a new MAJOR means the # prior major's criteria file is copied to 0-canon/rsr/archive/ and pinned # there; a freeze guard fails any PR that mutates a frozen major. -version = "2.0.1" +version = "2.0.2" spec_family = "rhodium-standard-repositories" status = "draft" # draft | stable released = "2026-09-17" @@ -102,7 +126,7 @@ authority = "0-canon/constitution/ESTATE-CONSTITUTION.adoc" # The full git ref that realises this canon. A tag alone is not sufficient # (tags move); a commit alone is not sufficient (it has no version). Both. commit = "0000000000000000000000000000000000000000" # ← fill at release -tag = "canon-v2.0.1" +tag = "canon-v2.0.2" # --------------------------------------------------------------------------- # THE ARTEFACT SET — the files that ARE the canon. @@ -115,11 +139,11 @@ tag = "canon-v2.0.1" [canon.artifacts] criteria = { path = "0-canon/rsr/rsr-criteria-v2.a2ml", # relocated from the vendored copy - sha256 = "efd024ad9cbdf0d36d4dbce7e491531dd4ccccbfc747a04223ce4149f4b9a53d", + sha256 = "7804d77127001ed50263f0783d8a11f7211e72cb5e9f6443f2acde4b08d9ab1e", slot = "criteria", normative = true } gates = { path = ".machine_readable/template-capability-gates.toml", # from .machine_readable/ - sha256 = "8b1a77669c9ab78e9081669dbb2ab141d8af29700affc327f3dcde99f3dcd243", + sha256 = "6a8b9b420519dccdd2c586da06a9a302bdbbb3dc917f49e4a7b308882471d68a", slot = "gates", normative = true } applicability = { path = "TEMPLATE-APPLICABILITY-POLICY.adoc",