SN Provenance Ledger — landed record

The graph is now a robust provenance ledger: every non-superseded StandardName traces to ≥1 StandardNameSource. Built and executed 2026-07-09 in imas-codex (the plan lives in ISN; the code is in imas-codex). All work landed on main.

Result on the live graph (production)

Live names with no PRODUCED_NAME source before 1818 after 0 Anchorless residue routed to source_type='manual' first rebuild 95 corrected 22

The first rebuild fell back to manual for 95 names because it skipped derived-parent source materialisation and the surviving source_paths anchor. The corrected rebuild runs the full fresh-build fixpoint sequence (incl. seed_parent_sources): 67 derived parents gained a composed-from-children derived source, 6 recovered real dd sources from their source_paths scalar, leaving 22 genuinely anchorless composed leaves as auditable manual residue.

Outcomes by workstream

WorkstreamStatusResultCommits
WS1 — provenance rebuild to fresh-parity ✓ landed New provenance_rebuild.py: replays the deterministic fresh-build (reattach → rederive structure → seed_parent_sources → relink FROM_DD_PATH) then binds remaining orphans by anchor authority (a2f8831 map → surviving source_paths → derived parent → manual). Ran on production: 1818→0 orphans, content preserved. 013849db, 91e83a1a
WS5 — ledger invariant + reattach + gate ✓ landed ledger.py invariant queries; reconcile_provenance gains a reattach pass (heals live scalar/missing-edge desyncs); persist_refined_name repoints the migrated source's scalar; sn run reports the orphan count every cycle; graph-marked read-only invariant tests assert 0 orphans / 0 desyncs. Wired to release Gate A via a graph-marked test under tests/standard_names/. f3edb899, 718471f4
WS3/WS4 — full-sources export + diff-by-id reconciler ✓ landed export.py now emits the full sources projection (source_type + provenance) — a lossless ledger snapshot. New catalog_reconcile.py restores the graph by id (scalar deltas + rebuild StandardNameSource from sources), never recreating nodes. 2255b7ff, 67a0a93a
WS2sn merge PR acceptance ✓ landed New merge.py run_merge: reads the catalog-PR diff, matches by id, attaches each edit like sn edit (apply_edit(refine=False), rename via the cascade carrying pn_sources), full review with NO refine (structural — transitions synchronously to accepted/quarantined), ≥θ accept else validation_status='quarantined'. Refine pools proven never called. c344e4c2
Schema — manual source type ✓ landed Added manual to StandardNameSourceType for anchorless residue (explicit, auditable; never a fabricated DD path). b3d541dc
CLI hygiene — drop one-shot recovery verbs ✓ landed Removed the sn rebuild-provenance / sn reconcile-catalog verbs (one-shot/restore-only). The tested modules remain scriptable; ongoing healing (reattach + orphan report) fires automatically in sn run. bf79f091
Bulk import removed completely (no backwards compat) ✓ landed Deleted the node-recreating, provenance-dropping run_import + _write_import_entries + the sn import CLI verb + all import/round-trip tests; superseded by sn merge (acceptance) and catalog_reconcile (restore). Kept check_catalog (publish) + shared helpers. test_no_bulk_import.py locks the removal. 4b949931
sn merge CLI verb wired ✓ landed Exposes run_merge as sn merge --isnc <dir> --base <ref> [--threshold F] [--dry-run]; exits non-zero on any edit that could not be attached. (this session)

What's next