From 88807d0edce584e2c710a5ec8c9bcab1299e0f04 Mon Sep 17 00:00:00 2001 From: Saatvik Arya Date: Wed, 24 Jun 2026 20:37:59 +0530 Subject: [PATCH 1/2] perf(semantic-search): pin manifest snapshots per run Cover the manifest snapshot invariant that scans use the create-time manifest even if the live catalog changes before scan. This protects the KV-only scan path from accidental live-manifest fallback. --- .../src/sdk/tool-search-index.test.ts | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/packages/plugins/semantic-search/src/sdk/tool-search-index.test.ts b/packages/plugins/semantic-search/src/sdk/tool-search-index.test.ts index 111b1a147..59165a69d 100644 --- a/packages/plugins/semantic-search/src/sdk/tool-search-index.test.ts +++ b/packages/plugins/semantic-search/src/sdk/tool-search-index.test.ts @@ -1032,6 +1032,44 @@ describe("ToolSearchIndex manifest snapshot", () => { }), ); + it.effect("scans the create-time manifest snapshot when the live manifest changes", () => + Effect.gen(function* () { + const [tool] = makeTools(1); + if (tool === undefined) return; + let liveManifests = [manifestForTool(tool, "fp-at-create", "source-at-create")]; + const counters = { manifest: 0 }; + const executor: Pick = { + tools: { + list: () => Effect.succeed([tool]), + manifest: () => { + counters.manifest++; + return Effect.succeed(liveManifests); + }, + schema: () => Effect.succeed(null), + }, + cache: makeMemoryCache(), + }; + const base = makeBase(executor as Executor); + + yield* create({ ...base, runId: "run-snapshot-stability", partitionCount: 1 }); + liveManifests = [manifestForTool(tool, "fp-after-create", "source-after-create")]; + + const scanned = yield* scan({ + ...base, + runId: "run-snapshot-stability", + partition: 0, + limit: 10, + }); + + expect(scanned).toMatchObject({ processed: 1, changed: 1, skipped: 0 }); + expect(counters.manifest).toBe(1); + expect([...base.jobs.data.values()][0]).toMatchObject({ + fingerprint: "fp-at-create", + sourceRevision: "source-at-create", + }); + }), + ); + it.effect("fails the scan when the run snapshot is missing (no D1 fallback)", () => Effect.gen(function* () { const { executor, counters } = makeCountingExecutor(makeTools(2)); From 65d62e1c2c0f07972543834f3f337cb5b971eddd Mon Sep 17 00:00:00 2001 From: Saatvik Arya Date: Fri, 26 Jun 2026 18:01:46 +0530 Subject: [PATCH 2/2] test(semantic-search): assert snapshot test fixture (greptile) --- .../plugins/semantic-search/src/sdk/tool-search-index.test.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/plugins/semantic-search/src/sdk/tool-search-index.test.ts b/packages/plugins/semantic-search/src/sdk/tool-search-index.test.ts index 59165a69d..6efa0797f 100644 --- a/packages/plugins/semantic-search/src/sdk/tool-search-index.test.ts +++ b/packages/plugins/semantic-search/src/sdk/tool-search-index.test.ts @@ -1035,6 +1035,7 @@ describe("ToolSearchIndex manifest snapshot", () => { it.effect("scans the create-time manifest snapshot when the live manifest changes", () => Effect.gen(function* () { const [tool] = makeTools(1); + expect(tool).toBeDefined(); if (tool === undefined) return; let liveManifests = [manifestForTool(tool, "fp-at-create", "source-at-create")]; const counters = { manifest: 0 };