ACP v0.9 has no per-session destroy, so the adapter's stdio shutdown is
the session end — but nothing ever wrote it: session rows created with
source="acp" kept ended_at NULL forever, the ended-session guard in
hermes_state_maintenance (prune/archive share it) could never select
them, and the desktop recents list accumulated one auto-titled row per
editor wake.
- SessionManager.end_all_sessions(): best-effort end_session("acp_disconnect")
for every live session; called from entry.py's finally so EOF, SIGINT and
a crash all stamp the rows.
- _restore() reopens a row ended by a previous adapter process before
resuming it — the same contract the TUI gateway's cold resume uses, so
load/resume across editor restarts keeps working.
- Desktop sidebar: 'acp' joins SIDEBAR_EXCLUDED_SOURCES (recents) and
LOCAL_SESSION_SOURCE_IDS (keeps it out of the messaging slice); the
conversations live in the editor, not the app's recents.
The prune/archive "open session(s) also match these filters" warning the
issue asks for already exists on main (count_open_prune_matches in
_cmd_prune_or_archive).