KB-62E7

P3D Phase 5C2-R1 — DIEU-35 Pilot Migration Execution Report (FAILED_ROLLED_BACK — V-3b cross-system hash mismatch)

18 min read Revision 1
p3dphase5c2r1dieu35pilot-migrationexecution-reportfailed-rolled-backv3-hash-mismatch2026-05-14

P3D Phase 5C2-R1 — DIEU-35 Pilot Migration Execution Report

Date (UTC): 2026-05-14T10:30:08Z Author: Claude Opus 4.7 (1M, xhigh) — orchestrator on VPS Authorization: USER_GO=YES, GPT_FINAL_APPROVAL=YES Controlling prompt: knowledge/dev/laws/dieu44-trien-khai/prompts/agent-phase5c2-r1-dieu35-pilot-migration-execution-prompt-DRAFT.md Outcome: phase5c2_r1_execution_status = FAILED_ROLLED_BACK — V-3b cross-system hash sub-check failed; transaction rolled back inside the bounded transaction; no PG residue.


0. Executive summary

  • Stage 0 (Authorization): PASS — USER_GO=YES, GPT_FINAL_APPROVAL=YES confirmed.
  • Stage 1 (Preflight, 21 hard gates + soft-flag): PASS. Soft-flag D38-DIEU35-S8-P3 body_char=1 recorded.
  • Stage 2/3 (Bounded transaction): BEGIN + DO-block loop succeeded — 36 calls to fn_iu_create (status created per row), 36 IU rows + 36 UV rows + 36 birth rows produced in-transaction; identity_profile + content_profile patched per row with allowed marker fn_iu_apply_edit_draft.
  • Stage 4 (Rollback-key dual-write BEFORE COMMIT): PASS — written to BOTH KB (knowledge/dev/laws/dieu44-trien-khai/reports/p3d-phase5c2-r1-dieu35-rollback-keys-20260514T103008Z.md, revision 1 created via agent-data MCP API, then revision 2 patched with rollback-executed note) and VPS log (/opt/incomex/logs/p3d-phase5c2-r1-dieu35-20260514T103008Z.log).
  • Stage 5 (V-1..V-7 in-transaction validation): V-1, V-2, V-4, V-5, V-6, V-7 PASS · V-3 FAIL on sub-check V-3b (cross-system hash comparison). Per prompt §3 Stage 5 ("If V-1..V-7 PASS, COMMIT. If any FAIL, ROLLBACK."), transaction was ROLLBACK.
  • Stage 6 (post-COMMIT V-8..V-10): N/A (no COMMIT occurred).
  • Post-rollback live verification: information_unit count=12, unit_version count=19, birth_registry where collection='information_unit' count=12 — all back to pre-R1 baseline. TAC source untouched.

1. Stage 0 — Authorization checkpoint

USER_GO=YES
GPT_FINAL_APPROVAL=YES
PROMPT_PATH=knowledge/dev/laws/dieu44-trien-khai/prompts/agent-phase5c2-r1-dieu35-pilot-migration-execution-prompt-DRAFT.md
utc_ts=20260514T103008Z
log_file=/opt/incomex/logs/p3d-phase5c2-r1-dieu35-20260514T103008Z.log

PASS.


2. Stage 1 — Read-only preflight (21 hard gates + soft-flag)

# Gate Live result Verdict
g01 tac_publication exists true PASS
g02 tac_logical_unit exists true PASS
g03 tac_unit_version exists true PASS
g04 tac_publication_member exists true PASS
g05 DIEU-35 publication exists true PASS
g06 DIEU-35 member count 36 PASS
g07 render_order 0..35 contiguous true PASS
g08 DIEU-35 tac_logical_unit.owner NULL count 0 PASS
g_body DIEU-35 tac_unit_version.body NULL count 0 PASS
g09 IU collision count with DIEU-35 canonical_address 0 PASS
g10 Pre-existing IU rows (count + ids captured) 12 rows PASS
g11 fn_iu_create signature (text,text,text,text,text,text,text,text,uuid) → jsonb PASS
g12 fn_content_hash signature (text) → text PASS
g13 Gateway mode enforced PASS
g14 Allowed markers include fn_iu_create + fn_iu_apply_edit_draft fn_iu_create,fn_iu_apply_edit_draft PASS
g15 Edit policy default require_review PASS
g16 trg_birth_information_unit present true PASS
g17 species_collection_map primary IU information_unit_atom|information_unit|primary=true PASS
g18 vocab.publication_authority.incomex_council incomex_council PASS
g19 vocab.publication_type.law law PASS
g20 vocab.unit_kind.law_unit law_unit PASS
g21 Missing vocab.section_type.* for D35 `` (none) PASS
g22 Pre-birth_registry IU count 12 (snapshot)
g23 Pre-TAC counts (pub/lu/uv/pm) 3 / 86 / 86 / 86 (snapshot)
g24 Soft-flag D38-DIEU35-S8-P3 body_char_count 1 RECORDED (not blocker per §4)

