KB-59F7 rev 4

DOT-119 Repair P1 — Metadata DDL + Seed + PG Enforcement Report

9 min read Revision 4
dot-119p1metadataddlseedpg-enforcementreportdieu44

DOT-119 Repair P1 — Metadata DDL + Seed + PG Enforcement Report

Date: 2026-05-05 Agent: Opus 4.7 (1M ctx) Controlling: 18b-P1 prompt rev 6 + 18a rev4 + 18b rev3 + GPT P1a decision Status: PASS — all gates green, COMMIT both transactions, fn_hash invariant preserved.


1. Bước 0 — Controlling docs read

Read on KB:

  • knowledge/dev/laws/dieu44-trien-khai/design/18a-dot119-metadata-driven-no-clobber-redesign.md (rev 4 FINAL)
  • knowledge/dev/laws/dieu44-trien-khai/design/18b-dot119-repair-execution-pack.md (rev 3 PASS, umbrella)
  • knowledge/dev/laws/dieu44-trien-khai/reviews/gpt-review-dot119-p1a-schema-tool-inspection-and-p1-decision-2026-05-05.md (P1a + GPT P1 hybrid DDL decision: DOT-063 for fields)
  • knowledge/dev/laws/dieu44-trien-khai/reviews/gpt-review-p1-partial-stop-birth-registry-drift-and-restart-directive-2026-05-05.md (anti-hardcode note for live counts)
  • Prompt: knowledge/dev/laws/dieu44-trien-khai/prompts/18b-p1-dot119-metadata-ddl-and-seed-prompt.md (rev 6)

Confirmed scope: 3 fields via DOT-063; metadata seed; PG enforcement. No DOT-119 execution, no script rewrite, no fn edit, no IU trigger/rows, no Pack 2B.


2. Bước 1 — Baselines (live)

Check Value Gate
fields_existing (PG cols of 3 target names) 0 OK (≤0)
fn_birth_registry_auto md5 1f729b3571a74963089bb3ef388217f3 OK (matches expected)
trigger_count (trg_birth_%) 30 baseline
birth_registry rows 75469 baseline

3. Bước 2 — Env + path

  • VPS: 38.242.240.89, postgres container postgres, db directus, user directus.
  • set -a; . /opt/incomex/.env.local; set +a; . /opt/incomex/dot/config/environment.sh; init_environment --cloudDIRECTUS_URL=https://directus.incomexsaigoncorp.vn, token length 64.
  • dot-schema-apply resolved at /opt/incomex/dot/bin/dot-schema-apply (executable, 9440 bytes).

4. Bước 3 — DOT-063 field creation

4.1 Bước 3-pre — Inspect existing field template

GET /fields/collection_registry/collection_name returned meta with these boolean fields:

  • readonly: false
  • hidden: false
  • required: true
  • searchable: true

sortable and filterable are not present in this Directus 11.x field meta schema. Spec written with the 4 detected booleans only (all set to false for new fields).

4.2 Bước 3a — Spec

File: /opt/incomex/dot/specs/collection_registry_birth_identity_fields.json

md5sum: 3a5a7b545258f8c544d2047870c726ea

3 fields, all string is_nullable: true:

  1. birth_code_strategyselect-dropdown with 6 choices (column/synthetic_id/legacy_id_single_colon/subordinate/disabled/unclassified)
  2. birth_code_columninput text
  3. birth_identity_sourceselect-dropdown with 5 choices (inferred_from_existing_trigger/manual/migration_seed/system_default/unclassified)

Boolean meta on each: readonly=false, hidden=false, required=false, searchable=false.

4.3 Bước 3b — Dry-run

DOT SCHEMA APPLY v1.0.0 — Mode: DRY RUN
Would create: birth_code_strategy
Would create: birth_code_column
Would create: birth_identity_source
Summary: Created 3, Skipped 0, Failed 0.

4.4 Bước 3c — Live

DOT SCHEMA APPLY v1.0.0 — Mode: LIVE
✅ Created: birth_code_strategy
✅ Created: birth_code_column
✅ Created: birth_identity_source
Summary: Created 3, Skipped 0, Failed 0.

4.5 Bước 3d — Verify

Verify Value Gate
PG cols (information_schema) 3 (all character varying, is_nullable=YES) OK
directus_fields rows 3 (interfaces match: select-dropdown, input, select-dropdown) OK
fn_birth_registry_auto md5 1f729b3571a74963089bb3ef388217f3 OK (unchanged)
birth_registry rows 75472 live drift (+3 vs baseline; live writes — anti-hardcode note applies)

5. Bước 4 — Metadata seed

