* fix(#1761): skip conflated progress in state json read-path when milestone unbounded ADR-1769 Phase 7 (#1794) closed the state sync WRITE path — when a milestone version is asserted in frontmatter but the ROADMAP has no versioned heading for it, sync leaves Progress untouched. But the state json READ path rebuilds progress via buildStateFrontmatter, whose roadmapPhaseCount loop counts phase headings across the WHOLE document when extractCurrentMilestone can't bound the milestone. state json therefore reported a conflated total_phases (sum of sibling milestones) + a derived percent — exactly the value the sync guard was added to prevent. (Repro from the issue: total_phases 8 = 4+4, percent 13.) Mirror the cmdStateSync guard inside buildStateFrontmatter: when the asserted milestone cannot be bounded to a versioned ROADMAP heading (the same versionedHeading test the sync path uses), fall back to the on-disk phase-dir count for total_phases and skip percent. Bounded milestones (versioned ROADMAP, or no milestone asserted) are unchanged. The signal rides on the existing _diskScanCache (new milestoneBounded field) so neither extractCurrentMilestone's return contract nor its other callers change. Regression: extend tests/bug-1761-state-sync-wrong-progress.test.cjs with the read-path case (unbounded → no percent, no conflated total_phases) and a bounded control (versioned ROADMAP → unchanged percent + total_phases). * docs(#1761): add changeset fragment for state json read-path fix
6 lines
1.0 KiB
Markdown
6 lines
1.0 KiB
Markdown
---
|
|
type: Fixed
|
|
pr: 1818
|
|
---
|
|
**`gsd-tools state json` no longer reports conflated progress for an unversioned milestone (#1761)** — the ADR-1769 Phase 7 fix (#1794) taught `state sync` to leave Progress untouched when a milestone version is asserted but the ROADMAP has no versioned heading for it, but the `state json` **read** path still rebuilt progress via `buildStateFrontmatter`, whose phase-heading count fell back to the whole document and summed sibling milestones. `state json` therefore reported a conflated `total_phases` (e.g. 8 = 4+4 across two milestones) plus a derived `percent`, contradicting the sync guard on the very same project. The read path now mirrors the sync guard: when the asserted milestone cannot be bounded to a versioned ROADMAP heading, `total_phases` falls back to the on-disk phase-dir count and `percent` is omitted. Bounded milestones (versioned ROADMAP, or no milestone asserted) are unchanged; the signal rides on the existing `_diskScanCache` so `extractCurrentMilestone`'s return contract and its other callers are untouched.
|