KB-587A

IU-0 Pack 2A — Description/Birth Contract Discovery (READ-ONLY)

27 min read Revision 1
iu-0pack-2adiscoverydescriptionbirthcollection-registryread-only2026-05-04

IU-0 Pack 2A — Description/Birth Contract Discovery (READ-ONLY)

Date: 2026-05-04 Scope: Read-only runtime evidence for description/birth contract of dot-collection-register and collection_registry. No INSERT/UPDATE/DELETE, no DDL, no DOT execution. VPS: 38.242.240.89 (contabo). DB: postgres container, directus database.

Pre-reads completed: law-03-metadata, dieu3-phu-luc-description-templates, law-04-birth-process, dieu35-dot-governance-law, dieu36-collection-protocol-law, dieu20-thiet-ke-truoc-trien-khai, file 12 (Pack 2A design), GPT review of file 12.


Q1. dot-collection-register contract

Raw evidence — header + usage (verbatim, lines 1–60)

#!/usr/bin/env bash
# =============================================================================
# dot-collection-register — Register a collection in collection_registry
# =============================================================================
# CHECKED-NO-DUPLICATE: [searched dot/bin/dot-*register* — no collection register tool]
# VERSION: 1.1.0
# §0-E DOT-FIRST: All governance declarations MUST go through DOT tools.
#
# CHANGELOG:
#   v1.1.0 (2026-03-21): S157-A — add --update mode (upsert)
#   v1.0.0: Initial — create-only, skip if exists
#
# Usage:
#   dot-collection-register <collection_name> [options]
#
# Options:
#   --update              Update existing record (upsert mode)
#   --storage_role X      primary|junction|log|system
#   --governance_role Y   governed|observed|excluded
#   --source_kind Z       registry|native|derived|policy
#   --migration_state W   unclassified|classified|pilot|stable (default: unclassified)
#   --description D       Description text
#   --cloud|--local       Environment selection
#   --dry-run             Show what would be done
#   --help, -h            Show help
#
# Examples:
#   dot-collection-register dot_tools --storage_role primary --governance_role governed
#   dot-collection-register some_table   # → COL-NNN, migration_state=unclassified
#   dot-collection-register dot_tools --update --governance_role governed  # upsert

Raw evidence — write path (POST + PATCH via Directus REST API)

INSERT (lines ~205–224):

RESP=$(curl -sS --globoff -k -X POST "${BASE_URL}/items/collection_registry" \
    -H "Authorization: Bearer $DOT_TOKEN" \
    -H "Content-Type: application/json" \
    -d "$PAYLOAD" -w "\n%{http_code}")

UPDATE (lines ~148–151):

PATCH_RESP=$(curl -sS --globoff -k -X PATCH "${BASE_URL}/items/collection_registry/${EX_ID}" \
        -H "Authorization: Bearer $DOT_TOKEN" \
        -H "Content-Type: application/json" \
        -d "$PATCH_PAYLOAD" -w "\n%{http_code}")

INSERT payload only sets these fields (lines ~204–219):

{ code, name, collection_name, status:"active", migration_state }
+ optional: description, storage_role, governance_role, source_kind

Auto-generates COL-NNN by reading ?sort=-code&limit=1 and incrementing.

Interpretation

  • Accepts --description ✅, --governance_role ✅, --source_kind ✅, --migration_state ✅, --storage_role ✅.
  • Has --update mode (upsert/PATCH).
  • Writes via Directus REST API (/items/collection_registry) — NOT raw SQL. Auth via DOT_TOKEN.
  • Does NOT pass species_code, _dot_origin, or any explicit provenance label — relies on triggers.
  • Has truncation read-back diagnostic post-write (TD-334).

Unknowns

  • No --unregister, --rollback, or --delete flag in source. Q5 confirms no separate DOT tool either.
  • INSERT payload always sets status:"active" — no flag to override.

Q2. Runtime description enforcement

Raw evidence — dot_config keys

                    key                    |                                           value
