KB-AB82

dot-iu-cutter v0.2 — Phase α Rollback Draft (2026-05-15)

15 min read Revision 1
dieu44-trien-khaidot-iu-cutterv0.2phase-alpharollback-draftdo-not-execute2026-05-15

dot-iu-cutter v0.2 — Phase α Rollback Draft

⚠️ DO NOT EXECUTE WITHOUT EXPLICIT GPT / USER PROMPT. Rollback alters production state. Authorization to author a rollback DDL is NOT authorization to execute it. Execution requires a separate explicit prompt that names:

  1. the rollback as the intended operation,
  2. the environment (dry-run or production), and
  3. the trigger condition (which verification gate failed and why rollback is the chosen response).
document_path: knowledge/dev/laws/dieu44-trien-khai/v0.2-ddl-authoring/dot-iu-cutter-v0.2-phase-alpha-rollback-draft-2026-05-15.md
revision: r1
date: 2026-05-15
author: Agent (Claude Code CLI, Opus 4.7 1M)
phase: v0.2 — Phase α rollback DRAFT (planning only; not executable on its own)
ddl_authored: TRUE
ddl_executed: FALSE
rollback_executed: FALSE
mutation_performed: FALSE

§1 — Purpose

Provide the rollback plan for the Phase α DDL. The plan covers two contexts:

  1. Dry-run rollback — used when a dry-run scenario fails. Low-risk because the dry-run env is isolated.
  2. Production rollback — used when a production-side verification gate (§4 of the verification plan) fails post-DDL. Higher consequence because Phase α columns may already have been populated; dropping them loses data.

This document is a draft — it describes the SQL pattern and the data-loss considerations. The actual rollback SQL is NOT to be dispatched against any database until a separate explicit prompt authorizes the operation in the appropriate environment.


§2 — Rollback Scope (matches Phase α DDL exactly)

operations_to_reverse_in_order (LIFO):
  1. DROP cutter_governance.canonical_address_alias indexes (PG auto-drops with table)
  2. DROP TABLE cutter_governance.canonical_address_alias
  3. ALTER TABLE sandbox_tac.logical_unit DROP COLUMN authority
  4. ALTER TABLE sandbox_tac.logical_unit DROP COLUMN canonical_address_format_version
  5. (REVERT step 3 backfill — see §4.4 for the data-loss caveat; rollback cannot precisely reconstruct prior NULL state on a row-by-row basis if the column has been touched by other writes)
  6. ALTER TABLE public.tac_logical_unit DROP COLUMN authority
  7. ALTER TABLE public.tac_logical_unit DROP COLUMN canonical_address_format_version

operations_NOT_in_scope_of_phase_α_rollback:
  - dropping the cutter_governance schema (that schema is v0.1; not Phase α)
  - dropping the existing tac_logical_unit.canonical_address column (SSOT; never touched by Phase α)
  - dropping any v0.1 cutter_governance table (decision_backlog_entry, dot_pair_signature, cut_change_set, cut_change_set_affected_row, verify_result)
  - touching sister tables (event_outbox, information_unit, etc.)

§3 — Rollback SQL Draft (DO NOT EXECUTE)

-- ============================================================================
-- dot-iu-cutter v0.2 — Phase α ROLLBACK DRAFT
-- DO NOT EXECUTE WITHOUT EXPLICIT GPT/USER PROMPT.
-- ============================================================================
-- Target environment:    dry-run OR production (caller chooses; same SQL)
-- Target PG version:     PostgreSQL 16.13
-- Migration role:        workflow_admin
-- ============================================================================
-- Pre-rollback safety:
--   1. Caller MUST capture a snapshot of authority and canonical_address_format_version
--      values BEFORE dispatching this script, IF rollback is being executed in production
--      and the operator wants the ability to re-apply Phase α later without re-running backfill.
--      Suggested capture:
--        COPY (
--          SELECT id, authority, canonical_address_format_version, updated_at
--            FROM public.tac_logical_unit
--          ORDER BY id
--        ) TO '/opt/incomex/backups/dieu44_phase_alpha_rollback_<stamp>/tac_metadata_capture.csv' CSV HEADER;
--      (capture is OPTIONAL; values are derivable from backfill rule if needed)
--   2. Caller MUST have a fresh production backup taken < 60 min before rollback (matching the v0.1 production execution pattern). The Phase α production execution session's fresh backup may be reused if the rollback fires within the same window.
-- ============================================================================

BEGIN;

SET LOCAL statement_timeout = 0;
SET LOCAL lock_timeout = '30s';
SET LOCAL idle_in_transaction_session_timeout = '60s';

