From 6cffd1731fbdda5ab28a33de513b061c6cff3650 Mon Sep 17 00:00:00 2001 From: "Jonathan D.A. Jewell" <6759885+hyperpolymath@users.noreply.github.com> Date: Wed, 7 Oct 2026 08:51:39 +0100 Subject: [PATCH] feat(uuid): ADR-008 strict now, v8-only gates, .a2ml skipped (D320) Owner ruling D320 (2026-10-07): the UUID gates run strict, version 8 only, estate-wide, now rather than at P4. Refs #787. - governance-reusable.yml (uuid-v7-conformance) and uuid-v7.yml run check-uuid-v8.sh --strict; workflow/job names unchanged, so no required context moves. Rollback: drop --strict. - check-uuid-v8.sh skips *.a2ml / *.a2ml.in: A2ML is dead and may not be hand-converted (D313); its IDs move to v8 via kcX -> deed. Four new suite cases; both mutants (skip removed, skip widened) are killed. - standards itself passes --strict: two illustrative literals flipped to v8; the clade mapping's P-1 now states the profile C rule. - ADR-008 gains the D320 amendment (decision, shim, rollback, impact). Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01X3hgXxWm6umMgZkjYyHnnm --- .github/workflows/governance-reusable.yml | 7 ++- .github/workflows/uuid-v7.yml | 7 ++- .../deed/mappings/clade-to-repo-deed.adoc | 15 +++-- 2-protocols/axel/public/about.html | 2 +- .../ADR-008-uuid-v8-estate-standard.adoc | 62 ++++++++++++++++++- .../consent-layer/technical-architecture.adoc | 2 +- scripts/check-uuid-v8.sh | 10 ++- scripts/tests/uuid-v8-test.sh | 9 +++ 8 files changed, 96 insertions(+), 18 deletions(-) diff --git a/.github/workflows/governance-reusable.yml b/.github/workflows/governance-reusable.yml index 34401edea..a082badb0 100644 --- a/.github/workflows/governance-reusable.yml +++ b/.github/workflows/governance-reusable.yml @@ -101,10 +101,13 @@ jobs: sparse-checkout-cone-mode: false persist-credentials: false - - name: Reject UUID literals that are neither v8 nor v7 + # ADR-008 strict (owner ruling D320, 2026-10-07): v8 only. The job id and + # name are unchanged so no required context moves. Rollback is dropping + # --strict, which restores P2 dual-accept. + - name: Reject UUID literals that are not v8 run: | chmod +x .standards-uuid/scripts/check-uuid-v8.sh - .standards-uuid/scripts/check-uuid-v8.sh . + .standards-uuid/scripts/check-uuid-v8.sh --strict . allowlist-preflight: name: Allowlist Preflight diff --git a/.github/workflows/uuid-v7.yml b/.github/workflows/uuid-v7.yml index 2fb622fa1..75e984573 100644 --- a/.github/workflows/uuid-v7.yml +++ b/.github/workflows/uuid-v7.yml @@ -23,7 +23,8 @@ jobs: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - # ADR-008 P2 dual-accept: v8 and v7 literals pass. The workflow and job - # names are kept so no required context moves; v7 retires at P4 (--strict). - - run: scripts/check-uuid-v8.sh . + # ADR-008 strict (owner ruling D320, 2026-10-07): v8 only. The workflow and + # job names are kept so no required context moves. Rollback is dropping + # --strict, which restores P2 dual-accept. + - run: scripts/check-uuid-v8.sh --strict . - run: bash scripts/tests/uuid-v8-test.sh diff --git a/1-formats/deed/mappings/clade-to-repo-deed.adoc b/1-formats/deed/mappings/clade-to-repo-deed.adoc index 13d9ee5d8..433ecd427 100644 --- a/1-formats/deed/mappings/clade-to-repo-deed.adoc +++ b/1-formats/deed/mappings/clade-to-repo-deed.adoc @@ -99,11 +99,14 @@ Fields not listed do not exist in the deed era for this family. == 5. Provenance & validation -* **P-1 (identity validation):** the emitted UUID is a UUID v7 generated by - the estate-approved CSPRNG. UUIDs are opaque and MUST NOT be re-derived - from a repository name. The canonical rsr-template instance stores - `01a0eaa4-72db-734c-be6a-2cdd1f08fe03` (`enforce-uuid-provenance` - doctrine; the check errs on the side of specificity). +* **P-1 (identity validation):** the repo UUID is an ADR-008 **profile C** + UUIDv8, derived from the name in the `gv-clade-index` domain: + bytes 0..15 of `SHA-256("gv-clade-index:github.com//")`, + version nibble 8, RFC 9562 variant (owner ruling D320, 2026-10-07; it + replaces both the earlier CSPRNG-v7 rule and the UUIDv5 derivation). The + translator re-derives it from the name and never copies the hex from the + source: a v5 or v7 held in a retired `CLADE.a2ml` is the old identity, not + the deed's. * **P-2 (source must parse as a2ml first):** a source file that no longer parses as a2ml (e.g. already hand-"translated" halfway, containing `()`) is rejected before any output assignment. A source carrying `=` inside a @@ -129,7 +132,7 @@ Source (post-#122 template instance, abridged to fields): [source] ---- -uuid = "01a0eaa4-72db-734c-be6a-2cdd1f08fe03" +uuid = "…" # the retired v7; never copied (P-1) primary-forge = "github" primary-owner = "hyperpolymath" canonical-name = "rsr-template-repo" prefixed-name = "rm-rsr-template-repo" [clade] primary = "rm" primary-name = "Repo Management & Tooling" diff --git a/2-protocols/axel/public/about.html b/2-protocols/axel/public/about.html index e350aacff..eef818838 100644 --- a/2-protocols/axel/public/about.html +++ b/2-protocols/axel/public/about.html @@ -20,7 +20,7 @@