-------------------------------------------+-------------------------------------------------------------------------------------------
 description_enforcement_mode              | warn
 description_min_length                    | 30
 desc_template_collection_registry         | [{governance_role}] Collection {code}. Loài: {species_code}.
 desc_template_default                     | [{status}] {_table_display_name}: {_identifier}. Lớp: {composition_level}.
 desc_template_dot_config                  | Config key điều khiển {key}.
 desc_template_dot_domains                 | Domain [{code}] quản lý phạm vi {name}.
 desc_template_dot_operations              | [{code}] Operation: {name}.
 desc_template_dot_tools                   | [{tier}] [{domain}] {trigger_type} trigger. Operation: {operation}. Paired: {paired_dot}.
 desc_template_entity_species              | Loài [{code}] thuộc lớp {composition_level}.
 desc_template_level_atom                  | [{status}] Nguyên tử {code} trong {_source_table}.
 desc_template_level_compound              | [{status}] Hợp chất {code} trong {_source_table}.
 desc_template_level_molecule              | [{status}] Phân tử {code} trong {_source_table}.
 dot_tools_description_min_length          | 50
 hc_heal_description_basic_autofix_enabled | true
(14 rows)

No collection_registry_description_min_length row — only the global default of 30 applies to collection_registry.

Raw evidence — fn_description_birth_guard body (key excerpts)

DECLARE _mode TEXT; _gov_role TEXT; _min_len INT; _table_min INT;
        _desc TEXT; _tpl TEXT; _level TEXT; _ctx jsonb;
BEGIN
  SELECT governance_role INTO _gov_role
    FROM collection_registry WHERE collection_name = TG_TABLE_NAME;

  -- Auto-gen when description empty — fires on BOTH INSERT and UPDATE OF description.
  -- NT9: only fill when empty, never overwrite non-empty. Caller's UPDATE SET desc=''
  -- is an explicit regeneration request (intentional clear → auto-heal).
  IF _gov_role = 'governed' THEN
    _desc := btrim(COALESCE((to_jsonb(NEW)->>'description')::text, ''));
    IF _desc = '' THEN
      _ctx := fn_description_context(TG_TABLE_NAME, to_jsonb(NEW));
      _level := _ctx->>'composition_level';
      -- Đ3 §2.6: 4-tier lookup
      -- 1) desc_template_<table>_<level>
      -- 2) desc_template_<table>
      -- 3) desc_template_level_<level>
      -- 4) desc_template_default
      IF _tpl IS NOT NULL THEN
        NEW.description := fn_render_description_template(_tpl, _ctx);
      END IF;
    END IF;
  END IF;

  -- Original C1-C3 enforcement
  SELECT value INTO _mode FROM dot_config WHERE key='description_enforcement_mode'; -- default 'warn'
  SELECT value::int INTO _min_len FROM dot_config WHERE key='description_min_length'; -- default 30
  SELECT value::int INTO _table_min FROM dot_config WHERE key=TG_TABLE_NAME||'_description_min_length';

  IF _gov_role IS NULL THEN
    -- block raises exception, warn raises warning
  END IF;
  IF _gov_role = 'excluded' THEN RETURN NEW; END IF;

  _desc := btrim(...);
  IF _desc = '' OR length(_desc) < _min_len
     OR _desc ~ '^(.)\1{9,}$' OR _desc ~ '^[.\-_\s]{10,}$' THEN
     IF _gov_role='governed' AND _mode='block' THEN
       RAISE EXCEPTION 'Đ4 §2.1 + Đ3 §2.1: ... description >= % ký tự, không gaming.', _min_len;
     END IF;
  END IF;
  RETURN NEW;
END;

Interpretation

  • Auto-gen ONLY for governance_role='governed' AND empty description. Uses 4-tier lookup; for collection_registry Tier 2 hits desc_template_collection_registry.
  • Mode is currently warn globally — empty/short descriptions WARN but do NOT block (except gaming patterns or governed+block).
  • Min length default 30; no per-table override for collection_registry. dot_tools has 50.
  • Fires BEFORE INSERT and BEFORE UPDATE OF description.
  • Auto-heal only when desc is empty after btrim — non-empty existing descriptions are never overwritten.

Unknowns

  • The auto-gen path requires _gov_role='governed'. For governance_role='observed' or NULL, empty description passes through without fill (then enforcement is just a warning). Confirms that Pack 2A must pass an explicit --description for any non-governed collection.
  • desc_template_collection_registry references {species_code} — but species_code is set via species_collection_map, not on collection_registry directly. Auto-gen rendering of {species_code} for a freshly registered collection without a species mapping is unverified in this read-only pack.

Q3. Convention — top descriptions in collection_registry

Raw evidence

       collection_name        | governance_role |                                description
