feat(#39): milestone-prefixed phase IDs (M-NN convention) + migration tool + validation (#565)

* feat(#39): milestone-prefixed phase IDs (M-NN convention) + migration tool + validation

- Add getMilestoneFromPhaseId() / getPhaseDirFromPhaseId() helpers to core.cjs
- Fix isDirInMilestone to match M-NN-style dirs (02-01-setup) against M-NN ROADMAP headings
- Extend heading regex to tolerate [bracket-token] scope prefix on phase headings
- Add W021 validation rule for milestone prefix mismatch
- Add gsd-tools roadmap validate + roadmap upgrade --convention milestone-prefixed
- Add phase_id_convention config field (null default, backwards-compatible)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(#39): address 4 Codex review findings in milestone-prefixed phase ID implementation

- getMilestoneFromPhaseId: tighten regex to require a digit after the hyphen (rejects '1-' and '1-abc')
- isDirInMilestone: use convention-aware regex — only capture M-NN segments when ROADMAP itself uses hyphenated phase IDs, preventing legacy dirs like '01-02-setup' from being misread as phase '1-02'
- checkW021: add UNPREFIXED_PHASE_RE path so unprefixed headings (### Phase 1:) also fire W021 when convention is milestone-prefixed
- roadmap-upgrade: remove isMigratedDirName dir-name check (false-positive for legacy dirs); config + ROADMAP heading checks at lines 194 and 212 are sufficient

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* chore: update changeset pr reference to #565

* fix(#39): restore phaseDirNameRe 2-digit minimum; add roadmap-upgrade to inventory

- validate.cjs: \d{1,} → \d{2,} to keep single-digit prefix rejection per W005 contract
- docs/INVENTORY.md: 79 → 80, add roadmap-upgrade.cjs row
- docs/INVENTORY-MANIFEST.json: regenerated (roadmap-upgrade.cjs entry)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Tom Boucher
2026-05-31 23:15:55 -04:00
committed by GitHub
parent 48c1827028
commit 0a12b06381
21 changed files with 1593 additions and 63 deletions

View File

@@ -6,8 +6,19 @@ Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
## [Unreleased]
### Added
- Milestone-prefixed phase ID convention (M-NN) for globally unique phase IDs within a project (#39)
- `getMilestoneFromPhaseId()` and `getPhaseDirFromPhaseId()` helpers in core.cjs (#39)
- W021 validation rule: fires when a phase ID's integer prefix mismatches its enclosing milestone section (#39)
- `gsd-tools roadmap validate` subcommand for convention compliance checking (#39)
- `gsd-tools roadmap upgrade --convention milestone-prefixed` migration tool (dry-run by default, `--apply` to mutate) (#39)
- `phase_id_convention` config field (`null` | `'milestone-prefixed'` | `'free-form'`), defaults to `null` (legacy free-form, no breaking change) (#39)
### Fixed
- `isDirInMilestone` now correctly matches M-NN-style phase directories against milestone-prefixed ROADMAP headings (#39)
- `searchPhaseInContent` heading regex now tolerates `[bracket-token]` scope prefix (e.g., `### [GSD] Phase 2-01:`) (#39)
- **README version guidance now uses npm/package metadata as the source of truth** — README, localized READMEs, and the docs index no longer present archived release-note or canary-stream numbers as the current GSD Core package version. (#545)
## [1.2.0](https://www.npmjs.com/package/@opengsd/gsd-core/v/1.2.0) - 2026-05-31