KB-30D0
dot-iu-cutter v0.5 WS-Q5 Registry Substrate — Verification Plan (catalog-level; authoring only)
10 min read Revision 1
dot-iu-cutterv0.5ws-q5registry-substrateverification-plancatalog-levelauthoring-onlydieu442026-05-18
dot-iu-cutter v0.5 WS-Q5 Registry Substrate — Verification Plan
Phase:
v0_5_WS_Q5_registry_substrate_DDL_authoring· Nature:executable_DDL_authoring_only__no_execution· Date: 2026-05-18 Verifies:…-WS-Q5-registry-substrate-DDL-draft-2026-05-18.sql.md⚠️ GATING BANNER
phase: executable_DDL_authoring_only verification_executed: false # this is the PLAN of the checks, NOT a run checks_run: 0 verification_method: catalog-level ONLY (information_schema / pg_catalog) rendered_string_equality: FORBIDDEN (carry C-07 / v0.3 false-negative lesson) execution_authorized: false self_advance: PROHIBITEDEvery check below is a catalog-level structural assertion (system catalogs /
information_schema), neverpg_get_*def()rendered-string equality. Outcome vocabulary:PASS | FAIL(detail). Nothing is run here (QG4).
1. Pre-apply baseline (capture before any future apply)
B-1 cutter_governance has exactly its existing 12 tables; the 12 WS-Q5 names
are ABSENT (pg_class/pg_namespace). [negative precondition]
B-2 record production sysid + existing PK/FK counts (12 PK / 19 FK) for
before==after comparison.
B-3 no role/privilege baseline change expected (no GRANT authored).
2. Table existence (catalog)
TV-1 exactly 12 NEW tables present in schema cutter_governance:
matcher_config_registry, address_template_registry, grammar_profile,
grammar_profile_level, grammar_profile_status_marker,
source_family_registry, source_document_registry,
source_document_version_registry, entity_kind_registry,
entity_reference_registry, authority_override, metadata_key_registry
(pg_class JOIN pg_namespace WHERE nspname='cutter_governance').
TV-2 each new table relkind='r' (ordinary table), not view/matview/partition.
TV-3 cutter_governance total table count = previous 12 + 12 = 24 (no more, no less).
3. Columns / types / nullability (catalog — information_schema.columns)
CV-1 each table's column SET matches the DDL draft exactly (no extra/missing
column) — compare column NAME set per table from information_schema.columns.
CV-2 data_type per column matches intent: text -> 'text', timestamptz ->
'timestamp with time zone', jsonb -> 'jsonb', boolean -> 'boolean',
integer -> 'integer' (information_schema.columns.data_type; NOT a DDL
string compare).
CV-3 is_nullable correctness (spot-set, catalog-driven):
NOT NULL: all PK cols; matcher_config_registry.matcher_definition;
*_registry.registered_by/registered_at; lifecycle cols;
authority_override.scope/authority_role/set_by/set_at;
metadata_key_registry.key_namespace/key_type/cardinality_policy/
mutability_policy/index_policy/owner_role/created_by/created_at;
address_template_registry.{template_pattern,docprefix_separator,
level_separator,encodes_status}.
NULLABLE (DEFERRED/optional): entity_reference_registry.
permission_policy_ref, snapshot_policy_ref; authority_override.
iu_id, span_ref, reason, provenance;
source_document_version_registry.{source_format,authoritative_version,
version_status,provenance}; display_*/description cols.
CV-4 NO column has a DEFAULT (information_schema.columns.column_default IS NULL
for all new columns) — additive-discipline assertion.
4. Constraints — PK / FK / UNIQUE (catalog — pg_constraint)
KC-1 exactly 12 PRIMARY KEY constraints, deterministic names pk_<table>,
each on the intended column(s):
pk_grammar_profile_level (grammar_profile_ref, level_seq),
pk_grammar_profile_status_marker (grammar_profile_ref, marker),
others single-column as drafted.
KC-2 exactly 8 FOREIGN KEY constraints, exact names + exact referenced
table/column, compared via pg_constraint (conrelid/confrelid/conkey/
confkey resolved to names — STRUCTURAL, not pg_get_constraintdef text):
fk_grammar_profile_address_template_ref -> address_template_registry
fk_grammar_profile_level_profile -> grammar_profile
fk_grammar_profile_level_matcher -> matcher_config_registry
fk_gpsm_profile -> grammar_profile
fk_source_family_registry_grammar_profile -> grammar_profile
fk_source_document_registry_family -> source_family_registry
fk_sdvr_source_document -> source_document_registry
fk_entity_reference_registry_kind -> entity_kind_registry
KC-3 every FK is schema-qualified to cutter_governance on BOTH sides
(confrelid namespace = cutter_governance) — explicitly assert the
schema, since the C-07 false-negative arose from an unqualified compare.
KC-4 exactly 4 UNIQUE constraints, exact names + exact column set:
uq_grammar_profile_level_name (grammar_profile_ref, level)
uq_source_document_registry_docprefix (address_docprefix)
uq_sdvr_doc_checksum (source_document_ref, content_checksum)
uq_entity_reference_registry_natural (entity_kind, source_system, natural_key)
KC-5 FK confdeltype/confupdtype = 'a' (NO ACTION) for all 8 — i.e. NO
CASCADE/SET NULL anywhere (negative check).
KC-6 ZERO CHECK constraints and ZERO trigger objects on the 12 new tables
(pg_constraint contype='c' count = 0; pg_trigger count = 0) — confirms
the documented "no CHECK/trigger" authoring decision.
5. Deterministic naming
NM-1 all constraint names match the deterministic patterns
pk_<table> / fk_<table>_<ref> / uq_<table>_<cols>; no system-generated
constraint names ($-suffixed) present (pg_constraint.conname scan).
NM-2 all object names lowercase snake_case; no quoted mixed-case identifiers.
6. Canonical-address separator policy (BR-A1 LOCKED)
AC-1 address_template_registry has columns docprefix_separator,
level_separator, encodes_status with the nullability of CV-3 — the
structural carrier of BR-A1 exists.
AC-2 POLICY (value-level, checked at SEED command-review, NOT here): every
seeded address_template row MUST have docprefix_separator='/',
level_separator='-', encodes_status=false. Flagged: enforced via
governed seed + verification, NOT via CHECK (BATCH-1 precedent) — this
is a declared design decision, see design-delta.
AC-3 no canonical address is computed/stored by this DDL (registries only) —
negative assertion: no address data path created here.
7. No-hardcode policy
NH-1 matcher rule lives in matcher_config_registry.matcher_definition (jsonb
column exists) — i.e. the schema FORCES matcher-as-data, no inline-regex
column shape that would invite literals.
NH-2 vocab-like keys (source_family, entity_kind, metadata_key, matcher_ref,
grammar_profile_ref, address_template_ref) are PRIMARY KEYS of their own
registry tables -> resolvable only via registry, never a code literal
(structural anti-hardcode assertion).
NH-3 no enum type created (pg_type typtype='e' count for new objects = 0);
controlled vocabularies are text + documented values (BATCH-1 pattern),
not PG enums -> additive + evolvable without enum migration.
8. No unintended objects / additive-only
AO-1 diff(cutter_governance objects, baseline B-1) = EXACTLY the 12 tables +
their 12 PK + 8 FK + 4 UNIQUE constraints — nothing else
(no view, sequence, function, type, index beyond constraint-backed).
AO-2 the existing 12 tables: column sets, PKs, FKs UNCHANGED vs B-2
(no ALTER side-effect). [negative check]
AO-3 no DROP/ALTER on any pre-existing object occurred (additive-only).
AO-4 production sysid B-2 == post (registry apply does not touch identity).
AO-5 zero rows in all 12 new tables immediately post-apply (no DML seed in
this package) — registries are empty until a separate seed cycle.
9. Negative checks (must FAIL the apply if true)
NG-1 any of the 12 names already existed pre-apply with a DIFFERENT shape
-> FAIL (plain CREATE TABLE aborts; conflict surfaced, not hidden).
NG-2 any FK resolves to a table OUTSIDE cutter_governance -> FAIL
(no cross-schema FK permitted — v0.2 doctrine).
NG-3 any CASCADE / SET NULL / SET DEFAULT referential action present -> FAIL.
NG-4 any CHECK, trigger, DEFAULT, sequence, or enum type created -> FAIL
(out of authored scope).
NG-5 any GRANT / role / ownership change detected -> FAIL (privilege model is
a separate sovereign cycle; none authored).
NG-6 any row present in a new table post-apply -> FAIL (no seed authorized).
NG-7 any ALTER to an existing cutter_governance table -> FAIL.
10. Statements
- QG4: every check is catalog-level (pg_catalog / information_schema), zero
pg_get_*def()rendered-string equality; negative checks included (§9). QG2: nothing executed — this is the plan only. - KC-3 explicitly hard-codes the schema-qualified comparison to prevent recurrence of the C-07 / v0.3 false-negative.
- No repo/VPS access in this session.
code_changed: false,commit_made: false. - Self-advance PROHIBITED — doc 3 of 5; STOP after package complete → route GPT/User.
Companion files: DDL-draft, rollback-draft, design-delta-and-open-decisions, DDL-authoring-report.