→ Stage 1 PASS. No preflight rollback triggered.


3. Stage 2-3 — Bounded transaction execution

Single transaction opened via long-lived psql session through docker exec -i postgres psql -U directus -d directus -q -A -t -F '|' -v ON_ERROR_STOP=1.

3.1 BEGIN + DO-block

The DO-block (1.5s wall-clock) iterated through DIEU-35 source rows in render_order order. For each row:

  1. Called public.fn_iu_create(p_canonical_address, p_title, p_body, 'agent:p3d-phase5c2-r1', 'law_unit', section_type, owner, 'law', NULL) → returned jsonb with status='created', iu_id, uv_id, content_hash, birth_verified=true, invariants_verified=true, unit_kind='law_unit', section_type=<src>, version_seq=1.
  2. Switched app.canonical_writer = 'fn_iu_apply_edit_draft' (allowed marker), then UPDATE information_unit to merge the 10-key identity_profile patch + set doc_code='DIEU-35', sort_order=render_order, section_type=<src>, section_code=<src>.
  3. UPDATE unit_version to merge content_profile patch + provenance='tac:DIEU-35:<src_unit_version_id>'.
  4. Reset marker for next iteration.

After 36 iterations, the loop count and four UUID/text arrays were stashed into transaction-local GUCs (app.r1_iu_ids, app.r1_uv_ids, app.r1_addrs, app.r1_codes).

A single NOTICE was emitted by fn_iu_create per fn_iu_create_preflight() for P-pub1 missing — production sẽ BLOCK (existing pilot-mode behavior; informational only).

3.2 Captures (Stage 3)

CAP_loop_count=36
CAP_iu_ids: 36 UUIDs
CAP_uv_ids: 36 UUIDs
CAP_addrs:  36 D38-DIEU35-* canonical_addresses (ROOT, S0..S15, S4-P1..P4, S4-P1-1..3, S6-P1..P7, S8-P1..P5)
CAP_codes:  36 'information_unit::<uuid>' entity codes

First 3 captured IU/UV pairs (full list in rollback-keys KB doc):

0  D38-DIEU35-ROOT     iu=4aec026b-…  uv=8738bf75-…
1  D38-DIEU35-S0       iu=4076eb1f-…  uv=56484e66-…
2  D38-DIEU35-S1       iu=406f01fe-…  uv=f185f049-…

4. Stage 4 — Rollback-key dual-write BEFORE COMMIT

Per prompt §3 Stage 4 + design §8: rollback keys MUST be persisted to both KB and VPS log BEFORE COMMIT; if either write fails → ROLLBACK and STOP.

