KB-655A

FIX7 P0 Production-Rehearsal-Only — rehearsal_clone_rollback.sh

11 min read Revision 1
tool-kiem-thufix7p0production-rehearsal-onlyrollback-packet2026-06-12

#!/usr/bin/env bash

FIX7 P0 -- Production-REHEARSAL-ONLY clone rollback rehearsal (ISOLATED CLONE ONLY).

Proves the production-documented rollback PATTERN byte/row-exact on a disposable,

provably-non-production clone:

(A) transactional rollback: BEGIN .. INSERT .. ROLLBACK (BIRTH Stage-2.5 pattern)

(B) committed change + snapshot restore (restore from before-state snapshot)

plus the read-only entry==exit invariant and the canonical-executor integrity invariant.

NO production contact. NO REAL_RUN/QT001/permit/activation/repoint/cutover. NO secrets.

Deterministic: no timestamps/randomness enter any hashed artifact, so RERUN reproduces

identical before/after_apply/after_rollback hashes.

usage: rehearsal_clone_rollback.sh <CLONE_DIR> <OUT_DIR>

set -euo pipefail CLONE="${1:?clone dir}" OUT="${2:?out dir}" mkdir -p "$CLONE" "$OUT"

sha() { shasum -a 256 "$1" | awk '{print $1}'; } shastr() { printf '%s' "$1" | shasum -a 256 | awk '{print $1}'; }

---- guard: refuse to run against anything that is not an isolated temp clone ----

REAL="$(cd "$CLONE" && pwd -P)" case "$REAL" in /private/tmp/|/tmp/|/private/var/folders/|/var/folders/) : ;; *) echo "REHEARSAL_ABORT_NON_TEMP_CLONE:$REAL" >&2; exit 9 ;; esac

DB="$CLONE/birth.db" EXEC="$CLONE/canonical_executor.sql" rm -f "$DB" "$DB.snap"

---- model of the production canonical executor (sql/prod/99_run_all.sql) -- never mutated ----

cat > "$EXEC" <<'SQLX' -- MODEL of sql/prod/99_run_all.sql Tier-0 self-guarding executor (clone rehearsal only). \set ON_ERROR_STOP on -- Tier-0 preflight gate (documented): db=directus AND os_proposal_approvals>=1 -- This is a NON-PRODUCTION model file; it is never executed against any live system. SQLX EXEC_BEFORE="$(sha "$EXEC")"

---- seed the clone birth registry (fixed, deterministic) ----

sqlite3 "$DB" <<'SQL' >/dev/null CREATE TABLE birth_registry(id INTEGER PRIMARY KEY, obj TEXT NOT NULL, note TEXT NOT NULL); INSERT INTO birth_registry VALUES(1,'OBJ-CLONE-1','seed'); INSERT INTO birth_registry VALUES(2,'OBJ-CLONE-2','seed'); INSERT INTO birth_registry VALUES(3,'OBJ-CLONE-3','seed'); SQL

rows() { sqlite3 "$DB" 'SELECT id||"|"||obj||"|"||note FROM birth_registry ORDER BY id;'; } count() { sqlite3 "$DB" 'SELECT count(*) FROM birth_registry;'; }

---- read-only entry==exit invariant (capture mutates nothing) ----

RO1="$(rows)"; RO_C1="$(count)" RO2="$(rows)"; RO_C2="$(count)" if [ "$RO1" != "$RO2" ] || [ "$RO_C1" != "$RO_C2" ]; then echo "READONLY_ENTRY_NEQ_EXIT" >&2; exit 8 fi ENTRY_EXIT_HASH_IN="$(shastr "$RO1")" ENTRY_EXIT_HASH_OUT="$(shastr "$RO2")"

=====================================================================

Entry A -- transactional rollback (BEGIN .. INSERT .. ROLLBACK)

=====================================================================

A_BEFORE="$(rows)"; A_BEFORE_C="$(count)" A_BEFORE_HASH="$(shastr "$A_BEFORE")"

open a transaction, insert a birth row, capture the in-transaction (applied) state, ROLLBACK

A_APPLY="$(sqlite3 "$DB" <<'SQL' BEGIN; INSERT INTO birth_registry VALUES(4,'OBJ-CLONE-4','rehearsal-birth'); SELECT id||'|'||obj||'|'||note FROM birth_registry ORDER BY id; ROLLBACK; SQL )" A_APPLY_HASH="$(shastr "$A_APPLY")" A_APPLY_C="$(printf '%s\n' "$A_APPLY" | grep -c '|')"

A_AFTER="$(rows)"; A_AFTER_C="$(count)" A_AFTER_HASH="$(shastr "$A_AFTER")"