-- ---------------------------------------------------------------------------
-- Step R-1 — Drop cutter_governance.canonical_address_alias (table + indexes)
-- ---------------------------------------------------------------------------
-- Indexes (PK + 4 btree) are auto-dropped by DROP TABLE.
-- Safe only because alias table is empty at rollback time (0 rows; Phase α
-- does not insert any). If somehow rows exist, this rollback would lose them.
-- Pre-rollback check (caller MUST run): SELECT count(*) FROM cutter_governance.canonical_address_alias; expected 0.
DROP TABLE IF EXISTS cutter_governance.canonical_address_alias;

-- ---------------------------------------------------------------------------
-- Step R-2 — Drop mirror columns on sandbox_tac.logical_unit
-- ---------------------------------------------------------------------------
-- DATA LOSS NOTICE: dropping authority column removes 76 NULL values
-- (sandbox is intentionally NOT backfilled; no real data is being lost).
-- Dropping format_version removes 76 'canonical-address-v1' DEFAULT values
-- (the DEFAULT can be re-applied trivially by Phase α retry).
ALTER TABLE sandbox_tac.logical_unit DROP COLUMN IF EXISTS authority;
ALTER TABLE sandbox_tac.logical_unit DROP COLUMN IF EXISTS canonical_address_format_version;

-- ---------------------------------------------------------------------------
-- Step R-3 — Drop columns on public.tac_logical_unit
-- ---------------------------------------------------------------------------
-- DATA LOSS NOTICE — see §4 below.
-- DROP COLUMN authority removes the BR-4-mapped value for all 86 rows.
-- DROP COLUMN canonical_address_format_version removes the BR-5 stamp for all 86 rows.
-- These values are deterministically reproducible by re-running Phase α DDL on the same dataset.
ALTER TABLE public.tac_logical_unit DROP COLUMN IF EXISTS authority;
ALTER TABLE public.tac_logical_unit DROP COLUMN IF EXISTS canonical_address_format_version;

-- ---------------------------------------------------------------------------
-- Final sanity SELECT (read-only confirmation inside the same transaction)
-- ---------------------------------------------------------------------------
SELECT
    (SELECT count(*) FROM information_schema.columns
       WHERE table_schema='public' AND table_name='tac_logical_unit'
         AND column_name IN ('authority', 'canonical_address_format_version'))     AS tac_new_cols_remaining,
    (SELECT count(*) FROM information_schema.columns
       WHERE table_schema='sandbox_tac' AND table_name='logical_unit'
         AND column_name IN ('authority', 'canonical_address_format_version'))     AS sandbox_new_cols_remaining,
    (SELECT count(*) FROM information_schema.tables
       WHERE table_schema='cutter_governance' AND table_name='canonical_address_alias') AS alias_table_remaining,
    (SELECT count(*) FROM public.tac_logical_unit)                                AS tac_row_count,
    (SELECT count(*) FROM sandbox_tac.logical_unit)                                AS sandbox_row_count;

-- Expected after rollback:
--   tac_new_cols_remaining       = 0
--   sandbox_new_cols_remaining   = 0
--   alias_table_remaining        = 0
--   tac_row_count                = 86  (unchanged; rollback does not touch existing data rows)
--   sandbox_row_count            = 76  (unchanged)

COMMIT;

§4 — Data-Loss Considerations

4.1 Alias table (Phase α; 0 rows expected)

data_at_risk: NONE in Phase α
reason: Phase α creates the alias table empty; no writers wired
caveat_for_post_phase_β_rollback:
  if a future rollback is requested AFTER Phase β writers have populated aliases,
  the rollback SQL above MUST be revised to capture alias rows before DROP.
  In Phase α scope, this is not a concern.

4.2 sandbox_tac.logical_unit columns

data_at_risk: NONE
reason:
  authority column on sandbox is NULL on all 76 rows (no backfill in Phase α)
  format_version column on sandbox has uniform DEFAULT value 'canonical-address-v1' across 76 rows; trivially re-applicable

4.3 public.tac_logical_unit.canonical_address_format_version

data_at_risk: LOW
reason:
  uniform DEFAULT value 'canonical-address-v1' across 86 rows
  re-running Phase α DDL produces the identical value via the same DEFAULT
  no operator-specific values exist in Phase α

4.4 public.tac_logical_unit.authority

data_at_risk: STANDARD (intended values are derivable from BR-4 mapping)
reason:
  - all 86 rows currently get authority='draft' from the Candidate B mapping (because all 86 are lifecycle_status='draft_only')
  - re-running Phase α DDL reproduces the same backfill values from the same source
  - the backfill is deterministic; no information is permanently lost

caveat — future state:
  - if Phase β has run and authority values have been UPDATED by the lifecycle-transition write hook (e.g., a row's lifecycle moved to 'active' and authority was set to 'enacted'), then a Phase α rollback AT THAT POINT would lose those updates
  - in Phase α scope (no Phase β yet), this is not a concern
  - recommendation: BEFORE executing this rollback in production, run the optional COPY snapshot in the rollback SQL header so values can be replayed if needed

caveat — updated_at side effect:
  - Phase α backfill bumped updated_at on all 86 rows
  - Phase α rollback does NOT restore the prior updated_at; the UPDATE during backfill is irreversible at the timestamp level
  - the original updated_at values can be recovered from the pre-Phase-α backup (HB-08-pattern .dump file taken before Phase α DDL)

4.5 Existing canonical_address column

data_at_risk: NONE
reason: Phase α NEVER modifies this column; rollback does not touch it

§5 — Rollback Decision Conditions

Rollback is NOT automatic. It is dispatched only under explicit prompt, triggered by one of the following verification failures (see verification plan §4):

trigger_condition_T-1:  V-α-1 / V-α-2 — new columns malformed or missing
trigger_condition_T-2:  V-α-3 / V-α-4 — alias table malformed or missing
trigger_condition_T-3:  V-α-6 — authority distribution unexpected (not {'draft' × 86})
trigger_condition_T-4:  V-α-7 — format_version distribution unexpected
trigger_condition_T-5:  V-α-13 — cutter_governance schema changed beyond additive alias table
trigger_condition_T-6:  V-α-14 / V-α-15 — row count drift on tac_logical_unit or sandbox_tac.logical_unit
trigger_condition_T-7:  V-α-16 — schema diff shows non-additive changes
trigger_condition_T-8:  Q-CHK-1/2/3 pre-backfill check failed AFTER the column was already added (rare race; mostly applies to dry-run)
trigger_condition_T-9:  any operational anomaly detected during the post-DDL window (e.g., trigger errors flooding logs)

decision_authority_for_rollback:
  Đ32 (standard path) + G-4 Custodian co-sign
  sovereign User explicit acknowledgement
  agent_self_authorize_rollback: PROHIBITED

§6 — Approval Requirements Before Rollback Dispatch

approval_chain:
  1. operator records the verification failure (which query, expected vs actual)
  2. operator escalates to GPT
  3. GPT reviews the failure evidence
  4. GPT issues an explicit rollback authorization prompt referencing this rollback draft by path
  5. operator executes the rollback in the same single-transaction posture as Phase α (ON_ERROR_STOP=1)
  6. operator verifies post-rollback state via the §3 final SELECT
  7. operator authors a rollback-execution report (similar pattern to v0.1 production execution report) and submits for GPT ratification

agent_self_advance_to_rollback_execution: PROHIBITED
each_step_terminates_at_GPT_review_or_explicit_user_prompt: TRUE

§7 — In-Transaction ROLLBACK (cheaper alternative when applicable)

if_DDL_failure_occurs_INSIDE_the_Phase_α_transaction_(--single-transaction --set ON_ERROR_STOP=1):
  - the transaction aborts automatically; database state is identical to pre-Phase-α
  - NO separate rollback script needed
  - this is the preferred failure mode: dispatch the Phase α DDL with single-transaction + ON_ERROR_STOP; let PG handle aborts
  - the rollback script in §3 is required ONLY when failure is detected POST-COMMIT (e.g., verification queries reveal a problem AFTER the COMMIT)

§8 — Hard Boundaries

no_rollback_executed: TRUE
no_DDL_executed_from_this_draft: TRUE
no_mutation: TRUE
no_dry_run_started: TRUE
no_production_rollback_dispatched: TRUE
self_advance_to_rollback_execution: PROHIBITED
output_form: phase_alpha_rollback_draft_review_only

§9 — Cross-References

fn_inspection:        knowledge/dev/laws/dieu44-trien-khai/v0.2-ddl-authoring/dot-iu-cutter-v0.2-phase-alpha-fn-tac-birth-gate-lu-inspection-2026-05-15.md
ddl_draft:            knowledge/dev/laws/dieu44-trien-khai/v0.2-ddl-authoring/dot-iu-cutter-v0.2-phase-alpha-ddl-draft-2026-05-15.sql.md
verification_plan:    knowledge/dev/laws/dieu44-trien-khai/v0.2-ddl-authoring/dot-iu-cutter-v0.2-phase-alpha-ddl-verification-plan-2026-05-15.md
authoring_report:     knowledge/dev/laws/dieu44-trien-khai/v0.2-ddl-authoring/dot-iu-cutter-v0.2-phase-alpha-ddl-authoring-report-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
v0_1_rollback_pattern: knowledge/dev/laws/dieu44-trien-khai/execution/dot-iu-cutter-v0.1-p0-production-command-review-package-2026-05-15.md  (§2.10 / §7)

End of Phase α rollback draft.

Back to Knowledge Hub knowledge/dev/laws/dieu44-trien-khai/v0.2-ddl-authoring/dot-iu-cutter-v0.2-phase-alpha-rollback-draft-2026-05-15.md