fix: prevent PROJECT.md drift and fix phase completion counters (#956) (#1130)

Two gaps in the standard workflow cycle caused planning document drift:

1. PROJECT.md was never updated during discuss → plan → execute → verify.
   Only transition.md (optional) and complete-milestone evolved it.
   Added an 'update_project_md' step to execute-phase.md that evolves
   PROJECT.md after phase completion: moves requirements to Validated,
   updates Current State, bumps Last Updated timestamp.

2. cmdPhaseComplete() in phase.cjs advanced 'Current Phase' but never
   incremented 'Completed Phases' counter or recalculated 'percent'.
   Added counter increment and percentage recalculation based on
   completed/total phases ratio.

Addresses the workflow-level gaps identified in #956:
- PROJECT.md evolution in execute-phase (gap #2)
- completed_phases counter not incremented (gap #1 table row 3)
- percent never recalculated (gap #1 table row 4)

Fixes #956
This commit is contained in:
Tom Boucher
2026-03-18 12:00:24 -04:00
committed by GitHub
parent e8dbc3031b
commit 7101ddcb9c
2 changed files with 50 additions and 0 deletions

View File

@@ -880,6 +880,34 @@ function cmdPhaseComplete(cwd, phaseNum, raw) {
`$1Phase ${phaseNum} complete${nextPhaseNum ? `, transitioned to Phase ${nextPhaseNum}` : ''}`
);
// Increment Completed Phases counter (#956)
const completedMatch = stateContent.match(/\*\*Completed Phases:\*\*\s*(\d+)/);
if (completedMatch) {
const newCompleted = parseInt(completedMatch[1], 10) + 1;
stateContent = stateContent.replace(
/(\*\*Completed Phases:\*\*\s*)\d+/,
`$1${newCompleted}`
);
// Recalculate percent based on completed / total (#956)
const totalMatch = stateContent.match(/\*\*Total Phases:\*\*\s*(\d+)/);
if (totalMatch) {
const totalPhases = parseInt(totalMatch[1], 10);
if (totalPhases > 0) {
const newPercent = Math.round((newCompleted / totalPhases) * 100);
stateContent = stateContent.replace(
/(\*\*Progress:\*\*\s*)\d+%/,
`$1${newPercent}%`
);
// Also update percent field if it exists separately
stateContent = stateContent.replace(
/(percent:\s*)\d+/,
`$1${newPercent}`
);
}
}
}
writeStateMd(statePath, stateContent, cwd);
}

View File

@@ -499,6 +499,28 @@ node "$HOME/.claude/get-shit-done/bin/gsd-tools.cjs" commit "docs(phase-{X}): co
```
</step>
<step name="update_project_md">
**Evolve PROJECT.md to reflect phase completion (prevents planning document drift — #956):**
PROJECT.md tracks validated requirements, decisions, and current state. Without this step,
PROJECT.md falls behind silently over multiple phases.
1. Read `.planning/PROJECT.md`
2. If the file exists and has a `## Validated Requirements` or `## Requirements` section:
- Move any requirements validated by this phase from Active → Validated
- Add a brief note: `Validated in Phase {X}: {Name}`
3. If the file has a `## Current State` or similar section:
- Update it to reflect this phase's completion (e.g., "Phase {X} complete — {one-liner}")
4. Update the `Last updated:` footer to today's date
5. Commit the change:
```bash
node "$HOME/.claude/get-shit-done/bin/gsd-tools.cjs" commit "docs(phase-{X}): evolve PROJECT.md after phase completion" --files .planning/PROJECT.md
```
**Skip this step if** `.planning/PROJECT.md` does not exist.
</step>
<step name="offer_next">
**Exception:** If `gaps_found`, the `verify_phase_goal` step already presents the gap-closure path (`/gsd:plan-phase {X} --gaps`). No additional routing needed — skip auto-advance.