Merge pull request #3564 from gsd-build/fix/3560-validate-health-w007-false-positive-scan
fix: prevent archived phase dirs from triggering W007
This commit is contained in:
5
.changeset/sturdy-wolves-glide.md
Normal file
5
.changeset/sturdy-wolves-glide.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
type: Fixed
|
||||
pr: 3564
|
||||
---
|
||||
**validate.health no longer raises W007 for archived milestone phases** - archived `v*-phases` directories remain valid for historical W006 checks, but W007 now only reports unexpected active phase directories. Fixes #3560.
|
||||
@@ -643,6 +643,26 @@ describe('validateHealth', () => {
|
||||
expect(w006s.some(w => String(w.message).includes('Phase 7'))).toBe(false);
|
||||
});
|
||||
|
||||
it('does not emit W007 for archived milestone-only phase dirs (#3560)', async () => {
|
||||
await createHealthyPlanning();
|
||||
await writeFile(join(tmpDir, '.planning', 'ROADMAP.md'), [
|
||||
'# Roadmap',
|
||||
'',
|
||||
'## v1.1: Current',
|
||||
'',
|
||||
'### Phase 21: Active',
|
||||
'',
|
||||
].join('\n'));
|
||||
await mkdir(join(tmpDir, '.planning', 'phases', '21-active'), { recursive: true });
|
||||
await mkdir(join(tmpDir, '.planning', 'milestones', 'v1.0-phases', '02-old-shipped-phase'), { recursive: true });
|
||||
|
||||
const result = await validateHealth([], tmpDir);
|
||||
const data = result.data as Record<string, unknown>;
|
||||
const warnings = data.warnings as Array<Record<string, unknown>>;
|
||||
const w007s = warnings.filter(w => w.code === 'W007');
|
||||
expect(w007s.some(w => String(w.message).includes('Phase 02'))).toBe(false);
|
||||
});
|
||||
|
||||
it('does not emit W006 for unchecked future phases with no directory (#3559)', async () => {
|
||||
await createHealthyPlanning();
|
||||
await writeFile(join(tmpDir, '.planning', 'ROADMAP.md'), [
|
||||
|
||||
@@ -621,12 +621,16 @@ export const validateHealth: QueryHandler = async (args, projectDir, workstream)
|
||||
}
|
||||
|
||||
const diskPhases = new Set<string>();
|
||||
const activeDiskPhases = new Set<string>();
|
||||
try {
|
||||
const entries = await readdir(phasesDir, { withFileTypes: true });
|
||||
for (const e of entries) {
|
||||
if (e.isDirectory()) {
|
||||
const dm = e.name.match(/^(\d+[A-Z]?(?:\.\d+)*)/i);
|
||||
if (dm) diskPhases.add(dm[1]);
|
||||
if (dm) {
|
||||
diskPhases.add(dm[1]);
|
||||
activeDiskPhases.add(dm[1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch { /* intentionally empty */ }
|
||||
@@ -655,7 +659,7 @@ export const validateHealth: QueryHandler = async (args, projectDir, workstream)
|
||||
}
|
||||
}
|
||||
|
||||
for (const p of diskPhases) {
|
||||
for (const p of activeDiskPhases) {
|
||||
const variants = phaseVariants(p);
|
||||
if (![...variants].some((variant) => roadmapPhaseVariants.has(variant))) {
|
||||
addIssue('warning', 'W007', `Phase ${p} exists on disk but not in ROADMAP.md`, 'Add to roadmap or remove directory');
|
||||
|
||||
Reference in New Issue
Block a user