dot-iu-cutter v0.2 — P0-2 Manifest DDL Draft (2026-05-16)
dot-iu-cutter v0.2 — P0-2 Manifest DDL Draft
document_path: knowledge/dev/laws/dieu44-trien-khai/v0.2-ddl-authoring/dot-iu-cutter-v0.2-p0-2-ddl-draft-2026-05-16.sql.md
revision: r1
date: 2026-05-16
author: Agent (Claude Code CLI, Opus 4.7 1M)
sovereign: User / anh Huyền
verifier: GPT (P0-2 DDL-authoring review — PENDING)
phase: v0.2 — P0-2 DDL AUTHORING ONLY
ddl_authored: true
ddl_executed: false
mutation_performed: false
dry_run_started: false
production_migration_allowed: false
⛔ DO NOT EXECUTE WITHOUT EXPLICIT GPT/USER PROMPT
This file is a DDL DRAFT for review only. It must NOT be run through
psql, a migration tool, a dry-run environment, or production. No idempotency wrapper, no automation hook, no copy-paste-to-shell. DDL execution is gated on: GPT review PASS of this package + explicit User execution prompt + a separate dry-run authorization first.
§1 — Scope & Posture
- Two new empty tables in schema
cutter_governance(placement rationale §6). - Exactly one PostgreSQL foreign key:
manifest_unit_block.envelope_id → manifest_envelope.envelope_id. - No cross-schema FK, no CHECK constraint, no trigger, no
DEFAULTclause (rationale §4), noalias_refcolumn, no edge tables, noINSERT— tables are created empty. - Single transaction (
BEGIN … COMMIT); all-or-nothing. - Rollback =
DROPthe two empty tables (see rollback draft). - Split/merge execution remains P1; this is the proposal/grouping layer only.
§2 — DDL Draft (NOT executed)
-- =====================================================================
-- dot-iu-cutter v0.2 — P0-2 MANIFEST DDL DRAFT
-- ⛔ DO NOT EXECUTE WITHOUT EXPLICIT GPT/USER PROMPT
-- =====================================================================
-- status : DDL DRAFT ONLY — authored for review
-- ddl_executed : false
-- target schema (recommended): cutter_governance
-- transaction : single BEGIN … COMMIT (atomic, all-or-nothing)
-- constraints policy : no CHECK / no trigger / no DEFAULT / no cross-schema FK
-- only FK : manifest_unit_block.envelope_id
-- -> manifest_envelope.envelope_id
-- data : tables created EMPTY (no INSERT)
-- rollback : DROP empty tables (see rollback draft)
-- GOV basis : GOV-1 O3-hybrid, GOV-2 O1-demote-to-draft,
-- GOV-3 O1 event-backed (no alias_ref column)
-- =====================================================================
BEGIN;
-- ---------------------------------------------------------------------
-- Table 1: manifest_envelope (proposal header; one row = one topology
-- proposal: first_cut | split | merge). Created empty; zero writers in v0.2.
-- ---------------------------------------------------------------------
CREATE TABLE cutter_governance.manifest_envelope (
envelope_id uuid NOT NULL,
operation_kind text NOT NULL, -- {first_cut,split,merge} app-layer enum (no PG CHECK)
status text NOT NULL, -- draft|under_review|accepted|rejected|withdrawn|enacted|superseded app-layer enum (no PG CHECK)
source_doc_ref text NOT NULL, -- source document / parent-unit identifier
escalation_ref uuid NULL, -- SOFT -> cutter_governance.decision_backlog_entry (NO PG FK; INV-5)
cut_change_set_ref uuid NULL, -- SOFT -> cutter_governance.cut_change_set (NO PG FK; INV-6)
created_by text NOT NULL, -- owner provenance
created_at timestamptz NOT NULL, -- no DEFAULT in P0-2 (§4); populated by the P1 writer
reviewer text NULL, -- reviewer provenance (Phase β)
reviewed_at timestamptz NULL, -- review conclusion (Phase β)
rationale text NULL, -- free-text proposal justification
superseded_by_envelope_id uuid NULL, -- SOFT self-reference (NO PG FK)
CONSTRAINT manifest_envelope_pkey
PRIMARY KEY (envelope_id)
);
-- ---------------------------------------------------------------------
-- Table 2: manifest_unit_block (one constituent unit of a proposal:
-- origin = consumed pre-image, result = produced post-image).
-- Composite identity (envelope_id, unit_local_id). Created empty.
-- ---------------------------------------------------------------------
CREATE TABLE cutter_governance.manifest_unit_block (
envelope_id uuid NOT NULL, -- PK part 1; in-schema FK -> manifest_envelope
unit_local_id text NOT NULL, -- PK part 2; unique WITHIN the envelope only
block_role text NOT NULL, -- {origin,result} app-layer enum (no PG CHECK)
source_span jsonb NOT NULL, -- MANDATORY; concrete form = jsonb (DDL-authoring decision, §5)
render_order numeric NOT NULL, -- carried ordering; recompute algorithm = P1
target_unit_id uuid NULL, -- SOFT -> public.tac_logical_unit.id (NO cross-schema FK)
proposed_canonical_address text NULL, -- proposal-only; manifest NEVER writes SSOT (INV-1; GOV-1 O3-hybrid semantics = P1)
proposed_authority text NULL, -- proposal-only; INV-2; GOV-2 O1 (results born draft) enforced app-layer/P1
payload_summary jsonb NULL, -- X-3 content/intent summary
candidate_edges jsonb NULL, -- edge-redistribution INTENT only; NO edge tables; executor = P1
report_summary jsonb NULL, -- X-3 segmentation/health-report context
decision_backlog_ref uuid NULL, -- SOFT -> cutter_governance.decision_backlog_entry (NO PG FK)
created_at timestamptz NOT NULL, -- no DEFAULT in P0-2 (§4); populated by the P1 writer
CONSTRAINT manifest_unit_block_pkey
PRIMARY KEY (envelope_id, unit_local_id),
CONSTRAINT manifest_unit_block_envelope_fk
FOREIGN KEY (envelope_id)
REFERENCES cutter_governance.manifest_envelope (envelope_id)
-- no ON DELETE / ON UPDATE clause: PostgreSQL default NO ACTION.
-- NO ACTION adds no cascade machinery; deliberately not CASCADE.
);
COMMIT;
-- =====================================================================
-- END OF DDL DRAFT — NOTHING ABOVE HAS BEEN EXECUTED.
-- No INSERT, no index beyond the two implicit PK indexes,
-- no GOV-3 alias_ref column, no edge table, no second FK.
-- =====================================================================
§3 — GOV-Decision Encoding Map
| Ratified decision | How the DDL honors it |
|---|---|
| GOV-1 O3-hybrid (split→extend tail, merge→new sequence) | proposed_canonical_address text NULL proposal-only column exists; coining rule is P1 logic, not a PG constraint — column shape is now safe to freeze because the rule is ratified. No CHECK encodes the grammar (app-layer). |
GOV-2 O1 demote-to-draft (results born draft) |
proposed_authority text NULL is a snapshot field only; "results start draft" is enforced by the P1 writer / app layer. No PG DEFAULT 'draft' (consistent with no-DEFAULT policy §4 and empty-table posture). |
| GOV-3 O1 event-backed (no coupling) | No alias_ref column on either table. Alias emission derived at P1 from operation_kind + block_role + target_unit_id + proposed_canonical_address. No manifest↔canonical_address_alias FK or column. |
§4 — DEFAULT Posture (no DEFAULT — explained)
The logical design notes annotated envelope_id with gen_random_uuid()
"at DDL time" and created_at with now() "at DDL time". The binding
constraints take precedence: GPT review §3 pg_CHECK_trigger_DEFAULT: avoid_in_P0_2, and the envelope/unit-block designs both assert
no_PG_CHECK_trigger_DEFAULT_data_in_P0_2: TRUE.
Reconciliation (the "prefer none if consistent" path requested):
- Tables are created empty and have zero writers in v0.2 — a
DEFAULTonly takes effect onINSERT, which first occurs in P1. A default in P0-2 is therefore inert and adds nothing. - Omitting
DEFAULTkeeps P0-2 strictly additive/structural and avoids pinning value-generation policy (gen_random_uuid()vs app-supplied uuid;now()vs proposal-authored timestamp) before the P1 write pathway is designed. - This is recorded as a reconciled deviation from the design doc annotations, not from the binding constraints — see the authoring report §"Deviations". Defaults (if wanted at all) are a P1 writer-layer decision.
Net: no DEFAULT clause anywhere in P0-2. Consistent.
§5 — source_span Concrete Form
Design left the concrete representation as an explicit DDL-authoring
decision (jsonb {start,end} vs PG range). Chosen: jsonb NOT NULL.
Rationale: a PG range/exclusion would invite a CHECK or exclusion
constraint (forbidden in P0-2); jsonb keeps span coverage/partition
validation as the intended application-layer / P1 dry-run concern while
still making the column mandatory so BR-6 span algebra is representable.
unit_local_id concrete type chosen text (stable labels like o1,
r1); render_order chosen numeric.
§6 — Schema Placement Recommendation
Recommendation: cutter_governance (no clear reason to deviate).
- v0.1 placed all 5 cutter tables there; Phase α added
canonical_address_aliasthere (schema now holds 6 tables). The manifest is the same governance family. - Every soft ref except one resolves within
cutter_governance(decision_backlog_entry,cut_change_set); the only cross-schema soft ref istarget_unit_id → public.tac_logical_unit.id. Co-locating the manifest with its referents minimizes the cross-schema surface. - Rollback symmetry: the v0.1 / Phase α
cutter_governanceprecedent is "drop empty governance objects" — identical posture here.
§7 — Idempotency Posture
No IF NOT EXISTS / no idempotency wrapper. Explained — this is
deliberate, not an omission.
- Plain
CREATE TABLEinside a single transaction is fail-fast: if an object of that name already exists, the migration aborts and rolls back cleanly, surfacing an unexpected-state signal instead of silently skipping and masking a shape mismatch — the correct posture for a gated governance migration. - Re-runnability is provided explicitly by the rollback draft (drop the
two empty tables) followed by re-applying this draft — a controlled,
reviewed cycle, not an implicit
IF NOT EXISTSskip. - The single
BEGIN … COMMITalready guarantees atomic all-or-nothing, so a partial-apply re-run hazard does not exist.
§8 — Hard Boundaries
ddl_authored: TRUE (this file)
ddl_executed: FALSE
no_psql_run: TRUE
no_mutation: TRUE
no_dry_run_env_created: TRUE
no_dry_run_run: TRUE
no_production_migration: TRUE
no_INSERT: TRUE
no_CHECK_no_trigger_no_DEFAULT: TRUE
no_cross_schema_FK: TRUE
no_alias_ref_column: TRUE
no_edge_tables: TRUE
single_in_schema_FK_only: TRUE (block.envelope_id -> envelope.envelope_id)
output_form: p0_2_ddl_draft
End of P0-2 DDL draft.