91000x · 02 — Apply 037-039 with surgical drift patches (Phase B PASS)
91000x · 02 — Apply 037-039 with surgical drift patches
Phase: B
Status: PASS for 037-039 (with patches); 040/041 NOT APPLIED
Date: 2026-05-26
Apply path
All three migrations applied via workflow_admin socket-trust channel:
ssh contabo 'docker exec -i postgres psql -U workflow_admin -d directus -v ON_ERROR_STOP=1' << EOSQL
…migration body…
EOSQL
Each migration was wrapped in BEGIN; … COMMIT;. Any error inside the TX rolls back atomically.
Migration 037 — applied (after 3 retries to discover live drifts)
Original authored body (90000x report 02) FAILED twice in pre-COMMIT state:
| Try | Error | TX | Fix |
|---|---|---|---|
| 1 | iu_core_retention_policy_keep_days_check violated (keep_days=0; live CHECK >=1) |
rolled back | keep_days 0 → 1 |
| 2 | iu_core_retention_policy_pkey duplicate (D36 Macro A pre-inserted these rows on 2026-05-25 12:48) |
rolled back | added ON CONFLICT (target_table) DO NOTHING |
| 3 | dot_iu_command_catalog_category_check violated (maintenance not in {collection,piece,lifecycle,read,health}) |
rolled back | category maintenance → lifecycle for both cleanup + unregister |
| 4 | none | COMMITTED | applied |
Live D9 deltas (post-apply 037)
post_037 | new_dots | dot_total | lifecycle_chk
----------+----------+-----------+-----------------------------------------------------------------
post_037 | 2 | 32 | CHECK ((lifecycle_status = ANY (ARRAY['pending','pending_review',
'approved','consumed','rejected','expired','cleaned'])))
037 fn body drift discovered after apply (patched in next TX)
Functions fn_iu_staging_cleanup and fn_iu_staging_unregister were CREATEd successfully (plpgsql defers SQL stmt resolution to runtime), but their INSERT INTO dot_iu_command_run (command_name, payload_json, actor, status) would fail at first apply=true call because:
payload_jsondoesn't exist — column isevidence(jsonb, NOT NULL default'{}')statusdoesn't exist — column isrun_status(NOT NULL, vocab{planned,applied,verified,refused,failed})categoryis required (NOT NULL, vocab{collection,piece,lifecycle,read,health})run_modeis required (NOT NULL, vocab{plan,apply,verify})
Patch via CREATE OR REPLACE (separate TX, atomic):
-- 91000x drift fix
INSERT INTO dot_iu_command_run (command_name, category, run_mode, run_status, mutating, actor, evidence)
VALUES ('dot_iu_staging_cleanup', 'lifecycle', 'apply', 'applied', true, p_actor,
jsonb_build_object('apply', true, 'ran_at', v_now));
(Similar pattern for unregister.)
Algorithm + axis A/B/C + lifecycle transitions unchanged.
Verification after patch:
dry_run_rows = 0 (cleanup, expected — all 3 existing staging rows within 15d)
unregister_not_found = {"ok": false, "reason": "not_found"}
Migration 038 — applied (with drift patches inline)
Authored body anticipated iu_staging_payload INSERT without byte_len, and same dot_iu_command_run schema mismatch. Applied with patches:
- Added
byte_lencomputation (octet_lengthper part) + INSERT column. - Rewrote
dot_iu_command_runINSERT to live schema. - DOT
dot_iu_mark_articlecategory'mark'→'piece'(live vocab).
After first apply attempt, second drift discovered at runtime in bounded proof:
iu_staging_payload_kind_chkvocab is{json,text,blob_ref}— author used'markdown'for mark_report.iu_staging_payload_exclusive_chkrequirespayload_kind='text' ⇒ payload_text NOT NULL AND payload_json NULL. Author wrote payload_json with kind=markdown.
Patch via CREATE OR REPLACE:
-- mark_report row: 'markdown' kind not in vocab; rewritten as 'text' going to payload_text
INSERT INTO iu_core.iu_staging_payload (…, part_name, payload_kind, payload_json, payload_text, byte_len, …)
VALUES
(…, 'cut_manifest', 'json', p_manifest, NULL, v_cm_len, …),
(…, 'mark_report', 'text', NULL, v_mr_text, v_mr_len, …),
(…, 'coverage_proof', 'json', p_coverage_proof, NULL, v_cp_len, …);
Live D9 deltas (post-apply 038)
post_038 | new_dot | dot_total
----------+---------+-----------
post_038 | 1 | 33
fn_iu_mark_create_manifest created with patched body. Contract identical to authored: same inputs, same return shape ({ok, staging_record_id, lifecycle_status, expires_at, manifest_digest}), same side effects (1 record + 3 payloads + 1 audit), same idempotency.
Migration 039 — applied (with patches)
Same dot_iu_command_run drift patches as 037/038, both in the REJECT path and the APPROVE path. DOT dot_iu_verify_mark_manifest category 'verify' → 'health'.
Axis A/B/C checks, coverage byte-match, 32-hex digest check — all unchanged from author intent.
Live D9 deltas (post-apply 039)
post_039 | new_dot | dot_total
----------+---------+-----------
post_039 | 1 | 34
Final state after 037+038+039 apply
| Object | Pre | Post | Delta |
|---|---|---|---|
dot_iu_command_catalog rows |
30 | 34 | +4 |
public schema functions |
470 | 474 | +4 |
iu_staging_record_lifecycle_chk vocab size |
6 | 7 | +1 (pending_review) |
iu_staging_record_consumed_consistency_chk |
required {consumed_at, consumed_by_run_id} | required {consumed_at, consumed_by_run_id, approved_at, approval_doc_id} | tightened |
iu_staging_record_expiry_ceiling_chk |
absent | expires_at <= created_at + 30d |
new |
iu_core_retention_policy rows |
6 | 6 | 0 (D36 prior; ON CONFLICT preserved) |
| All other surfaces (IU, VSP, staging rows, DIEU axes) | — | — | unchanged |
Migrations 040/041 — NOT APPLIED
Authored 040/041 reference live functions and tables that don't match observed live schema across at least 5 dimensions (see 00-summary "The exact gap"). Per user rule "do not re-author 040/041 in this run; do not redesign/re-author from scratch", these migrations are deferred to a 100000x macro that will author corrected bodies against live signatures.
Rollback (per migration)
| Migration | Rollback DDL (authored in 90000x report 02-04) | Notes |
|---|---|---|
| 037 | DROP fn_iu_staging_cleanup + fn_iu_staging_unregister; DELETE 2 catalog rows; DROP 3 CHECKs + restore prior CHECK vocab + consumed-consistency | refuses if any row currently in pending_review |
| 038 | DROP fn_iu_mark_create_manifest; DELETE catalog row dot_iu_mark_article |
refuses if any staging row was created by this fn (referenced_iu_ids handling) |
| 039 | DROP fn_iu_verify_mark; DELETE catalog row dot_iu_verify_mark_manifest |
no state to undo (proof was BEGIN/ROLLBACK) |
Full rollback bodies in 06-rollback-package.md.
Verdict
Phase B PASS for 037-039 with surgical drift patches. 040/041 deferred (exact gap in 00-summary).