KB-57DE

dot-iu-cutter v0.1 — P0 Rollback Test Plan

14 min read Revision 1
dot-iu-cutterimplementation-planningrollback-testp0-3p0-4dot-pairno-executionno-ddlrev5d

dot-iu-cutter v0.1 — P0 Rollback Test Plan

Date: 2026-05-15 Status: IMPLEMENTATION PLANNING — Lane "rollback-test" (X-8 authoring) Scope: PLANNING ONLY. No test executed, no DDL, no SQL, no migration, no PG mutation, no signature generated, no verify run. Master: implementation-planning/dot-iu-cutter-v0.1-p0-implementation-planning-master-2026-05-15.md


1. Purpose

Specify the synthetic-data dry-run scenario matrix for the rollback + verify safety surface of P0-3 and P0-4 (HIGH-risk items). This plan is the authoring half of X-8; the execution dry-run is performed in a separate session before production migration execution.

The plan covers:

  • rollback_key behavior
  • cut_change_set state transitions including invalid_drift
  • cut_change_set_affected_row before_state_snapshot fidelity
  • verify_result.verdict triggering rollback (FAIL) vs no rollback (NEEDS_HUMAN)
  • dot_pair_signature validation, revocation, and exactly-one-cross-reference rule
  • rollback failure recovery
  • signature timeout race conditions
  • signature_failure / dot_pair_drift signal routing

No SQL, no DDL, no actual signatures generated, no actual rollbacks run.

2. Source Inputs

  • migration-design/dot-iu-cutter-v0.1-p0-3-cut-change-set-rollback-key-migration-design-2026-05-15.md §6–§12
  • migration-design/dot-iu-cutter-v0.1-p0-4-verify-result-migration-design-2026-05-15.md §9–§15
  • risk-review/dot-iu-cutter-v0.1-dieu32-p0-high-risk-joint-review-p0-3-p0-4-2026-05-15.md §5–§9
  • risk-review/dot-iu-cutter-v0.1-p0-cross-cutting-decision-register-2026-05-15.md §3.8 (X-8)
  • implementation-planning/dot-iu-cutter-v0.1-p0-cross-cutting-resolution-plan-2026-05-15.md §10 (X-8) + §8 (X-6 polish)

3. Synthetic Data Dry-Run Plan

dry_run_environment_basis: per preflight plan §6
synthetic_data_principles:
  - no production data
  - no live DOT-pair identifiers (use scenario-local fake DOT IDs)
  - reset between scenarios — each scenario starts from a clean cutter_governance schema state
  - canonicalization rule v0.1 placeholder applied (NFC + LF + trim) for any markdown source used in axis-1 scenarios
  - signing scheme v0.1 hash-based pseudo-signature used (no cryptographic material)
synthetic_data_inventory:
  - 3 synthetic source markdown documents (small, medium, with multi-byte chars)
  - 2 synthetic manifest_envelope rows
  - up to 10 synthetic manifest_unit_block rows
  - up to 2 synthetic review_decision rows (PASS for the happy-path scenarios)
  - synthetic dot_pair_signature rows generated per scenario
  - synthetic cut_change_set + cut_change_set_affected_row rows generated per scenario
not_run_here: actual test execution

4. P0-3 / P0-4 Rollback / Verify Scenario Matrix

