fix(#2022): gate roadmap update-plan-progress checkbox on verification passed (#2030)

* fix(#2022): gate roadmap update-plan-progress checkbox on verification passed

cmdRoadmapUpdatePlanProgress stamped the phase checkbox + completion date
the moment all summaries landed, with NO verification gate — unlike
cmdPhaseComplete (phase.cts:1436) which checks readVerificationStatus. Since
update-plan-progress is called after every wave and every plan, the checkbox
fired before gsd-verifier confirmed the phase.

- src/roadmap.cts: isComplete now requires summaryCount >= planCount AND
  readVerificationStatus(phaseDir).status === 'passed'.
- tests/roadmap.test.cjs: 2 regression tests (no VERIFICATION.md → not
  complete; gaps_found → not complete) + updated 3 existing complete tests
  to include a passed VERIFICATION.md.

Closes #2022

* docs(#2022): backfill changeset pr 2030
This commit is contained in:
Tom Boucher
2026-07-05 16:59:23 -04:00
committed by GitHub
parent 9f0d785b61
commit bb01f46c6b
3 changed files with 93 additions and 2 deletions

View File

@@ -34,6 +34,9 @@ const { countMatchedSummaries } = coreUtils;
// eslint-disable-next-line @typescript-eslint/no-require-imports
import frontmatter = require('./frontmatter.cjs');
const { extractFrontmatter, parseMustHavesBlock } = frontmatter;
// eslint-disable-next-line @typescript-eslint/no-require-imports
import verificationMod = require('./verification.cjs');
const { readVerificationStatus } = verificationMod;
// ─── Types ────────────────────────────────────────────────────────────────────
@@ -504,7 +507,13 @@ function cmdRoadmapUpdatePlanProgress(cwd: string, phaseNum: string | null | und
return;
}
const isComplete = summaryCount >= planCount;
// Verification gate (#2022): do NOT check the phase checkbox or stamp a
// completion date until the phase's verification status is 'passed', matching
// cmdPhaseComplete's gate (phase.cts:1436). Previously the checkbox fired the
// moment the last plan summary landed — before gsd-verifier had verified.
const phaseDir = path.join(cwd, phaseInfo!.directory);
const verificationPassed = readVerificationStatus(phaseDir).status === 'passed';
const isComplete = summaryCount >= planCount && verificationPassed;
const status = isComplete ? 'Complete' : summaryCount > 0 ? 'In Progress' : 'Planned';
const today = realClock.today();