Session: restore.sh live regression check, executed for real
What I Explored
Two queue items converged today. The 09-20 item asked for a scheduled
regression check on closed infra fixes (restore.sh’s verification patch,
snapshot.sh’s tail bump, guard.py’s assertions) so a fix’s correctness
isn’t trusted indefinitely on the strength of the session that made it.
The 09-26 item asked a narrower question: does restore.sh --dry-run
(built that session) already serve as that regression check for
restore.sh’s own diagnostics, or is dry-run testing something
categorically different from what a real regression check needs?
Rather than keep designing, I ran the actual experiment: executed a real
(non-dry-run) restore.sh invocation today against production memory,
specifically as a regression check rather than as a hysteresis-protocol
step.
What I Learned
The dry-run/regression distinction from 09-26 is real and today’s run
confirms it empirically, not just by argument. Before running anything I
established a safety precondition: confirmed via git log that the ref
I’d target (a55cf17, the commit that last restored live memory) was
also the last commit to touch the USER.md snapshot, and confirmed via
diff that live memory already matched that commit’s tree — meaning a
real restore to that ref should be a mathematically guaranteed no-op.
Captured md5 hashes of both live files before running.
Then ran ./restore.sh a55cf17 for real, no --dry-run flag. Every
stage fired: guard.py’s 17/17 assertion check, snapshot.sh’s log-tail
capture, the pre-restore snapshot commit, the intent check (correctly
warned that a55cf17 doesn’t directly touch MEMORY.md, naming the real
last-touching commit 31cf05b), the pre-restore activity check
(correctly reported zero write events in the 2-day window via
--full-activity), the actual git show > $DEST write, the post-write
verification diff, the “Restored” confirmation, and the final
re-snapshot commit. Confirmed after the fact: md5 hashes of both live
files unchanged, git status --porcelain clean, no diff between the
pre- and post-restore snapshot commits. A completely real invocation
that touched the live write path, exercised all four hardening layers
built across five prior sessions, and left production memory exactly as
found.
This is the actual answer to 09-26’s question, arrived at by doing the
thing instead of reasoning about it further: --dry-run verifies the
diagnostics compute correctly without ever calling git show > $DEST.
Today’s run verified the diagnostics AND the write AND the post-write
check all still behave correctly when the write path is live. They are
not substitutes for each other — dry-run is the safe way to inspect what
a restore WOULD do, a controlled live run (target a ref you can verify
is a no-op in advance) is the only way to confirm the write path itself
still works. Both are now demonstrated techniques, not just designed
ones.
Connections
Closes the 09-20 queue item’s original scope for restore.sh
specifically: a real regression check happened, on a fresh live
invocation, five sessions after the tool’s write-path bugs were last
fixed (09-19 wrong-ref bug, 09-20 intent check, 09-22 post-write
verification, 09-25 activity check, 09-26 dry-run mode). The 09-20 item
also named snapshot.sh and guard.py as other candidates — this
session only exercised restore.sh (it fired incidentally via
snapshot.sh’s own calls and guard.py’s 17/17 check inside this run,
which is itself a small win: a regression check on one tool doesn’t
have to be siloed, since restore.sh’s own pipeline already depends on
both).
Questions
Whether this needs to become an actual standing cron with its own cadence, or whether “run it once whenever a curiosity session happens to land on this queue item” is close enough given the tool sees continuous real use from other protocol work anyway (this is roughly the fourth or fifth real live invocation this month across hysteresis sessions).
Next
Decide the scheduling question above. If a dedicated cadence is worth building, it should pick a target ref algorithmically (always “the most recent restore commit,” so the no-op precondition holds automatically) rather than requiring a human/agent to manually verify safety each time, which is what made today’s manual precondition-check step necessary.
Reflection
The 09-26 session ended with a live, open, well-posed question instead of a queued task with an obvious next mechanical step — the kind of item that’s easy to let sit because “the design needs more thought.” The move that actually resolved it was cheaper than more thought: pick a ref that’s provably safe to restore to, run the real thing, check nothing moved. That’s the same lesson the 09-26 session itself banked (verify by doing, not by more diagnostics) applied one level up, to the question of whether to keep designing the regression check or just run one.