# Scenario name Inputs Expected behavior Pass condition
S01 Happy-path commit synthetic CUT with both signatures valid, tool_revision_match=true, no drift cut_change_set → committed; verify_result.verdict=PASS committed + PASS observed
S02 Missing executor signature CUT with only verifier signature cut_change_set stays executing; signature_failure signal to G-2 state=executing; backlog entry present
S03 Missing verifier signature CUT with only executor signature cut_change_set stays executing; signature_failure signal to G-2 state=executing; backlog entry present
S04 Invalid signature payload CUT with mismatched payload_hash cut_change_set stays executing; validation_state=invalid on signature state=executing; signature.validation_state=invalid
S05 tool_revision_match=false executor and verifier tool_revisions differ cut_change_set → invalid_drift; dot_pair_drift signal state=invalid_drift; backlog entry present
S06 Rollback of committed change-set scenario S01 + manual rollback cut_change_set → rolled_back; affected_row entries retained; audit preserved state=rolled_back; affected_row count unchanged
S07 Rollback of pending change-set CUT enqueued but not signed; abort cut_change_set → rolled_back (aborted); no signatures present state=rolled_back
S08 Rollback of executing change-set CUT in progress, abort signal cut_change_set → rolled_back (mid-execution); affected_row entries retained for already-applied rows state=rolled_back; partial affected_row entries present
S09 Rollback of already-rolled-back change-set CUT already in rolled_back; rollback again NO-OP; success with note "already rolled back" no state change; idempotent return
S10 Rollback cascade overlap (default ERROR) Two change-sets A and B; B touches rows A also touched; rollback B then attempt rollback A rollback A errors with escalation; default ERROR + reviewer escalation error returned; backlog entry kind=rollback_cascade_blocked
S11 rollback_key collision attempt synthetic insert of duplicate rollback_key rejected at write time (application-layer uniqueness) reject observed
S12 Idempotency key on re-submit identical CUT submitted twice with same (manifest_id, manifest_version, review_decision_id) second submission rejected (idempotency) second submission rejected
S13 VERIFY round-trip PASS matching canonical_token streams verify_result.verdict=PASS; cut_change_set → committed verdict=PASS; committed
S14 VERIFY round-trip FAIL with auto-rollback drifting canonical_token stream beyond threshold verify_result.verdict=FAIL; rollback_triggered=true; cut_change_set → rolled_back FAIL + rollback chain observed
S15 VERIFY NEEDS_HUMAN — disagreement executor verdict PASS, verifier verdict FAIL verdict=NEEDS_HUMAN; no auto-rollback; escalation_ref populated NEEDS_HUMAN; cut_change_set stays executing
S16 VERIFY NEEDS_HUMAN — tool_revision drift both verdicts PASS but tool_revision_match=false verdict=NEEDS_HUMAN NEEDS_HUMAN observed
S17 VERIFY both-FAIL concurrence both executor and verifier verdicts FAIL verdict=FAIL; auto-rollback; rollback_triggered=true FAIL + rollback observed
S18 VERIFY signature timeout (race) executor signature arrives, verifier signature delayed past timeout verdict=NEEDS_HUMAN; escalation_ref populated NEEDS_HUMAN observed at timeout
S19 Canonicalization rule consistency same input run twice through canonical_token mapping identical token streams produced exact equality
S20 Canonicalization rule mid-cycle change (rejected scenario) attempt to apply different rule version to a previously-passing verify_result rejected — canonicalization_rule_used field on verify_result is immutable reject observed
S21 dot_pair_signature exactly-one-cross-reference attempt to set both cross_reference_change_set_id and cross_reference_verify_result_id non-null rejected (application-layer X-6 polish enforcement) reject observed
S22 dot_pair_signature revocation cascade mark a signature revoked → dependent change-sets flagged backlog entry created; dependent change-sets receive a review flag backlog entry present; dependent change-sets flagged
S23 Rollback failure recovery force rollback to fail (e.g., simulated DB error mid-rollback) new health signal emitted; backlog entry kind=rollback_failed; manual recovery path documented backlog entry present; recovery path documented
S24 before_state_snapshot fidelity (Standard) rollback a CUT and verify rows restored to snapshot state rows match snapshot match observed
S25 before_state_snapshot fidelity (HIGH risk-class) full-row snapshot used for HIGH risk_class CUT; rollback restores exactly rows match full-row snapshot match observed
S26 Re-VERIFY chain via prior_verify_result_id NEEDS_HUMAN resolved; new verify_result issued; prior chain set new row chains to prior; prior → superseded chain observed

5. Rollback_key Behavior Specification

rollback_key_format_under_test:
  - deterministic: "RBK-<change_set_id>"
  - uniqueness: globally unique across cutter_governance.cut_change_set
  - immutability: once assigned, never changes for that change_set_id
rollback_key_collision_handling:
  - write-time uniqueness check at application layer
  - if collision observed → reject + emit a backlog entry kind=rollback_key_collision
rollback_key_retention:
  - rollback_key retained indefinitely even after change_set is rolled_back
  - audit trail anchored on rollback_key

6. verify_result Behavior Specification

verify_result_verdict_paths_under_test:
  PASS:
    triggers: axis_1_status=pass + axis_2_status in (pass, not_applicable) + executor/verifier signatures valid + tool_revision_match=true + birth_gate_check passed
    side_effects: cut_change_set → committed; REPORT emits PASS
  FAIL:
    triggers: any of {axis_1 fail, birth_gate fail, signature invalid, tool_revision_mismatch}
    side_effects: rollback_triggered=true; cut_change_set → rolled_back; REPORT emits FAIL with verdict_rationale
  NEEDS_HUMAN:
    triggers: executor/verifier verdict disagreement OR axis_1 canonicalization ambiguity OR explicit needs_human flag OR signature timeout
    side_effects: no auto-rollback; cut_change_set stays executing; escalation_ref populated
