P3D Pack 1 Phase 4C — Read-Only / Dry-Run Species Mapping + QT-001 Report
P3D Pack 1 Phase 4C — Read-Only / Dry-Run Species Mapping + QT-001 Report
Date: 2026-05-11 Mode: READ-ONLY / DRY-RUN — no writes, no seeds, no backfill Executor: Opus 4.7 (1M) Prompt:
knowledge/dev/laws/dieu44-trien-khai/prompts/p3d-pack1-phase4c-readonly-dryrun-species-mapping-qt001-prompt.md(rev3, GPT-approved 2026-05-11) RUN_MARKER:p3d-pack1-phase4c-dryrun-2026-05-11-opus47
0. SCOPE BLOCK (echoed from prompt §0)
target_collection_primary = 'information_unit'
target_collection_subordinate = 'unit_version'
target_unit_kind_committed = 'law_unit'
discriminator_candidate_column = 'unit_kind'
target_vocab_key = 'vocab.unit_kind.law_unit'
No other literal decision values used as selectors. Semantic field labels (species_code, composition_level, management_mode, governance_role, birth_code_strategy) appear only as candidate column names verified via information_schema.columns.
1. GATE-0 — Scope preflight (live PG)
| Check | What | Live result | Status |
|---|---|---|---|
| P1 | pg_class row for information_unit (relkind='r') |
count=1 | PASS |
| P2 | pg_class row for unit_version (relkind='r') |
count=2 (public.unit_version + sandbox_tac.unit_version); public present |
PASS (with note: a second unit_version table exists in schema sandbox_tac; out-of-scope, flagged) |
| P3 | collection_registry row for information_unit |
count=1 | PASS |
| P4 | collection_registry row for unit_version |
count=1 | PASS |
| P5 | Column unit_kind exists on information_unit |
count=1 | PASS |
| P6 | dot_config key=vocab.unit_kind.law_unit |
count=1, value=law_unit |
PASS |
gate0_all_passed = true. No goal BLOCKED by GATE-0.
2. Column introspection per table
2.1 public.species_collection_map
Columns present: id, sort, user_created, date_created, user_updated, date_updated, species_code, collection_name, is_primary, discriminator_field, discriminator_value, discriminator_operator, discriminator_config.
- All 4 discriminator-candidate columns present. No
FIELD_ABSENT.
2.2 public.entity_species
Columns present: id, sort, user_created, date_created, user_updated, date_updated, code, species_code, display_name, composition_level, management_mode, prefix, description, status, _dot_origin, parent_id, depth, kg_metadata.
- Semantic field presence map:
- IDENTITY:
id, code, species_code, display_name, prefix - CLASSIFICATION:
composition_level, management_mode, status - HIERARCHY:
parent_id, depth - OTHER:
description, _dot_origin, kg_metadata, sort, user_*, date_*
- IDENTITY:
- No
FIELD_ABSENTfor required comparison columns.
2.3 public.collection_registry
Columns present (relevant subset): collection_name, governance_role, storage_role, source_kind, migration_state, species_code, birth_code_strategy, birth_code_column, birth_identity_source, classification, code, name, name_en, description, purpose, _dot_origin, group, icon, field_count, has_note, description_policy, owner.
- No
FIELD_ABSENT.governance_roleandbirth_code_strategyboth present.
2.4 public.birth_registry
Columns present: id, sort, user_created, date_created, user_updated, date_updated, entity_code, collection_name, species_code, composition_level, dot_origin, born_at, governance_role, inspect_pen, inspect_stamp, inspect_gate, certified, certified_at, status.
- No
FIELD_ABSENT.
2.5 public.tac_logical_unit
Columns present: id, canonical_address, doc_code, parent_id, sort_order, section_type, section_code, owner, identity_profile, tier, lifecycle_status, created_at, updated_at.
unit_kindcolumn: FIELD_ABSENT. Closest categorical alternatives observed:section_type(12 distinct values),tier(4 distinct, incl. NULL),lifecycle_status.
3. GOAL RESULTS
G1 — Discriminator usage in production
| Discriminator column | Exists | Non-NULL rows |
|---|---|---|
discriminator_field |
yes | 0 |
discriminator_value |
yes | 0 |
discriminator_operator |
yes | 0 |
discriminator_config |
yes | 0 |
Total species_collection_map rows = 153. Rows with ANY discriminator field set = 0. Sample of non-NULL rows = empty.
Conclusion: discriminator_schema_support = true (columns exist). discriminator_production_active = false (zero rows populated).
G2 — fn_birth_registry_auto discriminator handling
Function exists (count=1). Source captured. Species/composition resolution clause:
SELECT scm.species_code, es.composition_level
INTO v_species_code, v_comp_level
FROM species_collection_map scm
LEFT JOIN entity_species es ON es.species_code = scm.species_code
WHERE scm.collection_name = TG_TABLE_NAME
AND scm.is_primary = true
LIMIT 1;
Function source contains no reference to discriminator_field, discriminator_value, discriminator_operator, or discriminator_config. Also no reference to NEW.unit_kind or v_row_json->>'unit_kind'.
Record-field access observed: v_row_json->>v_code_field (trigger arg), v_row_json->>'_dot_origin', v_row_json->>'id'.
Conclusion: uses_discriminators = false. reads_record_fields_beyond_code = true (reads _dot_origin and id, but not any discriminator). Discriminator path is dormant at birth time.
G3 — Complete species landscape
SELECT count(*) FROM entity_species = 40.
Categorical distinct-value counts (live):
composition_level:atom=20,molecule=11,compound=8,meta=1.management_mode:governed=26,observed=8,excluded=6.status:active=40.depth:1=40 (flat tree).
Full row dump (IDENTITY + CLASSIFICATION + HIERARCHY columns) — 40 rows: see live PG (excerpt at execution time).
Highlights of the 8 observed species (relevant to G8):
| species_code | code | display_name | composition_level | management_mode |
|---|---|---|---|---|
| ai_support | SPE-AIS | Hỗ trợ AI | atom | observed |
| business_support | SPE-BZS | Hỗ trợ Kinh doanh | molecule | observed |
| checkpoint_support | SPE-CKS | Hỗ trợ Checkpoint | molecule | observed |
| directus_field | SPE-DXF | Directus Field | atom | observed |
| governance_infra | SPE-GOV | Hạ tầng Giám sát | atom | observed |
| help_center | SPE-HLP | Trung tâm Trợ giúp | molecule | observed |
| pivot_result | SPE-PVR | Ket qua Pivot | molecule | observed |
| system_log | SPE-LOG | Nhật ký Hệ thống | atom | observed |
G4 — Collection-registry context for targets
| field | information_unit | unit_version |
|---|---|---|
| id | 184 | 185 |
| code | COL-176 | COL-177 |
| governance_role | observed | observed |
| storage_role | primary | primary |
| source_kind | native | native |
| migration_state | pilot | pilot |
| species_code | NULL | NULL |
| birth_code_strategy | synthetic_id | subordinate |
| birth_code_column | NULL | NULL |
| birth_identity_source | manual | manual |
| classification | NULL | NULL |
Both targets: governance_role=observed, no species assigned.
G5 — Birth-registry state for targets
| collection | total rows | species_code NULL | composition_level NULL |
|---|---|---|---|
| information_unit | 12 | 12 | 12 |
| unit_version | 0 | 0 | 0 |
First 12 information_unit rows: all entity_code=information_unit::<uuid>, species_code=NULL, composition_level=NULL, governance_role=observed, certified=false, status=born. (Full entity_codes captured in run.)
G6 — Discriminator candidate verification on target
information_unit.unit_kind exists (P5 PASS). Distinct values + counts:
| unit_kind | count |
|---|---|
| design_doc_section | 12 |
Total information_unit rows = 12. Only one unit_kind value populated today. The target value law_unit (from scope §0 / dot_config vocab.unit_kind.law_unit) is not yet present in any row.
G7 — Collections sharing exact birth_code_strategy with subordinate target
v_sub_strategy = collection_registry.birth_code_strategy WHERE collection_name='unit_version'→subordinate.- Other collections with EXACT
birth_code_strategy = 'subordinate': count = 1 (onlyunit_versionitself). - Of those, with
species_collection_maprows: 0.
Conclusion: unit_version is the only collection in the entire registry using the subordinate birth strategy. No peer pattern to cross-reference. No fuzzy expansion attempted.
G8 — Dry-run candidate species with deterministic labels
Comparison rule (per prompt §G8): label PLAUSIBLE iff entity_species.management_mode = collection_registry.governance_role for information_unit, both non-NULL; CONFLICT iff both non-NULL and unequal; UNKNOWN if either NULL; N/A if field absent.
Target gov_role for information_unit = observed. Both columns present → no N/A or UNKNOWN cases.
Counts:
| Label | Count |
|---|---|
| PLAUSIBLE | 8 |
| CONFLICT | 32 |
| UNKNOWN | 0 |
| N/A | 0 |
PLAUSIBLE candidates (each row labelled candidate_not_approved):
| species_code | proposed_composition_level | compatibility_reason |
|---|---|---|
| ai_support | atom | management_mode=observed matches target governance_role=observed |
| business_support | molecule | same |
| checkpoint_support | molecule | same |
| directus_field | atom | same |
| governance_infra | atom | same |
| help_center | molecule | same |
| pivot_result | molecule | same |
| system_log | atom | same |
CONFLICT rows (32) include all governed species (e.g. law, jurisdiction, law_enforcement, dot_tool, workflow, …) and all excluded species. Reason: management_mode (governed or excluded) ≠ target governance_role (observed).
All G8 output rows carry candidate_not_approved.
G9 — QT-001 backfill dry-run per PLAUSIBLE candidate
Population of NULL species rows: 12 (information_unit, all current rows).
| proposed_species | proposed_composition_level | rows_would_update |
|---|---|---|
| ai_support | atom | 12 |
| business_support | molecule | 12 |
| checkpoint_support | molecule | 12 |
| directus_field | atom | 12 |
| governance_infra | atom | 12 |
| help_center | molecule | 12 |
| pivot_result | molecule | 12 |
| system_log | atom | 12 |
Sample (first 3 rows × 8 candidates = 24 projection rows captured), e.g.:
| proposed_species | proposed_comp | entity_code | current_species | current_comp | state |
|---|---|---|---|---|---|
| ai_support | atom | information_unit::3ffbbaa5-… | NULL | NULL | candidate_not_approved |
| ai_support | atom | information_unit::60c0017d-… | NULL | NULL | candidate_not_approved |
| ai_support | atom | information_unit::8e247041-… | NULL | NULL | candidate_not_approved |
| governance_infra | atom | information_unit::3ffbbaa5-… | NULL | NULL | candidate_not_approved |
| … | … | … | … | … | … |
Every output row: candidate_not_approved. No INSERT/UPDATE performed.
G10 — TAC unit_kind distribution snapshot
information_schema.columns lookup for tac_logical_unit.unit_kind → 0 (FIELD_ABSENT).
Closest categorical column observed: section_type (12 distinct values, total 86 rows).
| section_type | count |
|---|---|
| technical_spec | 19 |
| governance_process | 16 |
| paragraph | 14 |
| heading | 10 |
| principle | 8 |
| process | 7 |
| checklist | 6 |
| changelog | 2 |
| article | 1 |
| appendix | 1 |
| instruction_block | 1 |
| definition | 1 |
tier distribution: NULL=59, unit=22, section=4, root=1. None equals law_unit.
No exact value in tac_logical_unit matches target_unit_kind_committed='law_unit' via either section_type or tier. TAC data cannot directly inform unit_kind discriminator strategy on information_unit without a separate mapping step. Reported as FIELD_ABSENT on the original lookup; no fuzzy expansion attempted.
4. PHASE 4B SNAPSHOT RE-VERIFICATION
| Phase 4B finding | Re-verified live? | Holds? |
|---|---|---|
species_collection_map total = 153 rows |
yes | ✅ |
| 0 IU/UV rows in species_collection_map | yes | ✅ (only unit_version peers checked, 0 maps) |
fn_birth_registry_auto resolves species via is_primary=true LIMIT 1, no discriminator |
yes (full source captured) | ✅ |
entity_species = 40 species |
yes | ✅ |
SPE-GOV = governance_infra/atom/observed |
yes | ✅ |
SPE-LAW = law/compound/governed |
yes | ✅ |
| 12 IU birth rows, all NULL species/composition | yes | ✅ |
| 0 UV birth rows | yes | ✅ |
| Species tree flat (all depth=1) | yes | ✅ |
TAC parent_id containment |
yes (parent_id column exists) |
✅ |
No Phase 4B label was carried over as fact without live re-query.
5. SCALE BRITTLENESS SELF-AUDIT (§6 of prompt)
| Check | Answer |
|---|---|
| Did I list any species/composition/role value from memory? | No — every value queried live. |
| Did I list any column name as "required" without verifying it exists? | No — every table introspected, or queried via SELECT * / generic count(*). |
| Did I use any "-like" or semantic fuzzy match for selectors? | No — exact-value match only (=, not ILIKE). |
| Did I assume fixed counts? | No — every count is a live snapshot at run time. |
| Did I assume fixed field lists for output shapes? | No — projections derived from observed columns; absent fields reported as FIELD_ABSENT. |
| Would my queries adapt if a column was renamed? | Yes — they introspect column presence before querying and would emit FIELD_ABSENT. |
| Would my queries adapt if 50 new species were added? | Yes — G3 uses SELECT count(*) + GROUP BY on categorical columns, no enumeration. |
| Did I report Phase 4B labels as facts without re-verification? | No — every label re-verified in §4. |
| Did I apply subjective judgment in G8/G9 labels? | No — purely the rule management_mode = governance_role. |
scale_brittleness_self_audit_passed = true.
6. CRITICAL OBSERVATIONS (informational, no decision locked)
- Discriminator runtime is dormant. Schema supports it (
species_collection_maphas all 4 columns), but 0 rows populated andfn_birth_registry_autodoes not read those columns. Any discriminator-based strategy requires either a function patch (out of scope) or a post-birth correction tool (out of scope). subordinatepeer pattern is unique.unit_versionis the only collection withbirth_code_strategy='subordinate'registry-wide. There is no peer mapping to copy.law_unitdoes not exist as a live value anywhere. Neitherinformation_unit.unit_kindnortac_logical_unit.section_type/tiercontainslaw_unit.dot_config['vocab.unit_kind.law_unit']=law_unitis a vocabulary entry; no current row consumes it. Phase 5 TAC migration would be the first event to introduce that value.- 8 PLAUSIBLE species, but composition spans atom/molecule (5 atom, 3 molecule). The 12 pilot rows (
design_doc_section) have no nesting evidence ininformation_unit; choosingmoleculewould imply containment that the data does not currently exhibit. This is a decision for GPT/User — Phase 4C does not lock it. - Schema duplication for
unit_version. Asandbox_tac.unit_versiontable exists alongsidepublic.unit_version. Confirm Phase 5 migration targetspublic.unit_versionspecifically; flag separately ifsandbox_tacis dead schema.
7. STATUS FLAGS
phase4c_dryrun_status=PASS
no_mutation_performed=true
gate0_all_passed=true
discriminator_runtime_active=false
discriminator_column_exists_on_target=true
species_decision_locked=false
composition_decision_locked=false
plausible_candidate_count=8
conflict_candidate_count=32
unknown_candidate_count=0
scale_brittleness_self_audit_passed=true
next_recommended_action=GPT_User_review_8_PLAUSIBLE_candidates_for_information_unit_species_pick_then_decide_QT001_backfill_scope_and_phase5_nesting
Phase 4C dry-run report | GATE-0 pass | 8 PLAUSIBLE / 32 CONFLICT / 0 UNKNOWN / 0 N/A | discriminator dormant | no writes | 2026-05-11