------------------------------+-----------------+----------------------------------------------------------------------------
 kb_documents_history         | observed        | Version history snapshots for KB documents. Auto-populated by PG triggers.
 kb_audit_log                 | observed        | Audit trail for all KB write operations. Auto-populated by PG triggers.
 directus_fields              | observed        | Directus fields system table. System observed — overlay only.
 entity_labels                | excluded        | Junction table gan nhan cho entities. Junction governed.
 admin_fallback_log           | law_artifact    | Admin fallback log (D35 6.5) - retroactive APR tracking
 law_version_verification_log | law_artifact    | Law version verification log (HP) - pre-enact checks
 apr_action_types             | governed        | Catalog of APR proposed actions (Dieu32 v1.1 §3.2)
 categories                   | excluded        | [excluded] Collection COL-032. Loài: collection.
 block_cta                    | excluded        | [excluded] Collection COL-012. Loài: collection.
 contacts                     | observed        | [observed] Collection COL-037. Loài: collection.
(10 rows)

Interpretation

  • Hand-written descriptions (governed, observed, law_artifact rows at top): functional purpose + key cross-reference. Style: {Purpose}. {Source/scope/law citation}.
  • Auto-generated descriptions (rows 8–10, prefix [excluded]/[observed]): match desc_template_collection_registry format [{governance_role}] Collection {code}. Loài: {species_code}. — exactly the auto-gen template output.
  • Convention difference governed vs observed: governed authors describe purpose ("Catalog of APR proposed actions (Dieu32 v1.1 §3.2)"); observed often describe origin/system role ("System observed — overlay only").

Unknowns

  • The handwritten governed examples are short (≤80 chars). No long-form (≥150 char) examples surface in the top-10. Likely indicates no rich, prose-style governed descriptions exist yet — or none meet length cutoff that highly. (Cannot infer maximum convention without running a different query.)
  • law_artifact is a 4th observed governance_role value not in the --governance_role flag whitelist (governed|observed|excluded). UNKNOWN — needs design decision whether IU-0 needs that role.

Q4. Birth trigger chain on collection_registry

Raw evidence

                trigger_name                 | action_timing | event_manipulation |                action_statement
---------------------------------------------+---------------+--------------------+-------------------------------------------------
 trg_before_birth_gate_collection_registry   | BEFORE        | INSERT             | EXECUTE FUNCTION fn_birth_gate()
 trg_auto_code_collection_registry           | BEFORE        | INSERT             | EXECUTE FUNCTION gen_code_collection_registry()
 trg_desc_guard_collection_registry          | BEFORE        | INSERT             | EXECUTE FUNCTION fn_description_birth_guard()
 trg_desc_guard_collection_registry          | BEFORE        | UPDATE             | EXECUTE FUNCTION fn_description_birth_guard()
 trg_validate_dot_origin_collection_registry | BEFORE        | INSERT             | EXECUTE FUNCTION fn_validate_dot_origin()
 trg_validate_dot_origin_collection_registry | BEFORE        | UPDATE             | EXECUTE FUNCTION fn_validate_dot_origin()
 birth_trigger_collection_registry           | AFTER         | INSERT             | EXECUTE FUNCTION fn_birth_registry_auto('code')
 trg_birth_collection_registry               | AFTER         | INSERT             | EXECUTE FUNCTION fn_birth_registry_auto('code')
 trg_desc_provenance_collection_registry     | AFTER         | INSERT             | EXECUTE FUNCTION fn_auto_label_provenance()
 trg_label_assign_collection_registry        | AFTER         | INSERT             | EXECUTE FUNCTION fn_auto_label_assignment()
 trg_label_assign_collection_registry        | AFTER         | UPDATE             | EXECUTE FUNCTION fn_auto_label_assignment()
 trg_count_collection_registry               | AFTER         | INSERT             | EXECUTE FUNCTION refresh_registry_count()
 trg_count_collection_registry               | AFTER         | UPDATE             | EXECUTE FUNCTION refresh_registry_count()
 trg_count_collection_registry               | AFTER         | DELETE             | EXECUTE FUNCTION refresh_registry_count()
 trg_refresh_collection_count                | AFTER         | INSERT             | EXECUTE FUNCTION fn_refresh_collection_count()
 trg_refresh_collection_count                | AFTER         | DELETE             | EXECUTE FUNCTION fn_refresh_collection_count()
 trg_refresh_orphan_col                      | AFTER         | INSERT             | EXECUTE FUNCTION trg_fn_refresh_orphan_col()
 trg_refresh_orphan_col                      | AFTER         | DELETE             | EXECUTE FUNCTION trg_fn_refresh_orphan_col()
