perf(sessions): share one enumeration across archive retention sweeps#91957
Conversation
|
Codex review: needs maintainer review before merge. Reviewed June 15, 2026, 7:07 AM ET / 11:07 UTC. Summary PR surface: Source +20, Tests +104. Total +124 across 5 files. Reproducibility: yes. Current main shows save-time maintenance calls Review metrics: none identified. Stored data model Merge readiness Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch. Rank-up moves:
Risk before merge
Maintainer options:
Next step before merge
Security Review detailsBest possible solution: Land the focused internal coalescing change after normal maintainer review, while leaving broader session-listing cache and reset-retention cleanup-service work to their separate PRs. Do we have a high-confidence way to reproduce the issue? Yes. Current main shows save-time maintenance calls Is this the best way to solve the issue? Yes. Coalescing rules at AGENTS.md: found and applied where relevant. Codex review notes: model internal, reasoning high; reviewed against e7ee1c55b433. Label changesLabel changes:
Label justifications:
Evidence reviewedPR surface: Source +20, Tests +104. Total +124 across 5 files. View PR surface stats
What I checked:
Likely related people:
What the crustacean ranks mean
Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics. How this review workflow works
|
|
/clawsweeper re-review |
|
🦞🧹 I asked ClawSweeper to review this item again. Re-review progress:
|
VerificationTested rebased onto current Affected suites — 24 files / 213 tests passed (Testbox Behavioral E2E (real
Checks (Testbox Not run: live NFS re-trace (as noted in the description) — the readdir-count proof is the in-process equivalent of the captured two-scans-per-save signature. |
…openclaw#91957) Co-authored-by: Alex Knight <[email protected]>
…openclaw#91957) Co-authored-by: Alex Knight <[email protected]>
…openclaw#91957) Co-authored-by: Alex Knight <[email protected]>
Summary
Every non-warn session-store save runs archived-transcript retention cleanup, and reset-archive retention defaults on (
resolveResetArchiveRetentionMsfalls back topruneAfterMswhen unset). SosaveSessionStoreUnlockedinvokedcleanupArchivedSessionTranscriptstwice back-to-back — reason"deleted", then reason"reset"— and each call performed its own fullreaddirof the per-agent sessions directory. Session-store saves happen per agent turn, which means active agents paid two full directory enumerations per turn by default.A production NFSv4.1 profile (Node trace of an active agent) captured exactly this signature: scans of
agents/main/sessionsin back-to-back pairs (inter-scan gaps of +0.00s), 3.4–3.8s per scan (~100 entries, with the NFS server amplifying each READDIR into per-entry metadata reads), each pair immediately preceding thesessions.jsonstore write — ~21.7s of directory enumeration inside a 27-second active window. The pairs also serialize against transcript-append lock traffic on the same directory (lock open/unlink stalls of 2.6–3.5s while a scan is in flight).The fix makes retention rules share one listing:
cleanupArchivedSessionTranscriptsnow acceptsrules: Array<{ reason, olderThanMs }>and applies every rule from a singlereaddirper directory. An archive filename carries exactly one.{reason}.{timestamp}suffix, so per-entry matching is first-match.readSessionsDirFilesstat'd every session file serially; stats now run with bounded concurrency (8), so a budget sweep no longer serializes ~N per-file latency round trips on networked filesystems.Behavior is otherwise preserved: identical removal semantics per reason/threshold, same
removed/scannedaccounting, all callers migrated in this change.Related work on the other enumeration sources the same investigation surfaced: #91091 (destructive sweeps must not act on failed enumerations) and #91841 (memory delta syncs stop full-scanning). This PR removes the store-save scan-pair source the trace actually captured.
Verification
node scripts/run-vitest.mjs src/gateway/session-transcript-files.fs.archive-cleanup.test.ts src/gateway/session-transcript-files.fs.archive-events.test.ts src/config/sessions/disk-budget.test.ts src/config/sessions/store.pruning.integration.test.ts src/commands/sessions-cleanup.test.ts— all 3 Vitest shards passed.pnpm tsgo:core,pnpm tsgo:core:test,node scripts/run-oxlint.mjson touched files — clean.readdir(spy-counted); per-rule age thresholds applied independently; archives whose reason has no rule are preserved; invalid rules dropped with no listing at all.sessions.jsonwrite should become single scans.