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) <noreply@anthropic.com>
This commit is contained in:
Lex Christopherson 2026-03-13 23:51:04 -06:00
parent 6d5d918c40
commit fe11285ed5

View file

@ -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