fix(sdk): fix executor plan loading, plan ID derivation, and verification outcome parsing

Bug 1: phasePlanIndex derived empty planId for bare PLAN.md files.
Fixed to use 'PLAN' as the ID, with matching SUMMARY.md detection.

Bug 2: executeSinglePlan passed null to buildPrompt instead of the
actual parsed plan. The executor needs the plan content (tasks,
objectives) to know what to build. Now loads and parses the plan
file before building the prompt.

Bug 3: parseVerificationOutcome checked session exit code, not what
the verifier wrote. A session that runs without errors but writes
status: gaps_found to VERIFICATION.md was treated as 'passed'. Now
queries check.verification-status to read the actual VERIFICATION.md
frontmatter status field.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Lex Christopherson
2026-04-25 13:55:08 -06:00
parent 377a6d2c6e
commit 25d9763878
3 changed files with 68 additions and 14 deletions

View File

@@ -263,9 +263,9 @@ export const phasePlanIndex: QueryHandler = async (args, projectDir, workstream)
const planFiles = phaseFiles.filter(f => f.endsWith('-PLAN.md') || f === 'PLAN.md').sort();
const summaryFiles = phaseFiles.filter(f => f.endsWith('-SUMMARY.md') || f === 'SUMMARY.md');
// Build set of plan IDs with summaries
// Build set of plan IDs with summaries — match the planId derivation logic
const completedPlanIds = new Set(
summaryFiles.map(s => s.replace('-SUMMARY.md', '').replace('SUMMARY.md', ''))
summaryFiles.map(s => s === 'SUMMARY.md' ? 'PLAN' : s.replace('-SUMMARY.md', ''))
);
const plans: Array<Record<string, unknown>> = [];
@@ -274,7 +274,9 @@ export const phasePlanIndex: QueryHandler = async (args, projectDir, workstream)
let hasCheckpoints = false;
for (const planFile of planFiles) {
const planId = planFile.replace('-PLAN.md', '').replace('PLAN.md', '');
// For named plans (01-01-PLAN.md): strip suffix to get '01-01'
// For bare PLAN.md: use the filename itself as the ID
const planId = planFile === 'PLAN.md' ? 'PLAN' : planFile.replace('-PLAN.md', '');
const planPath = join(phaseDir, planFile);
const content = await readFile(planPath, 'utf-8');
const fm = extractFrontmatter(content);