P3D Pack 1 Phase 5C2 — DIEU-35 Parallel IU Pilot — rev4 Self-Contained
P3D Pack 1 Phase 5C2 — DIEU-35 Parallel IU Pilot Migration — rev4
Date: 2026-05-12 Rev: 4 (self-contained operational prompt — Agent needs ONLY this document) Status: DISPATCH CANDIDATE — requires GPT final review + User GO Mode: MIGRATION WRITE — parallel IU pilot, TAC untouched, UI untouched
Effort: medium-high.
0. TAC→UI PRESERVATION CONTRACT
NO_TOUCH_CURRENT_TAC_UI — do NOT modify tac_* tables, Nuxt files, Directus permissions
PARALLEL_IU_PILOT_ONLY — IU rows alongside TAC, not replacing
UI_REDIRECT_FORBIDDEN_UNTIL_VERIFIED — Laws Page continues reading tac_*
TAC_SOURCE_REMAINS_CANONICAL_FOR_UI_DURING_PILOT — user sees TAC content only
1. SCOPE CONSTANTS
pilot_publication_code = 'DIEU-35'
strategy = D3a_hybrid
mode = PARALLEL_IU_PILOT_ONLY
hierarchy_carrier = identity_profile JSON
parent_or_container_ref_value = NULL
species = information_unit_atom
composition_lop = atom
publication_authority_ref_value = 'incomex_council'
publication_authority_vocab_key = 'vocab.publication_authority.incomex_council'
target_unit_kind = 'law_unit'
baseline_member_count_reference = 36 (REFERENCE ONLY — not used in any assertion)
logging_convention_path = /opt/incomex/logs (convention from 5C1/5C2B; if absent, discover via project root or report LOGGING_DIR_UNKNOWN)
ALL column names, join paths, function signatures → discovered via live introspection.
2. MULTIDIMENSIONALITY GUARD
This migration writes ONE coordinate: species=information_unit_atom, lớp=atom. No global 6-lớp logic. No branching by loài/lớp/Layer. Metadata preserved for future enrichment.
3. EXECUTION LOG
RUN_STARTED_AT=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
LOG_FILE=<logging_convention_path>/p3d-pack1-phase5c2-dieu35-$(date -u +%Y%m%dT%H%M%SZ).log
ON_ERROR_STOP=1. No retry after any failed gate.
4. TABLE-FAMILY REGISTRY
Before any query, verify each table exists in public schema:
SELECT table_name FROM information_schema.tables
WHERE table_schema = 'public'
AND table_name = '<table_name>';
| Family | Table | Role | Must exist |
|---|---|---|---|
| source_TAC_publication | tac_publication | Publication metadata | YES |
| source_TAC_member | tac_publication_member | Publication ↔ version mapping + render_order | YES |
| source_TAC_logical_unit | tac_logical_unit | Logical structure + hierarchy | YES |
| source_TAC_unit_version | tac_unit_version | Content (title + body) | YES |
| target_IU | information_unit | Migration target (IU rows) | YES |
| target_UV | unit_version | Migration target (version rows) | YES |
| governance_birth | birth_registry | Birth/species records | YES |
| governance_config | dot_config | Vocab entries | YES |
| governance_species_map | species_collection_map | Species ↔ collection mapping | YES |
Any missing → ABORT.
5. CONCEPT REGISTRY (full, self-contained)
Introspect all tables from §4:
SELECT table_name, column_name, data_type, is_nullable
FROM information_schema.columns
WHERE table_schema = 'public'
AND table_name IN ('tac_publication','tac_publication_member','tac_logical_unit','tac_unit_version',
'information_unit','unit_version','birth_registry','dot_config','species_collection_map')
ORDER BY table_name, ordinal_position;
Resolve each concept. Semantic hints are search guidance, NOT assertions:
5A. Source TAC concepts
| concept_id | table | semantic_hint | required_for | on_unresolved |
|---|---|---|---|---|
| tac_pub_pk | tac_publication | primary key / uuid | join, filter | ABORT |
| tac_pub_code | tac_publication | document code identifier | filter pilot pub | ABORT |
| tac_pub_version | tac_publication | version string | provenance | ABORT |
| tac_pub_lifecycle | tac_publication | lifecycle/status | report | ABORT |
| tac_pub_publication_type | tac_publication | publication type classification | identity_profile | ABORT |
| tac_member_pub_ref | tac_publication_member | FK to publication | join | ABORT |
| tac_member_uv_ref | tac_publication_member | FK to unit version | join | ABORT |
| tac_member_render_order | tac_publication_member | display ordering integer | identity_profile + assertions | ABORT |
| tac_lu_pk | tac_logical_unit | primary key / uuid | join, provenance | ABORT |
| tac_lu_parent_ref | tac_logical_unit | self-referential parent FK | D3a hierarchy | ABORT |
| tac_lu_sort_order | tac_logical_unit | sort order within parent | identity_profile | ABORT |
| tac_lu_address | tac_logical_unit | canonical/unique address string | fn_iu_create param | ABORT |
| tac_lu_section_type | tac_logical_unit | section type classification | fn_iu_create param | ABORT |
| tac_lu_owner_ref | tac_logical_unit | owner/author reference | fn_iu_create param | ABORT |
| tac_uv_pk | tac_unit_version | primary key / uuid | join, provenance | ABORT |
| tac_uv_lu_ref | tac_unit_version | FK to logical unit | join | ABORT |
| tac_uv_title | tac_unit_version | title text | fn_iu_create param | ABORT |
| tac_uv_body | tac_unit_version | body/content text | fn_iu_create param | ABORT |
| tac_uv_content_hash | tac_unit_version | content hash | provenance | ABORT |
5B. Target IU/UV concepts
| concept_id | table | semantic_hint | required_for | on_unresolved |
|---|---|---|---|---|
| iu_pk | information_unit | primary key / uuid | capture, verify | ABORT |
| iu_canonical_address | information_unit | canonical address | collision check | ABORT |
| iu_identity_profile | information_unit | identity profile JSONB | merge | ABORT |
| iu_parent_or_container | information_unit | parent/container ref | set NULL | ABORT |
| uv_pk | unit_version | primary key / uuid | capture, verify | ABORT |
| uv_body | unit_version | body/content text | hash verify | ABORT |
| uv_content_hash | unit_version | content hash | verify | ABORT |
| uv_provenance_profile | unit_version | provenance JSONB | merge | ABORT |
5C. Governance concepts
| concept_id | table | semantic_hint | required_for | on_unresolved |
|---|---|---|---|---|
| config_key | dot_config | config key text | vocab lookup | ABORT |
| config_value | dot_config | config value text | vocab verify | ABORT |
| birth_pk | birth_registry | primary key | rollback | ABORT |
| birth_entity_ref | birth_registry | entity id reference | verify | ABORT |
| birth_collection_key | birth_registry | collection name | filter | ABORT |
| birth_species_id | birth_registry | species identifier | verify value | ABORT |
| birth_composition | birth_registry | composition level | verify value | flag UNKNOWN if FIELD_ABSENT |
| scm_collection | species_collection_map | collection name | verify mapping | ABORT |
| scm_is_primary | species_collection_map | primary flag | verify mapping | ABORT |
Resolution rule: 0 candidates = FIELD_ABSENT. 1 = RESOLVED. >1 = AMBIGUOUS_FIELD.
5D. Join path resolution
SELECT tc.table_name, kcu.column_name, ccu.table_name AS fk_table, ccu.column_name AS fk_column
FROM information_schema.table_constraints tc
JOIN information_schema.key_column_usage kcu ON tc.constraint_name = kcu.constraint_name
JOIN information_schema.constraint_column_usage ccu ON tc.constraint_name = ccu.constraint_name
WHERE tc.constraint_type = 'FOREIGN KEY' AND tc.table_schema = 'public'
AND tc.table_name IN ('tac_publication_member','tac_unit_version','tac_logical_unit');
5E. fn_iu_create shape discovery
-- Inspect signature
SELECT pg_get_functiondef(oid) FROM pg_proc WHERE proname = 'fn_iu_create';
Determine return type:
- If JSONB → discover keys from planner or SAVEPOINT test
- If ROW/RECORD → map output columns
- If UNKNOWN → ABORT
If SAVEPOINT test used:
SAVEPOINT shape_test;
call fn_iu_create with first source row
capture result → resolve resolved_fn_result_iu_key + resolved_fn_result_uv_key
ROLLBACK TO SAVEPOINT shape_test;
verify: 0 residual IU rows, 0 residual UV rows, 0 residual birth_registry rows from test
if any residual → ABORT
RELEASE SAVEPOINT shape_test;
6. GATE-0 (all must PASS)
G0-1 4 source TAC tables exist
G0-2 2 target tables exist (information_unit, unit_version)
G0-3 fn_iu_create exists
G0-4 fn_content_hash exists
G0-5 fn_iu_verify_invariants exists
G0-6 DIEU-35 exists in tac_publication (live query using resolved tac_pub_code)
G0-7 All concepts in §5 RESOLVED
G0-8 Join paths RESOLVED (§5D)
G0-9 fn_iu_create result shape RESOLVED (§5E)
G0-10 species_collection_map: ≥1 is_primary=true for 'information_unit'
G0-11 birth_registry: 0 NULL species for 'information_unit'
G0-12 dot_config: publication_authority vocab exists, value = 'incomex_council'
G0-13 dot_config: unit_kind vocab 'vocab.unit_kind.law_unit' exists
G0-14 dot_config: publication_type vocab 'vocab.publication_type.law' exists
Any fail → ABORT.
7. PREFLIGHT (live-derived)
PF-1 source_count_live (4-table join, pilot pub filter)
PF-2 distinct section_types (live)
PF-3 vocab coverage for each section_type
PF-4 address collision = 0 (source addresses vs target IU)
PF-5 render_order min/max/distinct (ASSERT distinct = source_count_live)
PF-6 identity_profile dry-construct (1 sample, verify 5 birth-gate keys)
PF-7 source table pre-counts (4 tables)
PF-8 owner NULL check: count rows where tac_lu_owner_ref IS NULL → if >0 ABORT
8. COMPILED SQL/FUNCTION PREVIEW
Before any write, Agent must log these compiled templates (after concept resolution):
compiled_source_query — the 4-table join with resolved concepts
compiled_fn_iu_create_call_template — fn_iu_create(p_canonical_address:=..., ...)
compiled_identity_profile_patch — UPDATE SET <iu_identity_profile> = COALESCE(...) || ...
compiled_provenance_patch — UPDATE SET <uv_provenance_profile> = COALESCE(...) || ...
compiled_verification_queries — D1–D7 assertions with resolved concepts
Log to execution log file. Report compiled_sql_logged=true.
9. MIGRATION TRANSACTION
BEGIN;
-- 9A: pg_try_advisory_xact_lock(hashtext('p3d_pack1_phase5c2_dieu35_parallel_iu_pilot'))
-- false → ROLLBACK, LOCK_BUSY
-- 9B: In-transaction re-verify (address collision=0, source_count unchanged, authority vocab exists)
-- 9C: Migration loop (ordered by render_order ASC)
-- C1. Parent canonical_address lookup
-- C2. Build identity_profile JSON (10 keys)
-- C3. fn_iu_create call
-- C4. identity_profile merge (COALESCE + ||)
-- C5. provenance merge
-- C6. Capture IU/UV IDs
-- 9D: IN-TRANSACTION VERIFICATION
D1. captured count = source_count_live
D2. render_order contiguous
D3. authority_ref = 'incomex_council' on all (0 mismatch)
D4. Birth: row count match + null species=0 + species='information_unit_atom' + composition='atom' (if resolved)
D5. content_hash correct
D6. invariants PASS
D7. TAC source counts unchanged
D8. Persist rollback keys to VPS log
-- ALL PASS → COMMIT. ANY fail → ROLLBACK.
COMMIT;
10. POST-COMMIT
10A. KB rollback keys artifact
10B. Render fidelity
RF source of truth: live TAC query during migration run (not baseline snapshot)
RF-1 Tree: IU identity_profile tree vs live TAC tree. 0 mismatch.
RF-2 Body: UV body vs TAC UV body. 100% match.
RF-3 Order: IU render_order vs TAC render_order. Identical.
RF-4 Source untouched: 4 TAC table counts unchanged.
RF-5 TAC→UI preserved: tac_ui_untouched=true.
RF also reports drift vs baseline_member_count_reference (36) separately.
11. ROLLBACK
11A. In-transaction: automatic on D-fail.
11B. Post-COMMIT:
BEGIN;
DELETE FROM birth_registry WHERE <birth_collection_key>='information_unit' AND <birth_entity_ref>::uuid = ANY(<capture_iu_ids>);
DELETE FROM <target_UV> WHERE <uv_pk> = ANY(<capture_uv_ids>);
DELETE FROM <target_IU> WHERE <iu_pk> = ANY(<capture_iu_ids>);
COMMIT;
11C. Post-rollback verify: 0 residual IU + 0 UV + 0 birth by captured IDs. Source counts unchanged. Pattern matching PROHIBITED.
12. HARD BOUNDARIES
No DDL. No function/trigger patch. No TAC writes. No DIEU-28/32. No universal_edges.
No IU publication_member. No Directus/Nuxt/Qdrant changes. No nested dispatch.
No hardcoded gates. No pattern rollback. No UI cutover. No owner fallback (NULL → ABORT).
No CASE/IF/SWITCH by species/lớp/Layer. ui_cutover_performed=false always.
13. ENTITY LIVING DB HOOKS
| Heading | Hook after migration | Enrichment |
|---|---|---|
| Identity | birth + identity_profile 10 keys | JSONB extensible |
| Relations | FK IU→UV + D3a JSON | universal_edges Pack 2+ |
| Dependencies | IU uuid | entity_dependencies Pack 2+ |
| History | Directus auto | — |
| Labels | IU uuid | entity_labels Pack 2+ |
| Metrics | birth_registry row | pivot_definitions post-migration |
14. REPORT + FINAL RESPONSE
Report: knowledge/dev/laws/dieu44-trien-khai/reports/p3d-pack1-phase5c2-dieu35-pilot-migration-report.md
phase5c2_status=PASS|PARTIAL|ROLLED_BACK|BLOCKED|LOCK_BUSY
source_count_live=<N>
baseline_member_count_reference=36
inserted_iu_count=<N>
inserted_uv_count=<N>
publication_authority_ref_verified=true|false
species_auto_assigned=true|false
species_value_correct=true|false
content_hash_all_correct=true|false
render_fidelity_drift=<N>
tac_ui_untouched=true|false
no_tac_rows_modified=true|false
ui_cutover_performed=false
rollback_reference_available=both|kb|vps_log|none
concept_registry_fully_resolved=true|false
function_shape_resolved=true|false
compiled_sql_logged=true|false
owner_null_abort=true|false
execution_log_path=<path>
rollback_keys_path=<path>
next_recommended_action=GPT_REVIEW_PILOT_RESULT
Phase 5C2 | DIEU-35 Parallel IU Pilot | rev4 | Self-contained operational prompt | 2026-05-12