fix(#2640): report truthful state_updated + keep progress frontmatter in sync after phase remove (#2974)

* test(#2640): add regression for state_updated false positive + stale progress

Three cases: (1) state_updated reflects actual content change, not just
file existence; (2) progress.total_phases resync'd even when the body lacks
'Total Phases:' (the no-op guard was skipping syncStateFrontmatter);
(3) state_updated is false when STATE.md doesn't exist.

* fix(#2640): report truthful state_updated + force frontmatter resync

Two defects in cmdPhaseRemove:

1. state_updated was fs.existsSync(statePath) — trivially true, since the file
   existed before and readModifyWriteStateMd never deletes it. Now captures
   the boolean return from readModifyWriteStateMd (changed from void to
   boolean: true when content was written, false on no-op).

2. progress.* frontmatter stayed stale when the body lacked 'Total Phases:'
   or 'of N' — readModifyWriteStateMd's no-op guard (#948) skipped
   syncStateFrontmatter when the body transform was unchanged. Now the
   transform forces a body diff when a phase was actually removed, so the
   guard passes and syncStateFrontmatter rebuilds progress.* from the
   post-deletion disk/ROADMAP state.

* fix(#2640): address review — gate forced-diff on targetDir, strengthen assertions

Two MAJOR findings from isolated adversarial review:
1. Forced-diff injected a spurious 'Total Phases:' line even when no directory
   was removed (targetDir === null). Now gated on targetDir !== null.
2. Test #2 asserted 'not 3' instead of '2' — would pass for any wrong count.
   Now asserts exact value. Test #1 strengthened to assert body Total Phases
   and frontmatter total_phases both equal 1.

* chore(#2640): add changeset fragment

* chore(#2640): backfill changeset PR number 2974

---------

Co-authored-by: sim <sim@local>
This commit is contained in:
Tom Boucher
2026-08-01 11:56:34 -04:00
committed by GitHub
parent 000a322489
commit f0bb0787c9
4 changed files with 124 additions and 11 deletions

View File

@@ -0,0 +1,5 @@
---
type: Fixed
pr: 2974
---
**`phase remove` now reports accurate state_updated and keeps STATE.md progress counters in sync** — the command reported `state_updated: true` based on file existence (always true) rather than actual content change, and the frontmatter `progress.total_phases`/`completed_phases`/`percent` counters went stale when the STATE.md body lacked a `Total Phases:` field (the no-op write guard skipped the frontmatter resync). (#2640)