From fe11285ed523e69330c41976b3efdc15e93a1f4e Mon Sep 17 00:00:00 2001 From: Lex Christopherson Date: Fri, 13 Mar 2026 23:51:04 -0600 Subject: [PATCH] fix: treat unresolvable artifact paths as stale completion state (#313) verifyExpectedArtifact() returned true when resolveExpectedArtifactPath() returned null, conflating "unit type has no artifact" with "slice directory missing on disk". This caused /gsd auto to infinitely skip and re-dispatch the same stale completed-unit entry until OOM. Now only replan-slice (the sole type with no verifiable artifact) passes on null; all other types return false, triggering the existing eviction logic that removes the stale key and re-runs the unit. Co-Authored-By: Claude Opus 4.6 (1M context) --- src/resources/extensions/gsd/auto.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/resources/extensions/gsd/auto.ts b/src/resources/extensions/gsd/auto.ts index df94ca7be..78cd61ace 100644 --- a/src/resources/extensions/gsd/auto.ts +++ b/src/resources/extensions/gsd/auto.ts @@ -2891,7 +2891,10 @@ export function resolveExpectedArtifactPath(unitType: string, unitId: string, ba */ function verifyExpectedArtifact(unitType: string, unitId: string, base: string): boolean { const absPath = resolveExpectedArtifactPath(unitType, unitId, base); - if (!absPath) return true; + // Unit types with no verifiable artifact always pass (e.g. replan-slice). + // For all other types, null means the parent directory is missing on disk + // — treat as stale completion state so the key gets evicted (#313). + if (!absPath) return unitType === "replan-slice"; if (!existsSync(absPath)) return false; // execute-task must also have its checkbox marked [x] in the slice plan