Skip to content

docs(adr): determinism belongs at the publication boundary (ADR 0038) - #1457

Merged
DecisionNerd merged 4 commits into
mainfrom
docs/1456-determinism-boundary-adr
Sep 18, 2026
Merged

DecisionNerd merged 4 commits into
mainfrom
docs/1456-determinism-boundary-adr

Conversation

@DecisionNerd

@DecisionNerd DecisionNerd commented Sep 17, 2026 •

Copy link
Copy Markdown
Contributor

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_micros is SystemTime::now() at session open, written into shaped-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_intent unlinks every part-, staged- and shaped- 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

  1. A resumed run produces the same graph as an uninterrupted one.
  2. The same logical input produces the same query answers.
  3. A content-addressed digest names the bytes it claims to name — SHA-256 unchanged wherever a digest is an identity.

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 on 13632d4b, 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.


View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need. Autofix is disabled.

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>
@coderabbitai

coderabbitai Bot commented Sep 17, 2026 •

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Advanced

Run ID: a691d1d0-38cb-48de-95fa-4d989da38837

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions github-actions Bot added documentation Improvements or additions to documentation release:none No release note or version impact labels Sep 17, 2026
…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>
@github-actions github-actions Bot added the tooling Developer tooling and automation label Sep 17, 2026
DecisionNerd and others added 2 commits September 17, 2026 21:30
…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>
@DecisionNerd
DecisionNerd added this pull request to the merge queue Sep 18, 2026
Merged via the queue into main with commit caead55 Sep 18, 2026
23 checks passed
@DecisionNerd
DecisionNerd deleted the docs/1456-determinism-boundary-adr branch October 1, 2026 14:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation release:none No release note or version impact tooling Developer tooling and automation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant