feat: add /gsd:fix-phase — reopen completed phases for targeted gap closure#1515
feat: add /gsd:fix-phase — reopen completed phases for targeted gap closure#1515grgbrasil wants to merge 11 commits intogsd-build:mainfrom
Conversation
trek-e
left a comment
There was a problem hiding this comment.
Adversarial Review -- PR #1515
Author: grgbrasil
Title: feat: add /gsd:fix-phase -- reopen completed phases for targeted gap closure
Summary
Adds a new /gsd:fix-phase command with a 5-stage pipeline (freshness check, gap analysis, fix interview, fix planning, fix execution). Introduces a new gsd-gap-analyzer agent, new CLI subcommands (phase freshness, state begin-fix, state end-fix, init fix-phase), a new fixing state, and a full workflow file. 10 commits across 10 files (4 new files, 6 modified). Includes spec and implementation plan docs.
Merge Status
CONFLICTING -- this PR cannot be merged in its current state. The branch has conflicts with main that must be resolved.
Correctness Assessment
The implementation is structurally sound. The 5-stage pipeline is well-decomposed and reuses existing infrastructure (gsd-planner, existing plan execution). Key observations:
-
cmdPhaseFreshness-- walks the phase directory, checks git log for post-completion changes, returns a staleness JSON. Reasonable approach. However, thegit log --sincedate extraction from VERIFICATION.md relies on a specific format (## Verified:) that may not always be present -- there is no fallback if the verification file has a different format or is missing the date. -
cmdStateBeginFix/cmdStateEndFix-- stores previous state before enteringfixingand restores it on end-fix. The previous state is stored in the same STATE.md file. If the process crashes between begin-fix and end-fix, the previous state is preserved in the file, which is good for recovery. -
cmdInitFixPhase-- returns phase metadata and artifact inventory. Clean implementation. -
gsd-gap-analyzeragent -- the agent definition referencesFIX-GAPS.mdas output but the workflow file referencesFIX-GAPS.mddifferently in the pipeline. The agent instructions say to write{phaseDir}/FIX-GAPS.mdbut the workflow reads gaps from a different variable. Verify the contract between agent output and workflow consumption is consistent. -
Missing tests -- no automated tests for any of the new CLI subcommands. The PR description shows manual testing checkboxes but no test files were added. Given the repo has >1500 existing tests and the PR adds 4 new CLI commands, this needs test coverage.
-
Docs committed -- the spec and implementation plan are fine for the PR but 1192 lines of implementation plan is a large addition to track in the repo permanently.
Requested Changes
-
Rebase onto main -- this PR is in CONFLICTING state. Please rebase onto
main, resolve conflicts, and force-push. The PR cannot be reviewed for merge until conflicts are resolved. -
Add tests -- add unit tests for
cmdPhaseFreshness,cmdStateBeginFix,cmdStateEndFix, andcmdInitFixPhase. The repo usesnode:test-- follow existing patterns intests/. -
Verify agent-workflow contract -- confirm
gsd-gap-analyzeroutput path matches what thefix-phase.mdworkflow reads.
Verdict: REQUEST CHANGES
Rebase onto main, add tests, verify the gap-analyzer output contract.
…leness Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…tatus Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…se artifacts Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
… fix-phase Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…tion Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Tests for cmdPhaseFreshness, cmdStateBeginFix, cmdStateEndFix, and cmdInitFixPhase covering error cases, happy paths, and round-trips. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
3ef2aff to
b8fa408
Compare
Review ResponseThanks for the thorough review @trek-e! 1. Rebase onto main ✅Rebased and force-pushed. Conflict in 2. Tests added ✅Added
All 18 tests passing. 3. Agent-workflow contract verified ✅Confirmed the
Contract is consistent — both reference 🤖 Generated with Claude Code |
Re-Review — PR #1515@grgbrasil — the rebase is confirmed (MERGEABLE), the 18 tests in `tests/fix-phase.test.cjs` are present, and the agent-workflow contract for `FIX-GAPS.md` is consistent. Those three prior issues are resolved. However, CI is failing across all platforms with 4 distinct failures that must be fixed before this can merge: Failure 1: `gsd-gap-analyzer` missing anti-heredoc instructionThe test suite requires every agent file to contain an anti-heredoc instruction. `agents/gsd-gap-analyzer.md` does not have it. Check how existing agents implement this (e.g., `agents/gsd-planner.md` or any other agent in the `agents/` directory) and add the same instruction to `gsd-gap-analyzer.md`. Failure 2: `gsd-gap-analyzer` missing commented hooks pattern in frontmatterEvery agent frontmatter must include the commented hooks pattern. Same file, same fix location — look at existing agents for the required pattern and add it. Failure 3: `gsd-gap-analyzer` not listed in expected agent files (copilot install test)`tests/copilot-install.test.cjs` maintains an allowlist of expected agent files. `gsd-gap-analyzer` needs to be added to that list. Failure 4: `fix-phase.md` workflow missing `@file:` handler`tests/windows-robustness.test.cjs` requires that every workflow calling `gsd-tools init` has an `@file:` handler for its output. `get-shit-done/workflows/fix-phase.md` calls `gsd-tools init fix-phase` but does not have the required `@file:` handler. Check how other workflows (e.g., `execute-phase.md`) handle this and apply the same pattern. All 4 are mechanical fixes — look at the patterns in existing agent and workflow files and mirror them. Fix, push, and CI should go green. |
trek-e
left a comment
There was a problem hiding this comment.
Adversarial Re-Review — REQUEST CHANGES
Author pushed updates after last review. Two of three issues addressed, one remains.
Prior Issue Tracking
1. Rebase onto main (CONFLICTING state): NOT FIXED
GitHub reports "mergeable": "CONFLICTING". The PR cannot be merged until conflicts are resolved. Please rebase onto main.
2. Add tests: FIXED
A test file tests/fix-phase.test.cjs has been added. The PR now has 11 files including the test file. Without reading the full test content (large diff), the presence of a dedicated test file for the new CLI subcommands addresses the prior concern.
3. Verify agent-workflow contract (gap-analyzer output path): VERIFIED
The gsd-gap-analyzer.md agent writes FIX-GAPS.md in the phase directory. The fix-phase.md workflow reads from the same location. The contract is consistent.
New Issues Check
No new issues in the implementation. The scope is clean (11 files: 4 new, 6 modified, 1 test file).
Verdict: REQUEST CHANGES — rebase onto main to resolve conflicts. Implementation is otherwise approvable.
trek-e
left a comment
There was a problem hiding this comment.
Code Review
Verdict: REQUEST_CHANGES
Security
No issues found. The cmdPhaseFreshness shell interpolation of completionDate and file paths into git log strings is constrained — dates come from ROADMAP regex matches and file paths come from codebase file existence checks, so injection surface is low. The --since flag value is always an ISO date string from a controlled source.
Logic / Correctness
cmdPhaseFreshness — division-by-zero safe, but staleness math uses a subset denominator
The staleness percentage divides changedFiles.length / referencedFiles.size. However, changedFiles only counts files that exist on disk (fs.existsSync guard), while referencedFiles.size counts all extracted paths. Files deleted since phase completion inflate staleness toward 0 rather than toward 100, which is the wrong direction — a deleted file is more stale, not less. Correct approach: count non-existent files as changed, or use the filtered set as the denominator.
cmdStateEndFix — restored status is always "Ready to plan"
The function reads currentPhase from STATE.md but the derived restoredStatus is hardcoded to "Ready to plan" regardless. The if (currentNum) branch overwrites restoredStatus with the exact same string. The variable currentNum is extracted but never used in determining the restored status. If the original status before fixing was "Executing Phase N" or "Waiting for input", that context is lost. Consider persisting the pre-fix status in STATE.md and restoring it, or at minimum documenting that "Ready to plan" is an intentional simplification.
cmdInitFixPhase — gap_analyzer_model may resolve to undefined
resolveModelInternal(cwd, 'gsd-gap-analyzer') resolves a model by agent name. The gsd-gap-analyzer agent is new in this PR and may not have an entry in the model config, causing gap_analyzer_model to be undefined in the JSON output. Other agents in the repo have fallback model entries. Verify a fallback is present or add one.
fix-phase workflow — gsd-codebase-mapper and gsd-plan-checker agent names assumed to exist
The workflow spawns gsd-codebase-mapper and gsd-plan-checker but neither is listed in this PR's file changes. If those agents don't exist in the repo, the workflow silently fails at Stage 1/4. The workflow should check for agent availability or document the prerequisite agents.
Test Coverage
CI is failing on all platforms — the agent-frontmatter.test.cjs suite requires every agent file to include an anti-heredoc instruction, and agents/gsd-gap-analyzer.md does not have one. This is the sole blocker. All other tested agents (gsd-codebase-mapper, gsd-debugger, gsd-executor, gsd-planner, gsd-verifier, etc.) pass this check.
Error from CI:
not ok 6 - gsd-gap-analyzer has anti-heredoc instruction
error: 'gsd-gap-analyzer missing anti-heredoc instruction'
The fix-phase unit tests themselves (tests/fix-phase.test.cjs, 398 lines) cover error cases, happy paths, and round-trips for all 4 new CLI commands — coverage quality is good.
The end-to-end test is explicitly unchecked in the PR description ([ ] End-to-end /gsd:fix-phase execution on a real project), which is acceptable for a feature this size.
Style
The FIX-GAPS.md output format uses Portuguese field names (O que era esperado, O que foi entregue, Severidade, Gaps Identificados, Notas) while the rest of the GSD system uses English artifact names. This is an inconsistency with the existing convention but may be intentional given the project's bilingual nature. If unintentional, align with English or document the language policy.
The cmdStateEndFix has dead code — currentNum is extracted from currentPhase but is read and immediately discarded. Remove or use it.
Summary
The feature design is solid and the implementation is well-structured, but CI is blocked by a single missing anti-heredoc instruction in agents/gsd-gap-analyzer.md. The cmdStateEndFix status-restore logic also has a correctness bug where the pre-fix status is always discarded in favor of a hardcoded string.
trek-e
left a comment
There was a problem hiding this comment.
Code Review Update (Pass 2)
Verdict: REQUEST_CHANGES — CI still failing, issues partially addressed
CI Status
Tests fail on all platforms. The gsd-gap-analyzer agent is still missing the required anti-heredoc instruction — this is the same blocker flagged in the previous review and it has not been fixed. All CI runs will fail until this is added.
Previously Flagged Issues
UNRESOLVED (CI blocker): agents/gsd-gap-analyzer.md missing anti-heredoc instruction. The error is unchanged from the prior review run:
not ok - gsd-gap-analyzer has anti-heredoc instruction
error: 'gsd-gap-analyzer missing anti-heredoc instruction'
PARTIALLY ADDRESSED: cmdStateEndFix status restoration. Commit 8acbd515 adds phase validation to begin-fix/end-fix. Review that commit to confirm the hardcoded "Ready to plan" issue (status not restored from pre-fix state) was addressed — the commit message does mention "restore ST..." (truncated).
UNRESOLVED: cmdInitFixPhase — gap_analyzer_model may be undefined. resolveModelInternal(cwd, 'gsd-gap-analyzer') still likely returns undefined since gsd-gap-analyzer has no entry in model-profiles.cjs. Verify.
UNRESOLVED: Portuguese field names in FIX-GAPS.md. Fields (O que era esperado, Gaps Identificados) remain in Portuguese while the rest of the system uses English. If this is intentional, document it; otherwise align with English.
Summary
The single blocking action is adding the anti-heredoc instruction to agents/gsd-gap-analyzer.md. Everything else is secondary.
Summary
Adds
/gsd:fix-phase {N}— a new command that reopens completed phases to fix scope gaps without rebuilding from scratch. Reuses existing artifacts (CONTEXT, RESEARCH, UI-SPEC, plans) and generates surgical fix-plans.Problem: When a phase is executed and marked complete, users often discover that features were cut between the interview and execution, or delivered too superficially. Today the only option is creating an entirely new phase with full research/planning cycle — wasting all existing context.
Solution: A 5-stage pipeline that identifies what was missed, confirms with the user, and generates targeted fix-plans:
gsd-gap-analyzeragent cross-references CONTEXT/UI-SPEC/RESEARCH against SUMMARYs/VERIFICATION/codegsd-planner(researches only if needed)fixingstate, executes fix-plans, re-verifies entire phaseWhat's included
gsd-gap-analyzer— cross-references phase artifacts to identify scope gapsfix-phase.md— orchestrates the 5-stage pipeline/gsd:fix-phasewith--skip-interviewand--skip-analysisflagsphase freshness,state begin-fix,state end-fix,init fix-phaseFixing Phase {N}— distinct from Executing, lateral operation (doesn't block other phases)fix: truefrontmatterdocs/superpowers/specs/anddocs/superpowers/plans/Design decisions
fixingstatus (distinct fromexecutingandcompleted)Test plan
gsd-tools phase freshness 31returns correct JSON with staleness datagsd-tools init fix-phase 31returns phase info + artifact inventorygsd-tools state begin-fix --phase 31sets "Fixing Phase 31" statusgsd-tools state end-fix --phase 31restores previous status/gsd:fix-phaseexecution on a real project🤖 Generated with Claude Code