KB-1053

22-P0 — IU Native Create Contract Inspection Report

9 min read Revision 1
pack-22p0inspectionreportfn-iu-createread-only

22-P0 — IU Native Create Contract Inspection Report

Date: 2026-05-06 | Scope: READ-ONLY runtime inspection per Pack 22-P0 prompt rev2 Environment: VPS 38.242.240.89, container postgres, db directus, role directus


Existing mechanisms

  • PG functions matching contract namespace (LIKE fn_iu% / %iu_create% / %information_unit_create% / %content_hash%):
    • fn_iu_birth_gate_layer1 (0 args, volatile, secdef=f)
    • fn_iu_birth_gate_layer2 (0 args, volatile, secdef=f)
    • fn_iu_updated_at (0 args, volatile, secdef=f)
    • fn_sbx_compute_content_hash (4 args, immutable, secdef=f)
    • No fn_iu_create / fn_information_unit_create / fn_iu_resolve_* / fn_iu_classify_* / fn_iu_verify_* exist.
  • DOT tools (/opt/incomex/dot/bin/): no script matches iu_create|fn_iu|information_unit.*create (grep empty). No dot-iu* or *iu-create* scripts on host.
  • App/API hooks: no .js/.ts/.py under /opt/incomex/ references information_unit.*create|iu_create|fn_iu (xargs+grep empty).
  • Directus extensions:
    • /opt/incomex/docker/directus/extensions/: only l2-checkpoint-guard/ (index.js + package.json) — not IU-create related.
    • /opt/incomex/docker/nuxt-repo/directus/extensions/: no IU/iu_create references.
  • Recommendation: Create new fn_iu_create (no existing wrapper to extend). The 4 discovered functions are gate triggers + content-hash util + updated_at trigger — all complementary, none subsumes the create contract.

Schema

  • information_unit: 15 cols. Contract cols all PRESENT (10/10).
    • id uuid NOT NULL DEFAULT gen_random_uuid()
    • canonical_address text NOT NULL
    • unit_kind text NOT NULL
    • owner_ref text NOT NULL
    • created_by text NOT NULL, updated_by text NOT NULL
    • identity_profile jsonb NOT NULL DEFAULT '{}'::jsonb
    • parent_or_container_ref uuid NULL
    • version_anchor_ref uuid NULL
    • content_anchor_ref text NULL
    • Plus: lifecycle_status (default 'draft'), conformance_status (default 'open'), created_at, updated_at, deleted_at.
  • unit_version: 9 cols. Contract cols all PRESENT (6/6).
    • id uuid NOT NULL DEFAULT gen_random_uuid()
    • unit_id uuid NOT NULL
    • body text NOT NULL, content_hash text NOT NULL
    • version_seq integer NOT NULL
    • created_by text NOT NULL
    • Plus: lifecycle_status (default 'draft'), content_profile jsonb (default '{}'), created_at.
  • birth_registry: required cols PRESENT — entity_code (varchar), collection_name (varchar), born_at (timestamptz).
  • collection_registry: required cols PRESENT — collection_name (varchar), birth_code_strategy (varchar). governance_role also present.
  • Optional cols (updated_by/date_created/date_updated): ABSENT on both unit_version and information_unit (the latter uses created_at/updated_at, not date_*). Function MUST NOT write to non-existent date_* columns.

Deferrable FK IU→UV

  • Count: 1 (PASS — exactly 1 needed).
  • Name: fk_iu_version_anchor
  • Definition: FOREIGN KEY (version_anchor_ref) REFERENCES unit_version(id) DEFERRABLE INITIALLY DEFERRED
  • condeferrable=t, condeferred=t.

Trigger inventory (information_unit)

trigger function timing+event (from def) enabled constraint? deferrable?
trg_birth_information_unit fn_birth_registry_auto AFTER INSERT FOR EACH ROW O (enabled) no no
trg_iu_birth_gate_layer1 fn_iu_birth_gate_layer1 BEFORE INSERT FOR EACH ROW O no no
trg_iu_birth_gate_layer2 fn_iu_birth_gate_layer2 AFTER INSERT OR UPDATE FOR EACH ROW (CONSTRAINT TRIGGER, DEFERRABLE INITIALLY DEFERRED) O yes yes (init deferred)
trg_iu_updated_at fn_iu_updated_at BEFORE UPDATE FOR EACH ROW O no no

