Skip to content

Fix Cursor agentKv timestamp attribution#345

Open
ozymandiashh wants to merge 1 commit into
getagentseal:mainfrom
ozymandiashh:fix/cursor-agentkv-timestamps
Open

Fix Cursor agentKv timestamp attribution#345
ozymandiashh wants to merge 1 commit into
getagentseal:mainfrom
ozymandiashh:fix/cursor-agentkv-timestamps

Conversation

@ozymandiashh
Copy link
Copy Markdown
Contributor

Summary

Fixes #325 by removing the remaining Cursor timestamp fallback that could attribute historical usage to the SQLite database modification time.

This is separate from the undated bubbleId:% path fixed on main: bubble rows already require createdAt. The remaining risk was agentKv, where CodeBurn still dated every parsed agentKv session with statSync(state.vscdb).mtimeMs and fell back to new Date() if the stat failed.

Root Cause

Cursor can modify state.vscdb for background maintenance, migrations, or unrelated writes. Using the database file mtime as the usage timestamp means an old agentKv conversation can be reported as new usage whenever the DB file changes.

Concrete example covered by the tests:

  1. A Cursor agentKv session contains old user/assistant content.
  2. The SQLite file mtime is changed to 2099-01-01.
  3. Before this fix, CodeBurn could date that old session using the DB mtime.
  4. After this fix, CodeBurn only reports the session when the row carries an internal timestamp.

What Changed

  • Extracts internal Cursor agentKv timestamps from createdAt, timestamp, or time.
  • Accepts ISO strings, numeric millisecond timestamps, and numeric second timestamps stored as JSON numbers or numeric strings.
  • Keeps the first valid internal timestamp seen for a request/session.
  • Skips agentKv sessions with no internal timestamp instead of using state.vscdb mtime or parse time.
  • Bumps Cursor result cache version to recompute older cached results that may contain mtime-derived timestamps.
  • Adds CODEBURN_CACHE_DIR support to the Cursor result cache so tests can isolate cache state from the user's real cache.
  • Adds focused regression coverage for the mtime failure mode and valid internal timestamp paths.

Relation To #337

#337 invalidates cached results after the undated bubble-row fix. This PR includes the same cache-version/cache-dir hunk because agentKv timestamp semantics also change and v3 caches can contain mtime-bucketed agentKv calls.

If #337 merges first, this PR can be rebased to keep the agentKv parser/tests and drop the duplicate cache hunk if needed.

Validation

  • npx vitest run tests/providers/cursor-agentkv-timestamp.test.ts tests/providers/cursor.test.ts tests/providers/cursor-bubble-dedup.test.ts tests/providers/cursor-workspace-breakdown.test.ts - 24/24 tests passed.
  • npx tsc --noEmit --pretty false - passed.
  • npm run build - passed.
  • git diff --check - passed.
  • Argus-style strict local review - PASS; scope is limited to Cursor parser/cache/changelog/tests, no private data or unrelated files.
  • Claude Opus 4.7 effort max review - PASS.
  • Gemini 3.1 Pro Preview review - PASS.

Notes

I did not validate with real local Cursor history and did not include any local project names, prompts, paths, session IDs, usage values, screenshots, or private product details. The proof uses synthetic SQLite fixtures specifically constructed to reproduce the timestamp-attribution failure mode.

The intentional tradeoff is that legacy agentKv rows without any internal timestamp are skipped. That is safer than reporting historical usage under the wrong day.

@ozymandiashh ozymandiashh marked this pull request as ready for review May 17, 2026 22:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Inaccurate usage dates for Cursor due to mtime fallback on store.db

1 participant