[FEATURE] PostRewind hook event: hooks that manage external state cannot observe /rewind (re-files #18858, #86283)
Preflight Checklist
- [x] I have searched existing requests and this feature hasn't been requested yet — it has, four times, and every filing was closed by the stale bot as NOT_PLANNED without being triaged: #18858 (original, by @Glucksberg), #32780, #35412, #86283 (my re-file, closed 2026-09-18). #86283 cannot be reopened, so this is the requested new issue.
- [x] This is a single feature request (not multiple features)
Problem Statement
/rewind (checkpoint restore) truncates the conversation, but no hook event fires. As of 2026-09-20 the hooks reference at https://code.claude.com/docs/en/hooks lists no rewind event. Every other conversation-shaping action has one (SessionStart, UserPromptSubmit, PreCompact, SessionEnd, ...). Rewind is the one that silently invalidates state a hook keeps outside the transcript.
Concrete case: nthdegree, a persistent-memory and message-bus backend for Claude Code. Its UserPromptSubmit hook injects delivered messages and recalled memories into the turn and advances a per-session delivery cursor. After /rewind the injected block is gone from the transcript but the cursor stays advanced, so the rewound messages are never redelivered. The agent permanently loses supervisor instructions or job reports with no error anywhere.
Same failure class as claude-mem timelines showing "ghost" activity (#18858) and stale hook output replayed after rewind (#85455). Any hook that tracks "what this conversation has seen" has it.
Proposed Solution
A PostRewind hook event, firing after the transcript is truncated. Observe-only is enough; no blocking or mutation semantics needed. Minimal payload, matching the existing BaseHookInput shape:
{
"hook_event_name": "PostRewind",
"session_id": "...",
"transcript_path": "...",
"cwd": "...",
"rewound_to_uuid": "<transcript entry the conversation was restored to>",
"removed_uuids": ["..."]
}
The SDK already has SDKControlRewindFilesRequest internally, so the harness knows when this happens; the request is to expose it to hooks.
Alternative Solutions
Current workaround: the hook stashes the uuid of the transcript entry it injected into, and on every subsequent fire scans transcript_path for it. If the anchor is gone, a rewind happened and the cursor rolls back. This works but is a per-hook reimplementation of state the harness holds authoritatively, costs a transcript scan on every prompt, and every affected hook author has to discover the failure mode the hard way first.
Polling the transcript file from a daemon and detecting via missing tool_result entries were considered in #18858 and are race-prone or unreliable.
Priority
High - Significant impact on productivity
Additional Context
Prior filings: #18858, #32780, #35412, #86283. Related: #85455.