O8 production-run readiness & command package (Contabo) — 05-backup-rollback-disable-plan
O8 Report 05 — Backup / rollback / disable plan
- macro:
v0.6-o8-production-run-readiness-command-package - date_utc: 2026-05-21 · host:
vmi3080463(Contabo) - gate covered: G5 backup / rollback / disable plan
1. Disable plan (fastest-first — ratified O5 doc 05 §2)
| Level | Action | Effect | Cost |
|---|---|---|---|
| 0 kill-switch | __execution_enabled__ = False |
Mode.LIVE structurally refused |
1 line, instant |
| 1 withhold approval | do not issue / revoke SG_1 / SG_2 | --mode live refuses at the gate |
none |
| 2 void run | cutter orchestrate void --run-id |
clears idempotency safely | — CLI absent |
| 3 no-run | do not start the run | nothing happens | none |
Level 0 is currently engaged (False). Level 2 is not available —
the orchestrate CLI (incl. void) was never implemented.
2. Backup plan (pre_write_backup, phase 4)
Intended: a GPG-encrypted, narrow pg_dump --table of the mutation
surface (information_unit, unit_version, iu_lifecycle_log,
cutter_governance.*), sha-pinned into the RunContext.
Blocking facts:
- GAP-3 — GPG keyring is empty. No
BACKUP_GPG_FPRpublic key → no encrypted backup can be produced. The phase has aSTOP_BACKUP_GPG_PUBKEY_MISSINGroute for exactly this, but it fires before any backup exists. - GAP-9 — phase 4 has no live body. Its
Mode.DRYRUNbody computes a deterministic placeholder sha; there is no realpg_dump+GPG path.
A fresh, real pre-write backup is therefore not producible today.
3. Restore / backup-verification proof plan
Proposed (executable once GAP-3 + GAP-9 closed):
restore_proof:
1. take the narrow GPG pg_dump into a timestamped artifact dir
2. gpg --decrypt into a transient postgres:16 container
(precedent: container `pg-restore-test-20260520T031054Z`)
3. pg_restore into the throwaway DB; assert row counts == source
4. discard the container; never restore into live `directus`
This proof cannot be executed now (no GPG key, no live backup body).
4. Rollback plan for a first live cut
sql/lifecycle/rollback_runbook.sql IS present in the v0.6 tree, but
its own header states it is a lifecycle-DDL bundle teardown for
recovery / fresh-environment use only, and it REFUSES to run
against post-Phase-7 live state (60 enacted rows). It is not a
per-document cut-revert.
A first live cut of a small new document would create new draft
information_unit / unit_version rows (+ governance rows). Reverting
that is itself a production mutation (deleting/voiding the new draft
rows) and:
- there is no tested per-document cut-revert procedure (GAP-6),
- hard delete is forbidden without explicit approval,
cutter orchestrate void(idempotency-safe clear) does not exist.
5. Compensation doctrine
on_partial_or_wrong_live_write:
- immediately set __execution_enabled__ = False (level 0)
- do NOT auto-restore; do NOT hard-delete
- record exact mutated row ids + change_set_id from the sidecar
- escalate via SG_3 failure-escalation to a SEPARATE sovereign
compensation macro
- compensation = sovereign-approved, audited, reversible-where-possible
6. Verdict
G5_backup_rollback_disable: PLAN AUTHORED — PREREQUISITES NOT MET
disable_levels_available_now: 0,1,3 (level 2 `void` missing — CLI absent)
fresh_backup_producible_now: NO (GAP-3 empty GPG keyring; GAP-9 no live body)
restore_proof_executable_now: NO
per_cut_revert_tested: NO (GAP-6 — runbook is DDL teardown only)
blocking: GAP-3, GAP-6, GAP-9
G5 = PLAN DELIVERED; backup/rollback prerequisites are OPEN.