* fix(#557): Milestone marked complete while ROADMAP lists unstarted phases - Fix 1 — Broaden extractCurrentMilestone() (core.cjs): (a) Extend sectionPattern to also match <summary> tag content: when a milestone version appears only inside a <summary> tag, locate the enclosing <details> block and return its content directly instead of falling through to stripShippedMilestones(). (b) Extend activeMarkerPattern to include 🔄: change /\b(?:STARTED|ACTIVE|WIP)\b|in\s+progress|🚧/i to also match 🔄. (c) Extend the Step 2 fallback regex from /🚧\s*\*\*v(\d+\.\d+)\s/ to /(?:🚧|🔄)\s*\*\*v(\d+\.\d+)\s/ so the emoji-only fallback also catches 🔄. - Fix 2 — Add completion guard (milestone.cjs): Before writing "milestone complete" to STATE.md, check whether any phase in the current milestone has no directory on disk (disk_status: no_directory). When STATE.md milestone version matches the version being completed and unstarted phases are found, emit an error. Re-run with --force to override. - Fix 3 — Add W021 health check (verify.cjs): Check 14 (W021): if STATE.md status contains "milestone complete" or "archived", scan the current milestone section of ROADMAP.md; if any phase has no directory on disk, emit W021 warning: "STATE says milestone complete but ROADMAP lists N unstarted phase(s)". Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(#557): replace hand-written changeset with generated fragment Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(#557): address Codex review findings - core.cjs: add (?!Phase\s+\S) to sectionPattern so phase headings that mention the milestone version (e.g. ### Phase 1: v1.3 migration) cannot bypass the <summary> fallback path - milestone.cjs: replace loose numeric-prefix matching with phaseTokenMatches + normalizePhaseName so decimal (2.1) and letter-suffix (12A) phase IDs are handled correctly in the completion guard - verify.cjs: same correction in W021 check; also add phaseTokenMatches to core.cjs import Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(#557): fix getMilestonePhaseFilter version-heading false match getMilestonePhaseFilter's sectionPattern also lacked the (?!Phase\s+\S) exclusion that extractCurrentMilestone received in the previous commit. A phase title like "### Phase 4: v1.3 migration" could match as the milestone section start, mis-scoping the phase set used for completion stats and archive. Also handle the case where the version lives only in a <summary> tag: when there is no heading match but a <summary> match exists, skip setting missingExplicitVersion so milestone.complete does not incorrectly error with "no phases found". Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
8.8 KiB
8.8 KiB