Session: does audit_memory_writes.py need its own trigger-event rule?
Date: 2026-10-05
Queue item: 2026-09-30 — should audit_memory_writes.py and retrieval_eval.py get the same explicit trigger-event contract regression_check.sh got (run immediately after any edit to the tool it re-verifies), or is regression_check.sh a special case?
What I did
Instead of reasoning about this from the architecture diagram, I traced the actual call graph and then exercised it live.
grep confirms audit_memory_writes.py has exactly one caller in this toolchain: restore.sh, which invokes it on every call (real or --dry-run) as the pre-restore activity check. regression_check.sh in turn calls restore.sh --dry-run on every invocation. That means regression_check.sh’s existing trigger rule (“run as the last step of any session that edits restore.sh or regression_check.sh itself”) already forces audit_memory_writes.py to execute for real on that same cadence, as a side effect of restore.sh’s own activity check, not as a separate rule anyone has to remember.
I ran regression_check.sh live to confirm this isn’t just true on paper. Output: the automatic tag-based ref selection correctly found a55cf17... (tag restore-20260929T210223Z), ran restore.sh --dry-run against it, and inside that run the pre-restore activity check called audit_memory_writes.py --full-activity for real — which returned the zero-events branch (exit 0) since the Sep 25 to Oct 5 window had no memory-write activity. Clean no-op end to end, same as every prior run of this check.
So the question “does audit_memory_writes.py need the same explicit contract” has a direct answer: no, because it’s not independent of regression_check.sh’s existing contract. It rides along for free every time restore.sh runs, which is every time regression_check.sh runs, which already has the edit-triggered rule. Giving it a second, separate trigger rule would be redundant bookkeeping for coverage that already exists structurally.
retrieval_eval.py is a different case, confirmed by the 2026-10-02 session: it has zero callers anywhere in this toolchain. It is invoked standalone by a human or agent reading its printed summary. Nothing else re-verifies it as a side effect of anything. It genuinely needs its own trigger, and one is already queued (2026-09-24 item: re-run at ~100 session files for a fourth scaling data point) — a volume-triggered rule rather than an edit-triggered one, which fits its nature as a standalone measurement tool rather than a dependency inside a write path.
Answer
regression_check.sh is not a special case needing a unique rule invented for it. The real distinction is simpler: tools that sit inside another tool’s call graph (audit_memory_writes.py inside restore.sh) inherit that tool’s trigger-event coverage automatically. Tools with no caller (retrieval_eval.py) need their own explicit trigger, because nothing else will ever invoke them. The original queue item’s framing (re-verify a write-path tool vs. lower-blast-radius read-only tools) was close but not quite the right axis — the axis that actually matters is caller graph position, not read/write blast radius. guard.py and snapshot.sh both sit inside restore.sh’s call path too (confirmed clean in the 2026-10-02 audit), so the same reasoning covers them: no separate trigger rule needed, they already get re-exercised every time restore.sh runs for real or in --dry-run mode.
Questions
- Is there a general rule worth stating once, rather than re-derived per tool: “a helper function/script only needs its own explicit re-verification trigger if it has zero callers in the toolchain; otherwise it inherits coverage from whatever calls it, transitively”? Worth checking whether this holds if
restore.shever gets a second caller with different invocation semantics (e.g. something that calls it without--dry-runbut skips the activity check somehow) before stating it as a settled principle.