KB-5472

P3D Phase 5C2-R2 — DIEU-32 Retry (Synthesize-Title Policy) Execution Report (PASS)

14 min read Revision 1
p3dphase5c2r2dieu32retrysynthesize-titleexecution-reportpass2026-05-14

P3D Phase 5C2-R2 — DIEU-32 Retry (Synthesize-Title Policy) Execution Report

Date (UTC): 2026-05-14T14:46:44Z Author: Claude Opus 4.7 (1M, xhigh) — orchestrator on VPS Authorization: USER_GO=YES, GPT_FINAL_APPROVAL=YES, DIEU32_SYNTHESIZE_TITLE_POLICY_APPROVED=YES, DIEU32_RETRY_AUTHORIZED=YES Controlling prompt: knowledge/dev/laws/dieu44-trien-khai/prompts/agent-phase5c2-dieu32-retry-synthesize-title-policy-2026-05-14.md Outcome: PASS — 23/23 IU + 23/23 UV + 23/23 birth committed; 19 rows preserved verbatim, 4 rows synthesized from title under POLICY_SYNTHESIZE_TITLE_FOR_HEADING_NULL_BODY; conditional V-3b' fully verified; V-8..V-10 all PASS; TAC source unchanged; pre-existing 75 IU rows untouched.


0. Hard boundaries — all honored

Boundary Honored
No DDL / schema / trigger / fn / birth-system changes
No direct INSERT to IU/UV (used fn_iu_create only)
No TAC writes (V-6 PASS: 3/86/86/86 unchanged)
No UI / Nuxt / Directus / config / vector / event_outbox work
Pre-existing 75 IU untouched (V-9 PASS)
No publications beyond DIEU-32
No pattern-matching DELETE ✅ (no rollback needed; transactional COMMIT)
No automatic content repair beyond approved heading-title synthesis ✅ (only the 4 approved rows used title; non-heading NULL bodies would have aborted)

1. Stage A — Preflight (PASS)

doc_code=DIEU-32
publication_id=6e08315c-7c70-470a-8a6a-32d7e2ae1b94
publication_version=v1.1
publication_lifecycle=proposed
publication_type=law
member_count=23
render_order: min=0 max=22 distinct=23 count=23 contiguous=true
owner_null_count=0
body_null_count=4
null_body_addrs=[D38-DIEU32-ROOT, D38-DIEU32-S2, D38-DIEU32-S3, D38-DIEU32-S4]   <-- exactly the 4 approved synthesize rows
approved_synth_addrs={D38-DIEU32-ROOT, D38-DIEU32-S2, D38-DIEU32-S3, D38-DIEU32-S4}
collision_count=0
section_types_missing_vocab=<none>
pre_iu_count=75 / pre_uv_count=82 / pre_br_iu=75
pre_tac counts: pub=3 lu=86 uv=86 pm=86
gateway_mode=enforced / allowed_markers=fn_iu_create,fn_iu_apply_edit_draft / edit_policy=require_review
fn_iu_create signature OK (9-arg → jsonb)
species_collection_map primary IU: information_unit_atom|information_unit|primary=true
birth_trigger_present=true

All hard preflight gates PASS. The 4 NULL-body rows match exactly the approved synthesize set, and all satisfy section_type='heading' AND children > 0. No source drift since the root-cause investigation.


2. Stage B — Bounded transaction (23 fn_iu_create + per-row conditional patch)

Single BEGIN … COMMIT over one psql session via docker exec -i postgres psql -U directus -d directus -q -A -t -F '|' -v ON_ERROR_STOP=1. Wall-clock for DO block: ~0.6s.

Per-row pattern with conditional body preparation:

IF section_type='heading' AND body IS NULL AND children>0 THEN
  iu_body := source.title
  body_source := 'synthesized_from_title_due_to_tac_heading_null_body'
  src_body_was_null := true
ELSIF body IS NULL THEN
  RAISE EXCEPTION 'BLOCKED: non-heading-container NULL body'   -- would abort tx
ELSE
  iu_body := source.body
  body_source := 'preserved_from_tac_unit_version_body'
  src_body_was_null := false
ENDIF

Then fn_iu_create(...) (with iu_body, p_actor='agent:p3d-phase5c2-dieu32-retry', p_unit_kind='law_unit', p_publication_type='law', p_parent_ref=NULL), then SET LOCAL "app.canonical_writer" = 'fn_iu_apply_edit_draft' + UPDATE information_unit with identity_profile patch (including body_source + 10-key TAC provenance + hierarchy + authority + rendering), then UPDATE unit_version with content_profile patch (including body_source, src_body_was_null, src_title, src_content_hash, etc.) + provenance='tac:DIEU-32:<src_uv_id>'.

