Skip to content

fix(workflow): improve phase transition routing, progress detection, and commit recovery#823

Open
Tibsfox wants to merge 4 commits intogsd-build:mainfrom
Tibsfox:fix/workflow-transitions
Open

fix(workflow): improve phase transition routing, progress detection, and commit recovery#823
Tibsfox wants to merge 4 commits intogsd-build:mainfrom
Tibsfox:fix/workflow-transitions

Conversation

@Tibsfox
Copy link
Contributor

@Tibsfox Tibsfox commented Feb 28, 2026

Summary

This PR improves the reliability of GSD's workflow transition layer — the handoffs between planning, execution, verification, and progress routing. Four issues addressed across 4 files, ~95 lines total.

These changes build on the foundation fixes in PR #822 (phase lifecycle, milestone detection, state parsing). Together, they address the core plan-execute-advance loop that every GSD project relies on.


Changes

1. Progress routing: include roadmap phases in init data — Closes #689

The experience: Running /gsd:progress announces "Milestone Complete! All phases finished!" even though 4+ phases remain in the roadmap — they just haven't been scaffolded to disk yet. This has reproduced consistently across multiple sessions for users with multi-phase milestones.

Why it happens: init progress builds its phase overview by scanning .planning/phases/ directories. Phases defined in ROADMAP.md that haven't been planned yet don't have directories, so phase_count and completed_count end up equal. The progress workflow sees completed_count === phase_count and routes to "Milestone Complete."

The issue author identified this clearly: the current_phase, next_phase, phase_count, and completed_count fields from init "look authoritative but only reflect disk state." The LLM treats this output as self-sufficient and skips the roadmap analyze step that would reveal the unscaffolded phases.

The fix: After the disk scan, parse ROADMAP.md for phase headings. Add a roadmap_phase_count field that reflects the true total from the roadmap. When all disk phases are complete but the roadmap defines more, set next_phase to the first unscaffolded phase (with a roadmap_only: true marker so consumers can distinguish it from disk phases). The existing phase_count field stays unchanged — it still means "directories on disk" — so existing consumers aren't affected.

Files: bin/lib/init.cjs (+33 lines)

2. Verify-work routing after execution — Closes #117

The experience: When gsd-verifier returns human_needed, the execute-phase workflow displays a static text block listing items that need manual testing. But the user must manually discover and invoke /gsd:verify-work to actually perform the tests. Users may miss the items entirely, proceed to the next phase without testing, or not realize the phase is unverified.

The fix: Replace the passive text display with an AskUserQuestion offering three clear paths:

  • Start /gsd:verify-work — run the interactive UAT workflow (with /clear recommended for fresh context)
  • Mark all approved — skip manual testing and proceed
  • Review verification report — see the full VERIFICATION.md before deciding

This is complementary to PR #819 (browser pre-verification) — #819 makes the verification process itself smarter, while this fix makes the transition to verification automatic. They work well together.

Files: workflows/execute-phase.md (+16 lines, -8 lines)

3. Execute-phase offer after planning — Closes #136

The experience: After planning completes (in the non-auto-advance case), the workflow shows a static suggestion to run /gsd:execute-phase. The user has to read the suggestion, understand it, and manually invoke the command. This creates an unnecessary friction point in the plan-execute loop.

The fix: Add an AskUserQuestion to the <offer_next> section offering to execute immediately, review plans first, or clear context for a fresh start. This only fires when auto-advance is NOT enabled — the auto-advance path (step 14) already handles the transition automatically.

