Skip to content

fix(sessions): sweep orphan store temp files#90503

Open
sahibzada-allahyar wants to merge 1 commit into
openclaw:mainfrom
sahibzada-allahyar:fastino-89520-atomic-tmp-sweep-b
Open

fix(sessions): sweep orphan store temp files#90503
sahibzada-allahyar wants to merge 1 commit into
openclaw:mainfrom
sahibzada-allahyar:fastino-89520-atomic-tmp-sweep-b

Conversation

@sahibzada-allahyar

@sahibzada-allahyar sahibzada-allahyar commented Jun 5, 2026

Copy link
Copy Markdown
Contributor

Fixes #89520.

What Changed

  • Added a startup/load-time sweep for stale session store temp files matching the active store basename.
  • Preserves fresh temp files and unrelated files so an in-flight atomic write is not removed.
  • Added focused regression coverage for stale matching temps, fresh temps, unrelated temps, missing directories, and custom store basenames.

Real behavior proof

  • Behavior addressed: session store load now cleans up orphaned <store>.<pid>.<uuid>.tmp files older than five minutes, while preserving fresh or unrelated files.
  • Real environment tested: local OpenClaw source checkout on macOS arm64 (Darwin 25.5.0), Node v26.0.0.
  • Exact steps or command run after this patch:
git diff --check -- src/config/sessions/store-load.ts src/config/sessions/store-load.test.ts
node scripts/run-vitest.mjs src/config/sessions/store-load.test.ts
  • Evidence after fix:
[test] starting test/vitest/vitest.runtime-config.config.ts

 RUN  v4.1.7 /Users/allahyar/Documents/fastino-tasks/openclaw-tui-89520b


 Test Files  1 passed (1)
      Tests  4 passed (4)
   Start at  02:34:47
   Duration  884ms (transform 374ms, setup 13ms, import 802ms, tests 6ms, environment 0ms)

[test] passed 1 Vitest shard in 3.67s
  • Observed result after fix: the regression creates stale matching session-store temp files and verifies they are deleted; it also verifies fresh matching temp files, unrelated temp files, and temp files for other store basenames are preserved.
  • What was not tested: a months-long production gateway accumulation scenario.

Platforms tested

  • macOS arm64, Node v26.0.0.

Additional real checkout proof

After ClawSweeper asked for proof outside the Vitest-only path, I ran a real checkout probe that imports the actual changed sweepOrphanSessionStoreTemps function from this branch, creates a real sessions.json directory with stale, fresh, and unrelated temp files, then runs the sweep.

Exact command:

node_modules/.bin/tsx /private/tmp/openclaw-90503-proof.ts

Output:

proofDir /var/folders/zt/6txd70rn1wn9x37_3hkv_ft80000gn/T/openclaw-90503-proof-JXRX7r
before { stale: true, fresh: true, unrelated: true }
[sessions/store] deleted orphaned session store temp files
after { stale: false, fresh: true, unrelated: true }

Observed result: the stale sessions.json.<pid>.<uuid>.tmp file was removed, while the fresh matching temp file and unrelated temp file were preserved.

@openclaw-barnacle openclaw-barnacle Bot added size: S proof: supplied External PR includes structured after-fix real behavior proof. labels Jun 5, 2026
@clawsweeper

clawsweeper Bot commented Jun 5, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs maintainer review before merge. Reviewed June 4, 2026, 9:53 PM ET / 01:53 UTC.

Summary
Adds a session-store load-time sweep for stale matching atomic-write temp files and regression coverage for stale, fresh, unrelated, missing-directory, and custom-basename cases.

PR surface: Source +53, Tests +75. Total +128 across 2 files.

Reproducibility: yes. source-reproducible: current session writes stage matching temp files, and current main lacks an unconditional load-time sweep, so a stale temp beside sessions.json can remain until cleanup or disk-budget maintenance runs. I did not run a hard-kill reproduction because this review is read-only.

Review metrics: 1 noteworthy metric.

  • Runtime deletion path: 1 added. The PR adds a synchronous unlink path on session-store load, so the filename predicate and five-minute freshness guard are the key merge-safety checks.

Merge readiness
Overall: 🐚 platinum hermit
Proof: 🐚 platinum hermit
Patch quality: 🐚 platinum hermit
Result: ready for maintainer review.

Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch.

Rank-up moves:

  • none.

Next step before merge

  • No automated repair job is needed; the patch has no blocking findings and the remaining action is ordinary maintainer review and merge validation.

Security
Cleared: The diff adds constrained filesystem cleanup for stale session-store temp files and does not change dependencies, CI, secrets handling, permissions, or package execution paths.

Review details

Best possible solution:

Land the narrow load-time sweep using the existing temp filename contract and freshness guard; treat periodic cleanup as a separate defense-in-depth follow-up only if maintainers want it.

Do we have a high-confidence way to reproduce the issue?

Yes, source-reproducible: current session writes stage matching temp files, and current main lacks an unconditional load-time sweep, so a stale temp beside sessions.json can remain until cleanup or disk-budget maintenance runs. I did not run a hard-kill reproduction because this review is read-only.

Is this the best way to solve the issue?

Yes, this is an acceptable minimal fix: it reuses the existing session-store temp filename predicate and preserves fresh temps with the same five-minute safety window current cleanup already uses. A broader periodic sweep can be considered separately, but it is not required for this PR to solve startup cleanup.

AGENTS.md: found and applied where relevant.

Codex review notes: model gpt-5.5, reasoning high; reviewed against 6868cde4d45f.

Label changes

