dot-iu-cutter v0.1 — P0-3 cut_change_set + rollback_key Migration Design
dot-iu-cutter v0.1 — P0-3 cut_change_set + rollback_key Migration Design ⚠️ HIGH RISK
Date: 2026-05-15 Status: P0 MIGRATION DESIGN — Item 5 of 6 (HIGH risk; DOT-pair binding) Scope: DESIGN ONLY. No DDL, no SQL, no CREATE/ALTER TABLE, no column DDL, no migration execution, no PG mutation. Master:
migration-design/dot-iu-cutter-v0.1-p0-migration-design-master-2026-05-15.md
1. Purpose
P0-3 establishes the persistent PG SSOT for CUT execution change-sets carrying:
- Exact-key rollback identifier (
rollback_key). - References to all
tac_logical_unit+tac_unit_versionrows created/modified by one CUT. - DOT-pair joint signatures (executor + verifier).
- Tool-revision drift detection metadata.
This is the HIGH-risk item in P0 because criterion 28 (DOT-pair dual-signature) is implemented here. Without P0-3 correctness, no valid REPORT PASS can emit.
2. Source Design References
- D1 Operational Design — §4.6 (CUT stage), §4.8 (rollback model), §4.14 (DOT-pair).
- G-4 closure — DOT Registry Custodian; both-signatures-required rule; tool_revision drift rule.
- Đ44 Step 2 outcome —
cut_change_set+verify_resultjoint ratification (DOT-pair signature schema shared). - Council Ratification Outcome §5.5 G-4 acceptance.
- P0 Schema Planning §5.3 P0-3 detail.
3. Logical Object / Table Intent
Primary table: cut_change_set
Companion table: cut_change_set_affected_row (junction; references created/modified TAC rows)
Companion (joint with P0-4): dot_pair_signature (shared signature record across cut_change_set + verify_result)
Target DB: directus. Target Schema: TAC OR new manifest/cut schema (joint decision with P0-2). Target Layer: Kho (SSOT for cut execution record). Authority pattern: PG SSOT; immutable post-emission (frozen change-set semantics).
4. Proposed Fields at Conceptual Level
4.1 cut_change_set
| Field name | Type-class | Nullable | Notes |
|---|---|---|---|
change_set_id |
uuid | NO | primary identifier |
rollback_key |
text (deterministic) OR uuid | NO | exact-key rollback identifier; format proposal: RBK-<change_set_id> OR raw uuid |
manifest_id |
FK to manifest_envelope |
NO | source manifest |
manifest_version |
text (semver) | NO | exact manifest version cut |
review_decision_id |
FK to review_decision (P0-6) |
NO | the PASSed review that authorized this CUT |
executor_tool_revision |
text | NO | dot-iu-cutter revision performing CUT |
verifier_tool_revision |
text | NO | dot-iu-cutter-verify revision co-signing |
tool_revision_match |
boolean | NO | computed: true iff executor_tool_revision = verifier_tool_revision (G-4 drift rule) |
executor_signature_id |
FK to dot_pair_signature |
NO | executor's signed payload reference |
verifier_signature_id |
FK to dot_pair_signature |
NO | verifier's signed payload reference |
state |
enum-ref | NO | values: pending / executing / committed / rolled_back / superseded / invalid_drift |
cut_started_at |
timestamp UTC | NO | execution begin |
cut_committed_at |
timestamp UTC | YES | commit timestamp; null until committed |
rolled_back_at |
timestamp UTC | YES | rollback timestamp; null unless rolled back |
affected_unit_count |
integer | NO | total rows in cut_change_set_affected_row for this change set |
affected_publication_count |
integer | NO | count of affected publications |
payload_summary |
JSONB | YES | structured summary: counts by table, by operation_kind |
rollback_reason |
text | YES | populated on rollback |
rollback_initiated_by |
text actor | YES | actor performing rollback |
decision_backlog_entry_id |
FK to decision_backlog_entry (P0-5) |
YES | governance trail anchor |
emitted_by |
text actor | NO | executor DOT identifier |
version |
text (semver) | NO | record version per Đ38 (typically frozen at 1.0.0) |
4.2 cut_change_set_affected_row
| Field name | Type-class | Nullable | Notes |
|---|---|---|---|
affected_row_id |
bigserial OR uuid | NO | row identifier |
change_set_id |
FK to cut_change_set |
NO | parent change-set |
target_table |
enum-ref OR text | NO | values include: tac_logical_unit, tac_unit_version, tac_publication (and possibly more in future) |
target_row_id |
text OR uuid OR bigint | NO | identifier of affected row in target table |
operation_kind |
enum-ref | NO | values: create / update / supersede / link / unlink |
before_state_snapshot |
JSONB | YES | minimal snapshot for rollback (open decision §9 item 5) |
after_state_snapshot |
JSONB | YES | minimal snapshot for audit |
applied_at |
timestamp UTC | NO | when this affected-row record was applied |
4.3 dot_pair_signature (joint with P0-4)
| Field name | Type-class | Nullable | Notes |
|---|---|---|---|
signature_id |
uuid | NO | primary identifier |
signature_kind |
enum-ref | NO | values: executor_cut / verifier_cut / executor_verify / verifier_verify |
signer_dot_id |
text | NO | dot-iu-cutter or dot-iu-cutter-verify |
signer_tool_revision |
text | NO | revision at signing |
payload_hash |
text | NO | content-addressable hash of signed payload (no DDL for hashing function decided here) |
payload_envelope |
JSONB | NO | structured payload describing what was signed (e.g., change_set_id, manifest_id, verdict, timestamps) |
signature_payload |
text | NO | the signature itself (specific cryptographic scheme deferred to FUTURE — open decision §9 item 2) |
signed_at |
timestamp UTC | NO | signing timestamp |
cross_reference_change_set_id |
FK to cut_change_set |
YES | for cut signatures |
cross_reference_verify_result_id |
FK to verify_result (P0-4) |
YES | for verify signatures |
validation_state |
enum-ref | NO | values: pending / valid / invalid / revoked |
dot_pair_signature is a shared family across P0-3 (cut signatures) and P0-4 (verify signatures), as per Đ44 outcome A.3 (joint ratification due to shared DOT-pair signature schema).
5. Field Ownership / Vocabulary Dependency
| Field | Vocabulary owner |
|---|---|
state enum |
cutter-local v0.1; Đ24 confirmation path |
operation_kind enum |
cutter-local v0.1 |
target_table enum |
cutter-local + cross-link to existing TAC schema names |
signature_kind enum |
cutter-local v0.1; Đ24 confirmation path |
validation_state enum |
cutter-local v0.1 |
rollback_key format |
cutter-local |
payload_envelope JSONB shape |
Đ38 manifest-as-code style; structured but JSONB-flexible per Đ44 A.6 #3 |
6. Rollback Key Semantics
rollback_key_semantics:
uniqueness: globally unique
deterministic: derivable from change_set_id (proposal: rollback_key = "RBK-" + change_set_id) OR raw uuid
binding: identifies exactly ONE change-set; rollback of rollback_key reverses ONLY that change-set
idempotency:
rollback_of_already_rolled_back: NO-OP (returns success with note "already rolled back")
rollback_of_committed_change_set: executes rollback per affected_row entries (reverse order); transitions state to `rolled_back`
rollback_of_pending_or_executing: aborts the in-progress CUT; transitions to `rolled_back`
cascade_rules:
rollback_of_change_set_A_when_change_set_B_modifies_same_rows: ERROR by default; reviewer escalation required (open decision §9 item 4)
cascade_authority: NEVER auto-cascade; explicit reviewer + G-4 (Custodian) + Đ32 review
retention:
cut_change_sets_retained_indefinitely: YES (audit; can be archived but not deleted)
rollback_key_retained_indefinitely: YES
7. DOT-Pair Signature Concept (G-4 binding)
both_signatures_required_rule (Council Ratification Outcome §5.5):
rule: change_set state may transition to `committed` ONLY when:
- executor_signature_id is non-null AND validation_state='valid'
- verifier_signature_id is non-null AND validation_state='valid'
- tool_revision_match = true (G-4 drift rule)
enforcement:
v0_1: application-layer
FUTURE: PG constraint via trigger or check constraint
failure_mode:
missing_executor_signature: state stays `executing`; emit signature_failure signal to G-2 backlog
missing_verifier_signature: same as above
tool_revision_match=false: state transitions to `invalid_drift`; emit dot_pair_drift signal; CUT aborts
invalid_signature: state stays `executing`; signature_failure signal; route to G-4 Custodian
signing_scheme:
v0_1: deferred — open decision §9 item 2; v0.1 may use payload_hash + DOT-pair credential indirection
FUTURE: cryptographic signature (Ed25519 / RSA / similar)
payload_envelope MUST include:
- signer_dot_id
- signer_tool_revision
- signed_at
- cross_reference (change_set_id OR verify_result_id)
- intent (what is being signed: e.g., "cut_executed", "verify_pass")
8. Lifecycle
[change_set lifecycle]
pending (manifest passed review; CUT enqueued)
↓
executing (executor begins; affected rows being recorded)
↓
├── tool_revision_match=false → invalid_drift (terminal pre-commit)
├── missing/invalid signatures → stays executing; signature_failure signal
└── both signatures valid + drift match → committed
↓
├── rollback initiated → rolled_back
└── superseded by future cut → superseded (terminal)
Re-execution after rollback creates a NEW change-set (new rollback_key); the old one stays rolled_back for audit.
9. Open Decisions
- Schema placement — joint with P0-2 decision (TAC OR new schema class).
- Signing scheme (v0.1 vs FUTURE) — payload_hash + credential indirection v0.1, OR cryptographic signature from day one. Recommendation: payload_hash v0.1 with hash function via PG built-ins; cryptographic signature FUTURE post-G-4 operational seating.
rollback_keyformat — deterministic (RBK-<change_set_id>) OR raw uuid. Recommendation: deterministic prefix for human-readability + uuid uniqueness.- Cascade rules — default ERROR + reviewer escalation (chosen). Recommendation confirmed; FUTURE D4 capability intake may relax for specific patterns.
before_state_snapshotgranularity — full row JSONB OR field-level delta OR null (just FK + operation_kind). Recommendation: minimal snapshot (FK + key columns + JSONB delta of changed fields); full row only if risk-class=high; balance audit vs storage.- Affected-row tracking — table vs JSONB array on cut_change_set — separate table (chosen for queryability). Recommendation confirmed.
dot_pair_signatureshared with P0-4 — same table — chosen per Đ44 Step 2 joint ratification.payload_envelopeschema strictness — structured per signature_kind via application-layer validation v0.1; PGjsonb_checkFUTURE.stateenum extension —invalid_driftis a new value introduced here; Đ24 confirm path.- Idempotency key for re-submission — should CUT be idempotent on retry? Recommendation: yes; idempotency_key derived from (manifest_id, manifest_version, review_decision_id); rejected if duplicate.
- Rollback authority — who can initiate? Recommendation: executor DOT for automatic VERIFY-failure rollback; G-4 Custodian + Đ32 for manual mid-cycle rollback.
- Signature revocation —
validation_state='revoked'semantics. Recommendation: revocation triggers a backlog entry + Đ32 review; existing change-sets relying on revoked signatures are flagged.
10. Dependencies
upstream_dependencies:
governance:
- Council Ratification Outcome G-4 ratified_with_notes (DOT Registry Custodian; both-sig rule; drift rule)
- Council Ratification Outcome G-2 ratified_with_notes (backlog tracking)
- Đ44 Step 2 cut_change_set + verify_result joint ratification
- Đ44 governance_event umbrella (signature_failure event sub-kind)
- Đ24 Step 1 (signature_failure event-kind controlled term + risk_class enum)
schema:
- P0-5 decision_backlog_entry (governance trail anchor + signal routing)
- P0-2 manifest_envelope + manifest_unit_block (manifest FK)
- P0-6 review_decision (review_decision_id FK — PASS gate)
- P0-1 canonical_address (units referenced by affected_row track canonical_address indirectly)
external:
- dot-iu-cutter executor DOT (existing)
- dot-iu-cutter-verify verifier DOT (FUTURE registration per G-4)
downstream_dependents:
- P0-4 verify_result (FK to cut_change_set; shared dot_pair_signature)
- F2 Health/Correction (D3): rollback events feed health signals
- retrieval audit: change-set is the immutable cut audit
operational_dependencies:
- DOT-pair registration via G-4 Custodian
- signing scheme implementation (FUTURE)
- dot_pair_drift / signature_failure signal routing (G-2 backlog)
11. Risks
| Risk | Severity | Mitigation in this design |
|---|---|---|
| Missing or invalid signature silently allowed → CUT commits without valid co-sign (criterion 28 break) | HIGH | application-layer enforcement v0.1; PG constraint FUTURE; signature_failure signal routes immediately |
tool_revision_match=false allowed silently → invalid co-sign |
HIGH | invalid_drift state enforced; CUT cannot transition to committed; dot_pair_drift signal |
| Rollback cascades unintentionally to dependent change-sets | HIGH | default ERROR on overlap; explicit reviewer + G-4 + Đ32 review for cascade |
before_state_snapshot incomplete → rollback reconstructs wrong state |
HIGH | granularity decision (open §9 item 5); risk-class-high cases use full row snapshot |
rollback_key collisions |
Standard | deterministic format RBK-<change_set_id> ensures uniqueness; uuid backbone |
| Signature scheme placeholder (v0.1) accepted as production | Standard | open decision §9 item 2 explicit; FUTURE migration required for cryptographic |
| Idempotency violation: same manifest cut twice creates two change-sets | Standard | idempotency_key check (open §9 item 10) |
| Audit loss on rollback | HIGH | rollback NEVER deletes change_set or affected_row entries; state transitions only |
| Signature revocation cascade | Standard | open §9 item 12 |
| Cross-reference to verify_result that doesn't yet exist (FK timing) | Low | application-layer ordering; FK established post-VERIFY |
12. Đ32 Risk Review Notes
proposed_risk_class: HIGH
review_inputs_for_dieu32:
- logical design content (this document)
- rollback model (§6)
- DOT-pair signature concept (§7)
- both-signatures-required rule enforcement boundary (v0.1 app-layer; FUTURE PG)
- tool_revision drift rule
- cascade default ERROR + escalation path
- signing scheme placeholder (open decision §9 item 2)
- cross-law dependencies (Đ44, Đ32, Đ37 via G-4)
- migration execution preconditions:
- P0-5, P0-2, P0-6 migrated
- DOT-pair registered via G-4 Custodian
- signing scheme decided (v0.1 vs FUTURE)
- dot_pair_signature table strategy decided (shared with P0-4)
- signal routing (dot_pair_drift, signature_failure) wired to G-2 backlog
- backup directus before migration
- documented rollback test plan PRIOR to first real CUT
review_outputs_expected:
- Đ32 HIGH-RISK approval / approval_with_notes
- G-4 Custodian sign-off on both-sig + drift enforcement
- signing scheme decision (v0.1 acceptable v0.1; binding for FUTURE upgrade)
- rollback test plan reviewed
review_authority: Đ32 council (HIGH-risk path) + G-4 DOT Registry Custodian + Đ44 family ratifier + Đ37 council
review_phase: NOT_STARTED
Special Đ32 attention (HIGH risk):
- Criterion 28 enforcement — both-signatures-required and tool_revision_match must be enforced; Đ32 should require explicit acceptance of v0.1 app-layer posture OR demand PG-constraint enforcement before approval.
- Rollback test plan REQUIRED before first real CUT — must include scripted rollback simulation per affected_row scenarios.
- Signing scheme placeholder — v0.1 may use hash-based pseudo-signature; this is acceptable ONLY IF FUTURE upgrade is committed in D4 capability intake post-G-4 operational seating.
before_state_snapshotgranularity is HIGH-stakes for rollback fidelity; Đ32 should review per risk-class-high path explicitly.- Cascade default ERROR is fail-safe; Đ32 should confirm and approve the escalation path.
13. Explicit Confirmation
no_ddl_written: true
no_sql_written: true
no_create_table_or_alter_table_in_this_document: true
no_column_ddl_in_this_document: true
no_index_ddl: true
no_constraint_ddl_in_this_document: true
no_trigger_or_function_or_rls_policy_written: true
no_cryptographic_scheme_specified_in_this_document: true (deferred per open decision §9 item 2)
no_migration_executed: true
no_pg_mutation: true
no_qdrant_mutation: true
no_data_writes: true
no_implementation_planning: true
no_existing_file_modified: true
no_signature_actually_generated: true
output_form: logical_design_only