This is different from autopilot mode (#796): autopilot auto-advances through the full chain without asking. This fix is about the interactive case — offering a choice, not forcing execution. They're complementary features.

Files: workflows/plan-phase.md (offer_next section, +22 lines, -6 lines)

4. Commit recovery for auto-advance chains — Partially addresses #668

The experience: When discuss-phase --auto chains through plan → execute, the executor writes all files correctly but never commits them. The entire working tree is left dirty with all implementation changes unstaged.

Why it happens: The auto-advance chain runs discuss → plan → execute → executor, reaching 4 levels of Task nesting. At that depth, git operations from the innermost Task agent may not persist back to the parent working directory. The files are written correctly — only the commits are lost. When execute-phase is run directly (2 levels deep), commits work fine.

Important context: This may be a Claude Code Task tool behavior with deeply-nested subagents rather than a GSD logic bug. The fix is a pragmatic workaround inspired by the "read-your-writes" pattern from distributed systems: after each auto-advance Task returns, the calling orchestrator checks git status for uncommitted changes and commits them. This is harmless if the upstream behavior is resolved — if there are no uncommitted changes, the recovery step is a no-op.

The recovery is placed at two points in the chain:

  • plan-phase.md — after execute-phase Task returns (catches executor-level orphans)
  • discuss-phase.md — after plan-phase Task returns (catches anything the inner recovery missed)

Files: workflows/plan-phase.md (+14 lines), workflows/discuss-phase.md (+17 lines)


Verification

Fix Steps
#689 Create a project with 12 phases in ROADMAP.md, scaffold phases 1-12, complete all. Run init progress — should show roadmap_phase_count reflecting the full ROADMAP count and next_phase pointing to the first unscaffolded phase.
#117 Run execute-phase on a phase where the verifier returns human_needed. Verify that an AskUserQuestion prompt appears offering /gsd:verify-work, "Mark approved", or "Review report".
#136 Run plan-phase WITHOUT --auto. After planning completes, verify an AskUserQuestion prompt appears in <offer_next> offering to execute, review plans, or clear context.
#668 Run discuss-phase --auto through a full chain. After completion, check git log — source code changes from the executor should be committed (either by the executor directly or by the recovery step).

Overlap & Conflict Notes

This PR touches workflow files that are also modified by several active PRs from ethan-hurst:

Our diff is small (~95 lines) and each commit is atomic, so rebasing after any of these merge should be straightforward. The maintainer can also cherry-pick individual commits if preferred.

Relationship to PR #822

PR #822 fixes the foundation-level bugs (phase lifecycle scanning, milestone detection, state parsing) that these workflow improvements depend on. Specifically:

These PRs can merge independently, but together they address the full chain from data layer through workflow routing.


🤖 Generated with Claude Code

Tibsfox and others added 4 commits February 28, 2026 04:55
init progress only counts phase directories on disk, so when all
scaffolded phases are complete but ROADMAP.md defines more, the
output shows completed_count === phase_count with next_phase: null.
The progress workflow interprets this as "Milestone Complete" even
when unscaffolded phases remain.

Parse ROADMAP.md phase headings after the disk scan. Add a
roadmap_phase_count field for the true total, and when all disk phases
are complete, set next_phase to the first unscaffolded roadmap phase
with a roadmap_only:true marker so consumers can distinguish it.

Closes gsd-build#689

Co-Authored-By: Claude Opus 4.6 <[email protected]>
When gsd-verifier returns human_needed, the execute-phase workflow
displays a static text block listing test items but requires the user
to manually discover and invoke /gsd:verify-work. Users may miss the
items, proceed without testing, or not realize the phase is unverified.

Replace the passive display with an AskUserQuestion offering three
clear paths: start the verify-work UAT workflow, mark all items as
approved, or review the full verification report before deciding.

Closes gsd-build#117

Co-Authored-By: Claude Opus 4.6 <[email protected]>
…mits

Two changes to plan-phase.md:

1. Replace the static "Next Up" suggestion in <offer_next> with an
   AskUserQuestion offering to execute immediately, review plans, or
   clear context first. This only fires in the non-auto-advance case
   (auto-advance already handles the transition). Closes gsd-build#136

2. Add a verify-and-recover step after auto-advance execute-phase
   returns. When Task agents are nested 3+ levels deep, git commits
   from the executor may not persist to the working directory even
   though files are written correctly. The recovery step checks
   git status and commits any orphaned changes. Partially addresses gsd-build#668

Co-Authored-By: Claude Opus 4.6 <[email protected]>
When the auto-advance chain runs discuss → plan → execute → executor
(4 levels of Task nesting), git commits from the deepest level may
not persist back to the working directory. The files are written
correctly — only the commits are lost.

Add a verify-and-recover step to the discuss-phase return handler
that checks git status after plan-phase returns and commits any
orphaned changes. This is the outermost recovery point in the chain
and catches anything that the plan-phase recovery (previous commit)
might not cover.

Note: this may be a Claude Code Task tool behavior with deeply-nested
subagents rather than a GSD logic bug. The recovery pattern is
harmless if the upstream behavior is resolved. Partially addresses gsd-build#668

Co-Authored-By: Claude Opus 4.6 <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant