Files
msd-core/tests/roadmap-phase-fallback.test.cjs
Tom Boucher d17bb4ea1e fix(#145): extractCurrentMilestone selects active sub-milestone over closed sibling (#380)
* fix(#145): extractCurrentMilestone selects active sub-milestone over closed sibling

extractCurrentMilestone used a non-global regex with content.match()
(first-match) to locate the milestone section for the STATE.md version.
When the milestone is a shared semver prefix (e.g. v8.0) and ROADMAP.md
holds both a closed sub-milestone (## v8.0 ... CLOSED/FAIL) and an active
one (## v8.0-B ... STARTED), the first match was always the closed
heading, so the active section and its phases were excised from the slice
and downstream phase ops failed with "Phase N not found in current
milestone".

Switch to a global matchAll over candidate headings, skip headings
carrying a closed marker (CLOSED/ARCHIVED/ABANDONED/SHIPPED/FAILED/FAIL/
✅/🗄️), and select the first non-closed match (falling back to the first
match when every candidate is closed, preserving legacy behavior). Anchor
the preamble slice to the first heading index so a closed sibling's body
no longer leaks into the preamble when the selected section is later.

Harden version matching with a trailing word boundary (so v8.0-B does not
match v8.0-Beta), narrow the FAIL marker to FAILED, match a bare 🗄, and
add an active-marker override (STARTED/🚧/ACTIVE) so a heading carrying an
explicit active status is never treated as closed even if its name contains
a completion word. Also anchor the preamble at the first any-version
milestone heading so unmatched sibling sections do not leak into the
preamble.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* ci(#145): add changeset fragment for milestone-selection fix

Adds the required .changeset/*.md fragment for this user-facing fix
(changeset-lint gate).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-27 20:21:08 -04:00

19 KiB