Hooks break after context compaction: transcript_path points to frozen JSONL
Summary
PreToolUse and Stop hooks that read transcript_path to inspect tool evidence fail silently after context compaction. The session JSONL is frozen at compaction time, so hooks read stale data from a prior session window rather than the current turn.
Observed behavior
skills-reader-enforcer(PreToolUse): reads frozen transcript, finds an old INDEX read in a prior turn, returnsskills_read=yes, and passes the gate — even though the current turn never read the skills index. The hook is supposed to block writes to sensitive paths unless the skills index is read first.assertion-checker(Stop): reads frozen transcript, finds no tool calls for the current turn, and either emitsSTALE_IGNOREor fails closed depending on how staleness is handled. The checker added a stale-transcript wait loop as a workaround, but it is fragile.
Root cause
After compaction, transcript_path in the hook payload continues to point to the old JSONL file. New tool calls in the resumed session are not appended to that file. Hooks that use transcript_path to reconstruct "what happened this turn" therefore see an empty or stale picture of the current turn.
Expected behavior
After compaction, transcript_path should either:
- Point to a new JSONL that captures the resumed session, or
- The hook payload should include a
turn_start_indexor similar field that lets hooks identify where the current turn begins even in a continuous file, or - The docs should clearly state that
transcript_pathis unreliable post-compaction so hook authors know to handle it
Workaround applied
Added a stale-transcript detection block to skills-reader-enforcer: check stat -f%m on the file, wait up to 30 s for it to update, block fail-closed if it never does. This is a fragile workaround — it adds latency and still may not work if the resumed session writes to a different path.
Environment
- Claude Code (claude.ai/code)
- macOS 14
- Hook type:
PreToolUse,Stop - Trigger: context compaction (long sessions that exceed context window)