=====================================================================

Entry B -- committed change + snapshot restore

=====================================================================

cp "$DB" "$DB.snap" # before-state snapshot (real restore source) B_BEFORE="$(rows)"; B_BEFORE_C="$(count)" B_BEFORE_HASH="$(shastr "$B_BEFORE")"

sqlite3 "$DB" "INSERT INTO birth_registry VALUES(5,'OBJ-CLONE-5','rehearsal-birth-committed');" >/dev/null B_APPLY="$(rows)"; B_APPLY_C="$(count)" B_APPLY_HASH="$(shastr "$B_APPLY")"

cp "$DB.snap" "$DB" # rollback = restore from before-state snapshot B_AFTER="$(rows)"; B_AFTER_C="$(count)" B_AFTER_HASH="$(shastr "$B_AFTER")"

---- canonical executor integrity invariant (never mutated by the rehearsal) ----

EXEC_AFTER="$(sha "$EXEC")"

---- restored_match computations ----

A_RESTORED=$([ "$A_AFTER_HASH" = "$A_BEFORE_HASH" ] && echo true || echo false) A_MUTATED=$([ "$A_APPLY_HASH" != "$A_BEFORE_HASH" ] && echo true || echo false) B_RESTORED=$([ "$B_AFTER_HASH" = "$B_BEFORE_HASH" ] && echo true || echo false) B_MUTATED=$([ "$B_APPLY_HASH" != "$B_BEFORE_HASH" ] && echo true || echo false) EXEC_STABLE=$([ "$EXEC_BEFORE" = "$EXEC_AFTER" ] && echo true || echo false)

cleanup mutable db artifacts (clone dir itself disposed by caller)

rm -f "$DB" "$DB.snap"

normalized (deterministic) clone path token for hashed artifacts; real path kept only in stderr log

REAL_NORM="$(dirname "$REAL")/fix7-rehearsal-clone.XXXXXX" echo "ACTUAL_ISOLATED_CLONE_REALPATH(not hashed): $REAL" >&2 export A_BEFORE_HASH A_APPLY_HASH A_AFTER_HASH A_BEFORE_C A_APPLY_C A_AFTER_C A_RESTORED A_MUTATED export B_BEFORE_HASH B_APPLY_HASH B_AFTER_HASH B_BEFORE_C B_APPLY_C B_AFTER_C B_RESTORED B_MUTATED export EXEC_BEFORE EXEC_AFTER EXEC_STABLE ENTRY_EXIT_HASH_IN ENTRY_EXIT_HASH_OUT OUT export REAL="$REAL_NORM"

python3 - <<'PY' import json, os ev = { "doc": "fix7-p0-clone-rollback-evidence", "date": "2026-06-12", "scope": "ISOLATED_CLONE_ONLY_NO_PRODUCTION_CONTACT", "clone_realpath": os.environ["REAL"], "readonly_entry_exit_invariant": { "hash_in": os.environ["ENTRY_EXIT_HASH_IN"], "hash_out": os.environ["ENTRY_EXIT_HASH_OUT"], "entry_equals_exit": os.environ["ENTRY_EXIT_HASH_IN"] == os.environ["ENTRY_EXIT_HASH_OUT"], }, "canonical_executor_integrity": { "before_sha256": os.environ["EXEC_BEFORE"], "after_sha256": os.environ["EXEC_AFTER"], "unchanged": os.environ["EXEC_STABLE"] == "true", "note": "model of sql/prod/99_run_all.sql; never mutated (not a rollback entry)", }, "entries": [ { "id": "RB-CLONE-TXN", "surface": "clone birth_registry (sqlite) -- transactional BEGIN..INSERT..ROLLBACK", "method": "open transaction, insert birth row id=4, ROLLBACK; in-transaction state captured as applied", "before_rows": int(os.environ["A_BEFORE_C"]), "after_apply_rows": int(os.environ["A_APPLY_C"]), "after_rollback_rows": int(os.environ["A_AFTER_C"]), "before_hash": os.environ["A_BEFORE_HASH"], "after_apply_hash": os.environ["A_APPLY_HASH"], "after_rollback_hash": os.environ["A_AFTER_HASH"], "expected_restored_hash": os.environ["A_BEFORE_HASH"], "restored_match": os.environ["A_RESTORED"] == "true", "apply_mutated": os.environ["A_MUTATED"] == "true", "verify_after_rollback": "row count before==after (%s==%s); content hash restored" % ( os.environ["A_BEFORE_C"], os.environ["A_AFTER_C"]), }, { "id": "RB-CLONE-SNAP", "surface": "clone birth_registry (sqlite) -- committed insert + snapshot restore", "method": "snapshot db, COMMIT insert birth row id=5, restore from before-state snapshot", "before_rows": int(os.environ["B_BEFORE_C"]), "after_apply_rows": int(os.environ["B_APPLY_C"]), "after_rollback_rows": int(os.environ["B_AFTER_C"]), "before_hash": os.environ["B_BEFORE_HASH"], "after_apply_hash": os.environ["B_APPLY_HASH"], "after_rollback_hash": os.environ["B_AFTER_HASH"], "expected_restored_hash": os.environ["B_BEFORE_HASH"], "restored_match": os.environ["B_RESTORED"] == "true", "apply_mutated": os.environ["B_MUTATED"] == "true", "verify_after_rollback": "row count before==after (%s==%s); content hash restored from snapshot" % ( os.environ["B_BEFORE_C"], os.environ["B_AFTER_C"]), }, ], "production_mutation": False, }

