Orchestrata Ultimate › Plans › briefs › 2026-09-22-adr-0047-register-aware-adr-tooling
Brief: make the ADR tooling register-aware (execute ADR-0047)
Source: plans/briefs/2026-09-22-adr-0047-register-aware-adr-tooling.md at 8a2cb42ad · last changed 2026-09-22 · first committed 2026-09-22 · 105 lines.
Prose pending.
Plan text
Brief: make the ADR tooling register-aware (execute ADR-0047)
DESIGN_WAIVER: ADR-0047 (Accepted 2026-08-29). Scope is exactly that ADR's
mandate: "ids match as zero-padded strings — ADR-0001 (factory register,
docs/adr) and ADR-001 (project register, the wiki page) are different ids.
register becomes a graph-node property; the gate matches (register, padded
id); nothing renumbers."
GOAL
parse_adrs, ArchitectureWriter.upsert_architecture_decision,
scripts/sync_architecture_to_graph.py --adrs and
scripts/check_adr_graph_sync.py all key an ADR by (register, padded_id)
so the two registers on the wiki page never collapse onto one integer.
FACTS (measured 2026-09-22)
- The wiki page has 83
## ADR-…:headings: 58 four-digit (factory) and 25 three-digit (project). Numbers 1..25 are claimed by BOTH registers.parse_adrsreturns 83 entries with only 58 distinctnumbers. load_wiki_adrs/load_repo_adrs/load_graph_adrsin the gate all returndict[int, …], so the later heading silently wins.upsert_architecture_decisionbuildsid = f"{project}:ADR-{int(n):04d}", so a project entry is written under the factory id. That is how the single nodeorchestrata-ultimate:ADR-0001came to carry the project title 'Memgraph as Semantic Graph Backend', and why the sync now aborts withAdrImmutabilityErroron the factory ADR-0001 before writing anything else (46 gate violations, all downstream of this).- The graph the gate/sync use under the default
testprofile is 10.53.2.10orchkg; it holds exactly one ArchitectureDecision node (the one above). The one-time re-key of that node is NOT this brief's job; Mohamed ruled it and the orchestrator executes it after this lands.
FILES
src/orchestrata_ultimate/knowledge_graph/adr_parser.pysrc/orchestrata_ultimate/knowledge_graph/architecture_writer.pyscripts/sync_architecture_to_graph.pyscripts/check_adr_graph_sync.pytests/knowledge_graph/test_adr_parser.pytests/knowledge_graph/test_architecture_writer.pytests/scripts/test_sync_architecture_to_graph.pytests/scripts/test_check_adr_graph_sync.py- Nothing else. Do not touch the wiki page, docs/adr, or any env file.
DESIGN (settled)
ParsedAdrgains two fields:register: str("factory"when the heading id has 4 digits,"project"when it has 1–3 digits) andpadded_id: str(the heading's digits verbatim, e.g."0001"/"001").number: intstays for callers that only need the integer.parse_adrsandparse_adr_filepopulate both;parse_adr_file(docs/adr files) is alwaysfactory.upsert_architecture_decisiontakespadded_id: strandregister: str(keyword, required alongsideadr_number); the node id becomesf"{project}:ADR-{padded_id}";registerandpadded_idare written as node properties;adr_numberstays as today. Every existing caller is updated; the immutability check is unchanged.sync_adrspassesregisterandpadded_idthrough.- The gate keys every corpus by
(register, padded_id):load_repo_adrs(factory only, from filenames/headings),load_wiki_adrs(both registers, from headings),load_graph_adrs(readsn.register,n.padded_id; a node lacking them is reported as aLEGACY_UNKEYEDviolation naming its id and title, never silently binned).AdrSyncRowcarriesregisterandpadded_id; output lines printADR-<padded_id>prefixed by the register when it isproject. A wikiprojectentry with no docs mirror is NOT a violation (the wiki is that register's file of record). - Tests: extend the four test modules with real cases: a page holding
## ADR-001:and## ADR-0001:with different titles parses to two entries with distinct(register, padded_id); the writer creates two distinct nodes for them on the real test graph and neither raises immutability; the gate on that fixture reports 0 violations; a legacy node withoutregistersurfaces asLEGACY_UNKEYED. Writer/gate tests use the real graph exactly as the existing tests in those modules do.
CONSTRAINTS
- No mocks/fakes/stubs/monkeypatch, no skip, no xfail.
- Read Python through
scripts/serialize_codebase_ast.pyonly; edit with Edit/Write. Test runs: background,timeout 300,ORCHESTRATA_ENV_PROFILE=test,-p orchestrata_ultimate.core.threading.pytest_live_observer. - Do NOT run
scripts/sync_architecture_to_graph.py --adrsfor real and do NOT write toorchestrata-ultimate:ADR-0001on any graph; the orchestrator holds that ruling.--dry-runis fine. - Commit with
git -c user.name=Mohamed -c user.email=msamy@sufigeeks.org, no AI attribution lines (RUL-007 gate). Do not push.
DONE WHEN
- The four test modules pass (0 failed / 0 skipped / 0 xfailed) in one observed background run.
uv run ruff check+uv run ruff format --checkclean on all touched files;uv run pyrightreports no new errors in src/ or scripts/ for them.scripts/check_adr_graph_sync.pyrun for real (read-only) reports the stale node asLEGACY_UNKEYEDfor ADR-0001 and otherwise onlyMISSING_FROM_GRAPHrows (the sync has not run yet) — no crash, noAMBIGUOUS_COLLISIONon numbers 1..25.- One commit on master containing the eight files and this brief unchanged.
VERIFY (report verbatim)
- The pytest summary line of the run over the four modules.
- The first 8 lines of the real
check_adr_graph_sync.pyoutput. - The commit sha and
git show --stat HEAD.