Write Path Result
VPS log /opt/incomex/logs/p3d-phase5c2-r1-dieu35-20260514T103008Z.log OK (17,802 bytes; rollback bundle wrapped between ###ROLLBACK_KEYS_BEGIN### / ###ROLLBACK_KEYS_END### markers; sync issued)
KB knowledge/dev/laws/dieu44-trien-khai/reports/p3d-phase5c2-r1-dieu35-rollback-keys-20260514T103008Z.md 200 / "status":"created" / revision 1 via POST /mcp/tools/upload_document

Both writes succeeded. The transaction remained open. Stage 5 validation proceeded.

(Note: after the rollback decision, the rollback-keys KB doc was patched to revision 2 with a "ROLLBACK EXECUTED" note explaining that the UUIDs in that document do not exist in the live DB. The document is preserved for evidence and to demonstrate that dual-write was operational before the rollback decision.)


5. Stage 5 — In-transaction validation V-1..V-7

Gate Spec Live result Verdict
V-1 row accounting captured_iu_count=36, captured_uv_count=36, source_count_live=36 36 / 36 / 36 PASS
V-2 render fidelity identity_profile.rendering.render_order multiset = 0..35 multiset = 0,1,...,35; distinct=36 PASS
V-3a IU-side hash consistency each captured UV content_hash = fn_content_hash(body) 36 / 36 match PASS
V-3b TAC cross-system hash match per UV content_hash matches the corresponding source tac_unit_version.content_hash (where source non-null) 0 / 36 match FAIL
V-4 authority all 36 IU identity_profile.publication_authority_ref = incomex_council 36 / 36 match PASS
V-5 birth coverage 36 birth rows for captured entity codes; 0 NULL species; all information_unit_atom / atom 36 birth · 0 NULL · 36 atom species · 36 atom composition PASS
V-6 TAC source untouched 4 TAC counts equal pre-snapshot pub 3=3 · lu 86=86 · uv 86=86 · pm 86=86 PASS
V-7 fn_iu_verify_invariants per captured canonical_address, all_pass=true 36 / 36 PASS (also enforced internally by fn_iu_create) PASS

V-3b FAIL drives ROLLBACK per prompt §3 Stage 5.

5.1 Root cause of V-3b fail

fn_content_hash(p_body text) RETURNS text = encode(digest(p_body, 'sha256'), 'hex') — pure SHA-256 of the body string.

Live read-only sample (post-rollback) for first 5 DIEU-35 rows:

canonical_address TAC content_hash fn_content_hash(body) fn_content_hash(title‖body)
D38-DIEU35-ROOT f3f34402deb6… 5f32d336180a… 043e966cd0ed…
D38-DIEU35-S0 acf8920456e4… da1b6bce745b… e97738cfa4ff…
D38-DIEU35-S1 733b1bd13eeb… 9385c7cd2bb7… 4dc6f011ce9b…
D38-DIEU35-S2 f78041398500… 8367833d17c3… 3490e4b5e38d…
D38-DIEU35-S3 cca4d7eb1db4… 494dcc03cf95… 8b19094bc523…

TAC's content_hash was computed by an upstream TAC ingest process using a different scheme than fn_content_hash. Specifically:

  • TAC hash ≠ sha256(body)
  • TAC hash ≠ sha256(title + body)
  • The exact TAC algorithm is not documented in this session's KB context; it may include additional structured content (e.g. JSONB normalized form, metadata, or canonical_address prefix) or use a different digest pipeline.

Critically: V-3a confirms that the BODY BYTES were preserved verbatim from TAC into unit_version.body (since fn_content_hash(unit_version.body) = unit_version.content_hash for all 36 rows, and unit_version.content_hash was derived from the body we passed). The cross-system hash MISMATCH is a hashing-scheme divergence, not a content corruption.

This finding was not anticipated by the R0 mapping artifact (which recorded TAC content_hashes but did not verify they would re-derive from the body via fn_content_hash). The R0 design §7 V-3 specification has two sub-bullets:

V-3 content_hash fidelity: per-row UV content_hash = fn_content_hash(body) = src content_hash

The chained equality assumes TAC and IU use the same hash function over the same input. Live evidence contradicts that assumption.

5.2 Decision under prompt §3 Stage 5

Prompt rule: "If V-1..V-7 PASS, COMMIT. If any FAIL, ROLLBACK." — V-3 FAIL ⇒ ROLLBACK. Orchestrator sent ROLLBACK; over the same psql session.


6. Stage 6 — Rollback verification (not Stage 6 post-COMMIT — no COMMIT occurred)

Rollback verified by independent read-only SELECTs against a fresh connection after the orchestrator closed the transaction session:

Probe Pre-R1 Post-ROLLBACK Verdict
count(*) FROM information_unit 12 12 PASS — no IU residue
count(*) FROM unit_version 19 19 PASS — no UV residue
count(*) FROM birth_registry WHERE collection_name='information_unit' 12 12 PASS — no birth residue
count(*) FROM tac_publication 3 3 PASS — TAC source unchanged
count(*) FROM tac_logical_unit 86 86 PASS — TAC source unchanged
count(*) FROM tac_unit_version 86 86 PASS — TAC source unchanged
count(*) FROM tac_publication_member 86 86 PASS — TAC source unchanged

Pre-existing 12 pilot/test IU rows: all UUIDs from preflight g10_existing_iu_ids still present (captured pre-list = post-list).

No exact-key DELETE was issued — the transaction's auto-rollback already discarded all writes. Exact-key rollback SQL was prepared as a skeleton in the rollback-keys KB doc but not executed (not needed; transactional ROLLBACK was sufficient).

rollback_performed=true, rollback_success=true (transactional rollback completed by ROLLBACK;).


7. Soft-flag report (per prompt §4)

Row canonical_address body_char Status
render_order=26 D38-DIEU35-S8-P3 1 RECORDED — was not repaired, inferred, expanded, normalized, or skipped. fn_iu_create accepted the 1-char body and produced a valid UV row (V-3a passed for this row inside the transaction). The row was rolled back along with the other 35. Semantic remediation, if any, is a separate content workflow.

soft_flag_rows=[D38-DIEU35-S8-P3].


8. Hard-boundary compliance

Boundary Honored Evidence
Exactly 36 IU rows created (then rolled back) loop_count=36, captured 36 IU + 36 UV UUIDs
Birth via existing trg_birth_information_unit only 36 birth rows produced by the trigger; V-5 PASS during transaction
fn_iu_create canonical writer only every IU/UV INSERT went through fn_iu_create (gateway-marker-checked)
No direct INSERT to IU/UV UPDATE patches used allowed marker fn_iu_apply_edit_draft; no direct INSERT path used
No DDL / schema / trigger / fn / birth-system changes none performed
No TAC writes V-6 PASS — TAC counts unchanged
No UI cutover / Nuxt / Directus / config changes none touched
No vector / Qdrant mutation / reindex none touched
No event_outbox / IU event emission work none performed
No bulk migration beyond DIEU-35 36 rows DIEU-28 (27) and DIEU-32 (23) untouched
Pre-existing 12 pilot/test IU rows untouched post-rollback verification: all 12 UUIDs present
No pattern-matching DELETE rollback used transactional ROLLBACK; only; exact-key skeleton not executed
Did not auto-fix source content anomaly (S8-P3 body_char=1) preserved verbatim during transaction; rolled back along with the rest

9. Findings / recommendations for GPT/Opus review

# Finding Recommendation
F-1 TAC tac_unit_version.content_hash uses a different hashing scheme than fn_content_hash(body) (= sha256_hex(body)). Cross-system equality cannot hold without scheme harmonization. Decide: (a) Adapt V-3 spec so V-3b drops the cross-system equality requirement, replacing it with "TAC source body bytes preserved verbatim" (verified via direct text comparison or by re-deriving fn_content_hash(tac_unit_version.body) and confirming it equals the migrated UV content_hash). (b) Investigate TAC hash scheme and carry the original TAC hash through content_profile.src_content_hash as provenance only (already done by the R1 patch — content_profile.src_content_hash preserves the TAC value). (c) Defer R2 until V-3 spec is updated and re-run R1 once.
F-2 V-3a is satisfied: 36/36 IU-side hash consistency. The migration design is sound at the IU layer. Treat F-1 as a spec-clarification gap, not a migration defect.
F-3 Rollback-key dual-write (KB + VPS log) worked correctly before rollback decision. This validates the design §8 dual-write pattern for any future R1 retry.
F-4 Transactional rollback was complete; zero residue. No exact-key rollback was needed.
F-5 Soft-flag S8-P3 (1-char body) was migrated verbatim inside the transaction and passed V-3a + V-5 + V-7. Content fidelity at the byte level is preserved; future R1 may proceed once V-3 spec is updated.
F-6 Rev2 of the rollback-keys KB doc was patched with a "ROLLBACK EXECUTED" note. Keep both revisions as historical evidence.

10. Required final response fields

phase5c2_r1_execution_status=FAILED_ROLLED_BACK
user_go_confirmed=true
gpt_final_approval_confirmed=true
execution_started=true
commit_performed=false
rollback_performed=true
rollback_success=true
source_count_live=36
created_iu_count=0      (rolled back; 36 rows existed transiently)
created_uv_count=0      (rolled back; 36 rows existed transiently)
created_birth_count=0   (rolled back; 36 rows existed transiently)
pre_existing_iu_untouched=true
tac_source_untouched=true
render_fidelity_pass=true                  (V-2 passed inside the transaction)
content_hash_fidelity_pass=false           (V-3b cross-system mismatch — TAC scheme ≠ fn_content_hash; IU-side V-3a was true)
birth_coverage_pass=true                   (V-5 passed inside the transaction)
gateway_integrity_pass=true                (gateway-marker discipline observed; ROLLBACK did not perturb triggers)
soft_flag_rows=[D38-DIEU35-S8-P3]
ui_cutover_performed=false
vector_work_performed=false
bulk_migration_performed=false
rollback_keys_report_path=knowledge/dev/laws/dieu44-trien-khai/reports/p3d-phase5c2-r1-dieu35-rollback-keys-20260514T103008Z.md
execution_report_path=knowledge/dev/laws/dieu44-trien-khai/reports/p3d-phase5c2-r1-dieu35-pilot-migration-execution-report.md
next_recommended_action=GPT_REVIEW_R1_EXECUTION_REPORT

11. Evidence index

  • VPS log (full orchestrator run + rollback bundle): /opt/incomex/logs/p3d-phase5c2-r1-dieu35-20260514T103008Z.log (17,802 bytes)
  • KB rollback-keys doc (rev 2, with rollback-executed note): knowledge/dev/laws/dieu44-trien-khai/reports/p3d-phase5c2-r1-dieu35-rollback-keys-20260514T103008Z.md
  • Orchestrator script: /tmp/r1-orchestrator.py on VPS
  • Migration SQL: /tmp/r1-migrate.sql on VPS
  • Validation SQL: /tmp/r1-validate.sql on VPS
  • Summary JSON: /tmp/r1-summary.json on VPS

P3D Phase 5C2-R1 Execution Report | 2026-05-14T10:30:08Z | Claude Opus 4.7 xhigh | Conservative rollback on V-3b spec mismatch; zero residue. Awaiting GPT/Opus review.

Back to Knowledge Hub knowledge/dev/laws/dieu44-trien-khai/reports/p3d-phase5c2-r1-dieu35-pilot-migration-execution-report.md