Remove a persisted session file (compaction-transition rollback) AND its
journal, when one exists (Task 35) — a session and its journal live and
die together. A missing file is not an error — rollback must be idempotent.
Find a session by its assigned name (not partial ID).
Iterates session headers one file at a time and returns on first match,
avoiding a full directory scan when the named session appears early.
Follow the compacted_into chain from session to its final successor.
Returns the final session and a notice if any hops were taken.
Errors on cycles, missing successors, or exceeding the hop limit.
The limit most-recently-modified sessions (by file mtime), most-recent
first. Sorts the directory entries by mtime WITHOUT parsing, then reads only
the top limit headers — so /sessions is O(limit) reads instead of
O(#sessions). mtime is an exact proxy for updated_at (the file is rewritten
on every save).
Project canonical user content for display/title/compaction, never for inference.
Only top-level text and attachment labels are visible; in particular, tool
results are NOT user prompts and their nested content is never traversed.
The original message (including attachment sources) is left untouched.