fix(state): treat zero-slice roadmap as pre-planning instead of blocked (#1826)
Fixes #1785 Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
1a70f9daea
commit
b9a2a9a37b
2 changed files with 46 additions and 0 deletions
|
|
@ -550,6 +550,30 @@ async function _deriveStateImpl(basePath: string): Promise<GSDState> {
|
|||
};
|
||||
}
|
||||
|
||||
// ── Zero-slice roadmap guard (#1785) ─────────────────────────────────
|
||||
// A stub roadmap (placeholder text, no slice definitions) has a truthy
|
||||
// roadmap object but an empty slices array. Without this check the
|
||||
// slice-finding loop below finds nothing and returns phase: "blocked".
|
||||
// An empty slices array means the roadmap still needs slice definitions,
|
||||
// so the correct phase is pre-planning.
|
||||
if (activeRoadmap.slices.length === 0) {
|
||||
return {
|
||||
activeMilestone,
|
||||
activeSlice: null,
|
||||
activeTask: null,
|
||||
phase: 'pre-planning',
|
||||
recentDecisions: [],
|
||||
blockers: [],
|
||||
nextAction: `Milestone ${activeMilestone.id} has a roadmap but no slices defined. Add slices to the roadmap.`,
|
||||
registry,
|
||||
requirements,
|
||||
progress: {
|
||||
milestones: milestoneProgress,
|
||||
slices: { done: 0, total: 0 },
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
// Check if active milestone needs validation or completion (all slices done)
|
||||
if (isMilestoneComplete(activeRoadmap)) {
|
||||
const validationFile = resolveMilestoneFile(basePath, activeMilestone.id, "VALIDATION");
|
||||
|
|
|
|||
|
|
@ -957,6 +957,28 @@ slice: S01
|
|||
}
|
||||
}
|
||||
|
||||
// ─── Test: zero-slice roadmap → pre-planning, not blocked (#1785) ────
|
||||
console.log('\n=== zero-slice roadmap → pre-planning, not blocked (#1785) ===');
|
||||
{
|
||||
const base = createFixtureBase();
|
||||
try {
|
||||
// Write a stub roadmap with zero slices (placeholder text, no slice definitions)
|
||||
writeRoadmap(base, 'M001', `# M001: Stub Milestone\n\n**Vision:** Placeholder.\n\n## Slices\n\n_No slices defined yet._\n`);
|
||||
|
||||
const state = await deriveState(base);
|
||||
|
||||
assertEq(state.phase, 'pre-planning', 'phase is pre-planning when roadmap has zero slices');
|
||||
assertTrue(state.activeMilestone !== null, 'activeMilestone is set');
|
||||
assertEq(state.activeMilestone?.id, 'M001', 'activeMilestone is M001');
|
||||
assertEq(state.activeSlice, null, 'activeSlice is null');
|
||||
assertEq(state.activeTask, null, 'activeTask is null');
|
||||
assertEq(state.blockers.length, 0, 'no blockers reported');
|
||||
assertTrue(state.nextAction.includes('M001'), 'nextAction references M001');
|
||||
} finally {
|
||||
cleanup(base);
|
||||
}
|
||||
}
|
||||
|
||||
report();
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue