KB-AB82 rev 2

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

18 min read Revision 2
dieu44-trien-khaidot-iu-cutterv0.2phase-alpharollback-draftdo-not-executerevision-22026-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: r2
supersedes: r1 (2026-05-15)
date: 2026-05-15
revised: 2026-05-16
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

§0 — Revision 2 Changelog

trigger: GPT REVISION_REQUIRED on DDL draft r1 (PG fast-default pitfall); the
  DDL draft, authoring report and verification plan were revised to r2.

r2_impact_on_this_rollback: MINIMAL.
  The rollback reverses Phase α by DROP TABLE / DROP COLUMN. `DROP COLUMN`
  removes a column together with any attached DEFAULT in a single operation,
  so the r2 split of authority into "ADD COLUMN (no default)" + later
  "ALTER COLUMN SET DEFAULT" requires NO separate reversal step — dropping
  the column discards the default automatically. The rollback SQL body and
  data-loss reasoning are logically UNCHANGED from r1.

r2_changes_to_this_file:
  - revision r1 → r2
  - step-number references aligned to DDL draft r2 (authority backfill = Step 3;
    SET DEFAULT = Steps 4/7; alias table = Step 8; indexes = Step 9)
  - §4.2 clarified: sandbox authority is now GENUINELY NULL × 76 under r2
    (under r1 it would have been 'draft' × 76 — see verification plan §2.8)
  - explicit statement that DROP COLUMN subsumes the SET DEFAULT removal

no_execution: rollback authoring only — no rollback dispatched anywhere.

§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 r2 exactly)

operations_to_reverse_in_order (LIFO vs DDL draft r2):
  1. DROP cutter_governance.canonical_address_alias indexes  (DDL r2 Step 9; PG auto-drops with table)
  2. DROP TABLE cutter_governance.canonical_address_alias     (DDL r2 Step 8)
  3. ALTER TABLE sandbox_tac.logical_unit DROP COLUMN authority
       (DDL r2 Steps 6+7 — DROP COLUMN removes the column AND the Step 7 SET DEFAULT together)
  4. ALTER TABLE sandbox_tac.logical_unit DROP COLUMN canonical_address_format_version  (DDL r2 Step 5)
  5. (REVERT the DDL r2 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. DROP COLUMN in step 6 below discards it wholesale.)
  6. ALTER TABLE public.tac_logical_unit DROP COLUMN authority
       (DDL r2 Steps 2+3+4 — DROP COLUMN removes the column, the backfilled values, AND the Step 4 SET DEFAULT together)
  7. ALTER TABLE public.tac_logical_unit DROP COLUMN canonical_address_format_version  (DDL r2 Step 1)

note_on_set_default_reversal:
  there is NO separate "ALTER COLUMN ... DROP DEFAULT" step. DROP COLUMN
  eliminates the column and every property attached to it (default, comment,
  per-column privileges) atomically. The r2 add/default split is therefore
  invisible to the rollback.

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 (rev 2)
-- 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
-- Reverses:              dot-iu-cutter-v0.2-phase-alpha-ddl-draft-2026-05-15.sql.md (r2)
-- ============================================================================
-- 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 the BR-4 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 removes 76 NULL values
-- (r2: the sandbox column is genuinely NULL on all 76 rows — NOT backfilled;
--  no real data is being lost). DROP COLUMN also discards the DDL r2 Step 7
-- SET DEFAULT in the same operation.
-- 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 AND the
--   DDL r2 Step 4 SET DEFAULT, in one operation.
-- 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 r2 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.
  r2 note: this is now GENUINELY NULL — DDL draft r2 Step 6 adds the column
  WITHOUT a default and runs NO sandbox backfill. (Under DDL draft r1 the
  column would have read 'draft' × 76, which the verification plan §2.8 V-α-8
  would have flagged as a failure. r2 makes "no data at risk" actually true.)
  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 r2 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 the BR-4 mapping)
reason:
  - all 86 rows get authority='draft' from the Candidate B mapping applied by
    DDL draft r2 Step 3 (because all 86 are lifecycle_status='draft_only')
  - r2 note: under r2 these values are produced by the ACTUAL BR-4 backfill
    UPDATE (Step 3), not by a column default — so re-running Phase α DDL r2
    reproduces them deterministically 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 moved to 'active' and
    authority became 'enacted'), 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

caveat — updated_at side effect:
  - DDL draft r2 Step 3 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, no enacted/runtime/NULL})
trigger_condition_T-3b: V-α-8 — sandbox authority not {NULL × 76} (e.g. 'draft' values present → the r1-style column-default defect)
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-α
  - the column is never half-added and the backfill is never half-applied
  - NO separate rollback script needed
  - this is the preferred failure mode: dispatch the Phase α DDL r2 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
revision: r2 (revision tracking + step-renumber refs; reversal logic unchanged)

§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  (r2)
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  (r2)
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  (r2)
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 (revision 2).

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