mirror of
https://github.com/glittercowboy/get-shit-done
synced 2026-04-26 01:35:29 +02:00
* fix(#2633): use ROADMAP.md as authority for current-milestone phase counts initMilestoneOp (SDK + CJS) derives phase_count and completed_phases from the current milestone section of ROADMAP.md instead of counting on-disk `.planning/phases/` directories. After `phases clear` at the start of a new milestone the on-disk set is a subset of the roadmap, causing premature `all_phases_complete: true`. validateHealth W002 now unions ROADMAP.md phase declarations (all milestones — current, shipped, backlog) with on-disk dirs when checking STATE.md phase refs. Eliminates false positives for future-phase refs in the current milestone and history-phase refs from shipped milestones. Falls back to legacy on-disk counting when ROADMAP.md is missing or unparseable so no-roadmap fixtures still work. Adds vitest regressions for both handlers; all 66 SDK + 118 CJS tests pass. * fix(#2633): preserve full phase tokens in W002 + completion lookup CodeRabbit flagged that the parseInt-based normalization collapses distinct phase IDs (3, 3A, 3.1) into the same integer bucket, masking real STATE/ROADMAP mismatches and miscounting completions in milestones with inserted/sub-phases. Index disk dirs and validate STATE.md refs by canonical full phase token — strip leading zeros from the integer head only, preserve [A-Z] suffix and dotted segments, and accept just the leading-zero variant of the integer prefix as a tolerated alias. 3A and 3 never share a bucket. Also widens the disk and STATE.md regexes to accept [A-Z]? suffix tokens.
This commit is contained in:
@@ -550,6 +550,49 @@ describe('validateHealth', () => {
|
||||
expect(w003!.repairable).toBe(true);
|
||||
});
|
||||
|
||||
// Regression: #2633 — W002 must consult ROADMAP.md (current + shipped
|
||||
// milestones) for valid phase numbers, not only on-disk phase dirs. After
|
||||
// `phases clear` at the start of a new milestone, STATE.md can legitimately
|
||||
// reference future phases (current milestone) and history phases (shipped
|
||||
// milestones) that no longer have a corresponding disk directory.
|
||||
it('does not emit W002 for roadmap-valid future or history phase refs (#2633)', async () => {
|
||||
const planning = join(tmpDir, '.planning');
|
||||
await mkdir(join(planning, 'phases', '03-alpha'), { recursive: true });
|
||||
await mkdir(join(planning, 'phases', '04-beta'), { recursive: true });
|
||||
|
||||
await writeFile(join(planning, 'PROJECT.md'), '# Project\n\n## What This Is\n\nA project.\n\n## Core Value\n\nValue here.\n\n## Requirements\n\n- Req 1\n');
|
||||
await writeFile(join(planning, 'ROADMAP.md'), [
|
||||
'# Roadmap', '',
|
||||
'## v1.0: Shipped ✅ SHIPPED', '',
|
||||
'### Phase 1: Origin', '**Goal:** O', '',
|
||||
'### Phase 2: Continuation', '**Goal:** C', '',
|
||||
'## v1.1: Current', '',
|
||||
'### Phase 3: Alpha', '**Goal:** A', '',
|
||||
'### Phase 4: Beta', '**Goal:** B', '',
|
||||
'### Phase 5: Gamma', '**Goal:** C', '',
|
||||
].join('\n'));
|
||||
await writeFile(join(planning, 'STATE.md'), [
|
||||
'---', 'milestone: v1.1', 'milestone_name: Current', 'status: executing', '---', '',
|
||||
'# State', '',
|
||||
'**Current Phase:** 4',
|
||||
'**Next:** Phase 5',
|
||||
'',
|
||||
'## Accumulated Context',
|
||||
'- Decision from Phase 1',
|
||||
'- Follow-up from Phase 2',
|
||||
].join('\n'));
|
||||
await writeFile(join(planning, 'config.json'), JSON.stringify({
|
||||
model_profile: 'balanced',
|
||||
workflow: { nyquist_validation: true },
|
||||
}, null, 2));
|
||||
|
||||
const result = await validateHealth([], tmpDir);
|
||||
const data = result.data as Record<string, unknown>;
|
||||
const warnings = data.warnings as Array<Record<string, unknown>>;
|
||||
const w002s = warnings.filter(w => w.code === 'W002');
|
||||
expect(w002s).toEqual([]);
|
||||
});
|
||||
|
||||
it('returns warning W005 for bad phase directory naming', async () => {
|
||||
await createHealthyPlanning();
|
||||
await mkdir(join(tmpDir, '.planning', 'phases', 'bad_name'), { recursive: true });
|
||||
|
||||
Reference in New Issue
Block a user