(18 rows)

Interpretation — INSERT chain

  1. BEFORE INSERT (alphabetical order by trigger name unless explicitly ordered):
    • trg_auto_code_collection_registrygen_code_collection_registry() (assigns COL-NNN if not provided)
    • trg_before_birth_gate_collection_registryfn_birth_gate() (Đ4 gate)
    • trg_desc_guard_collection_registryfn_description_birth_guard() (auto-fill from template if governed+empty; warn/block on min-length)
    • trg_validate_dot_origin_collection_registryfn_validate_dot_origin() (Đ0-E DOT-first)
  2. AFTER INSERT:
    • birth_trigger_collection_registry AND trg_birth_collection_registry (DUPLICATE — both call fn_birth_registry_auto('code'))
    • trg_desc_provenance_collection_registryfn_auto_label_provenance() (assigns PROV-* label)
    • trg_label_assign_collection_registryfn_auto_label_assignment()
    • trg_count_collection_registry, trg_refresh_collection_count, trg_refresh_orphan_col (counters/views)

Auto-gen confirmation

  • fn_description_birth_guard auto-fills description from desc_template_collection_registry IF governance_role='governed' AND description empty after btrim. For observed/excluded/NULL: NO auto-fill, just min-length warn.
  • The 4-tier template lookup means even if desc_template_collection_registry were absent, fallback to desc_template_default would apply (still only for governed).

Birth record

  • fn_birth_registry_auto('code') will fire and create a birth record for the inserted collection_registry row itself, on key=code (i.e., COL-NNN).

Unknowns

  • Duplicate AFTER INSERT triggers birth_trigger_collection_registry and trg_birth_collection_registry both invoke the same function. UNKNOWN if intentional double-write or legacy artifact — needs design decision/cleanup but does not block Pack 2A.
  • Trigger ordering within same timing+event is alphabetical by name in PostgreSQL — so trg_auto_code runs before trg_before_birth_gate runs before trg_desc_guard. Cannot confirm explicit ordering directives without checking pg_trigger.tgconstrindid; ordering is consistent with name-alphabetical assumption.

Q5. Rollback tools

Raw evidence — dot_tools matching collection/unregister

                  code                  |                  name
----------------------------------------+----------------------------------------
 DOT_COLLECTION_CREATE                  | dot-collection-create
 DOT_COLLECTION_FIELD_SYNC              | dot-collection-field-sync
 DOT_COLLECTION_HEALTH                  | dot-collection-health
 DOT_COLLECTION_REGISTER                | dot-collection-register
 DOT_SCHEMA_REGISTRY_COLLECTIONS_ENSURE | dot-schema-registry-collections-ensure
 DOT-TAC-COLLECTION-REGISTER            | TAC Collection Register
 DOT-TAC-COLLECTION-VERIFY              | TAC Collection Verify
(7 rows)

ls /opt/incomex/dot/bin/ | grep -i -E 'collection|register|unregister' returned no *unregister* script.

dot-collection-register --help source has no --unregister / --rollback / --delete flag (header verified verbatim, Q1).

Interpretation

  • No DOT tool exists for unregistering / deleting / rolling back a collection_registry row.
  • Rollback in Pack 2A must rely on either (a) a future DOT tool to be designed, or (b) raw DELETE FROM collection_registry WHERE code='COL-NNN' — which would violate Đ0-E DOT-first.

Unknowns

  • UNKNOWN — needs design decision: should Pack 2A include a dot-collection-unregister companion, or is rollback explicitly out of scope (forward-only registration)? GPT review of file 12 likely flags this; deferring to law council.

Q6. Species for IU

Raw evidence — entity_species (40 rows)

  code   |    species_code     |    display_name    | composition_level
