diff --git a/src/resources/extensions/gsd/cache.ts b/src/resources/extensions/gsd/cache.ts index 0dcef5b4f..93eb05215 100644 --- a/src/resources/extensions/gsd/cache.ts +++ b/src/resources/extensions/gsd/cache.ts @@ -12,16 +12,18 @@ import { invalidateStateCache } from './state.js'; import { clearPathCache } from './paths.js'; import { clearParseCache } from './files.js'; +import { clearArtifacts } from './gsd-db.js'; /** * Invalidate all GSD runtime caches in one call. * * Call this after file writes, milestone transitions, merge reconciliation, * or any operation that changes .gsd/ contents on disk. Forgetting to clear - * any single cache causes stale reads (see #431). + * any single cache causes stale reads (see #431, #793). */ export function invalidateAllCaches(): void { invalidateStateCache(); clearPathCache(); clearParseCache(); + clearArtifacts(); } diff --git a/src/resources/extensions/gsd/gsd-db.ts b/src/resources/extensions/gsd/gsd-db.ts index 1a1adb708..70c0bbeb1 100644 --- a/src/resources/extensions/gsd/gsd-db.ts +++ b/src/resources/extensions/gsd/gsd-db.ts @@ -790,6 +790,21 @@ export function upsertRequirement(r: Requirement): void { /** * Insert or replace an artifact. Uses the `path` PK for idempotency. */ +/** + * Delete all rows from the artifacts table. + * The artifacts table is a read cache — clearing it forces the next + * deriveState() to fall through to disk reads (native Rust batch parse). + * Safe to call when no database is open (no-op). + */ +export function clearArtifacts(): void { + if (!currentDb) return; + try { + currentDb.exec('DELETE FROM artifacts'); + } catch { + // Clearing a cache should never be fatal + } +} + export function insertArtifact(a: { path: string; artifact_type: string;