|
| 1 | +# SPDX-License-Identifier: AGPL-3.0-or-later |
| 2 | +# SPDX-FileCopyrightText: 2026 Jonathan D.A. Jewell |
| 3 | +# REGISTRY.a2ml -- Verifiable Spec-Pointer Registry for hyperpolymath/standards |
| 4 | +# |
| 5 | +# WHY THIS EXISTS (and why it is NOT SATELLITES.a2ml) |
| 6 | +# --------------------------------------------------- |
| 7 | +# SATELLITES.a2ml registers repositories that were *absorbed* into this hub as |
| 8 | +# subdirectories -- their normative text now lives HERE. This registry is the |
| 9 | +# opposite case: specs whose source-of-truth deliberately lives ELSEWHERE |
| 10 | +# because they are coupled to a language, runtime, or service whose release |
| 11 | +# cadence the standards repo must not own. |
| 12 | +# |
| 13 | +# For those, the standards repo holds a POINTER, never a copy. Duplicating the |
| 14 | +# normative text would create two sources of truth and guarantee drift. Each |
| 15 | +# pointer records a `source_hash` of the upstream spec; hypatia (HYP-S006) |
| 16 | +# recomputes that hash against the canonical_url and flags any mismatch as |
| 17 | +# staleness. That hash is the anti-drift mechanism -- the registry is |
| 18 | +# verifiable, not merely descriptive. |
| 19 | +# |
| 20 | +# First user of this registry: the AffineScript v2 standards (.affine source |
| 21 | +# documents / faces, .affex face-interop manifest, .affmap provenance), whose |
| 22 | +# SSOT is hyperpolymath/affinescript. The standards repo only points at them. |
| 23 | + |
| 24 | +[registry] |
| 25 | +version = "1.0.0" |
| 26 | +schema = "spec-registry.v1" |
| 27 | +created = "2026-06-03" |
| 28 | +owner = "Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>" |
| 29 | +description = "Verifiable pointers to language/service-coupled specs whose SSOT lives in another repo. Pointers, never copies." |
| 30 | + |
| 31 | +[registry.relationship] |
| 32 | +# How this file relates to its sibling. |
| 33 | +companion = "SATELLITES.a2ml" |
| 34 | +distinction = "SATELLITES = absorbed repos (text lives here). REGISTRY = external SSOT (text lives upstream, we hold a verified pointer)." |
| 35 | +overlap = "none -- a given spec appears in exactly one of the two files." |
| 36 | + |
| 37 | +# ============================================================================ |
| 38 | +# SCHEMA -- self-describing field set for every [[registry.pointers]] entry. |
| 39 | +# Field set ratified by owner 2026-06-03 (7 base fields + provenance fields). |
| 40 | +# This block is documentation for humans and a contract for hypatia's loader. |
| 41 | +# ============================================================================ |
| 42 | + |
| 43 | +[registry.schema] |
| 44 | +id = "spec-registry.v1" |
| 45 | +# The seven base fields (owner directive 2026-06-03). |
| 46 | +required = [ |
| 47 | + "name", # stable registry key for the spec |
| 48 | + "canonical_url", # upstream source-of-truth location (the file hypatia hashes) |
| 49 | + "owning_repo", # repo that authors + versions the spec (org/repo) |
| 50 | + "version_pin", # upstream version/tag this pointer is pinned to |
| 51 | + "source_hash", # hash of the upstream spec content (anti-drift anchor) |
| 52 | + "conformance_level",# normative | draft | proposed | experimental |
| 53 | + "last_synced", # ISO-8601 timestamp hypatia last verified the hash (or "never") |
| 54 | +] |
| 55 | +# Provenance fields (owner-approved extension 2026-06-03). |
| 56 | +provenance = [ |
| 57 | + "source_hash_algo", # e.g. sha256 -- makes the anti-drift check unambiguous |
| 58 | + "spec_kind", # language-coupled | service-coupled (heterogeneous registry) |
| 59 | + "media_type", # consistency with SATELLITES media-types |
| 60 | + "lineage", # lineage convention key, consistency with the .affine lineage |
| 61 | +] |
| 62 | +# Operational fields (not part of the ratified set, but the loader tolerates them). |
| 63 | +optional = [ |
| 64 | + "sync_status", # awaiting-upstream | verified | drift-detected |
| 65 | + "format_version", # for regenerable artefacts whose format bumps independently |
| 66 | + "notes", |
| 67 | +] |
| 68 | + |
| 69 | +[registry.schema.source_hash_format] |
| 70 | +# A source_hash value is "<algo>:<hex>". When the upstream spec has not yet |
| 71 | +# landed, source_hash is the sentinel below and sync_status = "awaiting-upstream". |
| 72 | +# NEVER fabricate a hash -- an unknown hash is recorded as the sentinel. |
| 73 | +sentinel-unsynced = "PENDING-FIRST-SYNC" |
| 74 | +preferred-algo = "sha256" |
| 75 | +banned-algos = ["md5", "sha1"] # estate security policy: no MD5/SHA1 |
| 76 | + |
| 77 | +[registry.policy] |
| 78 | +ssot = "A pointer's canonical_url is the ONLY normative copy. The standards repo MUST NOT re-author or mirror the spec text." |
| 79 | +anti-drift = "hypatia HYP-S006 recomputes source_hash against canonical_url; mismatch => staleness finding." |
| 80 | +flag-only = "Registry findings are :review (flag), never :auto_execute -- consistent with estate no-automated-edit posture." |
| 81 | +versioning = "language-coupled specs pin version_pin to the language tag; regenerable artefacts ALSO carry format_version, bumped independently." |
| 82 | + |
| 83 | +# ============================================================================ |
| 84 | +# POINTERS |
| 85 | +# ============================================================================ |
| 86 | +# AffineScript v2 standards. SSOT = hyperpolymath/affinescript (NOT here). |
| 87 | +# Spec text is authored ONCE in AsciiDoc in that repo; faces govern how |
| 88 | +# AffineScript SOURCE is written, not how the SPECS are written. Multi-face |
| 89 | +# examples live upstream, never in this registry. |
| 90 | +# |
| 91 | +# source_hash is the sentinel until the separate affinescript PR lands the v2 |
| 92 | +# spec text (see "Upstream work" note at the foot of this file). On first |
| 93 | +# successful sync hypatia replaces the sentinel and sets last_synced. |
| 94 | + |
| 95 | +[[registry.pointers]] |
| 96 | +name = "affine-spec" |
| 97 | +spec_kind = "language-coupled" |
| 98 | +owning_repo = "hyperpolymath/affinescript" |
| 99 | +canonical_url = "https://github.com/hyperpolymath/affinescript/blob/main/spec/affine.adoc" |
| 100 | +version_pin = "v2.0.0" |
| 101 | +source_hash = "PENDING-FIRST-SYNC" |
| 102 | +source_hash_algo = "sha256" |
| 103 | +conformance_level = "draft" # v2 proposed direction; promote to normative when upstream lands |
| 104 | +media_type = "application/vnd.affinescript.affine" |
| 105 | +lineage = "affinescript:affine@2" |
| 106 | +last_synced = "never" |
| 107 | +sync_status = "awaiting-upstream" |
| 108 | +notes = "Source documents / faces. Defines faces, canonical-lowering invariant, canonical islands, idiom packs, mimicry bindings, project face policy." |
| 109 | + |
| 110 | +[[registry.pointers]] |
| 111 | +name = "affex-manifest" |
| 112 | +spec_kind = "language-coupled" |
| 113 | +owning_repo = "hyperpolymath/affinescript" |
| 114 | +canonical_url = "https://github.com/hyperpolymath/affinescript/blob/main/spec/affex.adoc" |
| 115 | +version_pin = "v2.0.0" # language version this manifest format targets |
| 116 | +format_version = "2" # affex format version -- tracked INDEPENDENTLY (owner 2026-06-03) |
| 117 | +format_version_tracking = "independent" |
| 118 | +source_hash = "PENDING-FIRST-SYNC" |
| 119 | +source_hash_algo = "sha256" |
| 120 | +conformance_level = "draft" |
| 121 | +media_type = "application/vnd.affinescript.affex" |
| 122 | +lineage = "affinescript:affex@2" |
| 123 | +last_synced = "never" |
| 124 | +sync_status = "awaiting-upstream" |
| 125 | +notes = "Face-interop manifest. Derived, regenerable, source-authoritative artefact: declaration heads not full bodies. Because it is regenerable, format_version may bump freely without moving version_pin." |
| 126 | + |
| 127 | +[[registry.pointers]] |
| 128 | +name = "affmap-provenance" |
| 129 | +spec_kind = "language-coupled" |
| 130 | +owning_repo = "hyperpolymath/affinescript" |
| 131 | +canonical_url = "https://github.com/hyperpolymath/affinescript/blob/main/spec/affmap.adoc" |
| 132 | +version_pin = "v2.0.0" |
| 133 | +source_hash = "PENDING-FIRST-SYNC" |
| 134 | +source_hash_algo = "sha256" |
| 135 | +conformance_level = "draft" |
| 136 | +media_type = "application/vnd.affinescript.affmap" |
| 137 | +lineage = "affinescript:affmap@2" |
| 138 | +last_synced = "never" |
| 139 | +sync_status = "awaiting-upstream" |
| 140 | +# Owner 2026-06-03: .affmap gets its OWN pointer now (not folded under affex), |
| 141 | +# so its provenance format has an independent source_hash / staleness signal. |
| 142 | +notes = "Provenance format. Own registry entry (owner decision) for independent staleness tracking." |
| 143 | + |
| 144 | +# ---------------------------------------------------------------------------- |
| 145 | +# Citation profile note (NOT a pointer): |
| 146 | +# .affcite.a2ml is an A2ML document under the CodeCite citation profile |
| 147 | +# (consistent with the .affex sketch that names pixi.affcite.a2ml). Citation |
| 148 | +# CONTENTS live in that A2ML artefact inside the AffineScript repo, not in |
| 149 | +# .affex and not here. It is therefore not a separate spec pointer. |
| 150 | +# ---------------------------------------------------------------------------- |
| 151 | + |
| 152 | +# ============================================================================ |
| 153 | +# Upstream work (tracked, NOT done from this repo) |
| 154 | +# ============================================================================ |
| 155 | +# A separate PR in hyperpolymath/affinescript lands the v2 spec text these |
| 156 | +# pointers reference, using the lineage convention: |
| 157 | +# * .affine v2 -- faces, canonical-lowering invariant, canonical islands, |
| 158 | +# idiom packs, mimicry bindings, project face policy. |
| 159 | +# * .affex v2 -- derived, regenerable manifest; source-authoritative; |
| 160 | +# declaration heads not full bodies. |
| 161 | +# Writing that spec text HERE would violate SSOT and is out of scope. Once it |
| 162 | +# lands, run hypatia HYP-S006 to populate source_hash + last_synced. |
| 163 | + |
| 164 | +### End of REGISTRY.a2ml |
0 commit comments