---------+---------------------+--------------------+-------------------
 SPE-AGT | agent               | Agent              | atom
 SPE-AIS | ai_support          | Hỗ trợ AI          | atom
 SPE-APP | approval_request    | Yeu cau phe duyet  | compound
 SPE-BLK | cms_block           | CMS Block          | atom
 SPE-BZS | business_support    | Hỗ trợ Kinh doanh  | molecule
 SPE-CAT | catalog             | Danh muc he thong  | atom
 SPE-CKS | checkpoint_support  | Hỗ trợ Checkpoint  | molecule
 SPE-COL | collection          | Collection         | molecule
 SPE-CPS | checkpoint_set      | Bo checkpoint      | molecule
 SPE-CPT | checkpoint_type     | Loai checkpoint    | atom
 SPE-DEP | dependency          | Phu thuoc          | atom
 SPE-DOT | dot_tool            | DOT Tool           | atom
 SPE-DXF | directus_field      | Directus Field     | atom
 SPE-ENF | law_enforcement     | Thực thi DOT-Luật  | atom
 SPE-ERL | entity_rule         | Quy tac thuc the   | atom
 SPE-FAC | label_facet         | Chieu phan loai    | atom
 SPE-GAG | governance_agency   | Cơ quan Quản trị   | compound
 SPE-GOV | governance_infra    | Hạ tầng Giám sát   | atom
 SPE-GRL | governance_relation | Liên kết Quản trị  | atom
 SPE-HLP | help_center         | Trung tâm Trợ giúp | molecule
 SPE-ISS | system_issue        | Van de he thong    | atom
 SPE-JCT | junction_table      | Bảng Liên kết      | atom
 SPE-JUR | jurisdiction        | Phạm vi Pháp lý    | atom
 SPE-LAW | law                 | Văn bản Luật       | compound
 SPE-LBL | entity_label        | Entity Label       | atom
 SPE-LBR | label_rule          | Quy tac gan nhan   | atom
 SPE-LOG | system_log          | Nhật ký Hệ thống   | atom
 SPE-MOD | module              | Module             | compound
 SPE-OSC | os_crm              | OS CRM             | compound
 SPE-PGE | page                | Trang UI           | molecule
 SPE-PGW | website_page        | Trang Website      | molecule
 SPE-PVR | pivot_result        | Ket qua Pivot      | molecule
 SPE-SPE | species             | Loai               | meta
 SPE-SYS | system_backup       | Hệ thống/Backup    | atom
 SPE-TBL | table_ui            | Bang UI            | molecule
 SPE-TSK | task                | Nhiem vu           | compound
 SPE-WCR | wcr                 | De xuat thay doi   | compound
 SPE-WEB | website_content     | Nội dung Website   | molecule
 SPE-WFS | workflow_step       | Buoc quy trinh     | molecule
 SPE-WKF | workflow            | Quy trinh          | compound
(40 rows)

Raw evidence — species_collection_map for IU

 id | sort | ... | species_code | collection_name | is_primary | discriminator_field | ...
----+------+-----+--------------+-----------------+------------+---------------------+----
(0 rows)

Interpretation

  • No species exists for information_unit or unit_version. Closest semantic candidates: SPE-WEB (website_content, molecule) or SPE-MOD (module, compound) — but neither matches IU's intended semantics.
  • species_collection_map for IU collections is empty (expected — IU not yet registered).

Unknowns

  • UNKNOWN — needs design decision: must Pack 2A create a new species (e.g., SPE-IUN information_unit, level=compound or molecule) BEFORE registering the IU collections? Đ4 / Đ36 likely require species mapping for governed collections. Cannot infer composition_level for IU from existing evidence.

Q7. storage_role convention

Raw evidence

 storage_role
--------------
 junction
 system
 pg_only
 log
 primary
 derived
(6 rows)
     collection_name     | storage_role | governance_role
-------------------------+--------------+-----------------
 dot_domain_rules        | primary      | governed
 field_type_equivalences | primary      | governed
 governance_audit_log    | primary      | observed
 law_jurisdiction        | primary      | governed
 pivot_results           | derived      | observed
 dot_tools               | primary      | governed
 governance_registry     | primary      | governed
 governance_relations    | primary      | governed
 law_dot_enforcement     | primary      | governed
 normative_registry      | primary      | governed
(10 rows)

Interpretation

  • Six storage_role values in use: primary, junction, log, system, derived, pg_only.
  • dot-collection-register --help whitelist: primary|junction|log|system — DOES NOT include derived or pg_only. Those values entered DB by other paths (raw SQL or earlier tool versions). Tool's whitelist is narrower than DB reality.
  • Governed core tables → primary. Cross-link tables → junction. Audit/log → log. Computed views → derived. PG-only gov tables → pg_only (per S178 Fix 20 M3B memory).

