Home / Projects / Orchestrata Ultimate / Decisions / ADR index / ADR-0098

ADR-0098: First-docs-capture rule — a graph ADR node whose body was never captured from docs/adr/ (it holds a wiki summary or is empty) is baselined once from its docs body; immutability binds from that first docs capture onward

field value
Status Accepted — Accepted (ruling, Mohamed, 2026-10-13, verbatim: "agreed on 0098, rerun the sync fix when hooks land")
Date 2026-10-13
Register factory (docs/adr, 4-digit ids)
Source docs/adr/0098-first-docs-capture-rule-a-graph-adr-node-whose-body-was-never-captured-from-docs-is-baselined-once-from-docs.md — permalink at 3a3546ed3 (unchanged on master since that commit)
Wiki register entry ADR-0098 (wiki status: Accepted)

← ADR-0097 · ADR-0099 →

The record

Status: Accepted (ruling, Mohamed, 2026-10-13, verbatim: "agreed on 0098, rerun the sync fix when hooks land") · Date: 2026-10-13 · Extends ADR-0096 (which authorised one re-baseline, ADR-0073) · Evidence: the body comparison added to check_adr_graph_sync.py under ADR-0096, run read-only against the live graph by the builder on 2026-10-13 (worktree adr-sync-fix, checkpoint 09e29ec7e)

Context

ADR-0096 authorised a single re-baseline because the audit of the 36 sync refusals found only ADR-0073 with a stale graph body. The audit answered the question it was asked: of the ids the sync refused to overwrite, which had drifted. It could not see ids the sync never tried to compare by body.

The body comparison the builder added to the check (docs body_sha versus graph for every factory id) reports 35 BODY_DRIFT rows over 122 ids, 70 docs ids compared, and they are not the 35 pointer ids of the audit:

Two mechanisms produced this: the wiki pass ran alone on the day many nodes were first written (the --repo-adrs pass did not run), and the wiki parser folds whatever prose it finds into decision. The immutability guard then did its job on the wrong baseline: it now protects wiki summaries and empty bodies as if they were the accepted decisions. Under ADR-0096 as written, the check cannot reach OK: --repo-adrs fixes the Proposed nodes but the Accepted ones with wiki bodies are refused, and ADR-0096 names only 0073.

Decision (proposed)

  1. A docs body is the only body immutability protects. A graph ADR node whose stored body was captured from the wiki page or is empty has never held the accepted decision; baselining it from docs/adr/ is a first capture, not an edit. The guard binds from that first docs capture onward, and rebaselined_by/rebaselined_at record the event.
  2. The set is computed, not listed. The re-baseline path accepts an id when (a) a docs file exists for it and (b) the graph body hash equals the empty-body hash or equals the hash of the wiki entry's parsed body, or the node carries no docs-capture marker; it refuses any id whose graph body already came from docs and differs (that is real drift and needs its own ADR). The 35 ids above are the result of that rule today; the report lists them with the reason per id.
  3. One run, logged, under this ADR's authority. sync_architecture_to_graph.py --rebaseline-first-capture --authority ADR-0098 performs it once, logs a REBASELINED: line per id with the before/after hashes, and writes the docs-capture marker. ADR-0096's single-id path stays for named exceptions.
  4. The wiki pass never writes a body for a docs-owned id again (ADR-0096 rule 1), and --repo-adrs runs in every sync, so the condition cannot recur; the check's body comparison is the proof and must print 0 BODY_DRIFT after the run.
  5. ADR-0004 and ADR-0019 are unaffected (graph already holds their docs text; ADR-0096 rule 4 stands).

Alternatives rejected

Consequences

Provenance

Builder report of 2026-10-13 (check output: 35 BODY_DRIFT / 122 ids / 70 compared; id groups and the empty-body hash as quoted). Drafted by the coordinating session. Ruled Accepted by Mohamed on 2026-10-13 ("agreed on 0098, rerun the sync fix when hooks land"). The sync-fix builder's checkpoint d2d93ea53 already carries rebaseline_first_capture and the --rebaseline-first-capture --authority ADR-0098 path with tests (142 passed across 9 files), unexecuted; execution happens in the rerun after ADR-0097's hook fix is deployed.

Rulings cited

None.

Specs cited