Fix session recovery persistence cleanup / 修复会话恢复持久化清理#5976
Conversation
- Replay the event log tolerantly: torn tails are truncated by the next save instead of bricking LoadSession; foreign/legacy .events.jsonl files squatting the native log path are read-ignored and never written; logs from a newer schema fail loudly instead of being silently truncated. - Bound log growth: past a size threshold the log compacts to a single replace event, and every rewrite/compaction refreshes the .jsonl checkpoint so direct readers and older binaries stay bounded-stale. - Keep force saves (subagents, guardian, migrations, forks) single-file: they never bootstrap an event log and fold an existing one instead. - Sweep the event log/index from every deletion surface through store.SessionSidecarFiles — /clear, serve delete, ACP delete, subagent delete, desktop trash — so deleted conversations cannot leak or be resurrected; guardian sidecars are excluded from transcript discovery. - Guard desktop trash/delete with an external-lease busy check so removing lease files cannot break cross-process mutual exclusion. - Migrate frozen-checkpoint readers to event-aware APIs: prompt history, serve session list, auto topic titles, duplicate-trash comparison, history search recency, and doctor byte totals. - Count recovery-copy activity in topic summaries, hide recovery-only topics only when unpinned with no live runtime session, and mark conflict copies in the session tree and History drawer.
…ry-event-log-cleanup
Review follow-ups on the event-log hardening: - Close the probe-then-delete lease window: desktop trash, reconcile, and permanent delete now take a SessionRemovalGuard that holds the session's save lock and lease lock across the whole operation (built on esengine#5977's delete-while-holding-flock primitive), so another process can no longer acquire the lease between a busy probe and the sidecar removal and then lose its freshly locked lease file. Live owners surface as a sanitized busy error; the lock files are deleted atomically with the release. - Run overlong-named sessions (pre-bounded recovery cascade names) in checkpoint-only mode: their event log/index sidecars would exceed the filesystem name limit, so the probe treats them as non-native instead of failing saves with ENAMETOOLONG. - Fix staticcheck QF1003: tagged switch for the save-reason mapping.
|
Review follow-ups addressed in 7bb7290 (after merging Lease split-window on delete/trash paths (P1). The one-shot busy probe is gone. Desktop trash, trash-reconcile, and permanent delete now acquire an Interaction found while merging #5977. Its overlong-filename test caught that the event-index sidecar ( Lint (P2). QF1003 fixed (tagged switch on the save mode). #5968. No dependency from this PR; it touches the same desktop files and will need a rebase after whichever lands first. Verification on 7bb7290: |
Summary
LoadSession; replace events and checkpoint rewrites are fsynced; past a size threshold the log compacts to a single replace event and the.jsonlcheckpoint is refreshed, so direct readers and older binaries stay bounded-stale instead of frozen at first save..events.jsonltranscript sitting at the native log path is read-ignored and preserved byte-for-byte; logs written by a newer schema fail loudly instead of being silently truncated.store.SessionSidecarFiles—/clear, serve delete, ACP delete, subagent delete, and desktop trash — so deleted conversations can neither leak on disk nor be resurrected byLoadSession.Context
This addresses the recovery-chain and stale artifact behavior discussed around #5940, #5947, and #5960. It does not claim to fix an unrelated process crash without a concrete crash log; it reduces the recovery cascade surface, makes the authoritative transcript tolerant of the crashes that used to trigger cascades, and prevents leftover lock/display/log sidecars from accumulating through the built-in cleanup and delete flows.
Verification
go test -p 1 ./...go test .fromdesktop/pnpm --dir desktop/frontend typecheckpnpm --dir desktop/frontend check:cssgit diff --checkLoadSession, external-lease trash guard, event-aware prompt history / serve list / auto titles, duplicate-trash content comparison, and the recovery-only topic hiding matrix.