fix(ai-vault-search): clear a file's stale mark once the backfill indexes it

List scans queue every not-yet-indexed file as stale while the backfill runs;
nothing cleared the mark when the backfill reached the file, so the first
search after a backfill re-parsed the whole queue (8.4 s on 4,000 sessions).
This commit is contained in:
Jinwoo-H
2026-09-06 04:48:04 -04:00
parent 361c413327
commit ddbfcf7982
2 changed files with 18 additions and 0 deletions
@@ -149,6 +149,21 @@ describe('SessionSearchStore', () => {
expect(store.coverage().filesPending).toBe(0)
})
it('drops a stale mark once the backfill indexes the file', async () => {
const root = await makeTempDir()
const path = join(root, `${SESSION_ID}.jsonl`)
await writeFile(path, `${userRecord(0, 'queued behind the backfill')}\n`)
registerSessionSearchIndexSink(null)
await parse(path)
registerSessionSearchIndexSink(store)
await parse(path)
expect(store.coverage().filesPending).toBe(1)
await withSessionSearchIndexRequired(() => parse(path))
expect(store.coverage()).toMatchObject({ sessionsIndexed: 1, filesPending: 0 })
expect(store.takeStale()).toEqual([])
})
it('repairs a typo from the index vocabulary', async () => {
const root = await makeTempDir()
const path = join(root, `${SESSION_ID}.jsonl`)
@@ -58,6 +58,9 @@ export class SessionSearchStore implements SessionSearchIndexSink {
apply(update: SessionSearchIndexUpdate): void {
try {
this.writer.apply(update)
// Why: list scans queue every file the backfill has not reached yet; once
// it lands, a later search must not re-parse the whole queue (8 s live).
this.stale.delete(update.candidate.file.path)
this.lastIndexedAt = new Date().toISOString()
} catch (error) {
this.applyFailures += 1