verify_result_canonicalization_rule_field:
  required: true on every row
  immutable: true after row insert
verify_result_re_verify_chain:
  via: prior_verify_result_id self-FK
  superseded_lifecycle: prior row state → superseded

7. dot_pair_signature Behavior Specification

dot_pair_signature_validation_state_lifecycle_under_test:
  pending → valid (on validation pass)
  pending → invalid (on validation fail)
  valid → revoked (on revocation; revoked_at + revocation_reason populated)
dot_pair_signature_cross_reference_rule:
  exactly one of cross_reference_change_set_id or cross_reference_verify_result_id is non-null
  enforced at application layer (X-6 polish)
dot_pair_signature_revocation_cascade:
  on revocation: emit backlog entry (kind=signature_revoked)
  flag dependent change-sets / verify_results referencing the signature for Đ32 review
dot_pair_signature_signing_scheme_v0_1:
  hash-based pseudo-signature
  payload_envelope captures: signer_dot_id, signer_tool_revision, signed_at, cross_reference, intent
  signature_payload = deterministic hash of canonical payload
  v0.1 acceptance ONLY IF FUTURE upgrade to cryptographic signing scheme is committed via D4 capability intake

8. Expected Pass / Fail Distribution Across Scenarios

expected_pass_scenarios:
  - S01, S06, S07, S08, S09, S13, S19, S24, S25, S26 (commit/rollback happy paths + idempotency + canonicalization + snapshot + chain)
expected_state_transition_or_reject_scenarios:
  - S02, S03, S04 (signature failure paths)
  - S05 (invalid_drift)
  - S10 (rollback cascade overlap)
  - S11 (rollback_key collision)
  - S12 (idempotency)
  - S20 (rule immutability)
  - S21 (exactly-one cross-reference)
expected_verdict_outcome_scenarios:
  - S14 (FAIL + rollback)
  - S15 (NEEDS_HUMAN — disagreement)
  - S16 (NEEDS_HUMAN — drift)
  - S17 (FAIL — both-fail concurrence)
  - S18 (NEEDS_HUMAN — timeout)
expected_signal_routing_scenarios:
  - S02, S03, S04 (signature_failure signal observed in G-2 backlog channel)
  - S05 (dot_pair_drift signal observed)
  - S22 (revocation cascade signal observed)
  - S23 (rollback_failed signal observed)
overall_acceptance_threshold: 100% of scenarios pass their expected condition; any failure BLOCKS production execution

9. Failure Escalation

on_scenario_failure:
  - emit a backlog entry (kind=rollback_test_scenario_failed; scenario_id=<S##>)
  - notify Đ32 (HIGH-risk path) + G-4 Custodian
  - DO NOT proceed to production execution
  - root-cause analysis required before retry
retest_policy:
  - retry requires Đ32 sign-off
  - any change to the rollback test plan after first failure requires Đ32 review (plan revision)
sign_off_after_full_dry_run_pass:
  - Đ32 (HIGH-risk path) signs off
  - G-4 Custodian signs off
  - sign-off recorded as a closure file (separate session; not in this planning phase)

10. Coverage Map — Risks → Scenarios

Risk (from joint review) Scenarios
JR-1 rollback safety S06, S07, S08, S09, S10, S24, S25
JR-2 verify failure S13, S14, S15, S16, S17, S18
JR-3 dual signature S01, S02, S03, S04
JR-4 tool_revision drift S05, S16
JR-5 signature_failure S02, S03, S04, S18
JR-6 rollback test plan requirement this plan itself; full coverage across S01–S26
JR-7 canonicalization rule dependency S13, S14, S19, S20
JR-8 source_span ↔ axis_1_drift_unit (X-A) S19, S13, S14 (indirectly)

11. What This Plan Does NOT Do

this_file_does_NOT:
  - execute any scenario
  - generate any signature
  - run any verify
  - perform any rollback
  - touch any production data
  - emit any signal to a real backlog channel
  - mutate any PG / Qdrant / Directus state
  - write any SQL / DDL / migration script

12. Explicit Confirmation

no_test_executed: true
no_signature_generated: true
no_verify_run: true
no_rollback_run: true
no_signal_emitted: true
no_ddl_written: true
no_sql_written: true
no_migration_script_written: true
no_pg_mutation: true
no_qdrant_mutation: true
no_directus_mutation: true
no_data_writes: true
no_implementation_execution: true
no_phase_prior_file_modified: true
output_form: rollback_test_planning_only
Back to Knowledge Hub knowledge/dev/laws/dieu44-trien-khai/implementation-planning/dot-iu-cutter-v0.1-p0-rollback-test-plan-2026-05-15.md