KB-630B rev 2
dot-iu-cutter v0.2 — P0-6 + P0-5 Remainder DDL Draft (r2, A-1 resolved) (2026-05-16)
15 min read Revision 2
dot-iu-cutterdieu44v0.2p0-6p0-5-remainderddl-authoringddl-draftr2a1-resolvednot-executedready-for-gpt-review
dot-iu-cutter v0.2 — P0-6 + P0-5 Remainder DDL Draft
document_path: knowledge/dev/laws/dieu44-trien-khai/v0.2-ddl-authoring/dot-iu-cutter-v0.2-p0-6-p0-5-remainder-ddl-draft-2026-05-16.sql.md
revision: r2
supersedes: r1 (2026-05-16) — r1 SUPERSEDED, DO NOT EXECUTE
date: 2026-05-16
author: Agent (Claude Code CLI, Opus 4.7 1M)
sovereign: User / anh Huyên
verifier: GPT (P0-6 + P0-5-remainder r2 DDL re-revision review — PENDING)
phase: v0.2 — P0-6 + P0-5-remainder DDL AUTHORING REVISION (r2)
a1_status: RESOLVED in r2 (live decision_backlog_entry PK = entry_id uuid)
ddl_authored: true
ddl_executed: false
mutation_performed: false
dry_run_started: false
dry_run_allowed: false (until GPT r2 review PASS)
production_migration_allowed: false
⛔ r1 SUPERSEDED — DO NOT EXECUTE r1. THIS IS r2.
r1 referenced a non-existent column
decision_backlog_entry.decision_idand was correctly HALTED at the A-1 dry-run gate. r1 must NOT be executed. This r2 applies the GPT-selected fix (rename child columns to theentry_idfamily). r2 is still a DDL DRAFT for review only — nopsql, no migration tool, no dry-run env, no production. Execution gated on: GPT r2 review PASS + explicit dry-run authorization + explicit User production prompt + separate session.
§1 — A-1 Resolution (root cause + fix)
root_cause: live cutter_governance.decision_backlog_entry PK = entry_id uuid;
it has NO decision_id column (lean 6-col table:
entry_id uuid, kind text, status text, payload jsonb,
emitted_at timestamptz, scenario_ref text).
observed: production read-only catalog (workflow_admin @ `postgres`/directus),
2026-05-16; SELECT-only, zero mutation. A-1 is now RESOLVED by
direct observation — no longer an unverified assumption.
gpt_selected_fix: rename child columns to the entry_id family for consistency.
r2_changes (ONLY these; all other ratified decisions unchanged):
decision_backlog_history: decision_id -> entry_id
decision_backlog_dependency: from_decision_id -> from_entry_id
decision_backlog_dependency: to_decision_id -> to_entry_id
all three FK targets: cutter_governance.decision_backlog_entry(entry_id)
forbidden_in_r2: keeping decision_id / from_decision_id / to_decision_id names
unchanged: review_decision (FKs target manifest_envelope/manifest_unit_block/
self — all confirmed correct in r1 dry-run preflight); escalation_ref stays
a SOFT uuid (no FK) so the name mismatch never affected it.
§2 — Scope & Posture (unchanged from r1 except the A-1 fix)
- Four new empty tables in schema
cutter_governance:review_decision(P0-6),decision_backlog_history,decision_backlog_dependency,decision_backlog_sweep_log(P0-5 remainder). - 7 in-schema PostgreSQL FKs (count unchanged; targets corrected):
review_decision.manifest_id → manifest_envelope.envelope_idreview_decision (manifest_id, manifest_unit_local_id) → manifest_unit_block (envelope_id, unit_local_id)— nullable compositereview_decision.prior_review_decision_id → review_decision.review_decision_id(self)review_decision.superseded_by_review_decision_id → review_decision.review_decision_id(self)decision_backlog_history.entry_id → decision_backlog_entry.entry_id(r2)decision_backlog_dependency.from_entry_id → decision_backlog_entry.entry_id(r2)decision_backlog_dependency.to_entry_id → decision_backlog_entry.entry_id(r2)
- No cross-schema FK, PG enum, lookup table, Đ24 lookup FK, trigger,
CHECK,
DEFAULT,INSERT/seed/backfill,IF NOT EXISTS. Enum-class fields =text+ documented allowed values (BATCH-1). - Single transaction (
BEGIN … COMMIT); rollback = DROP the four empty tables.
§3 — Live Parent PK Facts (confirmed, production read-only 2026-05-16)
cutter_governance.decision_backlog_entry : PRIMARY KEY (entry_id) ; entry_id uuid
cutter_governance.manifest_envelope : PRIMARY KEY (envelope_id) ; envelope_id uuid
cutter_governance.manifest_unit_block : PRIMARY KEY (envelope_id, unit_local_id) ; envelope_id uuid, unit_local_id text
nullable_composite_FK_semantics: MATCH SIMPLE (default) — review→unit_block
composite FK not enforced when manifest_unit_local_id IS NULL.
§4 — DDL Draft r2 (NOT executed)
-- =====================================================================
-- dot-iu-cutter v0.2 — P0-6 + P0-5 REMAINDER DDL DRAFT (r2; A-1 RESOLVED)
-- ⛔ r1 SUPERSEDED — DO NOT EXECUTE. DO NOT EXECUTE r2 WITHOUT EXPLICIT
-- GPT r2 PASS + dry-run authorization + User prompt + separate session.
-- =====================================================================
-- r2 change vs r1: child column renames to entry_id family +
-- FK targets -> decision_backlog_entry(entry_id)
-- target schema : cutter_governance
-- transaction : single BEGIN … COMMIT (atomic)
-- constraints policy : no CHECK / no trigger / no DEFAULT / no PG enum /
-- no lookup table / no Đ24 lookup FK / no cross-schema FK
-- in-schema FKs only : 7 (unchanged count)
-- data : 4 tables created EMPTY (no INSERT/seed/backfill)
-- enum-class fields : text + documented allowed values (BATCH-1)
-- =====================================================================
BEGIN;
-- ---------------------------------------------------------------------
-- P0-6 — Table cutter_governance.review_decision (#9) [UNCHANGED from r1]
-- ---------------------------------------------------------------------
CREATE TABLE cutter_governance.review_decision (
review_decision_id uuid NOT NULL,
governance_event_kind text NOT NULL, -- fixed 'review_decision' (Đ44 Step 3 umbrella; no CHECK)
manifest_id uuid NOT NULL, -- in-schema FK -> manifest_envelope.envelope_id (RD-1)
manifest_version text NOT NULL,
review_scope text NOT NULL, -- {envelope_level,unit_level,mixed} (no CHECK)
manifest_unit_local_id text NULL, -- composite-FK part2 -> manifest_unit_block.unit_local_id (RD-2); NULL=envelope-level
status text NOT NULL, -- {pending,in_review,pass,fail,needs_human,escalated,superseded}
verdict text NOT NULL, -- {PASS,FAIL,NEEDS_HUMAN} cutter-local v0.2 (RD-4)
findings jsonb NOT NULL, -- D2 §4.6 10-item; all-10-for-PASS = app rule v0.2 (RD-5)
reviewer_class text NOT NULL, -- {ai,human,council,dot_pair_verifier}
reviewer_identity jsonb NOT NULL, -- polymorphic; pseudonymous (G-5)
reviewer_independence_evidence jsonb NULL, -- app-layer enforcement v0.2 (RD-6; no trigger)
risk_class_assessment text NOT NULL, -- {low,standard,high}
escalation_ref uuid NULL, -- SOFT -> cutter_governance.decision_backlog_entry (NO PG FK)
cut_change_set_ref uuid NULL, -- SOFT -> cutter_governance.cut_change_set (NO PG FK; P0-3 cross-link)
prior_review_decision_id uuid NULL, -- in-schema self-FK (RD-3)
superseded_by_review_decision_id uuid NULL, -- in-schema self-FK (RD-3)
decision_at timestamptz NOT NULL,
decided_by text NOT NULL,
tool_revision text NULL,
review_duration_ms integer NULL, -- advisory only
cross_signed_by_dot_verifier boolean NOT NULL, -- app-layer enforcement v0.2 (no DEFAULT)
version text NOT NULL, -- record semver Đ38
created_at timestamptz NOT NULL, -- no DEFAULT (writer = P1)
updated_at timestamptz NOT NULL, -- no DEFAULT
CONSTRAINT review_decision_pkey
PRIMARY KEY (review_decision_id),
CONSTRAINT review_decision_manifest_fk
FOREIGN KEY (manifest_id)
REFERENCES cutter_governance.manifest_envelope (envelope_id),
CONSTRAINT review_decision_unit_block_fk
FOREIGN KEY (manifest_id, manifest_unit_local_id)
REFERENCES cutter_governance.manifest_unit_block (envelope_id, unit_local_id),
-- MATCH SIMPLE (default): not enforced when manifest_unit_local_id IS NULL
CONSTRAINT review_decision_prior_fk
FOREIGN KEY (prior_review_decision_id)
REFERENCES cutter_governance.review_decision (review_decision_id),
CONSTRAINT review_decision_superseded_fk
FOREIGN KEY (superseded_by_review_decision_id)
REFERENCES cutter_governance.review_decision (review_decision_id)
);
-- ---------------------------------------------------------------------
-- P0-5 remainder — cutter_governance.decision_backlog_history (#10)
-- r2: child column `decision_id` RENAMED -> `entry_id`;
-- FK target -> decision_backlog_entry(entry_id).
-- Append-only Đ38 trail for the LIVE decision_backlog_entry.
-- ---------------------------------------------------------------------
CREATE TABLE cutter_governance.decision_backlog_history (
history_id uuid NOT NULL,
entry_id uuid NOT NULL, -- r2: was decision_id; in-schema FK -> decision_backlog_entry.entry_id
entry_version_before text NULL, -- NULL for change_kind='create'
entry_version_after text NOT NULL,
change_kind text NOT NULL, -- {create,status_change,field_update,closure,re_open,supersede} cutter-local v0.2 (DBH-2)
change_diff jsonb NULL, -- field-level delta for 'field_update'
changed_by text NOT NULL,
changed_at timestamptz NOT NULL, -- no DEFAULT
rationale text NULL,
CONSTRAINT decision_backlog_history_pkey
PRIMARY KEY (history_id),
CONSTRAINT decision_backlog_history_entry_fk
FOREIGN KEY (entry_id)
REFERENCES cutter_governance.decision_backlog_entry (entry_id)
);
-- ---------------------------------------------------------------------
-- P0-5 remainder — cutter_governance.decision_backlog_dependency (#11)
-- r2: child columns `from_decision_id`->`from_entry_id`,
-- `to_decision_id`->`to_entry_id`; FK targets -> entry_id.
-- Entry-to-entry directed graph; cycle detection = app-layer v0.2 (DBD-1).
-- ---------------------------------------------------------------------
CREATE TABLE cutter_governance.decision_backlog_dependency (
dependency_id uuid NOT NULL,
from_entry_id uuid NOT NULL, -- r2: was from_decision_id; in-schema FK -> decision_backlog_entry.entry_id
to_entry_id uuid NOT NULL, -- r2: was to_decision_id; in-schema FK -> decision_backlog_entry.entry_id
dependency_kind text NOT NULL, -- {blocks,supersedes,refines,related_to} cutter-local v0.2 (DBD-2)
created_at timestamptz NOT NULL, -- no DEFAULT
created_by text NOT NULL,
CONSTRAINT decision_backlog_dependency_pkey
PRIMARY KEY (dependency_id),
CONSTRAINT decision_backlog_dependency_from_fk
FOREIGN KEY (from_entry_id)
REFERENCES cutter_governance.decision_backlog_entry (entry_id),
CONSTRAINT decision_backlog_dependency_to_fk
FOREIGN KEY (to_entry_id)
REFERENCES cutter_governance.decision_backlog_entry (entry_id)
-- NO UNIQUE(from,to,kind): edge-dedup is app-layer (no extra constraint)
-- NO CHECK(from<>to) / NO cycle trigger: DBD-1 = application-layer v0.2
);
-- ---------------------------------------------------------------------
-- P0-5 remainder — cutter_governance.decision_backlog_sweep_log (#12)
-- [UNCHANGED from r1] Standalone sweep audit. NO FK, NO soft entity ref.
-- ---------------------------------------------------------------------
CREATE TABLE cutter_governance.decision_backlog_sweep_log (
sweep_id uuid NOT NULL,
swept_at timestamptz NOT NULL,
swept_by text NOT NULL,
trigger_kind text NOT NULL, -- {scheduled,governance_review,health_report,self_review,ad_hoc} cutter-local v0.2 (DBS-1)
entries_evaluated_count integer NOT NULL,
entries_re_surfaced_count integer NOT NULL,
escalations_routed_count integer NOT NULL,
mirror_regenerated_at timestamptz NULL,
mirror_path text NULL, -- soft text path to KB mirror (NOT an entity FK)
findings jsonb NULL,
CONSTRAINT decision_backlog_sweep_log_pkey
PRIMARY KEY (sweep_id)
);
COMMIT;
-- =====================================================================
-- END OF DDL DRAFT r2 — NOTHING ABOVE HAS BEEN EXECUTED.
-- 4 empty tables, 7 in-schema FKs, no INSERT/seed/backfill, no PG enum,
-- no lookup table, no Đ24 lookup FK, no cross-schema FK, no CHECK,
-- no trigger, no DEFAULT, no IF NOT EXISTS.
-- =====================================================================
§5 — Ratified-Decision Encoding Map (r2)
| Decision | r2 encoding |
|---|---|
| A-1 fix (GPT-selected) | history entry_id, dependency from_entry_id/to_entry_id; all 3 FKs → decision_backlog_entry(entry_id) |
| BATCH-1 text + documented values | all enum-class columns text + comment; no PG enum / lookup / lookup FK |
| RD-1 / RD-2 / RD-3 | review_decision FKs unchanged (manifest_envelope / nullable composite manifest_unit_block / 2 self-FKs) |
| RD-4 / RD-5 / RD-6 / DBH-1/2 / DBD-1/2 / DBS-1 | unchanged from r1 (text enums, app-layer rules, no trigger/CHECK) |
§6 — Table-Count Effect (unchanged)
cutter_governance_pre: 8
cutter_governance_post: 12 (+ review_decision + decision_backlog_history
+ decision_backlog_dependency + decision_backlog_sweep_log)
FK_count: 7 (unchanged; targets corrected in r2)
§7 — Hard Boundaries
revision: r2
r1_superseded: TRUE (DO NOT EXECUTE r1)
ddl_authored: TRUE (this file, r2)
ddl_executed: FALSE
no_psql_run: TRUE (no execution; A-1 resolved via prior read-only catalog observation)
no_mutation: TRUE
no_dry_run_env_created: TRUE
no_dry_run_run: TRUE
dry_run_allowed: FALSE (until GPT r2 review PASS)
production_migration_allowed: FALSE
no_INSERT_no_seed_no_backfill: TRUE
no_PG_enum / no_new_lookup_table / no_dieu24_lookup_FK: TRUE
no_cross_schema_FK / no_CHECK / no_trigger / no_DEFAULT: TRUE
in_schema_FK_only: TRUE (7)
agent_self_advance: PROHIBITED
output_form: p0_6_p0_5_remainder_ddl_draft_r2
End of P0-6 + P0-5-remainder DDL draft (r2, A-1 resolved).