refactor(verify-work): consolidate plan-fix into plan-phase --gaps
Unify gap handling - whether discovered by code verification or user testing, gaps feed into the same plan-phase --gaps workflow. Changes: - Delete commands/gsd/plan-fix.md (redundant) - Update verify-work to route to plan-phase --gaps - Update progress Route E to detect UAT gaps - Change UAT.md "Issues" section to "Gaps" with YAML format - Extend plan-phase --gaps to read from both VERIFICATION.md and UAT.md - Update diagnose-issues to output gaps in YAML format - Update all references (debug, templates, workflows) One path: gap discovered → diagnosed → plan-phase --gaps → fixed Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -377,7 +377,6 @@ You're never locked in. The system adapts.
|
||||
| Command | What it does |
|
||||
|---------|--------------|
|
||||
| `/gsd:verify-work [N]` | User acceptance test of phase or plan ¹ |
|
||||
| `/gsd:plan-fix [plan]` | Plan fixes for UAT issues |
|
||||
|
||||
### Milestones
|
||||
|
||||
|
||||
@@ -96,7 +96,7 @@ Task(
|
||||
- Display root cause and evidence summary
|
||||
- Offer options:
|
||||
- "Fix now" → spawn fix subagent
|
||||
- "Plan fix" → suggest /gsd:plan-fix
|
||||
- "Plan fix" → suggest /gsd:plan-phase --gaps
|
||||
- "Manual fix" → done
|
||||
|
||||
**If `## CHECKPOINT REACHED`:**
|
||||
|
||||
@@ -1,270 +0,0 @@
|
||||
---
|
||||
name: gsd:plan-fix
|
||||
description: Plan fixes for UAT issues from verify-work
|
||||
argument-hint: "<phase, e.g., '4'>"
|
||||
allowed-tools:
|
||||
- Read
|
||||
- Bash
|
||||
- Write
|
||||
- Glob
|
||||
- Grep
|
||||
- AskUserQuestion
|
||||
- SlashCommand
|
||||
---
|
||||
|
||||
<objective>
|
||||
Create FIX.md plan from UAT issues found during verify-work.
|
||||
|
||||
Purpose: Plan fixes for issues logged in {phase}-UAT.md.
|
||||
Output: {phase}-FIX.md in the phase directory, ready for execution.
|
||||
</objective>
|
||||
|
||||
<execution_context>
|
||||
@~/.claude/get-shit-done/references/plan-format.md
|
||||
@~/.claude/get-shit-done/references/checkpoints.md
|
||||
</execution_context>
|
||||
|
||||
<context>
|
||||
Phase: $ARGUMENTS (required - e.g., "4")
|
||||
|
||||
@.planning/STATE.md
|
||||
@.planning/ROADMAP.md
|
||||
</context>
|
||||
|
||||
<process>
|
||||
|
||||
<step name="parse">
|
||||
**Parse phase argument:**
|
||||
|
||||
$ARGUMENTS should be a phase number like "4" or "04".
|
||||
|
||||
If no argument provided:
|
||||
```
|
||||
Error: Phase number required.
|
||||
|
||||
Usage: /gsd:plan-fix 4
|
||||
|
||||
This creates a fix plan from .planning/phases/04-name/04-UAT.md
|
||||
```
|
||||
Exit.
|
||||
</step>
|
||||
|
||||
<step name="find">
|
||||
**Find UAT.md file:**
|
||||
|
||||
```bash
|
||||
ls .planning/phases/${PHASE_ARG}*/*-UAT.md 2>/dev/null
|
||||
```
|
||||
|
||||
If not found:
|
||||
```
|
||||
No UAT.md found for phase {phase}.
|
||||
|
||||
UAT.md files are created by /gsd:verify-work during testing.
|
||||
Run /gsd:verify-work {phase} first.
|
||||
```
|
||||
Exit.
|
||||
|
||||
If found but status is "testing":
|
||||
```
|
||||
UAT session still in progress.
|
||||
|
||||
Run /gsd:verify-work to complete testing first.
|
||||
```
|
||||
Exit.
|
||||
</step>
|
||||
|
||||
<step name="read">
|
||||
**Read issues from UAT.md:**
|
||||
|
||||
Read the "Issues for /gsd:plan-fix" section.
|
||||
|
||||
If section is empty or says "[none yet]":
|
||||
```
|
||||
No issues found in UAT.md.
|
||||
|
||||
All tests passed - no fix plan needed.
|
||||
```
|
||||
Exit.
|
||||
|
||||
Parse each issue:
|
||||
- ID (UAT-XXX)
|
||||
- Brief summary
|
||||
- Severity (blocker/major/minor/cosmetic)
|
||||
- Test number (for context)
|
||||
- **root_cause** (if diagnosed - may be empty)
|
||||
|
||||
Also read the corresponding test from "Tests" section to get:
|
||||
- expected behavior
|
||||
- reported issue (verbatim user description)
|
||||
- root_cause (if diagnosed)
|
||||
- debug_session (path to debug file, if diagnosed)
|
||||
|
||||
**Check if diagnosed:**
|
||||
- If UAT.md status is "diagnosed" OR root_cause fields are populated → issues have been investigated
|
||||
- If not diagnosed → plan based on symptoms only (less precise)
|
||||
</step>
|
||||
|
||||
<step name="plan">
|
||||
**Create fix tasks:**
|
||||
|
||||
For each issue (or logical group):
|
||||
- Create one task per issue OR
|
||||
- Group related cosmetic/minor issues into single task
|
||||
|
||||
**If diagnosed (root_cause available):**
|
||||
```xml
|
||||
<task type="auto">
|
||||
<name>Fix UAT-{NNN}: {issue summary}</name>
|
||||
<files>{files from diagnosis}</files>
|
||||
<action>
|
||||
**Root Cause:** {root_cause from diagnosis}
|
||||
**Issue:** {verbatim reported description}
|
||||
**Expected:** {from test}
|
||||
|
||||
**Fix:** {specific fix based on diagnosed root cause}
|
||||
|
||||
Debug session: {debug_session path} (for reference)
|
||||
</action>
|
||||
<verify>
|
||||
- Confirm root cause addressed
|
||||
- {expected behavior} now works correctly
|
||||
</verify>
|
||||
<done>UAT-{NNN} resolved - {root_cause} fixed</done>
|
||||
</task>
|
||||
```
|
||||
|
||||
**If NOT diagnosed (symptoms only):**
|
||||
```xml
|
||||
<task type="auto">
|
||||
<name>Fix UAT-{NNN}: {issue summary}</name>
|
||||
<files>[affected files - infer from test context]</files>
|
||||
<action>
|
||||
**Issue:** {verbatim reported description}
|
||||
**Expected:** {from test}
|
||||
|
||||
[Investigate and fix - root cause unknown]
|
||||
</action>
|
||||
<verify>
|
||||
- Reproduce original issue - confirm fixed
|
||||
- {expected behavior} now works correctly
|
||||
</verify>
|
||||
<done>UAT-{NNN} resolved - {expected behavior} works</done>
|
||||
</task>
|
||||
```
|
||||
|
||||
Prioritize: blocker → major → minor → cosmetic
|
||||
</step>
|
||||
|
||||
<step name="write">
|
||||
**Write FIX.md:**
|
||||
|
||||
Create `.planning/phases/XX-name/{phase}-FIX.md`:
|
||||
|
||||
```markdown
|
||||
---
|
||||
phase: XX-name
|
||||
plan: {phase}-FIX
|
||||
type: fix
|
||||
wave: 1
|
||||
depends_on: []
|
||||
autonomous: true
|
||||
---
|
||||
|
||||
<objective>
|
||||
Fix {N} UAT issues from phase {phase}.
|
||||
|
||||
Source: {phase}-UAT.md
|
||||
Diagnosed: {yes/no - whether root causes were identified}
|
||||
Priority: {blocker count} blocker, {major count} major, {minor count} minor, {cosmetic count} cosmetic
|
||||
</objective>
|
||||
|
||||
<execution_context>
|
||||
@~/.claude/get-shit-done/workflows/execute-plan.md
|
||||
@~/.claude/get-shit-done/templates/summary.md
|
||||
</execution_context>
|
||||
|
||||
<context>
|
||||
@.planning/STATE.md
|
||||
@.planning/ROADMAP.md
|
||||
|
||||
**Issues being fixed:**
|
||||
@.planning/phases/XX-name/{phase}-UAT.md
|
||||
|
||||
**Debug sessions (if diagnosed):**
|
||||
[Reference each debug_session path from UAT.md for full investigation context]
|
||||
|
||||
**Original plans for reference:**
|
||||
@.planning/phases/XX-name/{phase}-01-PLAN.md
|
||||
[other relevant plans]
|
||||
</context>
|
||||
|
||||
<tasks>
|
||||
[Generated fix tasks]
|
||||
</tasks>
|
||||
|
||||
<verification>
|
||||
Before declaring plan complete:
|
||||
- [ ] All blocker issues fixed
|
||||
- [ ] All major issues fixed
|
||||
- [ ] Minor/cosmetic issues fixed or documented as deferred
|
||||
- [ ] Each fix verified against original reported issue
|
||||
</verification>
|
||||
|
||||
<success_criteria>
|
||||
- All UAT issues from {phase}-UAT.md addressed
|
||||
- Tests pass
|
||||
- Ready for re-verification with /gsd:verify-work {phase}
|
||||
</success_criteria>
|
||||
|
||||
<output>
|
||||
After completion, create `.planning/phases/XX-name/{phase}-FIX-SUMMARY.md`
|
||||
</output>
|
||||
```
|
||||
</step>
|
||||
|
||||
<step name="offer">
|
||||
**Offer execution:**
|
||||
|
||||
```
|
||||
## Fix Plan Created
|
||||
|
||||
**{phase}-FIX.md** — {N} issues to fix
|
||||
|
||||
| Severity | Count |
|
||||
|----------|-------|
|
||||
| Blocker | {n} |
|
||||
| Major | {n} |
|
||||
| Minor | {n} |
|
||||
| Cosmetic | {n} |
|
||||
```
|
||||
|
||||
Use AskUserQuestion:
|
||||
- header: "Next"
|
||||
- question: "What would you like to do?"
|
||||
- options:
|
||||
- "Execute fix plan" — Run the fixes now
|
||||
- "Review plan first" — Look at the plan before executing
|
||||
- "Done for now" — Come back later
|
||||
|
||||
**If "Execute fix plan":**
|
||||
Invoke `/gsd:execute-plan .planning/phases/XX-name/{phase}-FIX.md`
|
||||
|
||||
**If "Review plan first":**
|
||||
Display the plan contents, then ask again whether to execute.
|
||||
|
||||
**If "Done for now":**
|
||||
```
|
||||
Fix plan saved. Run when ready:
|
||||
`/gsd:execute-plan .planning/phases/XX-name/{phase}-FIX.md`
|
||||
```
|
||||
</step>
|
||||
|
||||
</process>
|
||||
|
||||
<success_criteria>
|
||||
- [ ] UAT.md found and issues parsed
|
||||
- [ ] Fix tasks created for each issue
|
||||
- [ ] FIX.md written with proper structure
|
||||
- [ ] User offered next steps
|
||||
</success_criteria>
|
||||
@@ -114,28 +114,28 @@ List files in the current phase directory:
|
||||
```bash
|
||||
ls -1 .planning/phases/[current-phase-dir]/*-PLAN.md 2>/dev/null | wc -l
|
||||
ls -1 .planning/phases/[current-phase-dir]/*-SUMMARY.md 2>/dev/null | wc -l
|
||||
ls -1 .planning/phases/[current-phase-dir]/*-ISSUES.md 2>/dev/null | wc -l
|
||||
ls -1 .planning/phases/[current-phase-dir]/*-FIX.md 2>/dev/null | wc -l
|
||||
ls -1 .planning/phases/[current-phase-dir]/*-FIX-SUMMARY.md 2>/dev/null | wc -l
|
||||
ls -1 .planning/phases/[current-phase-dir]/*-UAT.md 2>/dev/null | wc -l
|
||||
```
|
||||
|
||||
State: "This phase has {X} plans, {Y} summaries, {Z} issues files, {W} fix plans."
|
||||
State: "This phase has {X} plans, {Y} summaries."
|
||||
|
||||
**Step 1.5: Check for unaddressed UAT issues**
|
||||
**Step 1.5: Check for unaddressed UAT gaps**
|
||||
|
||||
For each *-ISSUES.md file, check if matching *-FIX.md exists.
|
||||
For each *-FIX.md file, check if matching *-FIX-SUMMARY.md exists.
|
||||
Check for UAT.md files with status "diagnosed" (has gaps needing fixes).
|
||||
|
||||
```bash
|
||||
# Check for diagnosed UAT with gaps
|
||||
grep -l "status: diagnosed" .planning/phases/[current-phase-dir]/*-UAT.md 2>/dev/null
|
||||
```
|
||||
|
||||
Track:
|
||||
- `issues_without_fix`: ISSUES.md files without FIX.md
|
||||
- `fixes_without_summary`: FIX.md files without FIX-SUMMARY.md
|
||||
- `uat_with_gaps`: UAT.md files with status "diagnosed" (gaps need fixing)
|
||||
|
||||
**Step 2: Route based on counts**
|
||||
|
||||
| Condition | Meaning | Action |
|
||||
|-----------|---------|--------|
|
||||
| fixes_without_summary > 0 | Unexecuted fix plans exist | Go to **Route A** (with FIX.md) |
|
||||
| issues_without_fix > 0 | UAT issues need fix plans | Go to **Route E** |
|
||||
| uat_with_gaps > 0 | UAT gaps need fix plans | Go to **Route E** |
|
||||
| summaries < plans | Unexecuted plans exist | Go to **Route A** |
|
||||
| summaries = plans AND plans > 0 | Phase complete | Go to Step 3 |
|
||||
| plans = 0 | Phase not yet planned | Go to **Route B** |
|
||||
@@ -209,18 +209,18 @@ Check if `{phase}-CONTEXT.md` exists in phase directory.
|
||||
|
||||
---
|
||||
|
||||
**Route E: UAT issues need fix plans**
|
||||
**Route E: UAT gaps need fix plans**
|
||||
|
||||
ISSUES.md exists without matching FIX.md. User needs to plan fixes.
|
||||
UAT.md exists with gaps (diagnosed issues). User needs to plan fixes.
|
||||
|
||||
```
|
||||
---
|
||||
|
||||
## ⚠ UAT Issues Found
|
||||
## ⚠ UAT Gaps Found
|
||||
|
||||
**{plan}-ISSUES.md** has {N} issues without a fix plan.
|
||||
**{phase}-UAT.md** has {N} gaps requiring fixes.
|
||||
|
||||
`/gsd:plan-fix {plan}`
|
||||
`/gsd:plan-phase {phase} --gaps`
|
||||
|
||||
<sub>`/clear` first → fresh context window</sub>
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ Validate built features through conversational testing with persistent state.
|
||||
|
||||
Purpose: Confirm what Claude built actually works from user's perspective. One test at a time, plain text responses, no interrogation.
|
||||
|
||||
Output: {phase}-UAT.md tracking all test results, issues logged for /gsd:plan-fix
|
||||
Output: {phase}-UAT.md tracking all test results, gaps logged for /gsd:plan-phase --gaps
|
||||
</objective>
|
||||
|
||||
<execution_context>
|
||||
@@ -51,7 +51,7 @@ Phase: $ARGUMENTS (optional)
|
||||
- Don't ask severity — infer from description
|
||||
- Don't present full checklist upfront — one test at a time
|
||||
- Don't run automated tests — this is manual user validation
|
||||
- Don't fix issues during testing — log for /gsd:plan-fix
|
||||
- Don't fix issues during testing — log as gaps for /gsd:plan-phase --gaps
|
||||
</anti_patterns>
|
||||
|
||||
<success_criteria>
|
||||
|
||||
@@ -39,8 +39,6 @@ expected: [observable behavior]
|
||||
result: issue
|
||||
reported: "[verbatim user response]"
|
||||
severity: major
|
||||
root_cause: [filled by diagnose-issues, empty until diagnosed]
|
||||
debug_session: [path to DEBUG file, empty until diagnosed]
|
||||
|
||||
### 4. [Test Name]
|
||||
expected: [observable behavior]
|
||||
@@ -57,13 +55,18 @@ issues: [N]
|
||||
pending: [N]
|
||||
skipped: [N]
|
||||
|
||||
## Issues for /gsd:plan-fix
|
||||
## Gaps
|
||||
|
||||
- UAT-001: [brief summary] (blocker) - Test 3
|
||||
root_cause: [empty until diagnosed]
|
||||
|
||||
- UAT-002: [brief summary] (major) - Test 7
|
||||
root_cause: [empty until diagnosed]
|
||||
<!-- YAML format for plan-phase --gaps consumption -->
|
||||
- truth: "[expected behavior from test]"
|
||||
status: failed
|
||||
reason: "User reported: [verbatim response]"
|
||||
severity: blocker | major | minor | cosmetic
|
||||
test: [N]
|
||||
root_cause: "" # Filled by diagnosis
|
||||
artifacts: [] # Filled by diagnosis
|
||||
missing: [] # Filled by diagnosis
|
||||
debug_session: "" # Filled by diagnosis
|
||||
```
|
||||
|
||||
---
|
||||
@@ -87,49 +90,46 @@ skipped: [N]
|
||||
- `result` values: [pending], pass, issue, skipped
|
||||
- If issue: add `reported` (verbatim) and `severity` (inferred)
|
||||
- If skipped: add `reason` if provided
|
||||
- After diagnosis: add `root_cause` and `debug_session` fields to issues
|
||||
|
||||
**Summary:**
|
||||
- OVERWRITE counts after each response
|
||||
- Tracks: total, passed, issues, pending, skipped
|
||||
|
||||
**Issues for /gsd:plan-fix:**
|
||||
- APPEND only when issue found
|
||||
- Format: `- UAT-{NNN}: {summary} ({severity}) - Test {N}`
|
||||
- After diagnosis: add `root_cause:` line under each issue
|
||||
- This section feeds directly into /gsd:plan-fix
|
||||
**Gaps:**
|
||||
- APPEND only when issue found (YAML format)
|
||||
- After diagnosis: fill `root_cause`, `artifacts`, `missing`, `debug_session`
|
||||
- This section feeds directly into /gsd:plan-phase --gaps
|
||||
|
||||
</section_rules>
|
||||
|
||||
<diagnosis_lifecycle>
|
||||
|
||||
**After testing complete (status: complete), if issues exist:**
|
||||
**After testing complete (status: complete), if gaps exist:**
|
||||
|
||||
1. User runs diagnosis (from verify-work offer or manually)
|
||||
2. diagnose-issues workflow spawns parallel debug agents
|
||||
3. Each agent investigates one issue, returns root cause
|
||||
4. UAT.md updated with root causes:
|
||||
- Each issue test gets `root_cause:` and `debug_session:` fields
|
||||
- Issues section gets `root_cause:` under each issue
|
||||
3. Each agent investigates one gap, returns root cause
|
||||
4. UAT.md Gaps section updated with diagnosis:
|
||||
- Each gap gets `root_cause`, `artifacts`, `missing`, `debug_session` filled
|
||||
5. status → "diagnosed"
|
||||
6. Ready for /gsd:plan-fix with root causes
|
||||
6. Ready for /gsd:plan-phase --gaps with root causes
|
||||
|
||||
**After diagnosis:**
|
||||
```markdown
|
||||
### 2. Create Top-Level Comment
|
||||
expected: Submit comment via rich text editor, appears in list with author info
|
||||
result: issue
|
||||
reported: "works but doesn't show until I refresh the page"
|
||||
severity: major
|
||||
root_cause: useEffect in CommentList.tsx missing commentCount dependency
|
||||
debug_session: .planning/debug/comment-not-refreshing.md
|
||||
```
|
||||
```yaml
|
||||
## Gaps
|
||||
|
||||
```markdown
|
||||
## Issues for /gsd:plan-fix
|
||||
|
||||
- UAT-001: Comment doesn't appear until refresh (major) - Test 2
|
||||
root_cause: useEffect in CommentList.tsx missing commentCount dependency
|
||||
- truth: "Comment appears immediately after submission"
|
||||
status: failed
|
||||
reason: "User reported: works but doesn't show until I refresh the page"
|
||||
severity: major
|
||||
test: 2
|
||||
root_cause: "useEffect in CommentList.tsx missing commentCount dependency"
|
||||
artifacts:
|
||||
- path: "src/components/CommentList.tsx"
|
||||
issue: "useEffect missing dependency"
|
||||
missing:
|
||||
- "Add commentCount to useEffect dependency array"
|
||||
debug_session: ".planning/debug/comment-not-refreshing.md"
|
||||
```
|
||||
|
||||
</diagnosis_lifecycle>
|
||||
@@ -147,7 +147,7 @@ debug_session: .planning/debug/comment-not-refreshing.md
|
||||
- User responds with pass confirmation or issue description
|
||||
- Update test result (pass/issue/skipped)
|
||||
- Update Summary counts
|
||||
- If issue: append to Issues section, infer severity
|
||||
- If issue: append to Gaps section (YAML format), infer severity
|
||||
- Move Current Test to next pending test
|
||||
|
||||
**On completion:**
|
||||
@@ -182,7 +182,7 @@ Default: **major** (safe default, user can clarify if wrong)
|
||||
<good_example>
|
||||
```markdown
|
||||
---
|
||||
status: testing
|
||||
status: diagnosed
|
||||
phase: 04-comments
|
||||
source: 04-01-SUMMARY.md, 04-02-SUMMARY.md
|
||||
started: 2025-01-15T10:30:00Z
|
||||
@@ -191,13 +191,7 @@ updated: 2025-01-15T10:45:00Z
|
||||
|
||||
## Current Test
|
||||
|
||||
number: 4
|
||||
name: Visual Nesting
|
||||
expected: |
|
||||
Create 3+ level deep thread.
|
||||
Each level shows increased indentation with left border.
|
||||
Nesting caps at reasonable depth.
|
||||
awaiting: user response
|
||||
[testing complete]
|
||||
|
||||
## Tests
|
||||
|
||||
@@ -210,8 +204,6 @@ expected: Submit comment via rich text editor, appears in list with author info
|
||||
result: issue
|
||||
reported: "works but doesn't show until I refresh the page"
|
||||
severity: major
|
||||
root_cause: useEffect in CommentList.tsx missing commentCount dependency
|
||||
debug_session: .planning/debug/comment-not-refreshing.md
|
||||
|
||||
### 3. Reply to a Comment
|
||||
expected: Click Reply, inline composer appears, submit shows nested reply
|
||||
@@ -219,27 +211,37 @@ result: pass
|
||||
|
||||
### 4. Visual Nesting
|
||||
expected: 3+ level thread shows indentation, left borders, caps at reasonable depth
|
||||
result: [pending]
|
||||
result: pass
|
||||
|
||||
### 5. Delete Own Comment
|
||||
expected: Click delete on own comment, removed or shows [deleted] if has replies
|
||||
result: [pending]
|
||||
result: pass
|
||||
|
||||
### 6. Comment Count
|
||||
expected: Post shows accurate count, increments when adding comment
|
||||
result: [pending]
|
||||
result: pass
|
||||
|
||||
## Summary
|
||||
|
||||
total: 6
|
||||
passed: 2
|
||||
passed: 5
|
||||
issues: 1
|
||||
pending: 3
|
||||
pending: 0
|
||||
skipped: 0
|
||||
|
||||
## Issues for /gsd:plan-fix
|
||||
## Gaps
|
||||
|
||||
- UAT-001: Comment doesn't appear until refresh (major) - Test 2
|
||||
root_cause: useEffect in CommentList.tsx missing commentCount dependency
|
||||
- truth: "Comment appears immediately after submission in list"
|
||||
status: failed
|
||||
reason: "User reported: works but doesn't show until I refresh the page"
|
||||
severity: major
|
||||
test: 2
|
||||
root_cause: "useEffect in CommentList.tsx missing commentCount dependency"
|
||||
artifacts:
|
||||
- path: "src/components/CommentList.tsx"
|
||||
issue: "useEffect missing dependency"
|
||||
missing:
|
||||
- "Add commentCount to useEffect dependency array"
|
||||
debug_session: ".planning/debug/comment-not-refreshing.md"
|
||||
```
|
||||
</good_example>
|
||||
|
||||
@@ -46,7 +46,7 @@ Start directly at investigation_loop.
|
||||
|
||||
**goal: {goal}**
|
||||
|
||||
- `find_root_cause_only` — Diagnose but do NOT fix. Return root cause to orchestrator. Used by UAT diagnosis flow where plan-fix handles the fix.
|
||||
- `find_root_cause_only` — Diagnose but do NOT fix. Return root cause to orchestrator. Used by UAT diagnosis flow where plan-phase --gaps handles the fix.
|
||||
- `find_and_fix` — Find root cause, then fix and verify. Used by interactive /gsd:debug where user wants immediate resolution.
|
||||
</mode>
|
||||
|
||||
@@ -167,7 +167,7 @@ If you cannot proceed without user action or verification:
|
||||
- [file1]: [what's wrong]
|
||||
- [file2]: [related issue]
|
||||
|
||||
**Suggested Fix Direction:** [brief hint for plan-fix, not implementation]
|
||||
**Suggested Fix Direction:** [brief hint for gap closure plan, not implementation]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
@@ -213,7 +213,7 @@ Reply with A or B (or describe alternative)
|
||||
- Diagnose but don't fix
|
||||
- Stop after confirming root cause
|
||||
- Skip `fix_and_verify` step
|
||||
- Return root cause to caller (for plan-fix to handle)
|
||||
- Return root cause to caller (for plan-phase --gaps to handle)
|
||||
|
||||
**Default mode (no flags):**
|
||||
- Interactive debugging with user
|
||||
@@ -544,7 +544,7 @@ If unable to determine root cause after thorough investigation:
|
||||
**Debug Session:** {path to debug file}
|
||||
```
|
||||
|
||||
**Do NOT proceed to fix_and_verify.** The fix will be planned by /gsd:plan-fix using this diagnosis.
|
||||
**Do NOT proceed to fix_and_verify.** The fix will be planned by /gsd:plan-phase --gaps using this diagnosis.
|
||||
</step>
|
||||
|
||||
<step name="fix_and_verify">
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
<purpose>
|
||||
Orchestrate parallel debug agents to investigate UAT issues and find root causes.
|
||||
Orchestrate parallel debug agents to investigate UAT gaps and find root causes.
|
||||
|
||||
After UAT finds issues, spawn one debug agent per issue. Each agent investigates autonomously with symptoms pre-filled from UAT. Collect root causes, update UAT.md, then hand off to plan-fix with actual diagnoses.
|
||||
After UAT finds gaps, spawn one debug agent per gap. Each agent investigates autonomously with symptoms pre-filled from UAT. Collect root causes, update UAT.md gaps with diagnosis, then hand off to plan-phase --gaps with actual diagnoses.
|
||||
|
||||
Orchestrator stays lean: parse issues, spawn agents, collect results, update UAT.
|
||||
Orchestrator stays lean: parse gaps, spawn agents, collect results, update UAT.
|
||||
</purpose>
|
||||
|
||||
<paths>
|
||||
@@ -15,7 +15,7 @@ Debug files use the `.planning/debug/` path (hidden directory with leading dot).
|
||||
<core_principle>
|
||||
**Diagnose before planning fixes.**
|
||||
|
||||
UAT tells us WHAT is broken (symptoms). Debug agents find WHY (root cause). Plan-fix then creates targeted fixes based on actual causes, not guesses.
|
||||
UAT tells us WHAT is broken (symptoms). Debug agents find WHY (root cause). plan-phase --gaps then creates targeted fixes based on actual causes, not guesses.
|
||||
|
||||
Without diagnosis: "Comment doesn't refresh" → guess at fix → maybe wrong
|
||||
With diagnosis: "Comment doesn't refresh" → "useEffect missing dependency" → precise fix
|
||||
@@ -23,26 +23,27 @@ With diagnosis: "Comment doesn't refresh" → "useEffect missing dependency" →
|
||||
|
||||
<process>
|
||||
|
||||
<step name="parse_issues">
|
||||
**Extract issues from UAT.md:**
|
||||
<step name="parse_gaps">
|
||||
**Extract gaps from UAT.md:**
|
||||
|
||||
Read the "Issues for /gsd:plan-fix" section:
|
||||
```
|
||||
- UAT-001: Comment doesn't appear until refresh (major) - Test 2
|
||||
- UAT-002: Reply button position wrong (minor) - Test 5
|
||||
- UAT-003: Delete doesn't work (blocker) - Test 6
|
||||
Read the "Gaps" section (YAML format):
|
||||
```yaml
|
||||
- truth: "Comment appears immediately after submission"
|
||||
status: failed
|
||||
reason: "User reported: works but doesn't show until I refresh the page"
|
||||
severity: major
|
||||
test: 2
|
||||
artifacts: []
|
||||
missing: []
|
||||
```
|
||||
|
||||
For each issue, also read the corresponding test from "Tests" section to get:
|
||||
- expected: What should happen
|
||||
- reported: What user described (verbatim)
|
||||
- severity: blocker/major/minor/cosmetic
|
||||
For each gap, also read the corresponding test from "Tests" section to get full context.
|
||||
|
||||
Build issue list:
|
||||
Build gap list:
|
||||
```
|
||||
issues = [
|
||||
{id: "UAT-001", summary: "Comment doesn't appear until refresh", severity: "major", test_num: 2, expected: "...", reported: "..."},
|
||||
{id: "UAT-002", summary: "Reply button position wrong", severity: "minor", test_num: 5, expected: "...", reported: "..."},
|
||||
gaps = [
|
||||
{truth: "Comment appears immediately...", severity: "major", test_num: 2, reason: "..."},
|
||||
{truth: "Reply button positioned correctly...", severity: "minor", test_num: 5, reason: "..."},
|
||||
...
|
||||
]
|
||||
```
|
||||
@@ -52,50 +53,49 @@ issues = [
|
||||
**Report diagnosis plan to user:**
|
||||
|
||||
```
|
||||
## Diagnosing {N} Issues
|
||||
## Diagnosing {N} Gaps
|
||||
|
||||
Spawning parallel debug agents to investigate root causes:
|
||||
|
||||
| Issue | Summary | Severity |
|
||||
|-------|---------|----------|
|
||||
| UAT-001 | Comment doesn't appear until refresh | major |
|
||||
| UAT-002 | Reply button position wrong | minor |
|
||||
| UAT-003 | Delete doesn't work | blocker |
|
||||
| Gap (Truth) | Severity |
|
||||
|-------------|----------|
|
||||
| Comment appears immediately after submission | major |
|
||||
| Reply button positioned correctly | minor |
|
||||
| Delete removes comment | blocker |
|
||||
|
||||
Each agent will:
|
||||
1. Create DEBUG-UAT-{NNN}.md with symptoms pre-filled
|
||||
1. Create DEBUG-{slug}.md with symptoms pre-filled
|
||||
2. Investigate autonomously (read code, form hypotheses, test)
|
||||
3. Return root cause
|
||||
|
||||
This runs in parallel - all issues investigated simultaneously.
|
||||
This runs in parallel - all gaps investigated simultaneously.
|
||||
```
|
||||
</step>
|
||||
|
||||
<step name="spawn_agents">
|
||||
**Spawn debug agents in parallel:**
|
||||
|
||||
For each issue, fill the debug-subagent-prompt template and spawn:
|
||||
For each gap, fill the debug-subagent-prompt template and spawn:
|
||||
|
||||
```
|
||||
Task(
|
||||
prompt=filled_debug_subagent_prompt,
|
||||
subagent_type="general-purpose",
|
||||
description="Debug UAT-{NNN}"
|
||||
description="Debug: {truth_short}"
|
||||
)
|
||||
```
|
||||
|
||||
**All agents spawn in single message** (parallel execution).
|
||||
|
||||
Template placeholders:
|
||||
- `{issue_id}`: UAT-001, UAT-002, etc.
|
||||
- `{issue_summary}`: Brief description
|
||||
- `{truth}`: The expected behavior that failed
|
||||
- `{expected}`: From UAT test
|
||||
- `{actual}`: Verbatim user description (what actually happened)
|
||||
- `{actual}`: Verbatim user description from reason field
|
||||
- `{errors}`: Any error messages from UAT (or "None reported")
|
||||
- `{reproduction}`: "Test {test_num} in UAT"
|
||||
- `{timeline}`: "Discovered during UAT"
|
||||
- `{goal}`: `find_root_cause_only` (UAT flow - plan-fix handles fixes)
|
||||
- `{slug}`: Generated from issue_summary
|
||||
- `{goal}`: `find_root_cause_only` (UAT flow - plan-phase --gaps handles fixes)
|
||||
- `{slug}`: Generated from truth
|
||||
</step>
|
||||
|
||||
<step name="collect_results">
|
||||
@@ -118,14 +118,14 @@ Each agent returns with:
|
||||
- {file1}: {what's wrong}
|
||||
- {file2}: {related issue}
|
||||
|
||||
**Suggested Fix Direction:** {brief hint for plan-fix}
|
||||
**Suggested Fix Direction:** {brief hint for plan-phase --gaps}
|
||||
```
|
||||
|
||||
Parse each return to extract:
|
||||
- root_cause: The diagnosed cause
|
||||
- files: Files involved
|
||||
- debug_path: Path to debug session file
|
||||
- suggested_fix: Hint for plan-fix
|
||||
- suggested_fix: Hint for gap closure plan
|
||||
|
||||
If agent returns `## INVESTIGATION INCONCLUSIVE`:
|
||||
- root_cause: "Investigation inconclusive - manual review needed"
|
||||
@@ -134,34 +134,27 @@ If agent returns `## INVESTIGATION INCONCLUSIVE`:
|
||||
</step>
|
||||
|
||||
<step name="update_uat">
|
||||
**Update UAT.md with root causes:**
|
||||
**Update UAT.md gaps with diagnosis:**
|
||||
|
||||
For each issue in the Tests section, add root_cause field:
|
||||
For each gap in the Gaps section, add artifacts and missing fields:
|
||||
|
||||
```markdown
|
||||
### 2. Create Top-Level Comment
|
||||
expected: Submit comment via rich text editor, appears in list with author info
|
||||
result: issue
|
||||
reported: "works but doesn't show until I refresh the page"
|
||||
severity: major
|
||||
root_cause: "useEffect in CommentList.tsx missing commentCount dependency - doesn't re-render when new comment added"
|
||||
debug_session: ${DEBUG_DIR}/comment-not-refreshing.md
|
||||
```yaml
|
||||
- truth: "Comment appears immediately after submission"
|
||||
status: failed
|
||||
reason: "User reported: works but doesn't show until I refresh the page"
|
||||
severity: major
|
||||
test: 2
|
||||
root_cause: "useEffect in CommentList.tsx missing commentCount dependency"
|
||||
artifacts:
|
||||
- path: "src/components/CommentList.tsx"
|
||||
issue: "useEffect missing dependency"
|
||||
missing:
|
||||
- "Add commentCount to useEffect dependency array"
|
||||
- "Trigger re-render when new comment added"
|
||||
debug_session: .planning/debug/comment-not-refreshing.md
|
||||
```
|
||||
|
||||
Update the "Issues for /gsd:plan-fix" section with root causes:
|
||||
|
||||
```markdown
|
||||
## Issues for /gsd:plan-fix
|
||||
|
||||
- UAT-001: Comment doesn't appear until refresh (major) - Test 2
|
||||
root_cause: useEffect missing dependency in CommentList.tsx
|
||||
|
||||
- UAT-002: Reply button position wrong (minor) - Test 5
|
||||
root_cause: CSS flex order incorrect in ReplyButton.tsx
|
||||
|
||||
- UAT-003: Delete doesn't work (blocker) - Test 6
|
||||
root_cause: API endpoint returns 403 - missing auth header
|
||||
```
|
||||
Update status in frontmatter to "diagnosed".
|
||||
|
||||
Commit the updated UAT.md:
|
||||
```bash
|
||||
@@ -176,31 +169,31 @@ git commit -m "docs({phase}): add root causes from diagnosis"
|
||||
```
|
||||
## Diagnosis Complete
|
||||
|
||||
| Issue | Root Cause | Files |
|
||||
|-------|------------|-------|
|
||||
| UAT-001 | useEffect missing dependency | CommentList.tsx |
|
||||
| UAT-002 | CSS flex order incorrect | ReplyButton.tsx |
|
||||
| UAT-003 | API missing auth header | api/comments.ts |
|
||||
| Gap (Truth) | Root Cause | Files |
|
||||
|-------------|------------|-------|
|
||||
| Comment appears immediately | useEffect missing dependency | CommentList.tsx |
|
||||
| Reply button positioned correctly | CSS flex order incorrect | ReplyButton.tsx |
|
||||
| Delete removes comment | API missing auth header | api/comments.ts |
|
||||
|
||||
Debug sessions saved to ${DEBUG_DIR}/
|
||||
|
||||
---
|
||||
|
||||
Next steps:
|
||||
- `/gsd:plan-fix {phase}` — Create fix plan with root causes
|
||||
- `/gsd:plan-phase {phase} --gaps` — Create fix plans from diagnosed gaps
|
||||
- Review debug sessions for details
|
||||
```
|
||||
</step>
|
||||
|
||||
<step name="offer_next">
|
||||
**Offer plan-fix:**
|
||||
**Offer gap closure:**
|
||||
|
||||
```
|
||||
Root causes identified. Ready to plan fixes?
|
||||
|
||||
`/gsd:plan-fix {phase}`
|
||||
`/gsd:plan-phase {phase} --gaps`
|
||||
|
||||
The fix plan will use diagnosed root causes for targeted fixes.
|
||||
The fix plans will use diagnosed root causes for targeted fixes.
|
||||
```
|
||||
</step>
|
||||
|
||||
@@ -208,7 +201,7 @@ The fix plan will use diagnosed root causes for targeted fixes.
|
||||
|
||||
<context_efficiency>
|
||||
**Orchestrator context:** ~15%
|
||||
- Parse UAT.md issues
|
||||
- Parse UAT.md gaps
|
||||
- Fill template strings
|
||||
- Spawn parallel Task calls
|
||||
- Collect results
|
||||
@@ -221,30 +214,30 @@ The fix plan will use diagnosed root causes for targeted fixes.
|
||||
- Returns root cause
|
||||
|
||||
**No symptom gathering.** Agents start with symptoms pre-filled from UAT.
|
||||
**No fix application.** Agents only diagnose - plan-fix handles fixes.
|
||||
**No fix application.** Agents only diagnose - plan-phase --gaps handles fixes.
|
||||
</context_efficiency>
|
||||
|
||||
<failure_handling>
|
||||
**Agent fails to find root cause:**
|
||||
- Mark issue as "needs manual review"
|
||||
- Continue with other issues
|
||||
- Mark gap as "needs manual review"
|
||||
- Continue with other gaps
|
||||
- Report incomplete diagnosis
|
||||
|
||||
**Agent times out:**
|
||||
- Check DEBUG-UAT-{NNN}.md for partial progress
|
||||
- Check DEBUG-{slug}.md for partial progress
|
||||
- Can resume with /gsd:debug
|
||||
|
||||
**All agents fail:**
|
||||
- Something systemic (permissions, git, etc.)
|
||||
- Report for manual investigation
|
||||
- Fall back to plan-fix without root causes
|
||||
- Fall back to plan-phase --gaps without root causes (less precise)
|
||||
</failure_handling>
|
||||
|
||||
<success_criteria>
|
||||
- [ ] Issues parsed from UAT.md
|
||||
- [ ] Gaps parsed from UAT.md
|
||||
- [ ] Debug agents spawned in parallel
|
||||
- [ ] Root causes collected from all agents
|
||||
- [ ] UAT.md updated with root causes
|
||||
- [ ] UAT.md gaps updated with artifacts and missing
|
||||
- [ ] Debug sessions saved to ${DEBUG_DIR}/
|
||||
- [ ] User knows next steps (plan-fix)
|
||||
- [ ] User knows next steps (plan-phase --gaps)
|
||||
</success_criteria>
|
||||
|
||||
@@ -102,18 +102,29 @@ If `--gaps` present in arguments, switch to gap_closure_mode (see `<step name="g
|
||||
</step>
|
||||
|
||||
<step name="gap_closure_mode">
|
||||
**Triggered by `--gaps` flag.** Plans address verification gaps.
|
||||
**Triggered by `--gaps` flag.** Plans address verification gaps OR UAT gaps.
|
||||
|
||||
**1. Load VERIFICATION.md:**
|
||||
**1. Find gap sources:**
|
||||
|
||||
```bash
|
||||
PHASE_DIR=$(ls -d .planning/phases/${PHASE_ARG}* 2>/dev/null | head -1)
|
||||
cat "$PHASE_DIR"/*-VERIFICATION.md
|
||||
|
||||
# Check for VERIFICATION.md (code verification gaps)
|
||||
ls "$PHASE_DIR"/*-VERIFICATION.md 2>/dev/null
|
||||
|
||||
# Check for UAT.md with diagnosed status (user testing gaps)
|
||||
grep -l "status: diagnosed" "$PHASE_DIR"/*-UAT.md 2>/dev/null
|
||||
```
|
||||
|
||||
**2. Parse gaps from YAML frontmatter:**
|
||||
**Priority:** If both exist, load both and combine gaps. UAT gaps (user-discovered) may overlap with verification gaps (code-discovered).
|
||||
|
||||
Extract `gaps:` array. Each gap has:
|
||||
**2. Parse gaps:**
|
||||
|
||||
**From VERIFICATION.md** (if exists): Parse `gaps:` from YAML frontmatter.
|
||||
|
||||
**From UAT.md** (if exists with status: diagnosed): Parse gaps from `## Gaps` section (YAML format).
|
||||
|
||||
Each gap has:
|
||||
- `truth`: The observable behavior that failed
|
||||
- `reason`: Why it failed
|
||||
- `artifacts`: Files with issues
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<purpose>
|
||||
Validate built features through conversational testing with persistent state. Creates UAT.md that tracks test progress, survives /clear, and feeds into /gsd:plan-fix.
|
||||
Validate built features through conversational testing with persistent state. Creates UAT.md that tracks test progress, survives /clear, and feeds gaps into /gsd:plan-phase --gaps.
|
||||
|
||||
User tests, Claude records. One test at a time. Plain text responses.
|
||||
</purpose>
|
||||
@@ -153,7 +153,7 @@ issues: 0
|
||||
pending: [N]
|
||||
skipped: 0
|
||||
|
||||
## Issues for /gsd:plan-fix
|
||||
## Gaps
|
||||
|
||||
[none yet]
|
||||
```
|
||||
@@ -224,9 +224,15 @@ reported: "{verbatim user response}"
|
||||
severity: {inferred}
|
||||
```
|
||||
|
||||
Append to Issues section:
|
||||
```
|
||||
- UAT-{NNN}: {brief summary from response} ({severity}) - Test {N}
|
||||
Append to Gaps section (structured YAML for plan-phase --gaps):
|
||||
```yaml
|
||||
- truth: "{expected behavior from test}"
|
||||
status: failed
|
||||
reason: "User reported: {verbatim user response}"
|
||||
severity: {inferred}
|
||||
test: {N}
|
||||
artifacts: [] # Filled by diagnosis
|
||||
missing: [] # Filled by diagnosis
|
||||
```
|
||||
|
||||
**After any response:**
|
||||
@@ -321,12 +327,12 @@ Spawning parallel debug agents to investigate each issue.
|
||||
- Spawn parallel debug agents for each issue
|
||||
- Collect root causes
|
||||
- Update UAT.md with root causes
|
||||
- Proceed to `offer_plan_fix`
|
||||
- Proceed to `offer_gap_closure`
|
||||
|
||||
Diagnosis runs automatically - no user prompt. Parallel agents investigate simultaneously, so overhead is minimal and fixes are more accurate.
|
||||
</step>
|
||||
|
||||
<step name="offer_plan_fix">
|
||||
<step name="offer_gap_closure">
|
||||
**Offer next steps after diagnosis:**
|
||||
|
||||
```
|
||||
@@ -334,14 +340,14 @@ Diagnosis runs automatically - no user prompt. Parallel agents investigate simul
|
||||
|
||||
## Diagnosis Complete
|
||||
|
||||
| Issue | Root Cause |
|
||||
|-------|------------|
|
||||
| UAT-001 | {root_cause} |
|
||||
| UAT-002 | {root_cause} |
|
||||
| Gap | Root Cause |
|
||||
|-----|------------|
|
||||
| {truth 1} | {root_cause} |
|
||||
| {truth 2} | {root_cause} |
|
||||
...
|
||||
|
||||
Next steps:
|
||||
- `/gsd:plan-fix {phase}` — Create fix plan with root causes
|
||||
- `/gsd:plan-phase {phase} --gaps` — Create fix plans from diagnosed gaps
|
||||
- `/gsd:verify-work {phase}` — Re-test after fixes
|
||||
```
|
||||
</step>
|
||||
@@ -349,18 +355,23 @@ Next steps:
|
||||
</process>
|
||||
|
||||
<update_rules>
|
||||
**Section update rules:**
|
||||
**Batched writes for efficiency:**
|
||||
|
||||
| Section | Rule | When |
|
||||
|---------|------|------|
|
||||
Keep results in memory. Write to file only when:
|
||||
1. **Issue found** — Preserve the problem immediately
|
||||
2. **Session complete** — Final write before commit
|
||||
3. **Checkpoint** — Every 5 passed tests (safety net)
|
||||
|
||||
| Section | Rule | When Written |
|
||||
|---------|------|--------------|
|
||||
| Frontmatter.status | OVERWRITE | Start, complete |
|
||||
| Frontmatter.updated | OVERWRITE | Every update |
|
||||
| Current Test | OVERWRITE | Each test transition |
|
||||
| Tests.{N}.result | OVERWRITE | When user responds |
|
||||
| Summary | OVERWRITE | After each response |
|
||||
| Issues | APPEND | When issue found |
|
||||
| Frontmatter.updated | OVERWRITE | On any file write |
|
||||
| Current Test | OVERWRITE | On any file write |
|
||||
| Tests.{N}.result | OVERWRITE | On any file write |
|
||||
| Summary | OVERWRITE | On any file write |
|
||||
| Gaps | APPEND | When issue found |
|
||||
|
||||
**Update file AFTER processing each response.** If context resets, file shows exactly where to resume.
|
||||
On context reset: File shows last checkpoint. Resume from there.
|
||||
</update_rules>
|
||||
|
||||
<severity_inference>
|
||||
@@ -383,8 +394,7 @@ Default to **major** if unclear. User can correct if needed.
|
||||
- [ ] Tests presented one at a time with expected behavior
|
||||
- [ ] User responses processed as pass/issue/skip
|
||||
- [ ] Severity inferred from description (never asked)
|
||||
- [ ] File updated after each response
|
||||
- [ ] Can resume perfectly from any /clear
|
||||
- [ ] Batched writes: on issue, every 5 passes, or completion
|
||||
- [ ] Committed on completion
|
||||
- [ ] Clear next steps based on results
|
||||
- [ ] Clear next steps based on results (plan-phase --gaps if issues)
|
||||
</success_criteria>
|
||||
|
||||
Reference in New Issue
Block a user