acpmux: fix closed summary cache invalidation

TE
4d ago
+123-36

Follow-up correctness fixes for the closed-summary cache:

  • keep list and full serialized rows on independent generations, so building one form cannot make the other form appear fresh;
  • capture the generation before constructing a row;
  • remove cached bytes when a session is purged, deleted, or reopened;
  • invalidate time-expiring tags when their deadline passes;
  • keep summary construction out of write_snapshot, avoiding nested metadata and permission locks in the writer;
  • cover list-then-full reads, appends after close, shown/attached state, tag expiry, concurrent writers, cold loading, and purge eviction against an uncached walk.

Leo asked: “you (or other guys) should audit my computer and see what is taking up all the CPU and optimize against that.” The prior cache benchmark on a profiled Mac running the NEXT nightly measured the same 7,828-record fixture (7,295 closed) at 227.378→150.376 ms for watch/list, 207.694→149.910 ms for sessions?usage, and 235.739→181.206 ms for peer summaries. These follow-ups preserve those bytes and invalidation behavior.

metricbeforeafterdeltaharness
watch/list full build CPU227.378 ms150.376 ms-33.9%measure_7828_full_idle_closed_summary_cache
sessions?usage full build CPU207.694 ms149.910 ms-27.8%measure_7828_full_idle_closed_summary_cache
peer sync summaries CPU235.739 ms181.206 ms-23.1%measure_7828_full_idle_closed_summary_cache

Validation runs through cmux-ci for the acpmux test suite and clippy.

agent-identity footer --repo manaflow-ai/cmux
Agent session: agent session


View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need.


Summary by cubic

Fixes correctness bugs in the closed-summary cache so cached rows never serve stale data, and reorders the purge event so watchers can't resolve a just-purged session.

  • Tracks list and full serialized rows on independent generations and tag-expiry deadlines, so building one form can't make the other look fresh; empty rows are never served.
  • Builds rows lazily on cache miss; write_snapshot only evicts entries, avoiding nested metadata and permission locks in the writer.
  • Evicts entries when tags expire or sessions are purged, deleted, or reopened.
  • Emits the purge event only after the session is unregistered from live lookup and its cache entry is removed.
  • Adds tests covering list-then-full reads, appends after close, shown/attached state, tag expiry, concurrent writers, cold loading, and purge eviction.