feat: redesign verify-work as conversational UAT with persistent state

- One test at a time instead of full checklist upfront
- Plain text responses instead of AskUserQuestion forms
- Severity inferred from description, never asked
- Persistent UAT.md survives /clear (like debug workflow)
- Single file per phase replaces per-plan ISSUES.md
- Updated plan-fix to read from UAT.md

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Lex Christopherson
2026-01-14 09:56:09 -06:00
parent 41d27bae84
commit 9e0808b409
5 changed files with 635 additions and 394 deletions

View File

@@ -1,7 +1,7 @@
---
name: gsd:plan-fix
description: Plan fixes for UAT issues from verify-work
argument-hint: "[plan, e.g., '04-02']"
argument-hint: "<phase, e.g., '4'>"
allowed-tools:
- Read
- Bash
@@ -14,8 +14,8 @@ allowed-tools:
<objective>
Create FIX.md plan from UAT issues found during verify-work.
Purpose: Plan fixes for issues logged in phase-scoped ISSUES.md files.
Output: {plan}-FIX.md in the phase directory, ready for execution.
Purpose: Plan fixes for issues logged in {phase}-UAT.md.
Output: {phase}-FIX.md in the phase directory, ready for execution.
</objective>
<execution_context>
@@ -24,9 +24,8 @@ Output: {plan}-FIX.md in the phase directory, ready for execution.
</execution_context>
<context>
Plan number: $ARGUMENTS (required - e.g., "04-02" or "09-01")
Phase: $ARGUMENTS (required - e.g., "4")
**Load project state:**
@.planning/STATE.md
@.planning/ROADMAP.md
</context>
@@ -34,52 +33,68 @@ Plan number: $ARGUMENTS (required - e.g., "04-02" or "09-01")
<process>
<step name="parse">
**Parse plan argument:**
**Parse phase argument:**
$ARGUMENTS should be a plan number like "04-02" or "09-01".
Extract phase number (XX) and plan number (NN).
$ARGUMENTS should be a phase number like "4" or "04".
If no argument provided:
```
Error: Plan number required.
Error: Phase number required.
Usage: /gsd:plan-fix 04-02
Usage: /gsd:plan-fix 4
This creates a fix plan from .planning/phases/XX-name/04-02-ISSUES.md
This creates a fix plan from .planning/phases/04-name/04-UAT.md
```
Exit.
</step>
<step name="find">
**Find ISSUES.md file:**
**Find UAT.md file:**
Search for matching ISSUES.md:
```bash
ls .planning/phases/*/{plan}-ISSUES.md 2>/dev/null
ls .planning/phases/${PHASE_ARG}*/*-UAT.md 2>/dev/null
```
If not found:
```
No ISSUES.md found for plan {plan}.
No UAT.md found for phase {phase}.
ISSUES.md files are created by /gsd:verify-work when UAT finds issues.
If no issues were found during testing, no fix plan is needed.
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:**
**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.
Read the ISSUES.md file.
Parse each issue:
- ID (UAT-XXX)
- Title
- Severity (critical/major/minor)
- Description/steps to reproduce
- Acceptance criteria
- Brief summary
- Severity (blocker/major/minor/cosmetic)
- Test number (for context)
Count total issues by severity.
Also read the corresponding test from "Tests" section to get:
- expected behavior
- reported issue (verbatim user description)
</step>
<step name="plan">
@@ -87,42 +102,50 @@ Count total issues by severity.
For each issue (or logical group):
- Create one task per issue OR
- Group related minor issues into single task
- Group related cosmetic/minor issues into single task
Task structure:
```xml
<task type="auto">
<name>Fix UAT-001: [issue title]</name>
<files>[affected files from issue]</files>
<name>Fix UAT-{NNN}: {issue summary}</name>
<files>[affected files - infer from test context]</files>
<action>
[What to fix based on issue description]
[Reference original acceptance criteria]
**Issue:** {verbatim reported description}
**Expected:** {from test}
[Specific fix approach]
</action>
<verify>[Test that issue is resolved]</verify>
<done>[Issue acceptance criteria met]</done>
<verify>
- Reproduce original issue - confirm fixed
- {expected behavior} now works correctly
</verify>
<done>UAT-{NNN} resolved - {expected behavior} works</done>
</task>
```
Prioritize: critical → major → minor
Prioritize: blocker → major → minor → cosmetic
</step>
<step name="write">
**Write FIX.md:**
Create `.planning/phases/XX-name/{plan}-FIX.md`:
Create `.planning/phases/XX-name/{phase}-FIX.md`:
```markdown
---
phase: XX-name
plan: {plan}-FIX
plan: {phase}-FIX
type: fix
wave: 1
depends_on: []
autonomous: true
---
<objective>
Fix {N} UAT issues from plan {plan}.
Fix {N} UAT issues from phase {phase}.
Source: {plan}-ISSUES.md
Priority: {critical count} critical, {major count} major, {minor count} minor
Source: {phase}-UAT.md
Priority: {blocker count} blocker, {major count} major, {minor count} minor, {cosmetic count} cosmetic
</objective>
<execution_context>
@@ -135,10 +158,11 @@ Priority: {critical count} critical, {major count} major, {minor count} minor
@.planning/ROADMAP.md
**Issues being fixed:**
@.planning/phases/XX-name/{plan}-ISSUES.md
@.planning/phases/XX-name/{phase}-UAT.md
**Original plan for reference:**
@.planning/phases/XX-name/{plan}-PLAN.md
**Original plans for reference:**
@.planning/phases/XX-name/{phase}-01-PLAN.md
[other relevant plans]
</context>
<tasks>
@@ -147,20 +171,20 @@ Priority: {critical count} critical, {major count} major, {minor count} minor
<verification>
Before declaring plan complete:
- [ ] All critical issues fixed
- [ ] All blocker issues fixed
- [ ] All major issues fixed
- [ ] Minor issues fixed or documented as deferred
- [ ] Original acceptance criteria from issues met
- [ ] Minor/cosmetic issues fixed or documented as deferred
- [ ] Each fix verified against original reported issue
</verification>
<success_criteria>
- All UAT issues from {plan}-ISSUES.md addressed
- All UAT issues from {phase}-UAT.md addressed
- Tests pass
- Ready for re-verification
- Ready for re-verification with /gsd:verify-work {phase}
</success_criteria>
<output>
After completion, create `.planning/phases/XX-name/{plan}-FIX-SUMMARY.md`
After completion, create `.planning/phases/XX-name/{phase}-FIX-SUMMARY.md`
</output>
```
</step>
@@ -169,37 +193,39 @@ After completion, create `.planning/phases/XX-name/{plan}-FIX-SUMMARY.md`
**Offer execution:**
```
---
## Fix Plan Created
## ✓ Fix Plan Created
**{plan}-FIX.md** — {N} issues to fix
**{phase}-FIX.md** — {N} issues to fix
| Severity | Count |
|----------|-------|
| Critical | {n} |
| Blocker | {n} |
| Major | {n} |
| Minor | {n} |
| Cosmetic | {n} |
---
Would you like to:
1. Execute the fix plan now
2. Review the plan first
3. Modify the plan before executing
---
Next steps:
- Execute: `/gsd:execute-plan .planning/phases/XX-name/{phase}-FIX.md`
- Review plan first: `cat .planning/phases/XX-name/{phase}-FIX.md`
- Re-test after fixes: `/gsd:verify-work {phase}`
```
Use AskUserQuestion to get response.
If execute: `/gsd:execute-plan .planning/phases/XX-name/{plan}-FIX.md`
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
</step>
</process>
<success_criteria>
- [ ] ISSUES.md found and parsed
- [ ] UAT.md found and issues parsed
- [ ] Fix tasks created for each issue
- [ ] FIX.md written with proper structure
- [ ] User offered to execute or review
- [ ] User offered next steps
</success_criteria>

View File

@@ -1,7 +1,7 @@
---
name: gsd:verify-work
description: Guide manual user acceptance testing of recently built features
argument-hint: "[optional: phase or plan number, e.g., '4' or '04-02']"
description: Validate built features through conversational UAT
argument-hint: "[phase number, e.g., '4']"
allowed-tools:
- Read
- Bash
@@ -9,63 +9,57 @@ allowed-tools:
- Grep
- Edit
- Write
- AskUserQuestion
---
<objective>
Guide the user through manual acceptance testing of recently built features.
Validate built features through conversational testing with persistent state.
Purpose: Validate that what Claude thinks was built actually works from the user's perspective. The USER performs all testing — Claude generates the test checklist, guides the process, and captures issues.
Purpose: Confirm what Claude built actually works from user's perspective. One test at a time, plain text responses, no interrogation.
Output: Validation of features, any issues logged to phase-scoped ISSUES.md
Output: {phase}-UAT.md tracking all test results, issues logged for /gsd:plan-fix
</objective>
<execution_context>
@~/.claude/get-shit-done/workflows/verify-work.md
@~/.claude/get-shit-done/templates/uat-issues.md
@~/.claude/get-shit-done/templates/UAT.md
</execution_context>
<context>
Scope: $ARGUMENTS (optional)
- If provided: Test specific phase or plan (e.g., "4" or "04-02")
- If not provided: Test most recently completed plan
Phase: $ARGUMENTS (optional)
- If provided: Test specific phase (e.g., "4")
- If not provided: Check for active sessions or prompt for phase
**Load project state:**
@.planning/STATE.md
**Load roadmap:**
@.planning/ROADMAP.md
</context>
<process>
1. Validate arguments (if provided, parse as phase or plan number)
2. Find relevant SUMMARY.md (specified or most recent)
3. Follow verify-work.md workflow:
- Extract testable deliverables
- Generate test checklist
- Guide through each test via AskUserQuestion
- Collect and categorize issues
- Log issues to `.planning/phases/XX-name/{phase}-{plan}-ISSUES.md`
- Present summary with verdict
4. Offer next steps based on results:
- If all passed: Continue to next phase
- If issues found: `/gsd:plan-fix {phase} {plan}` to create fix plan
1. Check for active UAT sessions (resume or start new)
2. Find SUMMARY.md files for the phase
3. Extract testable deliverables (user-observable outcomes)
4. Create {phase}-UAT.md with test list
5. Present tests one at a time:
- Show expected behavior
- Wait for plain text response
- "yes/y/next" = pass, anything else = issue (severity inferred)
6. Update UAT.md after each response
7. On completion: commit, present summary, offer next steps
</process>
<anti_patterns>
- Don't run automated tests (that's for CI/test suites)
- Don't make assumptions about test results — USER reports outcomes
- Don't skip the guidance — walk through each test
- Don't dismiss minor issues — log everything user reports
- Don't fix issues during testing — capture for later
- Don't use AskUserQuestion for test responses — plain text conversation
- 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
</anti_patterns>
<success_criteria>
- [ ] Test scope identified from SUMMARY.md
- [ ] Checklist generated based on deliverables
- [ ] User guided through each test
- [ ] All test results captured (pass/fail/partial/skip)
- [ ] Any issues logged to phase-scoped ISSUES.md (not global)
- [ ] Summary presented with verdict
- [ ] User knows next steps based on results
- [ ] UAT.md created with tests from SUMMARY.md
- [ ] Tests presented one at a time with expected behavior
- [ ] Plain text responses (no structured forms)
- [ ] Severity inferred, never asked
- [ ] File updated after each response (survives /clear)
- [ ] Committed on completion
- [ ] Clear next steps based on results
</success_criteria>

View File

@@ -0,0 +1,214 @@
# UAT Template
Template for `.planning/phases/XX-name/{phase}-UAT.md` — persistent UAT session tracking.
---
## File Template
```markdown
---
status: testing | complete
phase: XX-name
source: [list of SUMMARY.md files tested]
started: [ISO timestamp]
updated: [ISO timestamp]
---
## Current Test
<!-- OVERWRITE each test - shows where we are -->
number: [N]
name: [test name]
expected: |
[what user should observe]
awaiting: user response
## Tests
### 1. [Test Name]
expected: [observable behavior - what user should see]
result: [pending]
### 2. [Test Name]
expected: [observable behavior]
result: pass
### 3. [Test Name]
expected: [observable behavior]
result: issue
reported: "[verbatim user response]"
severity: major
### 4. [Test Name]
expected: [observable behavior]
result: skipped
reason: [why skipped]
...
## Summary
total: [N]
passed: [N]
issues: [N]
pending: [N]
skipped: [N]
## Issues for /gsd:plan-fix
- UAT-001: [brief summary] (blocker) - Test 3
- UAT-002: [brief summary] (major) - Test 7
```
---
<section_rules>
**Frontmatter:**
- `status`: OVERWRITE - "testing" or "complete"
- `phase`: IMMUTABLE - set on creation
- `source`: IMMUTABLE - SUMMARY files being tested
- `started`: IMMUTABLE - set on creation
- `updated`: OVERWRITE - update on every change
**Current Test:**
- OVERWRITE entirely on each test transition
- Shows which test is active and what's awaited
- On completion: "[testing complete]"
**Tests:**
- Each test: OVERWRITE result field when user responds
- `result` values: [pending], pass, issue, skipped
- If issue: add `reported` (verbatim) and `severity` (inferred)
- If skipped: add `reason` if provided
**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}`
- This section feeds directly into /gsd:plan-fix
</section_rules>
<lifecycle>
**Creation:** When /gsd:verify-work starts new session
- Extract tests from SUMMARY.md files
- Set status to "testing"
- Current Test points to test 1
- All tests have result: [pending]
**During testing:**
- Present test from Current Test section
- 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
- Move Current Test to next pending test
**On completion:**
- status → "complete"
- Current Test → "[testing complete]"
- Commit file
- Present summary with next steps
**Resume after /clear:**
1. Read frontmatter → know phase and status
2. Read Current Test → know where we are
3. Find first [pending] result → continue from there
4. Summary shows progress so far
</lifecycle>
<severity_guide>
Severity is INFERRED from user's natural language, never asked.
| User describes | Infer |
|----------------|-------|
| Crash, error, exception, fails completely, unusable | blocker |
| Doesn't work, nothing happens, wrong behavior, missing | major |
| Works but..., slow, weird, minor, small issue | minor |
| Color, font, spacing, alignment, visual, looks off | cosmetic |
Default: **major** (safe default, user can clarify if wrong)
</severity_guide>
<good_example>
```markdown
---
status: testing
phase: 04-comments
source: 04-01-SUMMARY.md, 04-02-SUMMARY.md
started: 2025-01-15T10:30:00Z
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
## Tests
### 1. View Comments on Post
expected: Comments section expands, shows count and comment list
result: pass
### 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
### 3. Reply to a Comment
expected: Click Reply, inline composer appears, submit shows nested reply
result: pass
### 4. Visual Nesting
expected: 3+ level thread shows indentation, left borders, caps at reasonable depth
result: [pending]
### 5. Delete Own Comment
expected: Click delete on own comment, removed or shows [deleted] if has replies
result: [pending]
### 6. Comment Count
expected: Post shows accurate count, increments when adding comment
result: [pending]
## Summary
total: 6
passed: 2
issues: 1
pending: 3
skipped: 0
## Issues for /gsd:plan-fix
- UAT-001: Comment doesn't appear until refresh (major) - Test 2
```
</good_example>
<difference_from_issues_md>
| UAT.md | ISSUES.md (global) |
|--------|-------------------|
| Created by /gsd:verify-work | Created by deviation rule 5 during execution |
| Tracks test session state | Tracks deferred enhancements |
| Phase-scoped, one per phase | Global, one per project |
| Feeds into /gsd:plan-fix | Feeds into /gsd:consider-issues |
| Contains pass/fail/skip results | Contains only deferred items |
</difference_from_issues_md>

