KB-4F84
dot-iu-cutter v0.2 — Phase α canonical_address Schema Design (2026-05-15)
13 min read Revision 1
dieu44-trien-khaidot-iu-cutterv0.2phase-alphaschema-designauthorityformat-versionno-ddl2026-05-15
dot-iu-cutter v0.2 — Phase α canonical_address Schema Design
document_path: knowledge/dev/laws/dieu44-trien-khai/v0.2-design/dot-iu-cutter-v0.2-phase-alpha-canonical-address-schema-design-2026-05-15.md
revision: r1
date: 2026-05-15
author: Agent (Claude Code CLI, Opus 4.7 1M)
phase: v0.2 — Phase α (LOGICAL DESIGN ONLY; no DDL written here)
no_ddl_written: TRUE
no_mutation: TRUE
§1 — Scope of This Document
Logical schema design for the Phase α additive columns and the alias support path on:
public.tac_logical_unit(the SSOT host table)sandbox_tac.logical_unit(mirror, per BR-7 Option II)- alias table support reference (full alias design lives in the companion
…-alias-design-2026-05-15.md)
No CREATE / ALTER / DROP statements appear in this document. Only field-level semantics, nullability/default phasing, backfill semantics, and compatibility statements.
§2 — Existing SSOT Posture (preserved unchanged)
public.tac_logical_unit.canonical_address:
type: text
nullable: NO
unique: UNIQUE (DB-level, via tac_logical_unit_canonical_address_key)
default: none
index: UNIQUE btree
row_count: 86 (as of 2026-05-15 discovery)
modified_in_phase_α: NO
what_phase_α_NEVER_does_to_this_column:
- no ALTER TYPE
- no ALTER NULL semantics
- no DROP constraint
- no RENAME
- no data write (no UPDATE)
§3 — public.tac_logical_unit.authority (new column, Phase α)
3.1 Field semantics
field_name: authority
purpose: represents the row's SOURCE AUTHORITY CLASS per Đ0-G birth-gate distinction
type: text
character_encoding: UTF-8 (PG default); content is ASCII-only by convention
case_sensitivity: case-sensitive; canonical values are lower-case ('enacted', 'draft', 'runtime')
allowed_values: { 'enacted', 'draft', 'runtime' } ratified at BR-4 closure
enforcement_in_phase_α: APPLICATION-LAYER only (no PG CHECK constraint; no FK)
enforcement_in_phase_β: PG-level CHECK / FK to a Đ24 vocabulary table — out of Phase α scope
relationship_to_lifecycle: authority and lifecycle_status are SEMANTICALLY DISTINCT (BR-4 §2.2 interpretation note)
relationship_to_runtime: 'runtime' authority does NOT apply to tac_logical_unit rows (reserved for runtime artifacts that live in information_unit and downstream tables — out of Phase α scope)
3.2 Nullability and default phasing
phase_α:
nullable: YES
default: 'draft' (applied at column-add time; also applied to any new row that does NOT explicitly set authority)
rationale: BR-4 closure §4 — promotion to NOT NULL waits for Phase β lifecycle-transition write hook
phase_β:
nullable: NO (NOT NULL)
default: 'draft' (retained)
add_check_constraint: optional Đ24-vocabulary FK in Phase γ
trigger: on lifecycle_status transition to 'active' OR 'retired', update authority via mapping; on no-change, leave alone
3.3 Backfill semantics (Phase α)
target_rows: 86 existing rows in public.tac_logical_unit
backfill_rule: BR-4 Candidate B
backfill_expression:
UPDATE public.tac_logical_unit
SET authority = CASE lifecycle_status
WHEN 'draft_only' THEN 'draft'
WHEN 'active' THEN 'enacted'
WHEN 'retired' THEN 'enacted'
END
WHERE authority IS NULL;
expected_outcome_on_current_86_rows: ALL 86 → 'draft' (because 100% have lifecycle_status='draft_only')
post_backfill_state: authority is fully populated on production tac_logical_unit; column remains nullable (intentional)
NOTE: the backfill expression above is shown for design clarity. The executable form belongs to a future Phase α DDL/migration session under explicit prompt. No execution here.
3.4 Default behavior for new writes (post-Phase α)
on_INSERT_without_explicit_authority: column gets DEFAULT 'draft' (most-conservative non-enacted floor)
on_INSERT_with_explicit_authority: value used verbatim; no validation in Phase α (application-layer responsibility)
on_UPDATE_setting_authority_to_NULL: permitted in Phase α (nullable); Phase β tightens this
3.5 Compatibility with existing readers/writers (BR-3)
Nuxt_SSR_chunk: READS canonical_address only; does NOT read authority; safe
Nuxt_client_bundle: reads explicit GraphQL field list; new column INVISIBLE without app update; safe
PG_functions_referencing_canonical_address (21): none of them reference authority by name; verified via BR-3 §4 inventory; safe
PG_triggers (11): none of them reference authority by name; safe
view_layer: 0 views reference canonical_address; safe
constraint_check_btrim_not_empty: applies to canonical_address ONLY on 3 sister tables; does not interact with authority; safe
identity_profile_jsonb: no authority-like key in jsonb (BR-2); no double-storage; safe
§4 — public.tac_logical_unit.canonical_address_format_version (new column, Phase α)
4.1 Field semantics
field_name: canonical_address_format_version
purpose: per-row version stamp for the canonical_address syntax format (forward-compat)
type: text
allowed_values_in_phase_α: { 'canonical-address-v1' } ratified at BR-5 closure
short_form_allowed: 'cav1' (BR-5 closure §2; for jsonb/index payloads where size matters; canonical column uses long form)
case_sensitivity: case-sensitive; canonical form is lower-case
enforcement_in_phase_α: none (no CHECK or FK)
enforcement_in_phase_γ: possible FK to a Đ24 vocabulary table; out of Phase α scope
4.2 Nullability and default phasing
phase_α:
nullable: NO (NOT NULL)
default: 'canonical-address-v1'
rationale: every row has a well-defined format; DEFAULT ensures column-add-time backfill is automatic
phase_β_or_γ:
nullable: unchanged (remains NOT NULL)
default: may evolve when v1.1 / v2 grammars land; per-row stamp enables lazy migration
4.3 Backfill semantics
backfill_method: AUTOMATIC at column-add time via DEFAULT
no_separate_UPDATE_needed: TRUE
expected_outcome_on_current_86_rows: all 86 → 'canonical-address-v1'
4.4 Compatibility
Nuxt: INVISIBLE (new column not in explicit field selection)
PG functions/triggers: none reference format_version by name
identity_profile_jsonb: no format_version-like key (BR-2); safe
§5 — cutter_governance.canonical_address_alias (new table, Phase α; support path)
note: full design lives in the companion alias-design doc
phase_α_summary:
- placement: cutter_governance schema (recommended; alternative options weighed in alias-design doc)
- rows_at_creation: 0
- phase_α_writers: NONE
- phase_α_readers: NONE
- PK: alias_id uuid
- logical_FK: target_unit_id uuid referencing public.tac_logical_unit.id (NO PG FK in Phase α; soft reference)
- alias_kind enum: { 'previous_canonical', 'rename', 'redirect', 'external_reference' } (application-layer)
- timestamps: valid_from, valid_until
- audit: created_by, rationale, scenario_ref
- no UNIQUE on alias_text (multiple aliases per address are expected)
See …-alias-design-2026-05-15.md for full rationale.
§6 — sandbox_tac.logical_unit mirror (Phase α)
6.1 Mirrored columns
sandbox_tac.logical_unit.authority:
type: text
nullable: YES
default: 'draft'
backfill_in_phase_α: NONE (76 rows have authority=NULL after column-add; backfill deferred to Phase β)
rationale: sandbox semantics may diverge from production; safer to defer backfill
sandbox_tac.logical_unit.canonical_address_format_version:
type: text
nullable: NO
default: 'canonical-address-v1'
backfill_in_phase_α: AUTOMATIC via DEFAULT (76 rows → 'canonical-address-v1')
6.2 sandbox alias table
decision: OMIT in Phase α
rationale: alias governance is a public-data concern; sandbox is a static test fixture; mirror would duplicate without operational benefit
revisit_if: sandbox usage pattern expands to exercise the alias pathway
§7 — Schema-Wide Compatibility Statements
public.tac_logical_unit.canonical_address (SSOT):
unchanged in Phase α (preserved verbatim)
preserved unique constraint
preserved NOT NULL
preserved index
sister tables (information_unit, unit_edit_draft, event_outbox, iu_notification_event, event_pending, birth_registry):
NOT touched in Phase α
canonical_address columns unchanged
constraints, indexes, triggers preserved
cutter_governance.* (v0.1 live tables):
NOT touched in Phase α
5 v0.1 tables (decision_backlog_entry, dot_pair_signature, cut_change_set, cut_change_set_affected_row, verify_result) remain empty and unchanged
cutter_governance.canonical_address_alias is the only NEW addition to this schema
PG functions and triggers:
NOT modified in Phase α
Phase β will introduce a lifecycle-transition trigger on tac_logical_unit OR an application-layer write hook — NOT in this phase
Directus collections:
NOT directly modified by Phase α (PG-direct migration)
Directus may auto-discover the new columns on its next schema reload; this is operationally normal
if Directus collection metadata needs explicit registration, a separate flow operation can be authored later (out of Phase α)
application_code (Nuxt, dot, agent-data):
NOT modified in Phase α
Nuxt new-column adoption (reading authority / format_version) is a future Phase β/γ task
§8 — Field Inventory Summary
| # | Schema.table | Column | Type | NULL | Default | Phase α action |
|---|---|---|---|---|---|---|
| 1 | public.tac_logical_unit |
authority |
text | YES | 'draft' |
ADD COLUMN + backfill (Candidate B) |
| 2 | public.tac_logical_unit |
canonical_address_format_version |
text | NO | 'canonical-address-v1' |
ADD COLUMN (DEFAULT-backfilled automatically) |
| 3 | sandbox_tac.logical_unit |
authority |
text | YES | 'draft' |
ADD COLUMN (no backfill) |
| 4 | sandbox_tac.logical_unit |
canonical_address_format_version |
text | NO | 'canonical-address-v1' |
ADD COLUMN (DEFAULT-backfilled automatically) |
| 5 | cutter_governance.canonical_address_alias |
(new table) | — | — | — | CREATE TABLE (0 rows; full design in alias doc) |
§9 — Open Items (deferred to companion docs)
- alias table FULL field set + placement rationale → alias-design doc
- dry-run scenarios + rollback test → dry-run plan doc
- risk-class enumeration + mitigations → risk review plan doc
- Phase α design report consolidation → design report doc
§10 — Hard Boundaries
no_DDL_written: TRUE
no_SQL_executed: TRUE
no_ALTER_TABLE_executed: TRUE
no_INSERT_UPDATE_DELETE: TRUE
no_migration: TRUE
no_change_to_tac_logical_unit (current production state): TRUE
no_change_to_sandbox_tac (current production state): TRUE
no_change_to_cutter_governance (current production state): TRUE
no_change_to_sister_tables: TRUE
no_design_advanced_beyond_schema_logical_layer: TRUE
no_phase_α_DDL_authoring_started_(belongs_to_future_session): TRUE
no_dry_run_started: TRUE
no_production_migration_allowed: TRUE
output_form: phase_alpha_schema_design_logical_only
§11 — Cross-References
phase_α_design_master: knowledge/dev/laws/dieu44-trien-khai/v0.2-design/dot-iu-cutter-v0.2-phase-alpha-design-master-2026-05-15.md
alias_design: knowledge/dev/laws/dieu44-trien-khai/v0.2-design/dot-iu-cutter-v0.2-phase-alpha-canonical-address-alias-design-2026-05-15.md
dry_run_plan: knowledge/dev/laws/dieu44-trien-khai/v0.2-design/dot-iu-cutter-v0.2-phase-alpha-dry-run-plan-2026-05-15.md
risk_review_plan: knowledge/dev/laws/dieu44-trien-khai/v0.2-design/dot-iu-cutter-v0.2-phase-alpha-risk-review-plan-2026-05-15.md
design_report: knowledge/dev/laws/dieu44-trien-khai/v0.2-design/dot-iu-cutter-v0.2-phase-alpha-design-report-2026-05-15.md
br_4_closure: knowledge/dev/laws/dieu44-trien-khai/v0.2-planning/dot-iu-cutter-v0.2-br-4-authority-backfill-rule-closure-2026-05-15.md
br_5_closure: knowledge/dev/laws/dieu44-trien-khai/v0.2-planning/dot-iu-cutter-v0.2-br-5-canonical-address-v1-ratification-closure-2026-05-15.md
br_2_3_7_consolidated: knowledge/dev/laws/dieu44-trien-khai/v0.2-planning/dot-iu-cutter-v0.2-br-2-3-7-discovery-report-2026-05-15.md
End of Phase α schema design.