From 08a79875bbb61c42696c557bc369ed4cf0abed66 Mon Sep 17 00:00:00 2001 From: Tibsfox Date: Mon, 6 Apr 2026 19:00:47 -0700 Subject: [PATCH] fix(gsd): fix pre-execution-checks false positives from backticks and task.files MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Three fixes: 1. Strip backtick wrapping in normalizeFilePath — LLM-generated paths like \`src/foo.ts\` resolve to nonexistent paths, causing false blocks 2. Exclude task.files from existence checks — it includes files the task will create, so they legitimately don't pre-exist 3. Lower minimum task count from 2 to 1 — single-task slices are valid per the planning prompt Closes #3649 Closes #3626 Co-Authored-By: Claude Opus 4.6 (1M context) --- .../extensions/gsd/pre-execution-checks.ts | 16 +++++++++++----- .../extensions/gsd/safety/content-validator.ts | 6 +++--- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/src/resources/extensions/gsd/pre-execution-checks.ts b/src/resources/extensions/gsd/pre-execution-checks.ts index f0a4b692e..7d682b6bf 100644 --- a/src/resources/extensions/gsd/pre-execution-checks.ts +++ b/src/resources/extensions/gsd/pre-execution-checks.ts @@ -237,9 +237,12 @@ export async function checkPackageExistence( */ export function normalizeFilePath(filePath: string): string { if (!filePath) return filePath; - + + // Strip backtick wrapping from LLM-generated paths (#3649) + let normalized = filePath.replace(/`/g, ""); + // Normalize path separators to forward slashes - let normalized = filePath.replace(/\\/g, "/"); + normalized = normalized.replace(/\\/g, "/"); // Remove leading ./ while (normalized.startsWith("./")) { @@ -272,10 +275,13 @@ function getExpectedOutputsUpTo(tasks: TaskRow[], taskIndex: number): Set = { function validatePlanSlice(content: string): ContentViolation[] { const violations: ContentViolation[] = []; - // Must have at least 2 task entries (checkbox pattern) + // Must have at least 1 task entry — single-task slices are valid (#3649) const taskCount = (content.match(/- \[[ x]\] \*\*T\d+/g) || []).length; - if (taskCount < 2) { + if (taskCount < 1) { violations.push({ severity: "warning", - reason: `Slice plan has only ${taskCount} task(s) — expected at least 2`, + reason: `Slice plan has ${taskCount} task(s) — expected at least 1`, }); }