KB-6602

dot-iu-cutter v0.2 — P0-2 Manifest DDL Draft (2026-05-16)

12 min read Revision 1
dot-iu-cutterdieu44v0.2p0-2ddl-authoringddl-draftnot-executedready-for-gpt-review

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 DEFAULT clause (rationale §4), no alias_ref column, no edge tables, no INSERT — tables are created empty.
  • Single transaction (BEGIN … COMMIT); all-or-nothing.
  • Rollback = DROP the 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 DEFAULT only takes effect on INSERT, which first occurs in P1. A default in P0-2 is therefore inert and adds nothing.
  • Omitting DEFAULT keeps 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_alias there (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 is target_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_governance precedent 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 TABLE inside 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 EXISTS skip.
  • The single BEGIN … COMMIT already 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.

Back to Knowledge Hub knowledge/dev/laws/dieu44-trien-khai/v0.2-ddl-authoring/dot-iu-cutter-v0.2-p0-2-ddl-draft-2026-05-16.sql.md