IU Core MVP — 04 DDL Migration + Rollback Package
IU Core MVP — 04 DDL Migration + Rollback Package
Date: 2026-05-21 · Author-only. NO DDL executed. Repo path
sql/iu-core/.
Forward migrations
| # | File | Objects | Notes |
|---|---|---|---|
| 001 | 001_iu_sql_link.sql |
table iu_sql_link + 3 indexes |
IU↔SQL object link; idempotency UNIQUE; object-shape CHECKs |
| 002 | 002_iu_event_routes.sql |
iu_sql_event_route, iu_outbound_route, iu_route_attempt + 5 indexes |
route registries; enabled=false OR dry_run=true CHECK on both routes |
| 003 | 003_parent_child_constraints.sql |
table iu_tree_path + 3 indexes + view v_iu_tree |
recursive view is cycle-safe (path-membership guard) |
| 004 | 004_structure_ops_lineage.sql |
iu_structure_operation, iu_relation + partial-unique + 4 indexes |
one active contains parent per child enforced |
| 005 | 005_trigger_contracts_and_guards.sql |
7 functions + view v_iu_sql_link_resolved |
NO CREATE TRIGGER; trigger DDL parked in commented SANDBOX-ONLY block |
Rollback package (reverse order 005 → 001)
Every forward file has rollback/NNN_*.rollback.sql. Each table rollback is a
DO block that RAISES and REFUSES if the table still holds rows. Rollback
005 drops functions/views in reverse dependency order and documents that a
sandbox-attached trigger must be dropped first (intentional fail-closed).
DDL constraint compliance
- No hard delete: zero
ON DELETE CASCADE; links/relations retire vialifecycle_status/relation_status+valid_to. - Idempotent shape:
CREATE TABLE/INDEX IF NOT EXISTS,CREATE OR REPLACE. - No
ALTERoninformation_unit,unit_version,event_*,cutter_governance.*. - No cross-schema FK to catalog internals (
pg_proc/pg_class/pg_trigger); resolution is a STABLE helper functionfn_iu_sql_link_validate. - Every table carries audit timestamps (
created_at/started_at/valid_from). - Every event/route table carries an idempotency/uniqueness guard
(
idempotency_keyUNIQUE on link + operation;(idempotency_key,attempt_no)UNIQUE on attempt;route_codeUNIQUE on both routes). - Disabled-by-default: route rows default
enabled=false, dry_run=true, fail_closed=true; a CHECK forbids an enabled+non-dry-run route in this package. - Owner/purpose/lifecycle in every file header +
COMMENT ONon tables. - Each migration wrapped
BEGIN; ... COMMIT;.
Idempotency key formats (from DDL brief, mirrored in cutter_agent/iu_core)
iu_sql_link : iu_sql_link:{unit_id}:{object_kind}:{schema}:{name}:{row_pk_hash}:{link_role}
inbound : iu_sql_in:{route_code}:{schema}.{table}:{pk_hash}:{op}:{content_or_tx}
outbound : iu_out:{event_domain}:{event_type}:{unit_id}:{version_ref}:{content_or_seq}
attempt : iu_attempt:{route_kind}:{route_code}:{event_ref}:{subject_hash}
operation : iu_op:{operation_type}:{sorted_source_ids}:{sorted_target_ids}:{payload_hash}
Acceptance checklist (DDL brief §G4) — status
Schema: exactly the approved objects (+ justified iu_route_attempt); no
ALTER; no trigger attached; UUID PK + gen_random_uuid(); metadata default
'{}'::jsonb; routes default safe — ALL PASS.
FK/check/index: link FKs to information_unit + unit_version; UNIQUE
idempotency_key; UNIQUE route_code ×2; CHECKs for kinds/direction/lifecycle/
sql_event/target_kind; lookup indexes; no catalog FK — ALL PASS.
No-mutation: authored only, not executed; sandbox plan separate; production
approval absent ⇒ STOP — PASS.
Rollback/disable: routes disable without trigger drop; links retire not
delete; future trigger has disable route + guard plan; DOT verifier planned —
PASS.