View File

@@ -1,143 +0,0 @@
# UAT Issues Template
Template for `.planning/phases/XX-name/{phase}-{plan}-ISSUES.md` - phase-scoped issues discovered during user acceptance testing.
**Purpose:** Capture issues found during /gsd:verify-work. Unlike global ISSUES.md (for deferred enhancements), this file tracks bugs and problems in specific delivered work.
**Location:** Same directory as the SUMMARY.md being tested.
---
## File Template
```markdown
# UAT Issues: Phase [X] Plan [Y]
**Tested:** [date]
**Source:** [path to SUMMARY.md that was tested]
**Tester:** User via /gsd:verify-work
## Open Issues
### UAT-001: [Brief description]
**Discovered:** [date]
**Phase/Plan:** [XX]-[YY]
**Severity:** [Blocker/Major/Minor/Cosmetic]
**Feature:** [Which feature from the test checklist]
**Description:** [User's description of the problem]
**Expected:** [What should have happened]
**Actual:** [What actually happened]
**Repro:** [Steps to reproduce, if captured]
### UAT-002: [Brief description]
...
## Resolved Issues
[Moved here after /gsd:plan-fix executes and fixes are verified]
### UAT-001: [Brief description]
**Resolved:** [date] - Fixed in [phase]-[plan]-FIX.md
**Commit:** [hash]
---
*Phase: XX-name*
*Plan: YY*
*Tested: [date]*
```
---
## Severity Guide
| Severity | Definition | Example |
|----------|------------|---------|
| **Blocker** | Feature completely unusable | App crashes on button click |
| **Major** | Feature works but significant problem | Form submits but data not saved |
| **Minor** | Feature usable but has issues | Button text slightly cut off |
| **Cosmetic** | Visual only, no functional impact | Wrong shade of color |
---
## UAT Numbering
- **Prefix:** `UAT-` (distinguishes from ISS- enhancement issues)
- **Scope:** Per-file numbering (UAT-001, UAT-002, etc. within each file)
- **No global numbering:** Each {phase}-{plan}-ISSUES.md has its own sequence
---
<good_examples>
```markdown
# UAT Issues: Phase 5 Plan 2
**Tested:** 2025-01-15
**Source:** .planning/phases/05-auth/05-02-SUMMARY.md
**Tester:** User via /gsd:verify-work
## Open Issues
### UAT-001: Login form doesn't show validation errors
**Discovered:** 2025-01-15
**Phase/Plan:** 05-02
**Severity:** Major
**Feature:** User login form
**Description:** When I enter an invalid email, nothing happens. No error message appears.
**Expected:** Red error message below email field saying "Invalid email format"
**Actual:** Field border turns red but no text explanation
**Repro:**
1. Go to /login
2. Enter "notanemail" in email field
3. Click Login button
### UAT-002: Password field allows paste
**Discovered:** 2025-01-15
**Phase/Plan:** 05-02
**Severity:** Cosmetic
**Feature:** User login form
**Description:** Can paste into password field. Minor UX inconsistency.
**Expected:** Paste disabled (matches signup form)
**Actual:** Paste works in login but not signup
**Repro:** Ctrl+V in password field
## Resolved Issues
[None yet]
---
*Phase: 05-auth*
*Plan: 02*
*Tested: 2025-01-15*
```
</good_examples>
<guidelines>
**When to create:**
- First time /gsd:verify-work finds an issue for a plan
- One file per plan tested
**Location:**
- `.planning/phases/XX-name/{phase}-{plan}-ISSUES.md`
- Lives alongside SUMMARY.md being tested
**Difference from global ISSUES.md:**
- Global ISSUES.md: Deferred enhancements (Rule 5 - nice-to-haves)
- UAT ISSUES.md: Actual problems found during testing
**Workflow:**
1. /gsd:verify-work creates this file with issues
2. /gsd:plan-fix reads this file and creates FIX.md plan
3. After FIX.md executes, issues move to "Resolved" section
4. File becomes historical record of what was found and fixed
**Resolution:**
- Don't delete resolved issues - move to "Resolved Issues" section
- Include fix reference (commit hash, plan that fixed it)
- File serves as audit trail
</guidelines>

