Dashboard sessions endpoints treated compression-continuation children as
independent rows in two places:
- /api/sessions/stats counted every physical row, so total/active_store/
archived were inflated by the hidden chain links while the paired
list_sessions_rich page collapses each chain to one row (#54298).
- The bulk and single delete endpoints removed only the selected physical
row. A list row carries the chain tip's id, so the root survived and the
next list reload re-projected it onto the previous link — deleted
conversations reappeared (#57543).
delete_session/delete_sessions gain include_compression_chain (opt-in; the
dashboard endpoints pass True). Lineage expansion walks compression edges in
both directions with the same edge definition as get_compression_tip and the
list-projection CTE (branch/reset/delegate/tool children excluded), collects
stale sibling continuations, threads the write-guard pass through the
expanded lineage, sweeps transcript files of every chain member, and keeps
the returned count equal to the selected rows. The default stays chain-blind
for existing callers (CLI /exit --delete, ACP, gateway API).
Fixes#54298, Fixes#57543
Salvaged from #54300 (stats exclude_children; @liuhao1024) and #57996
(lineage expansion; @draix), adapted onto the web_routers split and the
guard-aware delete paths.
Co-authored-by: liuhao1024 <sunsky.lau@gmail.com>
Co-authored-by: draix <draixagent@gmail.com>