Protocol Validation

  • Domain validation - Domains are well-formed
  • Port validation - Ports are in valid range (1-65535)
  • Method validation - HTTP methods are valid
  • URL validation - URLs are proven safe with ProvenSafeUrl

Execution Attestation

After execution, AXEL generates:

-

```json { "attestation_id": "01a0eaa4-72db-7eee-a662-4ca0b5f0b142", "protocol": "https", "domain": "example.com", "executed_at": "2026-01-30T20:00:00Z", "signature": "3045022100...", "proof": "Type-level proof included" } ```

+

```json { "attestation_id": "01a0eaa4-72db-8eee-a662-4ca0b5f0b142", "protocol": "https", "domain": "example.com", "executed_at": "2026-01-30T20:00:00Z", "signature": "3045022100...", "proof": "Type-level proof included" } ```

Architecture

TEA (The Elm Architecture)

AXEL uses The Elm Architecture for predictable state management:

diff --git a/docs/decisions/ADR-008-uuid-v8-estate-standard.adoc b/docs/decisions/ADR-008-uuid-v8-estate-standard.adoc index 8655068c8..943298ed9 100644 --- a/docs/decisions/ADR-008-uuid-v8-estate-standard.adoc +++ b/docs/decisions/ADR-008-uuid-v8-estate-standard.adoc @@ -5,7 +5,7 @@ [cols="1,4"] |=== -| Status | *Accepted* (owner ruling D305/D305b, 2026-10-06). Phase P1 tooling and P2 dual-accept start with this record; see <>. `ESTATE-UUID-V7` stays enforced, in dual-accept, until P4. +| Status | *Accepted* (owner ruling D305/D305b, 2026-10-06). *Amended* by owner ruling D320 (2026-10-07): the gates run strict, version 8 only, from the merge of that amendment; see <>. | Date | 2026-10-05 | Decided | 2026-10-06, `hyperpolymath/standards#787` (https://github.com/hyperpolymath/standards/issues/787#issuecomment-6023959688) | Supersedes | `docs/UUID-V7-ESTATE-STANDARD.adoc` (`ESTATE-UUID-V7` 1.0.0, effective 2026-09-29), progressively: see <> @@ -244,7 +244,63 @@ maps back to version 7 by the same one-nibble flip. A profile C value has no ver counterpart, so once identifiers are minted as profile C (P3), rollback means keeping them as external identifiers. +[[amendment-d320]] +== Amendment: strict now (owner ruling D320, 2026-10-07) + +*Decision.* The owner ruled, through the selection UI, that the gates move +straight to strict: version 8 only, estate-wide, now, rather than at P4. The +owner was told beforehand that about 888 local workflow directories call +`governance-reusable.yml@main`, so the change reaches them on merge, and +chose "flip strict now". D320 also rules: + +* *Retired A2ML files are not scanned.* `check-uuid-v8.sh` skips `*.a2ml` + and `*.a2ml.in`. A2ML is dead and may not be hand-converted (D313); its + identifiers become version 8 when kcX converts each file into deed. This is + the only arm that keeps strict-now, deed-first and D313 all true. Without + it, every repository holding a `CLADE.a2ml` (328 of 334 local copies carry + a UUIDv5) would be red until kcX exists. +* *Clade identifiers are profile C*, derived in the domain `gv-clade-index` + from `github.com//`. This replaces both the UUIDv5 derivation + gv-clade-index uses today and the CSPRNG-v7 rule in the clade mapping's P-1. + The change starts at the source (gv-clade-index), then reaches each + repository's chora deed once deed admits a version 8 literal. +* *A Julia package's own `uuid` is re-minted as version 8*, not exempted, + where the package is not registered in General. A registered package is a + separate question for the owner. + +*What this amendment ships.* + +* `governance-reusable.yml` (job `uuid-v7-conformance`) and the dogfood + `uuid-v7.yml` run `check-uuid-v8.sh --strict`. The workflow names, job ids + and job names are unchanged, so no required status context moves. +* `check-uuid-v8.sh` skips `*.a2ml` and `*.a2ml.in`. The test suite gains four + cases: both extensions are skipped, and a file merely named after A2ML + (`a2ml-notes.adoc`) or with a near-miss extension (`.a2mlx`) is still + checked. Removing the skip fails the first two; widening it to `*a2ml*` + fails the last two. +* This repository passes `--strict`. Two illustrative literals were flipped to + version 8 (the axel attestation example, the palimpsest consent-layer + example), and the clade mapping's P-1 and worked example now state the + profile C rule instead of quoting a version 7 identifier. + +*Shim and rollback (ADR-006).* This is a cutover, and it has no parallel run. +The shim is the reusable's own pinning: it checks out the validator at +`job.workflow_sha`, so a caller pinned to a SHA keeps the behaviour of that +SHA until it bumps. Callers on `@main` change on merge. Rollback is removing +the `--strict` argument in the two workflows, which restores P2 dual-accept; +nothing else changes. + +*Measured impact.* Measured on 2026-10-07 over the **default-branch tree** (`git archive origin/HEAD`, refs fetched within a day) of each of the 481 local clones under `hyper-repos/` and `meta-repos/`, so untracked files and side branches do not count. One clone, `julia-ecosystem`, timed out in both modes and is unmeasured. Of the other 480, the checker on standards `main` (dual-accept, no A2ML skip) passes 135 and fails 345. This checker with `--strict` passes 296 and fails 184. *168 repos turn green*, almost all because of the A2ML skip. *6 repos turn red*, not counting standards, whose 4 hits this change fixes. Only `kcq` calls the gate at `@main`, so it is the one repo that goes red on its next run (a v7 literal in two deed files). `phantom-metal-taste` (a placeholder UUID in a Julia `Project.toml`), `ZenodoDeposits.jl` (one v7 literal in its tests) and `sim-public-relations` (two literals) pin the gate to a SHA, so each goes red only when it bumps. `berrywiki` and `berrywiki-course-template` call no gate. The other 177 repos fail in both modes. On default branches, 3 repos call `governance-reusable.yml@main`, 357 pin it to a SHA, and 121 do not call it. The figure of about 888 quoted at decision time was not a default-branch count. + +*What still follows.* The deed grammar's version 8 literal (`#u8`, whose body +is the profile C preimage `domain:name`), its linter and fixtures, and the +shared profile T and C generators are the next standards increment. The +gv-clade-index derivation change follows it. Each repository then migrates +under P3 as before; strict only means a repository is red until it does. + == What this record does not do -It does not migrate any repository (P3), retire version 7 acceptance (P4), -change the deed grammar, or update `HYP-UUID-001`. +It does not migrate any repository (P3), change the deed grammar, or update +`HYP-UUID-001`. The D320 amendment retires version 7 acceptance at the gates; +P4 is now only the removal of `check-uuid-v7.sh` and the superseded v7 +standard once every in-scope repository is `complete` or `excluded`. diff --git a/rhodium-standard-repositories/satellites/palimpsest-license/campaigns/consent-layer/technical-architecture.adoc b/rhodium-standard-repositories/satellites/palimpsest-license/campaigns/consent-layer/technical-architecture.adoc index fcd73c928..a59c04123 100644 --- a/rhodium-standard-repositories/satellites/palimpsest-license/campaigns/consent-layer/technical-architecture.adoc +++ b/rhodium-standard-repositories/satellites/palimpsest-license/campaigns/consent-layer/technical-architecture.adoc @@ -30,7 +30,7 @@ bodies, security researchers. "https://consent-layer.org/ns/" ], "@type": "CreativeWork", - "identifier": "urn:uuid:a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "identifier": "urn:uuid:a1b2c3d4-e5f6-8890-abcd-ef1234567890", "name": "Work Title", "author": { "@type": "Person", diff --git a/scripts/check-uuid-v8.sh b/scripts/check-uuid-v8.sh index b092e2457..cfe4612fa 100755 --- a/scripts/check-uuid-v8.sh +++ b/scripts/check-uuid-v8.sh @@ -13,6 +13,11 @@ # # A literal scanner cannot tell profile T from profile C; ADR-008 puts the # profile in the field's declared type, which this script does not read. +# +# Retired A2ML files (*.a2ml, *.a2ml.in) are not scanned (owner ruling D320, +# 2026-10-07). A2ML is dead and may not be hand-converted (D313); its +# identifiers become v8 when kcX converts each file into deed, so checking +# them here would only force edits to a format the estate is deleting. set -eu strict=0 @@ -63,9 +68,10 @@ acceptable() { status=0 while IFS= read -r file; do [ -f "$file" ] || continue - # Ignore the checkers themselves; scan source and data files, not binaries. + # Ignore the checkers themselves and retired A2ML files (D320); scan source + # and data files, not binaries. case "$file" in - */.git/*|*/check-uuid-v7.sh|*/check-uuid-v8.sh) continue ;; + */.git/*|*/check-uuid-v7.sh|*/check-uuid-v8.sh|*.a2ml|*.a2ml.in) continue ;; esac if grep -IEni -- '[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}' "$file" >/dev/null 2>&1; then # Every UUID on a line is checked, not only the last one (grep -o). diff --git a/scripts/tests/uuid-v8-test.sh b/scripts/tests/uuid-v8-test.sh index 26c8ab6d8..6ec971e0f 100755 --- a/scripts/tests/uuid-v8-test.sh +++ b/scripts/tests/uuid-v8-test.sh @@ -83,6 +83,15 @@ expect 1 "a [deps] table outside a Julia project file is not exempt" fresh; mkdir -p "$WORK/t/docs"; printf '[[deps.X]]\nuuid = "%s"\n' "$V4" > "$WORK/t/docs/Manifest-v1.12.toml" expect 0 "a v4 in a Julia Manifest is accepted" +fresh; printf 'id = "%s"\n' "$V4" > "$WORK/t/CLADE.a2ml" +expect 0 "a v4 in a retired .a2ml file is ignored (D320)" +fresh; printf 'id = "%s"\n' "$V4" > "$WORK/t/CLADE.a2ml.in" +expect 0 "a v4 in a retired .a2ml.in template is ignored (D320)" +fresh; printf 'id = "%s"\n' "$V4" > "$WORK/t/a2ml-notes.adoc" +expect 1 "a v4 in a file merely NAMED after a2ml is still rejected" +fresh; printf 'id = "%s"\n' "$V4" > "$WORK/t/x.a2mlx" +expect 1 "a v4 in a .a2mlx file (near-miss extension) is still rejected" + echo "scan paths" got=0; "$SCRIPT" "$WORK/no-such-dir" >"$WORK/out" 2>&1 || got=$? if [ "$got" = 2 ]; then pass=$((pass+1)); echo " ok a missing scan path exits 2"