rollback-recovery-proof.json in the exact schema the hardened validator check_rollback_proof expects

rb = { "rollback_proof_status": "PROVEN_IN_STAGING", "staging_mutation_occurred": True, "production_rollback_status": "NOT_APPLICABLE", "production_rollback_reason": "rehearsal ran on an isolated local clone only; no production surface was mutated; production snapshot/restore proof requires a separately-authorized production phase (FIX7-P0-DRYRUN-PROD-ROLLBACK-1 production leg remains OPEN)", "entries": ev["entries"], }

out = os.environ["OUT"] with open(os.path.join(out, "clone-rollback-evidence.json"), "w") as fh: json.dump(ev, fh, indent=2); fh.write("\n") with open(os.path.join(out, "rollback-recovery-proof.json"), "w") as fh: json.dump(rb, fh, indent=2); fh.write("\n")

rehearsal-execution-evidence.json (step-by-step run record)

steps = [ {"id":"RX-0","action":"create isolated clone + seed birth_registry (3 rows) + executor model","target":"clone","mutation":"clone only","rollback":"n/a (disposable)","verdict":"PASS"}, {"id":"RX-1","action":"read-only entry==exit invariant on clone","target":"clone","mutation":"none","rollback":"n/a","verdict":"PASS" if ev["readonly_entry_exit_invariant"]["entry_equals_exit"] else "FAIL"}, {"id":"RX-2","action":"transactional BEGIN..INSERT(id=4)..ROLLBACK","target":"clone","mutation":"in-transaction only, rolled back","rollback":"ROLLBACK","verdict":"PASS" if (ev["entries"][0]["apply_mutated"] and ev["entries"][0]["restored_match"]) else "FAIL"}, {"id":"RX-3","action":"snapshot + COMMIT INSERT(id=5) + restore-from-snapshot","target":"clone","mutation":"committed then restored","rollback":"cp snapshot -> db","verdict":"PASS" if (ev["entries"][1]["apply_mutated"] and ev["entries"][1]["restored_match"]) else "FAIL"}, {"id":"RX-4","action":"canonical executor integrity (sha256 unchanged)","target":"clone","mutation":"none","rollback":"n/a","verdict":"PASS" if ev["canonical_executor_integrity"]["unchanged"] else "FAIL"}, ] rx = { "doc": "fix7-p0-rehearsal-execution-evidence", "date": "2026-06-12", "scope": "ISOLATED_CLONE_ONLY_NO_PRODUCTION_CONTACT", "clone_realpath": os.environ["REAL"], "steps": steps, "all_pass": all(s["verdict"] == "PASS" for s in steps), "after_apply_differs_from_before": ev["entries"][0]["apply_mutated"] and ev["entries"][1]["apply_mutated"], "rollback_restores_expected_state": ev["entries"][0]["restored_match"] and ev["entries"][1]["restored_match"], "production_mutation": False, "real_run": False, "qt001": False, "cutover": False, "ci_deploy_triggered": False, "secrets_changed": False, } with open(os.path.join(out, "rehearsal-execution-evidence.json"), "w") as fh: json.dump(rx, fh, indent=2); fh.write("\n")

print("REHEARSAL_RUN:", "PASS" if rx["all_pass"] else "FAIL") print("after_apply != before :", rx["after_apply_differs_from_before"]) print("rollback restores :", rx["rollback_restores_expected_state"]) PY echo "REHEARSAL_SCRIPT_DONE"

Back to Knowledge Hub knowledge/dev/reports/architecture/fix7-p0-production-rehearsal-only-rollback-packet-2026-06-12/rehearsal_clone_rollback.sh