View File

@@ -1,202 +1,352 @@
<purpose>
Guide manual user acceptance testing of recently built features. Extract deliverables from SUMMARY.md, generate test checklist, guide user through each test, log issues to phase-scoped file.
Validate built features through conversational testing with persistent state. Creates UAT.md that tracks test progress, survives /clear, and feeds into /gsd:plan-fix.
The USER performs all testing — Claude generates the checklist, guides the process, and captures issues.
User tests, Claude records. One test at a time. Plain text responses.
</purpose>
<philosophy>
**Show expected, ask if reality matches.**
Claude presents what SHOULD happen. User confirms or describes what's different.
- "yes" / "y" / "next" / empty → pass
- Anything else → logged as issue, severity inferred
No Pass/Fail buttons. No severity questions. Just: "Here's what should happen. Does it?"
</philosophy>
<template>
@~/.claude/get-shit-done/templates/UAT.md
</template>
<process>
<step name="identify">
**Determine what to test:**
If $ARGUMENTS provided:
- Parse as phase number (e.g., "4") or plan number (e.g., "04-02")
- Find corresponding SUMMARY.md file(s)
If no arguments:
- Find most recently modified SUMMARY.md
<step name="check_active_session">
**First: Check for active UAT sessions**
```bash
find .planning/phases -name "*SUMMARY.md" -type f -exec ls -lt {} + | head -5
find .planning/phases -name "*-UAT.md" -type f 2>/dev/null | head -5
```
Read the SUMMARY.md to understand what was built.
**If active sessions exist AND no $ARGUMENTS provided:**
Read each file's frontmatter (status, phase) and Current Test section.
Display inline:
```
## Active UAT Sessions
| # | Phase | Status | Current Test | Progress |
|---|-------|--------|--------------|----------|
| 1 | 04-comments | testing | 3. Reply to Comment | 2/6 |
| 2 | 05-auth | testing | 1. Login Form | 0/4 |
Reply with a number to resume, or provide a phase number to start new.
```
Wait for user response.
- If user replies with number (1, 2) → Load that file, go to `resume_from_file`
- If user replies with phase number → Treat as new session, go to `create_uat_file`
**If active sessions exist AND $ARGUMENTS provided:**
Check if session exists for that phase. If yes, offer to resume or restart.
If no, continue to `create_uat_file`.
**If no active sessions AND no $ARGUMENTS:**
```
No active UAT sessions.
Provide a phase number to start testing (e.g., /gsd:verify-work 4)
```
**If no active sessions AND $ARGUMENTS provided:**
Continue to `create_uat_file`.
</step>
<step name="extract">
<step name="find_summaries">
**Find what to test:**
Parse $ARGUMENTS as phase number (e.g., "4") or plan number (e.g., "04-02").
```bash
# Find phase directory
PHASE_DIR=$(ls -d .planning/phases/${PHASE_ARG}* 2>/dev/null | head -1)
# Find SUMMARY files
ls "$PHASE_DIR"/*-SUMMARY.md 2>/dev/null
```
Read each SUMMARY.md to extract testable deliverables.
</step>
<step name="extract_tests">
**Extract testable deliverables from SUMMARY.md:**
Parse for:
1. **Accomplishments** - Features/functionality added
2. **Files Created/Modified** - What changed
3. **User-facing changes** - UI, workflows, interactions
2. **User-facing changes** - UI, workflows, interactions
Focus on USER-OBSERVABLE outcomes, not implementation details.
For each deliverable, create a test:
- name: Brief test name
- expected: What the user should see/experience (specific, observable)
Examples:
- "Check-in menu item added to navigation" → User can see/click Check-in in nav
- "HomePage refreshes after check-in" → After check-in, home shows updated state
- Accomplishment: "Added comment threading with infinite nesting"
→ Test: "Reply to a Comment"
→ Expected: "Clicking Reply opens inline composer below comment. Submitting shows reply nested under parent with visual indentation."
Skip internal/non-observable items (refactors, type changes, etc.).
</step>
<step name="generate">
**Generate manual test checklist:**
<step name="create_uat_file">
**Create UAT file with all tests:**
Create structured test plan:
```
# User Acceptance Test: [Plan/Phase Name]
**Scope:** [What was built - from SUMMARY.md]
**Testing:** Manual user validation
## Pre-flight
- [ ] Application builds and runs without errors
- [ ] Application launches to expected state
## Feature Tests
### [Feature 1 from deliverables]
**What to test:** [User-observable behavior]
**Steps:**
1. [Specific action to take]
2. [What to look for]
3. [Expected result]
### [Feature 2 from deliverables]
...
## Edge Cases
- [ ] [Relevant edge case based on feature]
- [ ] [Another edge case]
## Visual/UX Check
- [ ] UI matches expected design
- [ ] No visual glitches or layout issues
- [ ] Responsive to interactions
```bash
mkdir -p "$PHASE_DIR"
```
Present this checklist to user.
</step>
Build test list from extracted deliverables.
<step name="guide">
**Guide user through each test:**
For each test item, use AskUserQuestion:
- header: "[Feature name]"
- question: "[Test description] - Did this work as expected?"
- options:
- "Pass" — Works correctly
- "Fail" — Doesn't work as expected
- "Partial" — Works but with issues
- "Skip" — Can't test right now
**If Pass:** Move to next test
**If Fail or Partial:**
Follow up with AskUserQuestion:
- header: "Issue details"
- question: "What went wrong?"
- options:
- "Crashes/errors" — Application error or exception
- "Wrong behavior" — Does something unexpected
- "Missing feature" — Expected functionality not present
- "UI/visual issue" — Looks wrong but functions
- "Let me describe" — Free-form description needed
</step>
<step name="collect">
**Collect and categorize issues:**
For each failed/partial test, gather:
- Feature affected
- What went wrong (from user input)
- Severity:
- **Blocker** — Can't use the feature at all
- **Major** — Feature works but significant problem
- **Minor** — Small issue, feature still usable
- **Cosmetic** — Visual only, no functional impact
</step>
<step name="log">
**Log issues to phase-scoped file:**
If any issues found:
1. Create `.planning/phases/XX-name/{phase}-{plan}-ISSUES.md` if doesn't exist
2. Use template from `@~/.claude/get-shit-done/templates/uat-issues.md`
3. Add each issue:
Create file:
```markdown
### UAT-[NNN]: [Brief description]
---
status: testing
phase: XX-name
source: [list of SUMMARY.md files]
started: [ISO timestamp]
updated: [ISO timestamp]
---
**Discovered:** [date] during user acceptance testing
**Phase/Plan:** [phase]-[plan] that was tested
**Severity:** [Blocker/Major/Minor/Cosmetic]
**Description:** [User's description of the problem]
**Expected:** [What should have happened]
**Actual:** [What actually happened]
## Current Test
<!-- OVERWRITE each test - shows where we are -->
number: 1
name: [first test name]
expected: |
[what user should observe]
awaiting: user response
## Tests
### 1. [Test Name]
expected: [observable behavior]
result: [pending]
### 2. [Test Name]
expected: [observable behavior]
result: [pending]
...
## Summary
total: [N]
passed: 0
issues: 0
pending: [N]
skipped: 0
## Issues for /gsd:plan-fix
[none yet]
```
**Note:** Issues go to phase-scoped file, NOT global `.planning/ISSUES.md`. This keeps UAT findings tied to the specific work being tested and enables `/gsd:plan-fix` to address them.
Write to `.planning/phases/XX-name/{phase}-UAT.md`
Proceed to `present_test`.
</step>
<step name="summarize">
**Present test summary:**
<step name="present_test">
**Present current test to user:**
Read Current Test section from UAT file.
Display:
```
# Test Results: [Plan/Phase Name]
## Test {number}: {name}
**Tests run:** [N]
**Passed:** [N]
**Failed:** [N]
**Partial:** [N]
**Skipped:** [N]
**Expected:** {expected}
## Issues Found
[List any issues with severity]
## Verdict
[Based on results:]
- ALL PASS: "All tests passed. Feature validated."
- MINOR ISSUES: "Feature works with minor issues logged."
- MAJOR ISSUES: "Significant issues found - review before proceeding."
- BLOCKERS: "Blocking issues found - must fix before continuing."
## Next Steps
[Based on verdict:]
- If clean: Suggest proceeding to next phase
- If issues: Suggest /gsd:plan-fix to address
Does this match what you see?
```
Wait for user response (plain text, no AskUserQuestion).
</step>
<step name="offer">
**Offer next actions based on results:**
<step name="process_response">
**Process user response and update file:**
Use AskUserQuestion:
- header: "Next"
- question: "What would you like to do?"
- options (based on results):
**If response indicates pass:**
- Empty response, "yes", "y", "ok", "pass", "next", "approved", "✓"
If all passed:
- "Continue to next phase" — Proceed with confidence
- "Test more" — Run additional manual tests
- "Done" — Finish testing session
Update Tests section:
```
### {N}. {name}
expected: {expected}
result: pass
```
If issues found:
- "Plan fixes" — Create plan to address issues (/gsd:plan-fix)
- "Log and continue" — Issues logged, proceed anyway
- "Review issues" — Look at logged issues in detail
- "Done" — Finish testing session
**If response indicates skip:**
- "skip", "can't test", "n/a"
Update Tests section:
```
### {N}. {name}
expected: {expected}
result: skipped
reason: [user's reason if provided]
```
**If response is anything else:**
- Treat as issue description
Infer severity from description:
- Contains: crash, error, exception, fails, broken, unusable → blocker
- Contains: doesn't work, wrong, missing, can't → major
- Contains: slow, weird, off, minor, small → minor
- Contains: color, font, spacing, alignment, visual → cosmetic
- Default if unclear: major
Update Tests section:
```
### {N}. {name}
expected: {expected}
result: issue
reported: "{verbatim user response}"
severity: {inferred}
```
Append to Issues section:
```
- UAT-{NNN}: {brief summary from response} ({severity}) - Test {N}
```
**After any response:**
Update Summary counts.
Update frontmatter.updated timestamp.
If more tests remain → Update Current Test, go to `present_test`
If no more tests → Go to `complete_session`
</step>
<step name="resume_from_file">
**Resume testing from UAT file:**
Read the full UAT file.
Find first test with `result: [pending]`.
Announce:
```
Resuming: Phase {phase} UAT
Progress: {passed + issues + skipped}/{total}
Issues found so far: {issues count}
Continuing from Test {N}...
```
Update Current Test section with the pending test.
Proceed to `present_test`.
</step>
<step name="complete_session">
**Complete testing and commit:**
Update frontmatter:
- status: complete
- updated: [now]
Clear Current Test section:
```
## Current Test
[testing complete]
```
Commit the UAT file:
```bash
git add ".planning/phases/XX-name/{phase}-UAT.md"
git commit -m "test({phase}): complete UAT - {passed} passed, {issues} issues"
```
Present summary:
```
## UAT Complete: Phase {phase}
| Result | Count |
|--------|-------|
| Passed | {N} |
| Issues | {N} |
| Skipped| {N} |
[If issues > 0:]
### Issues Found
[List from Issues section]
---
Next steps:
- `/gsd:plan-fix {phase}` — Create fix plan for issues
- `/gsd:verify-work {phase}` — Re-test after fixes
- Continue to next phase
[If issues == 0:]
All tests passed. Ready to continue.
- `/gsd:plan-phase {next}` — Plan next phase
- `/gsd:execute-phase {next}` — Execute next phase
```
</step>
</process>
<update_rules>
**Section update rules:**
| Section | Rule | When |
|---------|------|------|
| 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 |
**Update file AFTER processing each response.** If context resets, file shows exactly where to resume.
</update_rules>
<severity_inference>
**Infer severity from user's natural language:**
| User says | Infer |
|-----------|-------|
| "crashes", "error", "exception", "fails completely" | blocker |
| "doesn't work", "nothing happens", "wrong behavior" | major |
| "works but...", "slow", "weird", "minor issue" | minor |
| "color", "spacing", "alignment", "looks off" | cosmetic |
Default to **major** if unclear. User can correct if needed.
**Never ask "how severe is this?"** - just infer and move on.
</severity_inference>
<success_criteria>
- [ ] Test scope identified from SUMMARY.md
- [ ] Checklist generated based on deliverables
- [ ] User guided through each test via AskUserQuestion
- [ ] All test results captured (pass/fail/partial/skip)
- [ ] Any issues logged to phase-scoped ISSUES.md
- [ ] Summary presented with verdict
- [ ] User knows next steps based on results
- [ ] UAT file created with all tests from SUMMARY.md
- [ ] 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
- [ ] Committed on completion
- [ ] Clear next steps based on results
</success_criteria>