Unknowns

  • For IU: unit_version likely primary (or log if append-only history). information_unitprimary. Cannot finalize without IU schema design (Pack 2C territory).
  • Tool whitelist gap (derived, pg_only missing) is pre-existing tech debt — not blocking Pack 2A but may need flag widening if any IU child collection lands as derived.

Q8. Write path — Directus API or SQL?

Raw evidence

See Q1 raw evidence: curl -X POST/PATCH "${BASE_URL}/items/collection_registry". BASE_URL=$DIRECTUS_URL. Auth Bearer $DOT_TOKEN (DOT auth, see dot-auth).

No psql, no SQL string, no docker exec postgres anywhere in the script.

Interpretation

  • Writes go through Directus REST API (/items/collection_registry). Compliant with Đ7 ("Nghĩ PG, làm qua Directus") and Đ0-H (DOT routes through Directus where possible).
  • Audit trail = Directus directus_activity (Directus auto-logs item ops by token user) + PG triggers (fn_birth_registry_auto, fn_auto_label_provenance, fn_auto_label_assignment, refresh_registry_count).
  • Truncation read-back diagnostic post-write (TD-334).

Unknowns

  • Whether directus_activity actually captures the DOT_TOKEN's writes with role attribution sufficient for Đ35 audit needs is not verified in this pack (out of scope).

Q9. Provenance for description

Raw evidence (first 20 collection_registry codes)

 entity_code | label_code
-------------+------------
 COL-001     | PROV-DOT
 COL-002     | PROV-DOT
 COL-003     | PROV-DOT
 COL-004     | PROV-DOT
 COL-005     | PROV-DOT
 COL-006     | PROV-DOT
 COL-007     | PROV-DOT
 COL-008     | PROV-DOT
 COL-009     | PROV-DOT
 COL-010     | PROV-DOT
 COL-011     | PROV-DOT
 COL-012     | PROV-DOT
 COL-013     | PROV-DOT
 COL-014     | PROV-DOT
 COL-015     | PROV-DOT
 COL-016     | PROV-DOT
 COL-017     | PROV-DOT
 COL-018     | PROV-DOT
 COL-019     | PROV-DOT
 COL-020     | PROV-DOT
(20 rows)

Interpretation

  • All 20 sampled collection_registry rows carry PROV-DOT (and only PROV-DOT among the prov-* set). Assigned by fn_auto_label_provenance (AFTER INSERT trigger) — based on _dot_origin field default. No PROV-AI / PROV-HUMAN labels found among the sample.
  • Đ3 distinction: PROV-DOT description = basic/auto. To attach PROV-AI or PROV-HUMAN description provenance, the writing path must explicitly mark provenance — dot-collection-register does NOT pass any provenance flag, so any description supplied via --description still ends up tagged PROV-DOT (because the trigger uses _dot_origin, not description origin).

Unknowns

  • UNKNOWN — needs design decision: when Pack 2A calls dot-collection-register --description "<AI-authored>", the description provenance will be mislabeled as PROV-DOT. To honor Đ3 PROV-AI distinction, either (a) extend dot-collection-register with a --description-provenance flag and a follow-up label write, or (b) accept PROV-DOT for all DOT-channel writes and document this convention. GPT review of file 12 likely raises this point.
  • Cannot read 21+ rows in this query — sample is the first 20 by registry insertion order. No counter-example in sample.

Summary of design decisions still required (NOT decided here)

  1. Q5: Rollback strategy — add dot-collection-unregister companion or declare forward-only?
  2. Q6: Create new species (e.g., SPE-IUN information_unit, composition_level=?) before registering IU collections?
  3. Q7: Storage role for information_unit / unit_version (probably primary, but pending IU schema spec).
  4. Q9: Description provenance labeling — accept PROV-DOT for all DOT-channel writes, or extend tool to support PROV-AI/PROV-HUMAN tagging?
  5. Q4 cleanup: Duplicate AFTER INSERT triggers birth_trigger_collection_registry vs trg_birth_collection_registry — pre-existing tech debt; not blocking but should be logged.
  6. Q3: governance_role law_artifact exists in DB but not in tool whitelist. UNKNOWN if IU needs it.
  7. Q7 tech-debt: tool whitelist missing derived, pg_only.

HARD STOP — no further action.

Back to Knowledge Hub knowledge/dev/laws/dieu44-trien-khai/reports/iu0-pack2a-description-birth-contract-discovery.md