2.1 Per-row classification (captured)

Synthesized (4 rows — body = source.title):

ro canonical_address src section_type children iu.body
0 D38-DIEU32-ROOT heading 10 ĐIỀU 32: LUẬT PHÊ DUYỆT — v1.1 BAN HÀNH (= source title)
3 D38-DIEU32-S2 heading 4 §2. Nguyên tắc (= source title)
8 D38-DIEU32-S3 heading 5 §3. Schema approval (= source title)
14 D38-DIEU32-S4 heading 3 §4. Quorum approvals (= source title)

Preserved (19 rows — body = source.body byte-equal): ro=1 (S0/Preamble), ro=2 (S1), ro=4..7 (S2-P1..P4), ro=9..13 (S3-P1..P5), ro=15..17 (S4-P1..P3), ro=18 (S5), ro=19 (S6), ro=20 (S7), ro=21 (S8), ro=22 (S9).

synthesized_rows_count = 4, preserved_rows_count = 19, loop_count = 23.


3. Stage C — Rollback-key dual-write BEFORE COMMIT (PASS)

Target Path Result
VPS log /opt/incomex/logs/p3d-phase5c2-dieu32-20260514T144644Z.log OK (sync issued; rollback bundle wrapped ###ROLLBACK_KEYS_BEGIN###/###ROLLBACK_KEYS_END###)
KB knowledge/dev/laws/dieu44-trien-khai/reports/p3d-phase5c2-dieu32-rollback-keys-20260514T144644Z.md HTTP 200 / status=created / revision 1

The KB rollback doc captures all 23 IU+UV+entity-code UUIDs plus the 4 synthesized vs 19 preserved address lists plus the exact-key rollback SQL skeleton.


4. Stage D — V-1..V-7 with conditional V-3b' (all PASS)

Gate Spec Live result Verdict
V-1 captured_iu=captured_uv=source_count=23 23/23/23 PASS
V-2 identity_profile render_order multiset = source multiset = {0..22} captured=0..22; source=0..22 PASS
V-3a per UV content_hash = fn_content_hash(body) 23/23 PASS
V-3b' (preserved) body_source='preserved_…'uv.body = tac_unit_version.body byte-eq 19/19 byte-equal · 19/19 marked preserved PASS
V-3b' (synthesized) body_source='synthesized_…'uv.body = tuv.title AND tuv.body IS NULL AND tlu.section_type='heading' AND children>0 AND src_body_was_null=true AND src_title=tuv.title 4/4 satisfy ALL conditions · 4/4 marked synthesized PASS
V-3b' (identity_profile ↔ content_profile match) identity_profile.body_source = content_profile.body_source for every captured IU 23/23 PASS
V-3c content_profile.src_content_hash = tac_unit_version.content_hash (TAC hash provenance) 23/23 PASS
V-3d (REPORT ONLY) cross-system hash equality uv.content_hash = tuv.content_hash 0/23 (expected legacy divergence) NOT A GATE
V-4 all 23 IU identity_profile.publication_authority_ref = 'incomex_council' 23/23 PASS
V-5 23 birth rows; 0 NULL species; all information_unit_atom / atom 23 / 0 / 23 / 23 PASS
V-6 TAC counts unchanged (3/86/86/86) unchanged PASS
V-7 fn_iu_verify_invariants all_pass=true per address 23/23 PASS

→ All required gates PASS. COMMIT; issued.

4.1 Note on the validate-SQL fix

A first attempt of this retry hit a SQL error in the validate file (tlu.title referenced; tac_logical_unit has no title column — title lives on tac_unit_version). The migration DO block already used tuv.title correctly via the join alias. The validation file was repaired in-place (one-line fix: tlu.titletuv.title, two occurrences), then re-run. The first attempt's transaction was aborted automatically when psql exited under ON_ERROR_STOP=1; no data was committed and the DB returned to the pre-retry baseline (75/82/75) — verified before this re-run. The earlier rollback-keys KB doc from the aborted attempt (…rollback-keys-20260514T144335Z.md) is preserved as historical evidence of dual-write working before the validation error.


5. Stage E — Post-COMMIT V-8..V-10 + final counts (all PASS)

Probe Result Verdict
V-8 trg_aa_iu_gateway_write_guard + trg_aa_uv_gateway_write_guard attached; marker clean in fresh session true / true / true PASS
V-9 pre-existing 75 IU IDs all present post-COMMIT 75 / 75 PASS
V-10 KB rollback doc fetchable + VPS log present true / true PASS
Final information_unit count 98 (= 75 pre + 23 new) OK
Final unit_version count 105 (= 82 pre + 23 new) OK
Final birth_registry[information_unit] count 98 (= 75 pre + 23 new) OK
TAC counts unchanged pub=3 lu=86 uv=86 pm=86 OK
UI cutover / vector / bulk false / false / false OK

6. Policy extracted for dot-iu-cutter v0.1

The synthesize-title rule applied here is the first governed policy that the future Cắt luật A automated cutter must implement out-of-the-box. Specification for v0.1:

6.1 Body-source classification (per row, deterministic)

classify(source_row) -> body_source:
  IF source_row.section_type = 'heading'
       AND source_row.body IS NULL
       AND source_row.children_count > 0 THEN
    -> SYNTHESIZE_TITLE
  ELSIF source_row.body IS NULL THEN
    -> BLOCK             ('hard error; not a container heading')
  ELSE
    -> PRESERVE

6.2 Body preparation

prepare_body(source_row, body_source):
  CASE body_source:
    SYNTHESIZE_TITLE -> body := source_row.title
                       provenance.body_source        := 'synthesized_from_title_due_to_tac_heading_null_body'
                       provenance.src_body_was_null  := true
                       provenance.src_title          := source_row.title
    PRESERVE         -> body := source_row.body
                       provenance.body_source        := 'preserved_from_tac_unit_version_body'
                       provenance.src_body_was_null  := false

Both body_source and provenance fields land on:

  • information_unit.identity_profile (for IU-side discovery/UI use)
  • unit_version.content_profile (for UV-level integrity / migration audit)

They must match between the two locations for every row (verified by V-3b_ip_cp_body_source_match).

6.3 Conditional V-3b' (the cutter's contract)

