mirror of
https://github.com/stablyai/orca.git
synced 2026-10-31 17:17:38 +00:00
* Persist session parse results beyond the memory cache limit * Expire Session History parse rows by idle time instead of a count cap The parse cache dropped its oldest row once it held 4,096, so a scan over more transcripts evicted its own upcoming hits and re-parsed every file on every scan. Rows now stay until no reader has used them for 24 hours, swept after each completed History scan and each search-index pass. Only the live parser state keeps a 4,096 count bound; dropping it costs one whole re-read of a file that changed, never a re-parse of one that did not. Removes the overflow directory and the orcad persistence wiring from the earlier revision of this change. * Expire only rows History lists, and keep the newest transcripts under bounds The search pass ran the idle sweep every 20 s but never re-stores History's unchanged rows, so with search on a day away from History dropped them all and reopening it re-parsed everything. Only a completed History scan sweeps now, and it expires only rows History listed (on a monotonic clock). Rows only the search index or a title lookup created keep main's 4,096 count bound, so an index build can't grow the scanner process without limit. Scans store newest transcripts first, so every store-order bound dropped the newest, most active files: the saved snapshot kept the oldest ~11k rows and the resume bound stripped the newest files' parser state. The snapshot is now ordered by transcript mtime, and both count bounds drop the tenth of their rows with the oldest transcripts. * Drop the 24 h idle sweep; History rows live for the process The sweep let whichever listing ran last decide when a row died, and listings differ in scope: a smaller one (the phone's Agent History, a lower desktop limit) expired rows only a larger one used, so the next Unlimited scan re-parsed them. Rows History lists now live as long as the scanner process; the snapshot's newest-transcripts cap bounds what survives a reload, and rows other readers made keep the 4,096 bound. Also clears the resume bookkeeping for a row the unlisted bound drops in the same store. * Skip resume bookkeeping for a row the unlisted bound just dropped Running the resume trim first let a row the unlisted trim then deleted push the resume set over its bound and cost 409 live resume points. * perf(ai-vault): store the Session History parse cache one row per transcript The parse cache was persisted as one JSON file, rewritten whole after any change and capped at 64 MB / 1M tokens (about 11k rows). Past that cap, a restart re-read the oldest unchanged transcripts, and an agent writing while History was open rewrote 10-27 MB every few seconds. The scanner child now keeps the rows in their own SQLite file. A miss in the in-memory map reads the row by path; changes are written per row, debounced and chunked; deletes run immediately. A used_at column, refreshed at most daily, expires rows nothing has used for 30 days, so rows for transcripts deleted outside Orca have a way to die. The old JSON file is imported once and removed. Electron main only records the path for the child. The rebuild-on-corruption open moves out of the search index into a shared versioned cache database helper used by both. * fix(ai-vault): import the old parse cache at open and expire rows only for missing transcripts Review round 1 on the per-row parse cache store: - The old JSON was imported only by a History scan or search pass, and only into an empty database, but deleted either way. Tab-title sync writes a row first, so the import was skipped and the first History open after updating re-read everything. The import now runs when the database opens, before any lookup, write or delete can reach it, keeping rows already present. - A 30-day last-use expiry also dropped rows for transcripts that still exist, so opening History less than monthly re-read them. Rows unparsed for 30 days are now checked on disk and dropped only when the transcript is gone, then the freed pages are reclaimed. The daily last-use rewrite goes away. - 8 KB pages (a ~2.3 KB row filled a 4 KB page), busy_timeout before the WAL switch, and lookups served from rows still waiting to be written. - Revert accidental pnpm-lock.yaml churn. * chore: revert accidental pnpm-lock.yaml churn * fix(ai-vault): never stat WSL transcripts from the parse cache recheck A stat on a \\wsl.localhost path outside the scanner's running-distro filter and gated WSL lane could boot a stopped distro or hang on a stuck one. WSL rows now skip the existence check and age out after 180 days unparsed. SQLite-backed session keys use the shared OpenCode path splitter. * fix(ai-vault): register the parse cache database with the WSL mover census Each schema keeps its own meta table again, so the shared open helper creates none and the search schema's SQL is unchanged. The parse cache's tables are recorded as not moved: a cache rebuilt from transcripts. * fix(ai-vault): a forced whole read never reuses a row a failed database delete left behind