Label changes:

  • add proof: sufficient: Contributor real behavior proof is sufficient. The updated PR body includes terminal output from a real checkout probe showing the changed sweep deletes a stale matching temp file and preserves fresh and unrelated files.
  • add rating: 🐚 platinum hermit: Overall readiness is 🐚 platinum hermit; proof is 🐚 platinum hermit and patch quality is 🐚 platinum hermit.
  • add status: 👀 ready for maintainer look: ClawSweeper has no concrete contributor-facing blocker left for this PR. Sufficient (terminal): The updated PR body includes terminal output from a real checkout probe showing the changed sweep deletes a stale matching temp file and preserves fresh and unrelated files.
  • remove rating: 🦪 silver shellfish: Current PR rating is rating: 🐚 platinum hermit, so this older rating label is no longer current.
  • remove status: 📣 needs proof: Current PR status label is status: 👀 ready for maintainer look.

Label justifications:

  • P2: The PR addresses a real session-store disk-growth bug with limited surface area and focused tests, without evidence of an urgent live regression requiring P1.
  • rating: 🐚 platinum hermit: Overall readiness is 🐚 platinum hermit; proof is 🐚 platinum hermit and patch quality is 🐚 platinum hermit.
  • status: 👀 ready for maintainer look: ClawSweeper has no concrete contributor-facing blocker left for this PR. Sufficient (terminal): The updated PR body includes terminal output from a real checkout probe showing the changed sweep deletes a stale matching temp file and preserves fresh and unrelated files.
  • proof: sufficient: Contributor real behavior proof is sufficient. The updated PR body includes terminal output from a real checkout probe showing the changed sweep deletes a stale matching temp file and preserves fresh and unrelated files.
Evidence reviewed

PR surface:

Source +53, Tests +75. Total +128 across 2 files.

View PR surface stats
Area Files Added Removed Net
Source 1 53 0 +53
Tests 1 75 0 +75
Docs 0 0 0 0
Config 0 0 0 0
Generated 0 0 0 0
Other 0 0 0 0
Total 2 128 0 +128

What I checked:

  • Repository policy read: Root AGENTS.md was read fully; no scoped AGENTS.md applies to src/config/sessions, and the only maintainer note present is Telegram-specific. (AGENTS.md:1, 6868cde4d45f)
  • PR diff adds the sweep on load: The PR adds sweepOrphanSessionStoreTemps and calls it before reading sessions.json after the cache miss path. (src/config/sessions/store-load.ts:375, c68ca1c842f9)
  • Current writer temp-name contract: Current main writes session-store temp files with the store basename as tempPrefix, producing names the PR's matcher is intended to reclaim. (src/config/sessions/store.ts:895, 6868cde4d45f)
  • Existing temp predicate: Current main already centralizes matching for <store>.<pid>.<uuid>.tmp and legacy <store>.<uuid>.tmp session-store temp artifacts. (src/config/sessions/artifacts.ts:53, 6868cde4d45f)
  • Current main cleanup coverage is conditional: Current main removes stale session-store temps through disk-budget or explicit cleanup, but enforceSessionDiskBudget returns before scanning when disk-budget limits are unset or not exceeded. (src/config/sessions/disk-budget.ts:542, 6868cde4d45f)
  • Existing cleanup service path: The sessions cleanup service calls pruneUnreferencedSessionArtifacts during explicit cleanup apply, which confirms there is a maintenance path but not an unconditional load-time path. (src/config/sessions/cleanup-service.ts:560, 6868cde4d45f)

Likely related people:

  • Shakker: Current local blame for the session loader, writer temp-name contract, artifact predicate, and disk-budget temp cleanup points to Shakker, and git history also shows Shakker splitting the session store loader. (role: recent area contributor; confidence: medium; commits: 79b6dd049e4e, c2e93c76bd43; files: src/config/sessions/store-load.ts, src/config/sessions/store.ts, src/config/sessions/artifacts.ts)
  • Vincent Koc: The shallow history shows the latest release baseline commit adding the current session files, so this is weaker routing context rather than direct feature authorship. (role: release/import provenance; confidence: low; commits: 2e08f0f4221f; files: src/config/sessions/store-load.ts, src/config/sessions/store.ts, src/config/sessions/artifacts.ts)
What the crustacean ranks mean
  • 🦀 challenger crab: rare, exceptional readiness with strong proof, clean implementation, and convincing validation.
  • 🦞 diamond lobster: very strong readiness with only minor maintainer review expected.
  • 🐚 platinum hermit: good normal PR, likely mergeable with ordinary maintainer review.
  • 🦐 gold shrimp: useful signal, but proof or patch confidence is still limited.
  • 🦪 silver shellfish: thin signal; proof, validation, or implementation needs work.
  • 🧂 unranked krab: not merge-ready because proof is missing/unusable or there are serious correctness or safety concerns.
  • 🌊 off-meta tidepool: rating does not apply to this item.

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 keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.

@clawsweeper clawsweeper Bot added rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. P2 Normal backlog priority with limited blast radius. labels Jun 5, 2026
@sahibzada-allahyar

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

@clawsweeper

clawsweeper Bot commented Jun 5, 2026

Copy link
Copy Markdown
Contributor

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event repository_dispatch).
Result: the existing ClawSweeper review comment will be edited in place when the review finishes.

Re-review progress:

@clawsweeper clawsweeper Bot added proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. and removed rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. labels Jun 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

P2 Normal backlog priority with limited blast radius. proof: sufficient ClawSweeper judged the real behavior proof convincing. proof: supplied External PR includes structured after-fix real behavior proof. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. size: S status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Atomic write helper leaks orphan .tmp files; gateway never sweeps them (51 GB observed in the wild)

1 participant