All four enabled (tgenabled='O'). None internal.

  • Birth function: fn_birth_registry_auto — observed (runtime). Trigger arg '__birth_synthetic_id__' indicates synthetic_id strategy, matches collection_registry.birth_code_strategy='synthetic_id' for IU.
  • L1 gate function: fn_iu_birth_gate_layer1 — canonical name (matches contract).
  • L2 gate function: fn_iu_birth_gate_layer2 — canonical name; constraint trigger, deferred → fires at COMMIT.

Unique constraint on canonical_address

  • Exists: yes
  • Name: information_unit_canonical_address_keyUNIQUE (canonical_address) (auto-generated PG name; observed).

collection_registry

  • information_unit: birth_code_strategy='synthetic_id', governance_role='observed'
  • unit_version: birth_code_strategy='subordinate', governance_role='observed'

Vocab/defaults (dot_config)

Table exists. Three vocab entries seeded; no iu_create.* defaults:

  • vocab.unit_kind.design_doc_section = design_doc_section
  • vocab.section_type.section = section
  • vocab.publication_type.design_doc = design_doc
  • iu_create.*: 0 rows.

Hash + UUID

  • digest(text,text): available (signature resolved; live test → 9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08 for digest('test','sha256')).
  • gen_random_uuid(): available (live test returned valid UUIDv4).

Roles

  • current_user / session_user: directus / directus.
  • Login roles (excluding pg_*): context_pack_readonly (read-only), directus (table owner, login), incomex (login, no super), workflow_admin (super, createdb).
  • Table owner of information_unit AND unit_version: directus.
  • Privileges on information_unit:
    • directus: SELECT, INSERT, UPDATE, DELETE, REFERENCES, TRIGGER, TRUNCATE
    • context_pack_readonly: SELECT
  • INSERT holders: directus only.
  • Adapter role candidate: directus (only non-readonly, non-super login with INSERT). incomex lacks grants on IU; workflow_admin is superuser (avoid for app path).

Pilot IU

  • Present: yes, 1 row — pilot.iu0.test-001 (id=3ffbbaa5-f22a-4df4-8bc6-c27eab2787fe, lifecycle_status=draft).
  • IU total: 1 | UV total: 1.

P1 readiness

  • Blockers: none.
  • Warnings:
    • No iu_create.* defaults seeded in dot_config — function spec must either inline defaults or P1 must seed them before adapter rollout.
    • birth_code_strategy='synthetic_id' for IU + L1/L2 gate triggers → wrapper MUST set SET CONSTRAINTS fk_iu_version_anchor DEFERRED semantics implicit (already INITIALLY DEFERRED) and ensure UV row + IU version_anchor_ref update happen within same txn before COMMIT, else L2 constraint trigger will fire and reject.
    • governance_role='observed' for both IU and UV — caller pattern is observation/runtime, not law-governed; document in design.
  • TDs:
    • 4 PG functions in fn_iu_* namespace are pre-existing; new fn_iu_create should not collide with names fn_iu_birth_gate_layer1/2, fn_iu_updated_at.
    • No updated_by/date_* cols on UV — adapter must not pass them.
    • fn_sbx_compute_content_hash(4 args) exists — investigate signature in P1 to decide reuse vs. inline digest(text,'sha256').

Anti-hardcode self-check

  • Exact runtime names proposed without catalog evidence: no (all names from pg_proc/pg_trigger/pg_constraint).
  • Role grant target chosen without role inventory: no (pg_roles + role_table_grants consulted).
  • Count used as timeless truth: no (counts noted as observation at 2026-05-06).
  • Inaccessible path treated as absent: no (/opt/incomex/directus/ was inaccessible → re-resolved to /opt/incomex/docker/directus/ and /opt/incomex/docker/nuxt-repo/directus/; both inspected).

Verdict

P0 PASS

Schema, deferrable FK, gate triggers, unique constraint, hash/uuid, and adapter role all green. No existing fn_iu_create to conflict. Two non-blocking warnings: (1) iu_create.* defaults absent in dot_config; (2) governance_role=observed should be reflected in P1 design rationale. Ready for P1 (function creation) pending GPT/User decision on default-seed sequencing and fn_sbx_compute_content_hash reuse.

Back to Knowledge Hub knowledge/dev/laws/dieu44-trien-khai/reports/22-p0-iu-native-create-contract-inspection-report.md