@@ -1283,3 +1283,166 @@ references = [
12831283 "docs/PACKAGING.adoc (INT-04; the JS-package half)",
12841284 "docs/specs/SETTLED-DECISIONS.adoc (ADR-019 section)",
12851285]
1286+
1287+ [[adr]]
1288+ id = "ADR-020"
1289+ status = "proposed"
1290+ date = "2026-05-23"
1291+ title = "Ownership-section schema versioning (0xAF sentinel + u8 version)"
1292+ context = """
1293+ The `affinescript.ownership` Wasm custom section has been frozen at
1294+ v1 since typed-wasm Level 10 closure (2026-04-19) and is emitted in
1295+ identical form by AffineScript (`lib/codegen.ml`) and by ephapax
1296+ (`hyperpolymath/ephapax/src/ephapax-wasm`). The Rust verifier in
1297+ `hyperpolymath/typed-wasm` consumes it as the cross-compat target.
1298+
1299+ V1 has *no version field*. Today this is fine because both
1300+ producers are at v1 and the verifier expects v1 unconditionally.
1301+ The first multi-producer ABI change — when L1–6 / L14–16 emission
1302+ lands — will need version discrimination. Adding the version field
1303+ *now*, while we are still at v1, is much cheaper than retrofitting
1304+ it under load.
1305+
1306+ This ADR is filed alongside the broader typed-wasm widening roadmap
1307+ in `docs/specs/TYPED-WASM-ROADMAP.adoc` §"Tranche B".
1308+ """
1309+ decision = """
1310+ Move from v1 (unversioned) to v2 (versioned, with sentinel):
1311+
1312+ v1 payload:
1313+ u32 entry_count
1314+ entry*
1315+
1316+ v2 payload:
1317+ u8 version_tag ; 0xAF — "AffineScript Format"
1318+ u8 version ; 0x02 for v2.0
1319+ u32 entry_count
1320+ entry* ; same entry shape as v1; no new entry fields in v2.0
1321+
1322+ The 0xAF sentinel is byte-distinct from any plausible v1 entry-count
1323+ low byte for a module with ≤ 0xAE entries — i.e. practically every
1324+ module in existence. v1 readers fail cleanly on a v2 section (bad
1325+ entry-count); v2 readers see the sentinel and dispatch.
1326+
1327+ Coordinated landing protocol:
1328+ 1. Land ADR-020 in `hyperpolymath/affinescript` (this repo).
1329+ 2. Mirror ADR in `hyperpolymath/typed-wasm` (Rust verifier
1330+ dispatches on sentinel; accepts both v1 and v2 during
1331+ migration).
1332+ 3. Mirror ADR in `hyperpolymath/ephapax` (second producer emits
1333+ v2).
1334+ 4. Verifier ships v2-parse FIRST. Producers stay on v1 emit.
1335+ 5. Once verifier is deployed (in both OCaml + Rust paths),
1336+ producers flip to v2 emit together.
1337+ 6. After a deprecation window, v1-parse path is removed from
1338+ verifier.
1339+
1340+ The v2.0 entry shape is identical to v1 — this ADR introduces no
1341+ new ownership kinds, no new per-entry fields. Future widening
1342+ (e.g. v2.1 adding a region-id field per entry) is a separate ADR.
1343+ """
1344+ consequences = """
1345+ - Forward-compatible: any future widening (L1–6 / L14–16 carriers,
1346+ per-entry annotations) can negotiate via the version byte without
1347+ another sentinel-or-no-sentinel war.
1348+ - v1 callers fail cleanly on v2 sections (bad entry-count parse) —
1349+ no silent corruption.
1350+ - Single coordinated landing across three repos; complexity is in
1351+ the coordination, not the bytes.
1352+ - This decision is PROPOSED. Land or supersede explicitly; do not
1353+ silently drift.
1354+ - Cross-references the typed-wasm roadmap in
1355+ `docs/specs/TYPED-WASM-ROADMAP.adoc` §"B1".
1356+ """
1357+ references = [
1358+ "docs/specs/TYPED-WASM-INTERFACE.adoc",
1359+ "docs/specs/TYPED-WASM-INTERFACE.a2ml",
1360+ "docs/specs/TYPED-WASM-ROADMAP.adoc",
1361+ "lib/codegen.ml (build_ownership_section, ~line 159)",
1362+ "lib/tw_verify.ml (parse_ownership_section)",
1363+ "hyperpolymath/typed-wasm (Rust verifier crate — coordination target)",
1364+ "hyperpolymath/ephapax (second producer — coordination target)",
1365+ ]
1366+
1367+ [[adr]]
1368+ id = "ADR-021"
1369+ status = "proposed"
1370+ date = "2026-05-23"
1371+ title = "Multi-producer ABI coordination model for typed-wasm carriers"
1372+ context = """
1373+ typed-wasm is a separate, language-agnostic compilation target with
1374+ its own repository (`hyperpolymath/typed-wasm`) and its own
1375+ producers (today: AffineScript + ephapax; potentially more later).
1376+ The `affinescript.ownership` custom section is the first
1377+ multi-producer ABI we own.
1378+
1379+ Today coordination happens by `Refs #N` across repositories and
1380+ good intent. As the typed-wasm widening proposals land (ADR-020
1381+ schema versioning, then carriers for L1–6 and L14–16), this
1382+ informal model will break. The session-note record makes clear that
1383+ each ABI conversation has been one-off and ad-hoc; the failure mode
1384+ is two producers landing incompatible changes in parallel because
1385+ nobody owns "the protocol".
1386+
1387+ This ADR is filed alongside the typed-wasm widening roadmap in
1388+ `docs/specs/TYPED-WASM-ROADMAP.adoc` §"Tranche D" — D1 explicitly.
1389+ The reason to land *this* ADR before any concrete widening proposal
1390+ is that the coordination model is cheap now (no code), expensive
1391+ later (under conflicting pressure from multiple in-flight proposals).
1392+ """
1393+ decision = """
1394+ Adopt a formal four-axis multi-producer coordination model:
1395+
1396+ (1) Spec authority — which artefact is the source of record:
1397+ - Today: `lib/tw_verify.ml` (OCaml) is the spec of record.
1398+ - On C5.1 closure (INT-12 / CONV-05): authority flips to
1399+ `hyperpolymath/typed-wasm` Rust verifier crate.
1400+ - The flip is itself an ADR — does not happen silently.
1401+ - Until the flip, OCaml binds; on conflict, OCaml wins.
1402+
1403+ (2) Coordinated landing protocol:
1404+ - All ABI-touching ADRs live in all three repos (originated in
1405+ one, mirrored in the other two with `Mirrors hyperpolymath/X#N`
1406+ cross-references).
1407+ - Verifier always ships parse-support FIRST.
1408+ - Producers flip to emit support together, in a coordinated
1409+ window.
1410+ - Deprecation: a removed format MUST have a deprecation window
1411+ of at least the cycle between two coordinated landings.
1412+
1413+ (3) Test parity protocol:
1414+ - Every producer maintains a fixture corpus matching the
1415+ typed-wasm cross-compat suite (INT-12 / C5.1).
1416+ - Each ABI change requires a new fixture in the cross-compat
1417+ suite from each producer.
1418+ - Verifier accepts a producer's emit only if the cross-compat
1419+ corpus is up-to-date for that producer.
1420+
1421+ (4) Conflict resolution:
1422+ - In-flight ABI proposals from different producers MUST be
1423+ serialised — no parallel ABI ADRs.
1424+ - The serialisation queue is owned by `hyperpolymath/typed-wasm`
1425+ (today via issues; future a dedicated coordination ledger).
1426+ - A proposal blocked behind another in the queue is paused, not
1427+ refused.
1428+ """
1429+ consequences = """
1430+ - Single coordination ledger replaces ad-hoc Refs trails.
1431+ - ABI change cost goes up (more paperwork) but predictability goes
1432+ way up.
1433+ - Compatible with the existing Hypatia / gitbot rules (Hypatia
1434+ DOC-FORMAT / STACK-SIGNAL apply; ISSUE-CLOSURE applies to the
1435+ shared ADR mirrors).
1436+ - This decision is PROPOSED. Owner ratification required before any
1437+ ABI ADR (ADR-020 included) lands; ADR-020 is a "first test" of
1438+ this model and its own landing exercises the protocol.
1439+ - Cross-references the typed-wasm roadmap in
1440+ `docs/specs/TYPED-WASM-ROADMAP.adoc` §"D1".
1441+ """
1442+ references = [
1443+ "docs/specs/TYPED-WASM-INTERFACE.adoc",
1444+ "docs/specs/TYPED-WASM-ROADMAP.adoc",
1445+ ".claude/CLAUDE.md §Hypatia and gitbot-fleet standing rules",
1446+ "hyperpolymath/typed-wasm (coordination target)",
1447+ "hyperpolymath/ephapax (second producer — coordination target)",
1448+ ]
0 commit comments