Commit graph

2 commits

Author SHA1 Message Date
Doug Gabehart
46f2ddd2bc fix: close status-snapshot race, cline-cli fingerprint gap, symlinked dirs, env-var invisibility
Round 3 adversarial-panel fixes for PR #999:

- Snapshot writes now go through a per-queryKey file plus a CAS re-read
  guard before rename, closing the last-writer-wins race where a slower
  recompute against an older corpus could clobber a fresher save, and
  where distinct queryKeys used to evict each other's single shared slot
  (B-G1).
- cline-cli's discoverSessions now fingerprints the growing
  <sessionId>.messages.json sibling instead of the static
  <sessionId>.json metadata file, so new turns in a live session are no
  longer invisible to computeCorpusFingerprint (C-G1).
- computeCorpusFingerprint folds in computeEnvFingerprint per discovered
  provider, so non-discovery env vars like CODEBURN_CURSOR_MAX_BUBBLES
  and KIMI_MODEL_NAME can no longer serve a stale-forever snapshot (A-G1).
- collectFilesRecursive now resolves symlinked subdirectories and
  recurses into them (with a visited-inode guard against cycles) instead
  of misclassifying them as leaf files (C-G2).
- Added tests/session-cache-status-snapshot.test.ts covering concurrent
  writers against the snapshot file, mirroring session-cache-shards.test.ts's
  existing coverage for the main cache (D-G9).
2026-08-24 15:05:02 -05:00
Doug Gabehart
35ad1e6b3a fix(status-snapshot): address PR #999 review — 5 correctness bugs + doc relocation
Responds to ozymandiashh's CHANGES_REQUESTED review on #999.

Structural: kept the disk status-snapshot, scoped to serve's documented
CLI-spawn-fallback path, after bringing its invalidation to parity with
serve's own in-process memo (see docs/design/perf-cache-fix.md for the full
reconciliation reasoning against #972's serve.ts/watcher invalidation,
already merged into this branch's ancestry).

Correctness fixes:
1. queryKey now includes the same four pricing-config hashes parser.ts's
   own cacheKey deliberately includes (proxyPaths/modelAliases/
   priceOverrides/localModelSavings), so an edited pricing config
   invalidates the snapshot instead of waiting for an unrelated corpus
   change.
2. computeCorpusFingerprint now gives network providers (e.g.
   vercel-gateway) a now-stamped synthetic fingerprint entry every call,
   mirroring parseAllSessions' own treatment of the same sources, instead
   of letting them contribute nothing to the hash.
3. computeCorpusFingerprint generically expands any directory-shaped
   non-Claude source (e.g. mistral-vibe) via a new collectFilesRecursive
   helper, instead of only Claude getting leaf-file expansion.
4. saveStatusSnapshot is now gated on isSessionHydrationComplete(), so a
   degraded read-only parse can no longer be checkpointed as authoritative.
5. The settle-window defer in loadStatusSnapshot now anchors on wall-clock
   time since the fingerprint FIRST mismatched (persisted via a new
   mismatchFirstSeenAt field) instead of the corpus-wide newest mtime,
   which fix #2 can otherwise keep perpetually "recent."

Also fixes a 6th instance of the same defect class as #1, found while
root-causing a test failure: the query key omitted the active display
currency, so switching currencies kept serving stale numbers. Updates
tests/parse-workers.test.ts, whose "warm" assertion assumed every
menubar-json call does a full parse — no longer true within the settle
window after this PR's own snapshot feature.
2026-08-19 13:29:35 -05:00
Renamed from SPEC-perf-cache-fix.md (Browse further)