for every captured UV uv joined to source tuv (via content_profile.src_unit_version_id) and tlu (via tuv.logical_unit_id):

  IF uv.content_profile.body_source = 'preserved_from_tac_unit_version_body' THEN
    require  uv.body  =  tuv.body            -- byte-equality

  ELSIF uv.content_profile.body_source = 'synthesized_from_title_due_to_tac_heading_null_body' THEN
    require  uv.body                          =  tuv.title       -- synthesized body equals source title
    require  tuv.body                         IS NULL            -- source body confirmed null
    require  tlu.section_type                 =  'heading'       -- source is heading
    require  (count children of tlu)          > 0                -- source is container
    require  uv.content_profile.src_body_was_null  =  true
    require  uv.content_profile.src_title           =  tuv.title

  ELSE
    FAIL — unknown body_source policy

Plus the unconditional integrity gates V-3a (uv.content_hash = fn_content_hash(uv.body) for all rows) and V-3c (uv.content_profile.src_content_hash = tuv.content_hash for all rows). V-3d remains report-only.

6.4 Cutter risk profile

Risk Status
Hardcode risk None — rule is parameterless, applies live section_type/children/body
Scale risk None — 4 rows out of 23 in DIEU-32; rule is per-row and stateless
Cross-publication compatibility Verified: D28 headings use '' (no synthesize), D32 headings use NULL (synthesize), D35 has no container heading
Reverse migration risk LOW — synthesized rows are explicitly tagged in body_source; reverse process can detect and restore original body IS NULL state
Race / re-run idempotency Handled by fn_iu_create's canonical_address-keyed idempotent status (exists_complete on re-run)
Source defect detection Maintained — any NULL body that is NOT a heading-container still raises an error (per the BLOCK branch in classify)

7. Required final response fields

dieu32_retry_status=PASS
synthesize_title_policy_used=true
source_count_live=23
created_iu_count=23
created_uv_count=23
created_birth_count=23
synthesized_rows_count=4
preserved_rows_count=19
synthesized_rows=[D38-DIEU32-ROOT,D38-DIEU32-S2,D38-DIEU32-S3,D38-DIEU32-S4]
pre_existing_iu_untouched=true
tac_source_untouched=true
v3b_conditional_policy_pass=true
birth_coverage_pass=true
gateway_integrity_pass=true
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-dieu32-rollback-keys-20260514T144644Z.md
execution_report_path=knowledge/dev/laws/dieu44-trien-khai/reports/p3d-phase5c2-r2-dieu32-retry-synthesize-title-execution-report.md
completion_report_path=knowledge/dev/laws/dieu44-trien-khai/reports/p3d-phase5c2-86-units-completion-report.md
next_recommended_action=GPT_REVIEW_DIEU32_RETRY_THEN_START_DOT_IU_CUTTER_DESIGN

P3D Phase 5C2-R2 DIEU-32 Retry | 2026-05-14T14:46:44Z | PASS | Synthesize-title policy applied to 4 heading-container rows | 23/23 committed | Conditional V-3b' verified

Back to Knowledge Hub knowledge/dev/laws/dieu44-trien-khai/reports/p3d-phase5c2-r2-dieu32-retry-synthesize-title-execution-report.md