Skip to content

fix(usage): prune stale usage cache temp files#93725

Merged
vincentkoc merged 1 commit into
openclaw:mainfrom
markoub:markoub/prune-usage-cache-temps
Jun 16, 2026
Merged

fix(usage): prune stale usage cache temp files#93725
vincentkoc merged 1 commit into
openclaw:mainfrom
markoub:markoub/prune-usage-cache-temps

Conversation

@markoub

@markoub markoub commented Jun 16, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Problem: stale .usage-cost-cache*.tmp files can remain beside the durable usage-cost cache after older cache writers or hard process termination.
  • Why it matters: these orphaned files can silently consume disk in agent session directories.
  • What changed: usage-cost cache refresh now prunes stale usage-cache temp files after acquiring the cache refresh lock, while preserving recent temp files and lock-write temp files.
  • Scope boundary: cache contents, pricing calculations, transcript scanning, lock semantics, and normal atomic cache writes are unchanged.

Change Type

  • Bug fix
  • Feature
  • Refactor required for the fix
  • Docs
  • Security hardening
  • Chore/infra

Scope

  • Gateway / orchestration
  • Skills / tool execution
  • Auth / tokens
  • Memory / storage
  • Integrations
  • API / contracts
  • UI / DX
  • CI/CD / infra

Linked Issue/PR

Closes #78939

Real behavior proof

  • Behavior or issue addressed: stale usage-cost cache temp files are reclaimed during cache refresh instead of remaining indefinitely in agent session directories.
  • Real environment tested: macOS local source checkout, Node v26.3.0, pnpm v11.2.2, temporary OPENCLAW_STATE_DIR.
  • Exact steps or command run after this patch: created a temporary OpenClaw state dir, seeded a real agent session transcript, wrote stale legacy/current usage-cache temp files plus a recent usage-cache temp file and a lock temp file, then imported and called refreshCostUsageCache() and loadCostUsageSummaryFromCache() with node --import tsx.
  • Evidence after fix:
{
  "result": "refreshed",
  "staleLegacyExists": false,
  "staleCurrentExists": false,
  "recentTempExists": true,
  "lockTempExists": true,
  "totalTokens": 30,
  "totalCost": 0.03,
  "cacheStatus": "fresh"
}
  • Observed result after fix: both stale temp-file shapes were removed, the recent temp file and lock temp file were preserved, refresh returned refreshed, and the cache summary reported fresh with the expected totals.
  • What was not tested: live production cleanup on the reporter's Windows session store.

Root Cause

Current cache writes use the atomic replacement helper, which cleans up its own active temp path for ordinary failures. It does not sweep temp files left by older builds or hard exits, and the locked refresh path had no stale-temp reclamation step.

Regression Test Plan

  • Target test: src/infra/session-cost-usage.test.ts
  • Scenario locked in: cache refresh removes stale legacy and current usage-cost temp-file shapes while preserving recent temp files, preserving lock temp files, and producing a fresh usable cache.

Security Impact

  • New permissions/capabilities? No
  • Secrets/tokens handling changed? No
  • New/changed network calls? No
  • Command/tool execution surface changed? No
  • Data access scope changed? No

Validation

  • pnpm install --frozen-lockfile passed.
  • node scripts/run-vitest.mjs run --config test/vitest/vitest.infra.config.ts src/infra/session-cost-usage.test.ts -t "reclaims stale usage cache temp files before refreshing" --reporter=verbose passed: 1 test passed.
  • node scripts/run-vitest.mjs run --config test/vitest/vitest.infra.config.ts src/infra/session-cost-usage.test.ts passed: 53 tests passed.
  • node scripts/run-tsgo.mjs -p tsconfig.core.json --incremental --tsBuildInfoFile .artifacts/tsgo-cache/core.tsbuildinfo passed.
  • node scripts/run-tsgo.mjs -p test/tsconfig/tsconfig.core.test.json --incremental --tsBuildInfoFile .artifacts/tsgo-cache/core-test.tsbuildinfo passed.
  • node scripts/test-projects.mjs --changed origin/main passed: infra shard, 53 tests passed.
  • PATH="/opt/homebrew/opt/corepack/bin:$PATH" OPENCLAW_CHECK_CHANGED_REMOTE_CHILD=1 OPENCLAW_CHANGED_LANES_RAW_SYNC=1 CI=1 PNPM_CONFIG_VERIFY_DEPS_BEFORE_RUN=false node scripts/check-changed.mjs passed locally. The default Testbox delegation could not run because Blacksmith auth is not configured on this machine.
  • git diff --check passed.
  • .agents/skills/autoreview/scripts/autoreview --mode local passed: no accepted/actionable findings.

AI Assistance

AI-assisted: yes. I used AI assistance to inspect the issue, implement the narrow fix, run local validation, and prepare this PR text. No assistant signature, co-author footer, or generated-by footer is included.

@openclaw-barnacle openclaw-barnacle Bot added size: S proof: supplied External PR includes structured after-fix real behavior proof. labels Jun 16, 2026
@vincentkoc vincentkoc self-assigned this Jun 16, 2026
@vincentkoc

Copy link
Copy Markdown
Member

Land-ready maintainer verification:

  • Whole-path review: cleanup runs only after the usage-cache refresh lock, preserves recent temp files and lock-write temps, and matches the atomic cache temp naming contract.
  • node scripts/run-vitest.mjs src/infra/session-cost-usage.test.ts — 53 passed.
  • Focused oxlint and git diff --check origin/main...HEAD — passed.
  • Fresh branch autoreview — clean, no accepted/actionable findings.
  • Exact head f23e2302f983b6b1a81d9745a14df65a2967c9cd — no failed or pending check runs.

Known gap: I did not repeat the reporter-class Windows filesystem scenario; the PR's deterministic cleanup proof and focused regression cover the same stale/recent/lock-temp contract.

@vincentkoc
vincentkoc merged commit c6b1921 into openclaw:main Jun 16, 2026
177 of 182 checks passed
github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request Jun 17, 2026
crh-code pushed a commit to crh-code/openclaw that referenced this pull request Jun 18, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

proof: supplied External PR includes structured after-fix real behavior proof. size: S

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Usage-cost cache leaves orphaned .usage-cost-cache.json.*.tmp files in agent session stores

2 participants