docs(adr): determinism belongs at the publication boundary (ADR 0038) - #1457
Conversation
The construction path's determinism contract asserted byte-identical shaped and encoded artifacts at every partition count. We do not meet it -- #1416 records a wall clock written into shaped-runtime-catalog.parquet, and the determinism suite passes by pinning the session clock -- and it is stronger than anything depends on, since shaped intermediates are unlinked by recover_shape_intent on any incomplete run. It also constrained every attempt to parallelise construction (#1429, #1448), because reproducing a byte stream under an arbitrary schedule is what the evidence architecture's running peaks and ordered transition log exist to support. ADR 0038 moves the contract to the publication boundary: published artifacts stay canonically ordered and byte-stable; shaped intermediates may differ by schedule; worker count, execution partitioning and the recorded partition count remain three distinct numbers. Byte-equality of intermediates is replaced -- not dropped -- by semantic equivalence across forced worker counts and an interrupted-and-resumed run. Refs #1456, #1416, #1387 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Advanced Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Warning Billing warning: we have not been able to collect payment for this subscription for more than 72 hours. Please update the payment method or pay any pending invoices in Billing to avoid service interruption. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
…g them (#1390) Four places must agree with docs/adr/: two docs-site files, already generated, and two markdown tables that were hand-maintained. The docstring justified the split by saying the markdown tables carry hand-written titles and statuses -- but every cell in them is derived from the ADR file itself, which the script already parses for both '# ADR NNNN: Title' and '**Status:**'. Hand-maintaining four copies of one fact produced exactly the drift this script exists to catch: adding ADR 0038 meant editing two tables with different cell formats, and both were wrong on the first attempt. generate now rewrites the row bodies of all four indexes, leaving each table's header and separator alone. check is kept and still fails closed, so a hand edit is reported rather than silently overwritten on the next run -- proven by the existing 16-mutation suite, which still passes. Refs #1390 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…of prose (#1390) The ADRs already carried structured fields, in a form only a human could read reliably: 34 '**Status:**', 30 '**Date:**', 28 '**Related:**', 24 '**Build target:**'. The index script regex-scanned prose lines for title and status, and the field counts show the drift that follows from nothing enforcing them. docs-site already expects frontmatter: sync-content.mjs's upsertFrontmatter preserves a source file's frontmatter and only synthesises 'title:' when it is absent, and the Starlight docsSchema() is the collection schema. No ADR had any, so the site was working around the absence. 'title' keeps the full 'ADR NNNN: Title' form so published page titles are unchanged; the body keeps its H1 for readers on GitHub, which stripFirstH1 removes for the site. The parser now reads title / adr / status / date / superseded_by from frontmatter and validates that the frontmatter title, the filename number, the body heading and the status line all agree. 'supersedes' is deliberately NOT stored. Adding it surfaced that supersession here is transitive and flattened -- 0017 -> 0033 -> 0034 -> 0036, with 0017's status rewritten to name the final successor -- so an ADR's prose '**Supersedes:**' records history while 'superseded_by' records current state. Storing both invites exactly the drift this script removes, so one direction is the source and supersession_graph() derives the other. Mutation suite 16 -> 21 cases: missing frontmatter, missing status, adr number disagreeing with the filename, a title without its 'ADR NNNN:' prefix, and a body heading drifting from the frontmatter title. Refs #1390 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
) The frontmatter migration moved '**Status:**' out of ADR prose, and source_size_policy.py independently regex-scanned that line to confirm a cited ADR is Accepted. CI caught it: both registered exemptions failed with 'must have one **Status:** Accepted line' while main reported zero violations. A second consumer of the same prose, found only because the gate is fail-closed. It now reads the frontmatter 'status' field -- the same field the ADR index reads, so the two gates cannot disagree about what an ADR's status is. Its fixtures move to frontmatter with them, and the unaccepted cases now cover a prose-only ADR (the pre-migration shape, which must no longer satisfy the gate), a missing status key, and a duplicated one. Verified locally: source_size_policy 684 files / 0 violations, its 13 tests, adr-index check and its 21 mutations, gate-registry validate, test-pre-push-validation, test-python-lock-policy, ruff format and check. Refs #1390 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Summary
Records ADR 0038: Determinism belongs at the publication boundary, the decision behind epic #1456.
Why
The construction path's determinism contract read: identical logical input produces byte-identical shaped and encoded artifacts, across separate sessions and separate project directories, at every recorded partition count, and across an interrupted-and-resumed run.
We do not meet it. #1416 records that
ConstructionShape::runtime_catalog_now_microsisSystemTime::now()at session open, written intoshaped-runtime-catalog.parquet. The determinism suite passes by pinning the session clock. Byte-identity across sessions is a test fixture working around a defect.And it is stronger than anything depends on. Shaped intermediates are transient:
recover_shape_intentunlinks everypart-,staged-andshaped-name on an incomplete run. Nothing outside the construction session observes them.The cost is concrete: every attempt to parallelise construction (#1429, #1448) has been constrained by reproducing a byte stream under an arbitrary schedule, and the evidence architecture supporting it — running peaks over a global install-minus-unlink total, an ordered transition log — is schedule-dependent by construction.
What the contract becomes
Published artifacts stay canonically ordered and byte-stable. Shaped intermediates may differ by execution schedule. Worker count, execution partitioning, and the durable partition count with its recorded UUID splitters remain three distinct numbers.
The replacement check
Byte-equality of intermediates is replaced, not dropped — removing it without a replacement would remove the only total check on concurrency.
Semantic equivalence at the boundary: identical node and edge sets, identical adjacency, identical answers for the ladder's recorded queries, compared across forced worker counts, recorded partition counts, and an interrupted-and-resumed run. More expensive than a digest diff, and it checks the property rather than a proxy.
This follows three changes landed the same day that made the same move: a growth assertion replaced by a conservation law (#1435), a partition-balance row-count proxy replaced by distinct keys (#1440), and an observed call floor re-derived from remaining contributors (#1450).
Also superseded
Any test, comment or brief asserting that specific shaped-artifact digests are fixed values. The table in
construction_determinism_tests.rs's header documents a measurement on13632d4b, before the external merge tree was removed; two of its four rows were already stale, and no test asserted them.Scope
Docs only — ADR plus the four indexes. No behaviour change; the work it authorises is tracked in #1456.
python3 scripts/ci/adr-index.py check-> ok, 34 active and 3 superseded records agree across all four indexes.Refs #1456, #1416, #1387.
Need help on this PR? Tag
@codesmith-botwith what you need. Autofix is disabled.