Pre-seed total collection_registry rows: 166 (matches expected denominator). B4.before_birth_count = 75472.

Single transaction. UPDATE counts:

Group Rows
column strategy + 20 names with code 20
column law_catalog → law_code 1
column measurement_registry → measurement_id 1
column table_registry → table_id 1
column pivot_results → pivot_code 1
column workflows → process_code 1
legacy_id_single_colon (3 names) 3
synthetic_id information_unit 1
subordinate unit_version 1
disabled excluded role + NULL/unclassified 60
disabled views/birth_registry sweep 3
NULL→unclassified strategy 73
NULL→unclassified source 73

Post-seed distribution (must equal expected exactly):

birth_code_strategy count
column 25
disabled 63
legacy_id_single_colon 3
subordinate 1
synthetic_id 1
unclassified 73
Total 166

Other gates:

  • birth_code_strategy IS NULL0
  • birth_identity_source IS NULL0
  • fn_birth_registry_auto md5 = 1f729b3571a74963089bb3ef388217f3
  • trg_birth_% trigger count = 30 ✓ (unchanged)
  • B4.after_birth_count = 75472 (no drift inside txn)

COMMIT succeeded.


6. Bước 5 — PG enforcement

B5.before_birth_count = 75472.

Single transaction:

  1. ALTER COLUMN birth_code_strategy SET DEFAULT 'unclassified'
  2. ALTER COLUMN birth_identity_source SET DEFAULT 'unclassified'
  3. ALTER COLUMN birth_code_strategy SET NOT NULL
  4. ALTER COLUMN birth_identity_source SET NOT NULL
  5. ADD CONSTRAINT collection_registry_birth_code_strategy_check CHECK (...)
  6. ADD CONSTRAINT collection_registry_birth_identity_source_check CHECK (...)

Verify:

collection_registry_birth_code_strategy_check
  CHECK (birth_code_strategy = ANY ARRAY['column','synthetic_id',
    'legacy_id_single_colon','subordinate','disabled','unclassified'])

collection_registry_birth_identity_source_check
  CHECK (birth_identity_source = ANY ARRAY['inferred_from_existing_trigger',
    'manual','migration_seed','system_default','unclassified'])

Column states post-commit:

Column Nullable Default
birth_code_strategy NO 'unclassified'::varchar
birth_code_column YES NULL
birth_identity_source NO 'unclassified'::varchar
  • fn_birth_registry_auto md5 = 1f729b3571a74963089bb3ef388217f3
  • B5.after_birth_count = 75472 ✓ (no drift)

COMMIT succeeded.


7. Final invariants

Invariant Value Status
fn_birth_registry_auto md5 1f729b3571a74963089bb3ef388217f3 UNCHANGED through B1→B3d→B4→B5
trg_birth_% triggers 30 UNCHANGED
collection_registry rows 166 UNCHANGED
birth_registry live drift 75469 → 75472 (B1 → B5) live operational drift only (+3); anti-hardcode acknowledged
3 new fields birth_code_strategy, birth_code_column, birth_identity_source CREATED in PG + Directus
2 new CHECK constraints strategy + source enums INSTALLED
NOT NULL + DEFAULT strategy + source INSTALLED

8. Anomalies / notes

  • First seed-transaction attempt failed at the verify SELECT ('B4.dist:' || s || '=' || count(*) triggered Postgres aggregate functions are not allowed in GROUP BY because GROUP BY 1 referenced the composite expression including count). ON_ERROR_STOP=1 triggered ROLLBACK; pre-state preserved (verified: NULL=166). Verify SELECT was rewritten to use a subquery; second transaction COMMITted clean. No drift, no partial state.
  • dot-schema-apply is a bash wrapper to Directus REST /fields/{collection} POST; created Directus + PG columns atomically via Directus schema engine.
  • Sortable/filterable boolean meta fields are NOT part of this Directus 11.x version's field-meta schema for collection_registry/collection_name — spec deliberately omitted them per "include exactly the boolean meta fields detected" rule.

9. Out of scope (explicitly NOT performed)

Per 18b-P1 rev 6 boundary:

  • ✗ DOT-119 execution / script rewrite
  • fn_birth_registry_auto edit
  • ✗ IU trigger install / IU rows
  • ✗ Pack 2B steps

10. Verdict

P1 PASS. All gates green; both transactions COMMITted; fn_hash invariant preserved; trigger count preserved; constraint + default + NOT-NULL installed; Directus + PG fields registered. Ready for next phase per 18b umbrella.


P1 report | 2026-05-05 | Opus 4.7 (1M ctx) | HARD STOP after this upload.