FIX7 P0 Rollback-Validator Hardening Report (2026-06-11)
FIX7 P0 — Rollback-Validator Hardening Report (2026-06-11)
- Macro:
FIX7_P0_PRE_EXECUTION_HARDENING_AND_GOVERNANCE_CONSOLIDATION_MACRO_2026_06_11 - Authority:
PRE_EXECUTION_HARDENING_NON_AUTHORITY. Authorizes nothing. Staging/paper-only. - Final status:
FIX7_P0_PRE_EXECUTION_HARDENING_READY_GOVERNANCE_FOLD_PENDING - Production mutation: NO · Implementation execution: NO · REAL_RUN/QT001/cutover: NO
- Patch packet:
knowledge/dev/reports/architecture/fix7-p0-rollback-validator-hardening-packet-2026-06-11/(packet tree59788d04c8d7afb01b28e7c05f23aa9c2b708f03d5dae02096c4c024287e20e4) - Addresses:
T2-REC-ROLLBACK-HARDENING-1(non-blocking recommendation from the T2 independent review, which itself returnedT2_FIX7_P0_DRYRUN_EXECUTION_READINESS_REVIEW_PASS).
1. What was hardened
The original dry-run validator check_rollback_proof
(dryrun_validator.py, sha256 7fb2f11e8baec9703faefbb86c23b161366b75340d98860c5c87977ee7bcb297,
inside fix7-p0-dryrun-and-execution-readiness-packet-2026-06-11, tree 02b200e5…94e6)
verified that each rollback entry had before_hash/after_apply_hash/after_rollback_hash
present and that before_hash == after_rollback_hash (restored). It did not verify that
after_apply_hash != before_hash — so a fabricated proof in which the "apply" step changed
nothing (apply hash equal to before hash) could pass as "rollback proven".
hardened_dryrun_validator.py is a strict superset of the original — same byte-faithful
logic for all 11 gates, with rollback hardening added in check_rollback_proof.
A. Hardening target table
| file | current rule | missing guard | proposed patch | safe to patch? |
|---|---|---|---|---|
dryrun_validator.py check_rollback_proof |
before/after_apply/after_rollback present; before == after_rollback; restored_match True; production_rollback_status ∈ {None, NOT_APPLICABLE} | no check that after_apply_hash != before_hash → fake proof with no real mutation passes |
add ROLLBACK_APPLY_DID_NOT_MUTATE when both hashes present and equal; add optional expected_restored_hash pin check (ROLLBACK_NOT_RESTORED_TO_PIN) |
YES — additive only; removes no gate; preserves ABSENT sentinel; published as a separate hardened file, not an in-place rewrite |
The full required-guard set is now enforced when rollback_proof_status == PROVEN_IN_STAGING:
before_hash present · after_apply_hash present · after_rollback_hash present ·
after_apply_hash != before_hash · after_rollback_hash == before_hash (or == expected_restored_hash) ·
production_rollback_status stays NOT_APPLICABLE (production mutation forbidden).
2. Probes (Workstream B)
hardened_bad_input_probes.py runs against the real frozen T1 rollback evidence
(valid_evidence_recheck.json, entries copied byte-for-byte from rollback-recovery-proof.json
sha256 07acdf19…37ba). Result: 7/7 fail-closed, control passes, any_fail_open=false
(hardening_probe_results.json):
| # | probe | result | code(s) |
|---|---|---|---|
| 1 | after_apply_hash == before_hash while claiming mutation |
FAIL-CLOSED | ROLLBACK_APPLY_DID_NOT_MUTATE:RB-3 |
| 2 | missing after_apply_hash |
FAIL-CLOSED | ROLLBACK_ENTRY_MISSING_HASH:RB-3:after_apply_hash |
| 3 | missing before_hash |
FAIL-CLOSED | ROLLBACK_ENTRY_MISSING_HASH:RB-3:before_hash (+ NOT_RESTORED) |
| 4 | missing after_rollback_hash |
FAIL-CLOSED | ROLLBACK_ENTRY_MISSING_HASH:RB-3:after_rollback_hash (+ NOT_RESTORED/PIN) |
| 5 | production rollback claimed despite no production mutation | FAIL-CLOSED | PRODUCTION_ROLLBACK_CLAIMED |
| 6 | rollback proof claimed but no rollback step | FAIL-CLOSED | ROLLBACK_PROVEN_BUT_NO_MUTATION; ROLLBACK_PROVEN_NO_ENTRIES |
| 7 | valid existing T1 rollback evidence still passes | PASS (clean) | — |
No invalid input emitted any PASS/digest/cert/seal-like token (leak check enforced in expect_fail).
3. Valid-evidence recheck + no-regression
B. Rollback proof evidence table (real frozen T1 entries, hardened verdict)
| step | before hash | after_apply_hash | after_rollback_hash | distinct apply? | restored? |
|---|---|---|---|---|---|
| RB-2 | ABSENT | 30bdca6e… | ABSENT | YES (real hash ≠ ABSENT) | YES (absent again) |
| RB-3 | 49c386a9… | 91c520d9… | 49c386a9… (== pin) | YES | YES (== before/pin) |
| RB-4 | ABSENT | 1cddd95e… | ABSENT | YES (real hash ≠ ABSENT) | YES (absent again) |
hardened_dryrun_validator.py --selftest → PASS (real evidence passes; fabricated
no-mutation rollback fails closed). Exit 0.
No-regression cross-check (reconstructed the real dry-run packet, tree 02b200e5…94e6):
- original
dryrun_validator.py→ PASS (exit 0) — reproduces T1's verdict; hardened_dryrun_validator.pyfull-packet mode → PASS (exit 0) — hardened validator still accepts the real packet;- original 20
bad_input_probes.py→ 20/20 fail-closed (exit 0).
So the hardening neither breaks valid evidence nor weakens any existing gate.
4. Packet integrity
bash RERUN.sh → RERUN_RESULT: PASS; shasum -c HASH_MANIFEST.txt all OK;
packet_tree.sha256 == sha256(HASH_MANIFEST.txt) = 59788d04…e20e4.
KB round-trip: all 11 files re-fetched untruncated; 10 ASCII files' stored length equals their
local byte length exactly (byte-identical); README multibyte-consistent.
5. Boundaries honored
The original dry-run packet, its verdict history, and the T2/Codex review artifacts were not
modified or deleted. This is a patch packet marked REQUIRED_FOR_FUTURE_EXECUTION_MACRO. No N7/N8/P7
alteration. No production. No implementation execution. No REAL_RUN/QT001/permit/activation/repoint/cutover.
6. Disposition
The hardened validator is required for any future
AUTHORIZE_IMPLEMENTATION_EXECUTION_NO_PRODUCTION macro: it must replace dryrun_validator.py
as the rollback gate. Until then, nothing executes. Default owner decision: HOLD.