IU Core 30x Structure/Autocut — 05 PgStructureStore, auto-cut bridge, delivery seam
05 — PgStructureStore, Auto-cut Bridge, Delivery Seam
Python PgStructureStore — live SQL-backed driver
cutter_agent/iu_core/pg_structure_store.py — PgStructureStore is the live
counterpart of the in-memory InMemoryStructureStore test seam. It delegates
the whole plan→apply→verify→rollback envelope to the SQL execution layer of
record (fn_iu_structure_op_*).
Deliberate architecture: the SQL layer owns every safety property (structure-op
gate, IU Gateway write guard, fn_iu_create birth gate, acyclicity assertion,
compensation snapshot). PgStructureStore is a thin typed driver — it never
re-implements tree logic in Python and never writes a table directly. Driving
the granular StructureStore Protocol against Postgres would bypass those
gates; the live path goes through them.
Interface: structure_ops_enabled(), plan(StructureOpRequest) → op_id,
apply/verify/rollback(op_id) → PgStructureOpResult, drive(request) — the
workflow-equivalent plan→apply→verify. Takes any DB-API 2.0 connection;
imports no driver → import-safe without a database, unit-testable with a
recording fake connection (10 executable tests).
Auto-cut bridge — birth-gate handshake wiring
autocut_bridge.py gained BirthSpec — the IU birth attributes
(canonical_address/title/body/unit_kind/section_type) a cut must supply for
every new piece. CutResultUnit.birth_spec carries it;
map_cut_to_structure_ops puts it into payload['new_pieces'] — the same
birth-gate handshake the migration-012 SQL apply consumes.
End-to-end proof: CutResult with BirthSpec → AutocutBridge →
StructureOpRequest with new_pieces → PgStructureStore.drive() →
verdict.ok. The add/split mapping was also proven DB-backed in sandbox/070
P9 (autocut-mapped add_new_piece applies ok, past feature_not_supported).
Delivery seam — next-step package (NOT executed)
dry_run=false remains a separate sovereign macro. Current: fn_iu_route_ deliver RAISEs feature_not_supported; every structure route dry_run=true;
CHECK iu_outbound_route_safe_chk makes enabled+dry_run=false impossible.
Concrete dry_run=false package:
- Build
fn_iu_route_deliverwith asql_functionconsumer —fn_iu_structure_consumer(event_ref, safe_payload)recording aniu_tree_change_logprojection. In-PG, no network, idempotent onevent_ref. - Relax the route CHECK per-route — keep the blanket CHECK; add a
dot_configallowlist (iu_core.delivery_live_routes) + a guard. - Add
dot_config 'iu_core.delivery_enabled'— dedicated fail-closed kill-switch. - Rollback/disable package — stub restore, route →
dry_run=true, close the gate, dead-letter replay, truncatable projection.
The Python contract exists (delivery_seam.py — target-kind vocabulary,
request/outcome shapes, UnbuiltDeliveryTarget fail-closed default). Blast
radius strictly larger than dry-run — sovereign macro.