IU Core 480x — 03 Text-as-code roundtrip + sandbox proof
03 — Text-as-code roundtrip + sandbox proof
Durable text-as-code export — DONE
The export is real and durable, produced read-only from production via the
query_pg MCP tool and the text_as_code contract. Two snapshot inputs +
two committed export artifacts under iu-tree/:
| File | Content |
|---|---|
iu-tree/_corpus/corpus-snapshot-20260522.json |
read-only PG snapshot — 158 IUs (provenance) |
iu-tree/_corpus/collection-snapshot-20260522.json |
read-only PG snapshot — the pilot collection (provenance) |
iu-tree/_corpus/corpus-manifest.md |
the full 158-IU corpus as one deterministic text-as-code document — corpus_digest = ec7081e888ab1ec432e8aa7c79e75378 |
iu-tree/_collections/document/iu_core.composer.pilot-doc-001.md |
the pilot composed collection manifest — 3 pieces |
text_as_code.serialize_corpus is new: it serialises the whole corpus to ONE
deterministic, diffable document (sorted by doc_code, sort_order, iu_id),
metadata/structure only — no IU body content.
Import / roundtrip contract — IMPLEMENTED
The 240x macro shipped the serializer + validators; this macro adds the reverse direction, so a composition manifest genuinely round-trips:
parse_collection_manifest(text)— the exact inverse ofserialize_collection_manifest: reads the frontmatter block + the ordered piece lines; fail-closed (raisesValueErroron a malformed manifest).roundtrip_collection_manifest(manifest)—serialize -> parse -> serializeis byte-identical.CollectionImportProposal+propose_collection_import(text)— the fail-closed, NON-DESTRUCTIVE importer: it parses, validates (validate_collection_manifest), confirms the stored digest matches recomputation, and returns a proposal.executesis always False;IMPORT_IS_DESTRUCTIVEstaysFalse. A real durable apply remains a separate, separately-gated macro (doc 07).
Roundtrip proof on REAL production data
The one-shot generator ran text_as_code over the production snapshot:
corpus export -> iu-tree/_corpus/corpus-manifest.md (158 IUs)
collection validate ok=True errors=()
roundtrip byte-identical=True parsed_pieces=3
import_proposal_acceptable=True executes=False
The pilot collection's Python computed_digest() reproduced the digest the
SQL fn_iu_collection_manifest_refresh stored on production
(909ea67e8b9e7dd72da242cbbee02510) byte-for-byte — so the SQL digest,
the composer.py contract, and the text_as_code layer all agree on real
data. test_iu_core_480x_composer_events.py re-asserts this in CI.
sandbox/110 — composer event + workflow-as-pieces probe
sandbox/110_composer_event_workflow_probe.sql is the BEGIN...ROLLBACK
proof-on-apply for migration 016 — zero durable rows, safe on production. It
registers the event family in-tx and proves E1–E9: event types registered;
compose emits create + 2x added; add/remove/reorder emit; checkpoint emits
collection_validated; v_iu_composer_event_backlog + v_iu_collection _export_status surface the events; emission is fail-closed with the master
gate shut; a workflow is an ordered set of step pieces (E8); workflow
validation is fail-closed on a broken step (E9). It references the migration
016 objects so it runs after 016 is applied — exactly as sandbox/100
required migration 015.
Text-as-code import stays fail-closed — gate 13
IMPORT_IS_DESTRUCTIVE = False; propose_collection_import raises if that
invariant is ever flipped; CollectionImportProposal.executes is always
False; the proposal is rejected when the digest disagrees. The mandatory
gate 13 (text-as-code import fail-closed + non-destructive) holds.