c3de99bbf0
CLI `_rewind_persisted_user_turn`, TUI `_rewind_active_session_history` and gateway `rewind_session` each re-ran get_active_message_ids -> get_messages_as_conversation -> split_user_originated_turn -> rewind_to_message with their own warm/durable comparison helpers and three different out-of-range contracts (RuntimeError / ValueError / None). The durable transcript is the authority for a rewind, so the implementation now lives with the data: `SessionDB.rewind_user_turn` (hermes_state_rewind.py) with one typed out-of-range error (`RewindTargetUnavailableError`). Surfaces keep only lock, eviction and rendering glue and map that error to their own message.