P3D Phase 5C2 R1 retry + R2 — Consolidated Status Report (DIEU-35 PASS, DIEU-28 PASS, DIEU-32 BLOCKED)
P3D Phase 5C2 R1 retry + R2 — Consolidated Status Report
Date (UTC): 2026-05-14 Author: Claude Opus 4.7 (1M, xhigh) Authorization overlay:
USER_GO=YES,GPT_FINAL_APPROVAL=YES,V3_SPEC_PATCH_APPROVED=YES,R1_RETRY_AUTHORIZED=YES,CONDITIONAL_R2_AUTHORIZED=YESControlling prompt:knowledge/dev/laws/dieu44-trien-khai/prompts/agent-phase5c2-retry-r1-and-conditional-r2-patched-v3-2026-05-14.mdMode: BOUNDED WRITE EXECUTION across 3 publications, each in its own transaction.
0. Headline
| Publication | Source rows | Outcome | Δ IU | Δ UV | Δ Birth | utc_ts |
|---|---|---|---|---|---|---|
| DIEU-35 (R1 retry) | 36 | PASS | +36 | +36 | +36 | 20260514T140804Z |
| DIEU-28 (R2) | 27 | PASS | +27 | +27 | +27 | 20260514T140835Z |
| DIEU-32 (R2) | 23 | BLOCKED_BEFORE_BEGIN (4 NULL bodies, all section_type=heading) |
0 | 0 | 0 | 20260514T140900Z |
| TOTAL | 86 attempted (63 migrated, 23 deferred) | 2 PASS / 1 BLOCKED | +63 | +63 | +63 | — |
Final live counts (post-run):
information_unit = 75 (= 12 pre + 36 D35 + 27 D28)
unit_version = 82 (= 19 pre + 36 D35 + 27 D28)
birth_registry where collection='information_unit' = 75
tac_publication = 3 (unchanged)
tac_logical_unit = 86 (unchanged)
tac_unit_version = 86 (unchanged)
tac_publication_member = 86 (unchanged)
tac_source_untouched = true, pre_existing_iu_untouched = true, ui_cutover_performed = false, vector_work_performed = false, bulk_migration_performed = false, v3_patched_semantics_used = true, cross_system_hash_equality_used_as_gate = false.
1. Per-publication results
1.1 DIEU-35 — R1 retry — PASS
- Detailed report:
knowledge/dev/laws/dieu44-trien-khai/reports/p3d-phase5c2-r1-dieu35-retry-patched-v3-execution-report.md - Rollback-keys KB:
knowledge/dev/laws/dieu44-trien-khai/reports/p3d-phase5c2-dieu-35-rollback-keys-20260514T140804Z.md - VPS log:
/opt/incomex/logs/p3d-phase5c2-dieu-35-20260514T140804Z.log - V-1..V-7 all PASS (incl. patched V-3a/V-3b/V-3c). V-3d cross-system match = 0/36 (report-only).
- V-8..V-10 all PASS post-COMMIT.
- Soft-flag
D38-DIEU35-S8-P3(body_char=1) migrated verbatim; no repair attempted.
1.2 DIEU-28 — R2 — PASS
- Detailed report:
knowledge/dev/laws/dieu44-trien-khai/reports/p3d-phase5c2-r2-dieu28-pilot-migration-execution-report.md - Rollback-keys KB:
knowledge/dev/laws/dieu44-trien-khai/reports/p3d-phase5c2-dieu-28-rollback-keys-20260514T140835Z.md - VPS log:
/opt/incomex/logs/p3d-phase5c2-dieu-28-20260514T140835Z.log - 1 root (
D38-DIEU28-ROOT) + 26 children. 8 distinct section_types (all seeded). - All gates V-1..V-7 + V-8..V-10 PASS. V-3d cross-system match = 0/27 (report-only).
1.3 DIEU-32 — R2 — BLOCKED_BEFORE_BEGIN
- Detailed report:
knowledge/dev/laws/dieu44-trien-khai/reports/p3d-phase5c2-r2-dieu32-pilot-migration-execution-report.md - Cause: 4 source rows have
tac_unit_version.body IS NULL(D38-DIEU32-ROOT,D38-DIEU32-S2,D38-DIEU32-S3,D38-DIEU32-S4— allsection_type='heading'). - Per hard boundary "No automatic content repair" and stop condition "Missing vocab/owner/body > 0", the orchestrator stopped before BEGIN. No transaction opened; no rollback-keys doc generated (none needed).
- No mutation, no residue. State unchanged.
- Recommended remediation: upstream TAC fix to populate body for the 4 heading rows (e.g. body = title), then rerun the orchestrator for DIEU-32 only.
2. Patched V-3 semantics — verified live
The previous R1 attempt (reports/p3d-phase5c2-r1-dieu35-pilot-migration-execution-report.md) was rolled back because V-3 conflated two distinct concerns: IU-side hash consistency and cross-system hash equality. The patched V-3 separates these:
| Sub-gate | Spec | Live evidence (this run) | Result |
|---|---|---|---|
| V-3a IU-side hash consistency | uv.content_hash = fn_content_hash(uv.body) |
36/36 + 27/27 | PASS |
| V-3b Body preservation | uv.body = tac_unit_version.body (byte-equality) |
36/36 + 27/27 | PASS |
| V-3c TAC hash provenance | content_profile.src_content_hash = tac_unit_version.content_hash |
36/36 + 27/27 | PASS |
| V-3d Cross-system hash equality | uv.content_hash = tac_unit_version.content_hash |
0/36 + 0/27 | NOT A GATE — report only |
Conclusion: TAC and IU use different hashing schemes (TAC's algorithm includes structured content beyond body). The patched semantics correctly capture content fidelity at the byte level and preserve the original TAC hash as provenance, while accepting cross-system hash divergence as expected.
3. Hard-boundary compliance summary
| Boundary | DIEU-35 | DIEU-28 | DIEU-32 |
|---|---|---|---|
| No DDL / schema / trigger / fn / birth-system change | ✅ | ✅ | ✅ |
No direct INSERT to IU/UV (only fn_iu_create) |
✅ | ✅ | n/a (no tx) |
| No TAC writes | ✅ | ✅ | ✅ |
| No UI cutover / Nuxt / Directus / config | ✅ | ✅ | ✅ |
| No vector / Qdrant mutation / reindex | ✅ | ✅ | ✅ |
| No event_outbox / IU event emission | ✅ | ✅ | ✅ |
| Pre-existing 12 pilot/test IU untouched | ✅ | ✅ | ✅ |
| No pattern-matching DELETE | ✅ (no rollback needed) | ✅ (no rollback needed) | n/a |
| No auto content repair | ✅ (S8-P3 1-char body preserved) | ✅ | ✅ (4 NULL bodies left untouched) |
| Only DIEU-35/28/32 in scope | ✅ | ✅ | ✅ |
4. Toward automated cutter: lessons learned for "Cắt luật A"
This run proves that the migration can be operationalized as a small, deterministic, parametric tool. The orchestrator's stage structure is the prototype for Cắt luật A (a future automated cutter for any TAC publication into native IU/UV).
4.1 What this run proves
- Source discovery is FK-deterministic. The 4-table join
tac_publication → tac_publication_member → tac_logical_unit → tac_unit_version, filtered bydoc_code, plus a single recursive CTE for hierarchy depth, is enough to reconstruct the full mapping. No hand-crafted SQL per publication is needed. - Segmentation / mapping is a function of source row + static rules. Per-row payload (
p_canonical_address,p_title,p_body,p_section_type,p_owner_ref) plus three constants (p_unit_kind='law_unit',p_publication_type='law',p_actor) andp_parent_ref=NULLfor D3a hybrid covered both DIEU-35 (12 distinct section types, 36 rows) and DIEU-28 (8 distinct section types, 27 rows) without per-publication branching. - Vocab validation is one read query. A single
WITH d AS (DISTINCT section_type WHERE doc_code=…)+NOT EXISTS vocab.section_type.<value>is sufficient. R1 retry confirmed 0 missing vocab for DIEU-35; R2 confirmed 0 missing for DIEU-28 and DIEU-32. fn_iu_createbatches cleanly inside a single DO loop. 36 + 27 rows committed in ≤1s wall-clock each. The function's internalfn_iu_verify_invariantscall doubles as inline gate. No external batching framework needed.- Rollback-key dual-write (KB + VPS log) before COMMIT is fully operational as a primitive: a long-lived
docker exec -i postgres psqlsession driven by a Python orchestrator handles the pause-and-persist pattern. Both publications wrote rollback bundles successfully; both were post-COMMIT verified intact (V-10 PASS). - Patched V-3 hash semantics are the right abstraction. V-3a/V-3b/V-3c separate concerns cleanly; V-3d as report-only captures the legacy divergence without gating.
- Exact-source preservation is enforceable. Body bytes passed
tac_unit_version.body → fn_iu_create p_body → unit_version.bodyunchanged for all 63 migrated rows. V-3b is the canonical content-fidelity test. - Edge / provenance hooks live in JSONB.
identity_profile.tac_provenance/tac_hierarchy/rendering+content_profile.src_*carries enough metadata for future enrichment passes (parent FK backfill, render reconciliation, edge graph creation) without re-touching the IU/UV row layout.
4.2 What must become tooling
For "Cắt luật A" to handle arbitrary publications without per-run scripting, these capabilities should be extracted into a reusable DOT tool (e.g. dot-iu-cutter or dot-tac-to-iu):
- Parametric preflight gate runner taking
--doc_code→ exits with a structured gate report. Inputs:(g_tac_tables_exist, g_publication_exists, g_member_count, g_render_order_contiguous, g_owner_null, g_body_null, g_collision_count, g_vocab_coverage, g_fn_iu_create_present, g_gateway_enforced, g_edit_policy, g_birth_trigger, g_species_map, g_preexisting_iu). Hard fail on any required gate. Report soft flags. - Mapping artifact emitter (R0-equivalent) producing the per-row JSON artifact + summary. Read-only.
- Bounded transaction runner with patched V-3 + V-1/V-2/V-4..V-7 + post-COMMIT V-8/V-9/V-10. Dual-write rollback keys before COMMIT. Exact-key rollback path if post-COMMIT fails.
- NULL-body / NULL-owner / collision policy as a tool flag, not a code branch — e.g.
--on_null_body=block|skip|sythesize_from_title. Defaultblock(current behavior). Synthesize variants would be GPT-reviewed exceptions. - Rollback-keys writer abstraction that handles both KB upload (via MCP API or directus) and VPS log file. Reusable across publications.
- Report writer that emits per-publication and consolidated reports from the orchestrator's summary JSON.
- Idempotency by capturing pre-state hash (TAC counts + canonical_address set) and refusing to rerun a publication that's already migrated unless
--force-reapplyis set. - Hierarchy enrichment pass as a separate later tool (
dot-iu-parent-fk-enrich) that walksidentity_profile.tac_hierarchy.src_parent_canonical_addressand populatesinformation_unit.parent_or_container_refpost-migration once all rows exist. Out of scope for the cutter itself.
4.3 Edge cases this run exposed
- NULL bodies for heading-only rows (DIEU-32): treat as upstream data-quality concern. Cutter should
--on_null_body=blockby default. A future variant--on_null_body=synthesize_titleis GPT-reviewable, but would lose strict V-3b byte-preservation (would need a separateV-3b_synthesizedsub-gate). - TAC content_hash uses different algorithm than
fn_content_hash— confirmed across DIEU-35 + DIEU-28 (0% cross-system hash match across 63 rows). Cutter must NOT gate on V-3d. - Single-character body rows (DIEU-35 S8-P3): valid input;
fn_iu_createaccepts; all gates pass; soft-flag for human review only. - D3a hybrid
p_parent_ref=NULLis the correct default at create time. Hierarchy lives in JSONB; parent FK enrichment is a separate pass.
4.4 Recommended next design pack
"Cắt luật A" design (dot-iu-cutter v0.1) — DOT-registered, parametric, read+write, with exhaustive gate matrix; mandatory dual-write rollback; reusable per publication. Build it as the operationalization of this orchestrator. Validated by this run on 2 of the 3 currently-live TAC publications (63/86 source rows migrated).
5. Required final response fields (consolidated)
phase5c2_retry_r1_status=PASS
r2_dieu28_status=PASS
r2_dieu32_status=BLOCKED_BEFORE_BEGIN
total_publications_committed=2
total_iu_created_committed=63
total_uv_created_committed=63
total_birth_created_committed=63
tac_source_untouched=true
pre_existing_iu_untouched=true
ui_cutover_performed=false
vector_work_performed=false
bulk_migration_performed=false
v3_patched_semantics_used=true
cross_system_hash_equality_used_as_gate=false
rollback_reports=[
"knowledge/dev/laws/dieu44-trien-khai/reports/p3d-phase5c2-dieu-35-rollback-keys-20260514T140804Z.md",
"knowledge/dev/laws/dieu44-trien-khai/reports/p3d-phase5c2-dieu-28-rollback-keys-20260514T140835Z.md"
]
execution_reports=[
"knowledge/dev/laws/dieu44-trien-khai/reports/p3d-phase5c2-r1-dieu35-retry-patched-v3-execution-report.md",
"knowledge/dev/laws/dieu44-trien-khai/reports/p3d-phase5c2-r2-dieu28-pilot-migration-execution-report.md",
"knowledge/dev/laws/dieu44-trien-khai/reports/p3d-phase5c2-r2-dieu32-pilot-migration-execution-report.md"
]
consolidated_report_path=knowledge/dev/laws/dieu44-trien-khai/reports/p3d-phase5c2-r1-r2-consolidated-status-report.md
next_recommended_action=GPT_REVIEW_R1_R2_RESULTS_THEN_START_AUTOMATED_CUTTER_DESIGN
P3D Phase 5C2 R1+R2 Consolidated Status | 2026-05-14 | 63/86 rows migrated · 2/3 publications PASS · DIEU-32 BLOCKED upstream data-quality. Toward "Cắt luật A" automated cutter.