Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions .github/workflows/governance-reusable.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
7 changes: 4 additions & 3 deletions .github/workflows/uuid-v7.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
15 changes: 9 additions & 6 deletions 1-formats/deed/mappings/clade-to-repo-deed.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -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/<owner>/<name>")`,
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
Expand All @@ -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"
Expand Down
2 changes: 1 addition & 1 deletion 2-protocols/axel/public/about.html
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ <h3>Protocol Validation</h3>
<ul><li><strong>Domain validation</strong> - Domains are well-formed</li><li><strong>Port validation</strong> - Ports are in valid range (1-65535)</li><li><strong>Method validation</strong> - HTTP methods are valid</li><li><strong>URL validation</strong> - URLs are proven safe with ProvenSafeUrl</li></ul>
<h3>Execution Attestation</h3>
<p>After execution, AXEL generates:</p>
<p>```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" } ```</p>
<p>```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" } ```</p>
<h2>Architecture</h2>
<h3>TEA (The Elm Architecture)</h3>
<p>AXEL uses <strong>The Elm Architecture</strong> for predictable state management:</p>
Expand Down
62 changes: 59 additions & 3 deletions docs/decisions/ADR-008-uuid-v8-estate-standard.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -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 <<decision-record>>. `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 <<amendment-d320>>.
| 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 <<decision-record>>
Expand Down Expand Up @@ -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/<owner>/<name>`. 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`.
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
10 changes: 8 additions & 2 deletions scripts/check-uuid-v8.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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).
Expand Down
9 changes: 9 additions & 0 deletions scripts/tests/uuid-v8-test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
Loading