feat: add phase verification system

- verify-phase.md workflow: validates phase goal achievement vs task completion
- subagent-verify-prompt.md: template for spawning verification agents
- verification-report.md: VERIFICATION.md output template
- verification-patterns.md: common anti-patterns and verification strategies

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Lex Christopherson
2026-01-15 09:34:38 -06:00
parent e95186b2a7
commit 6d7246dcf5
4 changed files with 1762 additions and 0 deletions

View File

@@ -0,0 +1,595 @@
# Verification Patterns
How to verify different types of artifacts are real implementations, not stubs or placeholders.
<core_principle>
**Existence ≠ Implementation**
A file existing does not mean the feature works. Verification must check:
1. **Exists** - File is present at expected path
2. **Substantive** - Content is real implementation, not placeholder
3. **Wired** - Connected to the rest of the system
4. **Functional** - Actually works when invoked
Levels 1-3 can be checked programmatically. Level 4 often requires human verification.
</core_principle>
<stub_detection>
## Universal Stub Patterns
These patterns indicate placeholder code regardless of file type:
**Comment-based stubs:**
```bash
# Grep patterns for stub comments
grep -E "(TODO|FIXME|XXX|HACK|PLACEHOLDER)" "$file"
grep -E "implement|add later|coming soon|will be" "$file" -i
grep -E "// \.\.\.|/\* \.\.\. \*/|# \.\.\." "$file"
```
**Placeholder text in output:**
```bash
# UI placeholder patterns
grep -E "placeholder|lorem ipsum|coming soon|under construction" "$file" -i
grep -E "sample|example|test data|dummy" "$file" -i
grep -E "\[.*\]|<.*>|\{.*\}" "$file" # Template brackets left in
```
**Empty or trivial implementations:**
```bash
# Functions that do nothing
grep -E "return null|return undefined|return \{\}|return \[\]" "$file"
grep -E "pass$|\.\.\.|\bnothing\b" "$file"
grep -E "console\.(log|warn|error).*only" "$file" # Log-only functions
```
**Hardcoded values where dynamic expected:**
```bash
# Hardcoded IDs, counts, or content
grep -E "id.*=.*['\"].*['\"]" "$file" # Hardcoded string IDs
grep -E "count.*=.*\d+|length.*=.*\d+" "$file" # Hardcoded counts
grep -E "\\\$\d+\.\d{2}|\d+ items" "$file" # Hardcoded display values
```
</stub_detection>
<react_components>
## React/Next.js Components
**Existence check:**
```bash
# File exists and exports component
[ -f "$component_path" ] && grep -E "export (default |)function|export const.*=.*\(" "$component_path"
```
**Substantive check:**
```bash
# Returns actual JSX, not placeholder
grep -E "return.*<" "$component_path" | grep -v "return.*null" | grep -v "placeholder" -i
# Has meaningful content (not just wrapper div)
grep -E "<[A-Z][a-zA-Z]+|className=|onClick=|onChange=" "$component_path"
# Uses props or state (not static)
grep -E "props\.|useState|useEffect|useContext|\{.*\}" "$component_path"
```
**Stub patterns specific to React:**
```javascript
// RED FLAGS - These are stubs:
return <div>Component</div>
return <div>Placeholder</div>
return <div>{/* TODO */}</div>
return <p>Coming soon</p>
return null
return <></>
// Also stubs - empty handlers:
onClick={() => {}}
onChange={() => console.log('clicked')}
onSubmit={(e) => e.preventDefault()} // Only prevents default, does nothing
```
**Wiring check:**
```bash
# Component imports what it needs
grep -E "^import.*from" "$component_path"
# Props are actually used (not just received)
# Look for destructuring or props.X usage
grep -E "\{ .* \}.*props|\bprops\.[a-zA-Z]+" "$component_path"
# API calls exist (for data-fetching components)
grep -E "fetch\(|axios\.|useSWR|useQuery|getServerSideProps|getStaticProps" "$component_path"
```
**Functional verification (human required):**
- Does the component render visible content?
- Do interactive elements respond to clicks?
- Does data load and display?
- Do error states show appropriately?
</react_components>
<api_routes>
## API Routes (Next.js App Router / Express / etc.)
**Existence check:**
```bash
# Route file exists
[ -f "$route_path" ]
# Exports HTTP method handlers (Next.js App Router)
grep -E "export (async )?(function|const) (GET|POST|PUT|PATCH|DELETE)" "$route_path"
# Or Express-style handlers
grep -E "\.(get|post|put|patch|delete)\(" "$route_path"
```
**Substantive check:**
```bash
# Has actual logic, not just return statement
wc -l "$route_path" # More than 10-15 lines suggests real implementation
# Interacts with data source
grep -E "prisma\.|db\.|mongoose\.|sql|query|find|create|update|delete" "$route_path" -i
# Has error handling
grep -E "try|catch|throw|error|Error" "$route_path"
# Returns meaningful response
grep -E "Response\.json|res\.json|res\.send|return.*\{" "$route_path" | grep -v "message.*not implemented" -i
```
**Stub patterns specific to API routes:**
```typescript
// RED FLAGS - These are stubs:
export async function POST() {
return Response.json({ message: "Not implemented" })
}
export async function GET() {
return Response.json([]) // Empty array with no DB query
}
export async function PUT() {
return new Response() // Empty response
}
// Console log only:
export async function POST(req) {
console.log(await req.json())
return Response.json({ ok: true })
}
```
**Wiring check:**
```bash
# Imports database/service clients
grep -E "^import.*prisma|^import.*db|^import.*client" "$route_path"
# Actually uses request body (for POST/PUT)
grep -E "req\.json\(\)|req\.body|request\.json\(\)" "$route_path"
# Validates input (not just trusting request)
grep -E "schema\.parse|validate|zod|yup|joi" "$route_path"
```
**Functional verification (human or automated):**
- Does GET return real data from database?
- Does POST actually create a record?
- Does error response have correct status code?
- Are auth checks actually enforced?
</api_routes>
<database_schema>
## Database Schema (Prisma / Drizzle / SQL)
**Existence check:**
```bash
# Schema file exists
[ -f "prisma/schema.prisma" ] || [ -f "drizzle/schema.ts" ] || [ -f "src/db/schema.sql" ]
# Model/table is defined
grep -E "^model $model_name|CREATE TABLE $table_name|export const $table_name" "$schema_path"
```
**Substantive check:**
```bash
# Has expected fields (not just id)
grep -A 20 "model $model_name" "$schema_path" | grep -E "^\s+\w+\s+\w+"
# Has relationships if expected
grep -E "@relation|REFERENCES|FOREIGN KEY" "$schema_path"
# Has appropriate field types (not all String)
grep -A 20 "model $model_name" "$schema_path" | grep -E "Int|DateTime|Boolean|Float|Decimal|Json"
```
**Stub patterns specific to schemas:**
```prisma
// RED FLAGS - These are stubs:
model User {
id String @id
// TODO: add fields
}
model Message {
id String @id
content String // Only one real field
}
// Missing critical fields:
model Order {
id String @id
// No: userId, items, total, status, createdAt
}
```
**Wiring check:**
```bash
# Migrations exist and are applied
ls prisma/migrations/ 2>/dev/null | wc -l # Should be > 0
npx prisma migrate status 2>/dev/null | grep -v "pending"
# Client is generated
[ -d "node_modules/.prisma/client" ]
```
**Functional verification:**
```bash
# Can query the table (automated)
npx prisma db execute --stdin <<< "SELECT COUNT(*) FROM $table_name"
```
</database_schema>
<hooks_utilities>
## Custom Hooks and Utilities
**Existence check:**
```bash
# File exists and exports function
[ -f "$hook_path" ] && grep -E "export (default )?(function|const)" "$hook_path"
```
**Substantive check:**
```bash
# Hook uses React hooks (for custom hooks)
grep -E "useState|useEffect|useCallback|useMemo|useRef|useContext" "$hook_path"
# Has meaningful return value
grep -E "return \{|return \[" "$hook_path"
# More than trivial length
[ $(wc -l < "$hook_path") -gt 10 ]
```
**Stub patterns specific to hooks:**
```typescript
// RED FLAGS - These are stubs:
export function useAuth() {
return { user: null, login: () => {}, logout: () => {} }
}
export function useCart() {
const [items, setItems] = useState([])
return { items, addItem: () => console.log('add'), removeItem: () => {} }
}
// Hardcoded return:
export function useUser() {
return { name: "Test User", email: "test@example.com" }
}
```
**Wiring check:**
```bash
# Hook is actually imported somewhere
grep -r "import.*$hook_name" src/ --include="*.tsx" --include="*.ts" | grep -v "$hook_path"
# Hook is actually called
grep -r "$hook_name()" src/ --include="*.tsx" --include="*.ts" | grep -v "$hook_path"
```
</hooks_utilities>
<environment_config>
## Environment Variables and Configuration
**Existence check:**
```bash
# .env file exists
[ -f ".env" ] || [ -f ".env.local" ]
# Required variable is defined
grep -E "^$VAR_NAME=" .env .env.local 2>/dev/null
```
**Substantive check:**
```bash
# Variable has actual value (not placeholder)
grep -E "^$VAR_NAME=.+" .env .env.local 2>/dev/null | grep -v "your-.*-here|xxx|placeholder|TODO" -i
# Value looks valid for type:
# - URLs should start with http
# - Keys should be long enough
# - Booleans should be true/false
```
**Stub patterns specific to env:**
```bash
# RED FLAGS - These are stubs:
DATABASE_URL=your-database-url-here
STRIPE_SECRET_KEY=sk_test_xxx
API_KEY=placeholder
NEXT_PUBLIC_API_URL=http://localhost:3000 # Still pointing to localhost in prod
```
**Wiring check:**
```bash
# Variable is actually used in code
grep -r "process\.env\.$VAR_NAME|env\.$VAR_NAME" src/ --include="*.ts" --include="*.tsx"
# Variable is in validation schema (if using zod/etc for env)
grep -E "$VAR_NAME" src/env.ts src/env.mjs 2>/dev/null
```
</environment_config>
<wiring_verification>
## Wiring Verification Patterns
Wiring verification checks that components actually communicate. This is where most stubs hide.
### Pattern: Component → API
**Check:** Does the component actually call the API?
```bash
# Find the fetch/axios call
grep -E "fetch\(['\"].*$api_path|axios\.(get|post).*$api_path" "$component_path"
# Verify it's not commented out
grep -E "fetch\(|axios\." "$component_path" | grep -v "^.*//.*fetch"
# Check the response is used
grep -E "await.*fetch|\.then\(|setData|setState" "$component_path"
```
**Red flags:**
```typescript
// Fetch exists but response ignored:
fetch('/api/messages') // No await, no .then, no assignment
// Fetch in comment:
// fetch('/api/messages').then(r => r.json()).then(setMessages)
// Fetch to wrong endpoint:
fetch('/api/message') // Typo - should be /api/messages
```
### Pattern: API → Database
**Check:** Does the API route actually query the database?
```bash
# Find the database call
grep -E "prisma\.$model|db\.query|Model\.find" "$route_path"
# Verify it's awaited
grep -E "await.*prisma|await.*db\." "$route_path"
# Check result is returned
grep -E "return.*json.*data|res\.json.*result" "$route_path"
```
**Red flags:**
```typescript
// Query exists but result not returned:
await prisma.message.findMany()
return Response.json({ ok: true }) // Returns static, not query result
// Query not awaited:
const messages = prisma.message.findMany() // Missing await
return Response.json(messages) // Returns Promise, not data
```
### Pattern: Form → Handler
**Check:** Does the form submission actually do something?
```bash
# Find onSubmit handler
grep -E "onSubmit=\{|handleSubmit" "$component_path"
# Check handler has content
grep -A 10 "onSubmit.*=" "$component_path" | grep -E "fetch|axios|mutate|dispatch"
# Verify not just preventDefault
grep -A 5 "onSubmit" "$component_path" | grep -v "only.*preventDefault" -i
```
**Red flags:**
```typescript
// Handler only prevents default:
onSubmit={(e) => e.preventDefault()}
// Handler only logs:
const handleSubmit = (data) => {
console.log(data)
}
// Handler is empty:
onSubmit={() => {}}
```
### Pattern: State → Render
**Check:** Does the component render state, not hardcoded content?
```bash
# Find state usage in JSX
grep -E "\{.*messages.*\}|\{.*data.*\}|\{.*items.*\}" "$component_path"
# Check map/render of state
grep -E "\.map\(|\.filter\(|\.reduce\(" "$component_path"
# Verify dynamic content
grep -E "\{[a-zA-Z_]+\." "$component_path" # Variable interpolation
```
**Red flags:**
```tsx
// Hardcoded instead of state:
return <div>
<p>Message 1</p>
<p>Message 2</p>
</div>
// State exists but not rendered:
const [messages, setMessages] = useState([])
return <div>No messages</div> // Always shows "no messages"
// Wrong state rendered:
const [messages, setMessages] = useState([])
return <div>{otherData.map(...)}</div> // Uses different data
```
</wiring_verification>
<verification_checklist>
## Quick Verification Checklist
For each artifact type, run through this checklist:
### Component Checklist
- [ ] File exists at expected path
- [ ] Exports a function/const component
- [ ] Returns JSX (not null/empty)
- [ ] No placeholder text in render
- [ ] Uses props or state (not static)
- [ ] Event handlers have real implementations
- [ ] Imports resolve correctly
- [ ] Used somewhere in the app
### API Route Checklist
- [ ] File exists at expected path
- [ ] Exports HTTP method handlers
- [ ] Handlers have more than 5 lines
- [ ] Queries database or service
- [ ] Returns meaningful response (not empty/placeholder)
- [ ] Has error handling
- [ ] Validates input
- [ ] Called from frontend
### Schema Checklist
- [ ] Model/table defined
- [ ] Has all expected fields
- [ ] Fields have appropriate types
- [ ] Relationships defined if needed
- [ ] Migrations exist and applied
- [ ] Client generated
### Hook/Utility Checklist
- [ ] File exists at expected path
- [ ] Exports function
- [ ] Has meaningful implementation (not empty returns)
- [ ] Used somewhere in the app
- [ ] Return values consumed
### Wiring Checklist
- [ ] Component → API: fetch/axios call exists and uses response
- [ ] API → Database: query exists and result returned
- [ ] Form → Handler: onSubmit calls API/mutation
- [ ] State → Render: state variables appear in JSX
</verification_checklist>
<automated_verification_script>
## Automated Verification Approach
For the verification subagent, use this pattern:
```bash
# 1. Check existence
check_exists() {
[ -f "$1" ] && echo "EXISTS: $1" || echo "MISSING: $1"
}
# 2. Check for stub patterns
check_stubs() {
local file="$1"
local stubs=$(grep -c -E "TODO|FIXME|placeholder|not implemented" "$file" 2>/dev/null || echo 0)
[ "$stubs" -gt 0 ] && echo "STUB_PATTERNS: $stubs in $file"
}
# 3. Check wiring (component calls API)
check_wiring() {
local component="$1"
local api_path="$2"
grep -q "$api_path" "$component" && echo "WIRED: $component → $api_path" || echo "NOT_WIRED: $component → $api_path"
}
# 4. Check substantive (more than N lines, has expected patterns)
check_substantive() {
local file="$1"
local min_lines="$2"
local pattern="$3"
local lines=$(wc -l < "$file" 2>/dev/null || echo 0)
local has_pattern=$(grep -c -E "$pattern" "$file" 2>/dev/null || echo 0)
[ "$lines" -ge "$min_lines" ] && [ "$has_pattern" -gt 0 ] && echo "SUBSTANTIVE: $file" || echo "THIN: $file ($lines lines, $has_pattern matches)"
}
```
Run these checks against each must-have artifact. Aggregate results into VERIFICATION.md.
</automated_verification_script>
<human_verification_triggers>
## When to Require Human Verification
Some things can't be verified programmatically. Flag these for human testing:
**Always human:**
- Visual appearance (does it look right?)
- User flow completion (can you actually do the thing?)
- Real-time behavior (WebSocket, SSE)
- External service integration (Stripe, email sending)
- Error message clarity (is the message helpful?)
- Performance feel (does it feel fast?)
**Human if uncertain:**
- Complex wiring that grep can't trace
- Dynamic behavior depending on state
- Edge cases and error states
- Mobile responsiveness
- Accessibility
**Format for human verification request:**
```markdown
## Human Verification Required
### 1. Chat message sending
**Test:** Type a message and click Send
**Expected:** Message appears in list, input clears
**Check:** Does message persist after refresh?
### 2. Error handling
**Test:** Disconnect network, try to send
**Expected:** Error message appears, message not lost
**Check:** Can retry after reconnect?
```
</human_verification_triggers>

View File

@@ -0,0 +1,216 @@
# Subagent Verify Prompt Template
Template for spawning a verification subagent from execute-phase.md.
---
## Template
```markdown
<objective>
Verify Phase {phase_number} achieved its GOAL, not just completed its TASKS.
Your job: Goal-backward verification. Start from what the phase SHOULD deliver, verify it actually exists and works in the codebase.
**Critical mindset:** Do NOT trust SUMMARY.md claims. SUMMARYs document what Claude SAID it did. You verify what ACTUALLY exists in the code. These often differ.
</objective>
<execution_context>
@~/.claude/get-shit-done/workflows/verify-phase.md
@~/.claude/get-shit-done/templates/verification-report.md
@~/.claude/get-shit-done/references/verification-patterns.md
@~/.claude/get-shit-done/references/goal-backward.md
</execution_context>
<context>
**Phase being verified:**
- Phase: {phase_number} - {phase_name}
- Phase goal: {phase_goal_from_roadmap}
- Phase directory: .planning/phases/{phase_dir}/
**Must-haves to verify:**
{must_haves_yaml_from_plan_frontmatter}
**If must_haves not in frontmatter, derive from:**
- Phase goal (above)
- @.planning/ROADMAP.md (phase description)
- @.planning/REQUIREMENTS.md (requirements mapped to this phase)
**Context for verification:**
@.planning/PROJECT.md
@.planning/ROADMAP.md
@.planning/REQUIREMENTS.md (if exists)
@.planning/phases/{phase_dir}/*-SUMMARY.md (claims to verify against)
</context>
<verification_approach>
## Step 1: Establish Must-Haves
**If must_haves provided in context above:** Use them directly.
**If must_haves NOT provided:** Derive using goal-backward process:
1. State the phase goal
2. Ask: "What must be TRUE for this goal to be achieved?" (3-7 observable truths)
3. For each truth: "What must EXIST?" (concrete artifacts)
4. For each artifact: "What must be WIRED?" (connections between artifacts)
5. Identify key links (critical connections most likely to be stubs)
Document your derived must-haves before proceeding.
## Step 2: Verify Observable Truths
For each truth, determine if it's achievable given the codebase state.
A truth is:
- ✓ VERIFIED: Codebase makes this truth achievable
- ✗ FAILED: Codebase prevents this truth (missing/stub code)
- ? UNCERTAIN: Can't verify programmatically (needs human)
## Step 3: Verify Required Artifacts
For each artifact, check three levels:
**Level 1 - Exists:**
```bash
[ -f "{artifact_path}" ] && echo "EXISTS" || echo "MISSING"
```
**Level 2 - Substantive:**
- Is it more than a stub? (check line count, grep for stub patterns)
- Does it have expected exports/structure?
- Are there TODO/placeholder comments?
Use patterns from verification-patterns.md.
**Level 3 - Wired:**
- Is it imported somewhere?
- Is it called/used?
- Does data flow through it?
## Step 4: Verify Key Links
Key links are the critical connections. For each:
```bash
# Check if A calls B
grep -E "{pattern_for_call}" "{file_A}"
# Check if the call uses the response
grep -A 5 "{call_pattern}" "{file_A}" | grep -E "await|then|set"
```
Key links are where stubs hide. A component might exist and an API might exist, but the component doesn't actually call the API.
## Step 5: Check Requirements Coverage
If REQUIREMENTS.md exists and has requirements mapped to this phase:
- For each requirement, determine if the codebase satisfies it
- A requirement is BLOCKED if any supporting artifact is missing/stub
## Step 6: Scan for Anti-Patterns
Run stub detection across all phase-related files:
```bash
# Find all files modified in this phase (from SUMMARYs)
# Then scan for anti-patterns
grep -r -E "TODO|FIXME|placeholder|not implemented" {phase_files} -i
grep -r -E "return null|return \{\}|return \[\]" {phase_files}
grep -r -E "console\.log\(.*\)" {phase_files} | grep -v "error\|warn"
```
## Step 7: Generate Report
Create `.planning/phases/{phase_dir}/{phase}-VERIFICATION.md` using the verification-report.md template.
Include:
- All truths with status and evidence
- All artifacts with status and details
- All key links with status and details
- Requirements coverage
- Anti-patterns found
- Human verification needs
- Gap summary with fix recommendations
</verification_approach>
<critical_rules>
**DO NOT trust SUMMARY claims.** SUMMARYs say "implemented chat component" — you verify the component actually renders messages, not a placeholder.
**DO NOT assume existence = implementation.** A file existing is level 1. You need level 2 (substantive) and level 3 (wired) verification.
**DO NOT skip key link verification.** This is where 80% of stubs hide. The pieces exist but aren't connected.
**DO generate fix plans if gaps found.** Don't just report "this is broken" — recommend specific fix plans with tasks.
**DO flag for human verification when uncertain.** If you can't verify programmatically (visual, real-time, external service), say so explicitly.
**DO keep verification fast.** Use grep/file checks, not running the app. Goal is structural verification, not functional testing.
</critical_rules>
<output>
Create: `.planning/phases/{phase_dir}/{phase}-VERIFICATION.md`
Use the verification-report.md template structure.
Return to orchestrator with:
- Status: passed | gaps_found | human_needed
- Score: N/M must-haves verified
- If gaps_found: Summary of gaps and recommended fix plans
- If human_needed: List of items requiring human verification
</output>
<success_criteria>
- [ ] Must-haves established (from frontmatter or derived)
- [ ] All truths verified with evidence
- [ ] All artifacts checked (exists + substantive + wired)
- [ ] All key links traced
- [ ] Requirements coverage assessed
- [ ] Anti-patterns scanned
- [ ] VERIFICATION.md created with full report
- [ ] Fix plans recommended if gaps found
- [ ] Human verification items listed if uncertain
</success_criteria>
```
---
## Usage
The execute-phase orchestrator fills this template and spawns a subagent:
```typescript
Task(
prompt: filled_template,
subagent_type: "general-purpose",
description: "Verify phase {X} goal achievement"
)
```
The subagent:
1. Loads the verification workflow and references
2. Establishes must-haves (from frontmatter or derived)
3. Runs verification checks against codebase
4. Creates VERIFICATION.md report
5. Returns status to orchestrator
The orchestrator then:
- If `passed`: Proceeds to update_roadmap
- If `gaps_found`: Creates fix plans, executes them, re-verifies
- If `human_needed`: Presents human verification items to user
---
## Template Variables
| Variable | Source | Example |
|----------|--------|---------|
| `{phase_number}` | From execute-phase | `03` |
| `{phase_name}` | From ROADMAP.md | `chat-interface` |
| `{phase_goal_from_roadmap}` | From ROADMAP.md phase description | `Working chat interface where users can send and receive messages` |
| `{phase_dir}` | From filesystem | `03-chat-interface` |
| `{must_haves_yaml_from_plan_frontmatter}` | From PLAN.md frontmatter | YAML block with truths, artifacts, key_links |

View File

@@ -0,0 +1,322 @@
# Verification Report Template
Template for `.planning/phases/XX-name/{phase}-VERIFICATION.md` — phase goal verification results.
---
## File Template
```markdown
---
phase: XX-name
verified: YYYY-MM-DDTHH:MM:SSZ
status: passed | gaps_found | human_needed
score: N/M must-haves verified
---
# Phase {X}: {Name} Verification Report
**Phase Goal:** {goal from ROADMAP.md}
**Verified:** {timestamp}
**Status:** {passed | gaps_found | human_needed}
## Goal Achievement
### Observable Truths
| # | Truth | Status | Evidence |
|---|-------|--------|----------|
| 1 | {truth from must_haves} | ✓ VERIFIED | {what confirmed it} |
| 2 | {truth from must_haves} | ✗ FAILED | {what's wrong} |
| 3 | {truth from must_haves} | ? UNCERTAIN | {why can't verify} |
**Score:** {N}/{M} truths verified
### Required Artifacts
| Artifact | Expected | Status | Details |
|----------|----------|--------|---------|
| `src/components/Chat.tsx` | Message list component | ✓ EXISTS + SUBSTANTIVE | Exports ChatList, renders Message[], no stubs |
| `src/app/api/chat/route.ts` | Message CRUD | ✗ STUB | File exists but POST returns placeholder |
| `prisma/schema.prisma` | Message model | ✓ EXISTS + SUBSTANTIVE | Model defined with all fields |
**Artifacts:** {N}/{M} verified
### Key Link Verification
| From | To | Via | Status | Details |
|------|----|----|--------|---------|
| Chat.tsx | /api/chat | fetch in useEffect | ✓ WIRED | Line 23: `fetch('/api/chat')` with response handling |
| ChatInput | /api/chat POST | onSubmit handler | ✗ NOT WIRED | onSubmit only calls console.log |
| /api/chat POST | database | prisma.message.create | ✗ NOT WIRED | Returns hardcoded response, no DB call |
**Wiring:** {N}/{M} connections verified
## Requirements Coverage
| Requirement | Status | Blocking Issue |
|-------------|--------|----------------|
| {REQ-01}: {description} | ✓ SATISFIED | - |
| {REQ-02}: {description} | ✗ BLOCKED | API route is stub |
| {REQ-03}: {description} | ? NEEDS HUMAN | Can't verify WebSocket programmatically |
**Coverage:** {N}/{M} requirements satisfied
## Anti-Patterns Found
| File | Line | Pattern | Severity | Impact |
|------|------|---------|----------|--------|
| src/app/api/chat/route.ts | 12 | `// TODO: implement` | ⚠️ Warning | Indicates incomplete |
| src/components/Chat.tsx | 45 | `return <div>Placeholder</div>` | 🛑 Blocker | Renders no content |
| src/hooks/useChat.ts | - | File missing | 🛑 Blocker | Expected hook doesn't exist |
**Anti-patterns:** {N} found ({blockers} blockers, {warnings} warnings)
## Human Verification Required
{If no human verification needed:}
None — all verifiable items checked programmatically.
{If human verification needed:}
### 1. {Test Name}
**Test:** {What to do}
**Expected:** {What should happen}
**Why human:** {Why can't verify programmatically}
### 2. {Test Name}
**Test:** {What to do}
**Expected:** {What should happen}
**Why human:** {Why can't verify programmatically}
## Gaps Summary
{If no gaps:}
**No gaps found.** Phase goal achieved. Ready to proceed.
{If gaps found:}
### Critical Gaps (Block Progress)
1. **{Gap name}**
- Missing: {what's missing}
- Impact: {why this blocks the goal}
- Fix: {what needs to happen}
2. **{Gap name}**
- Missing: {what's missing}
- Impact: {why this blocks the goal}
- Fix: {what needs to happen}
### Non-Critical Gaps (Can Defer)
1. **{Gap name}**
- Issue: {what's wrong}
- Impact: {limited impact because...}
- Recommendation: {fix now or defer}
## Recommended Fix Plans
{If gaps found, generate fix plan recommendations:}
### {phase}-{next}-PLAN.md: {Fix Name}
**Objective:** {What this fixes}
**Tasks:**
1. {Task to fix gap 1}
2. {Task to fix gap 2}
3. {Verification task}
**Estimated scope:** {Small / Medium}
---
### {phase}-{next+1}-PLAN.md: {Fix Name}
**Objective:** {What this fixes}
**Tasks:**
1. {Task}
2. {Task}
**Estimated scope:** {Small / Medium}
---
## Verification Metadata
**Verification approach:** Goal-backward (derived from phase goal)
**Must-haves source:** {PLAN.md frontmatter | derived from ROADMAP.md goal}
**Automated checks:** {N} passed, {M} failed
**Human checks required:** {N}
**Total verification time:** {duration}
---
*Verified: {timestamp}*
*Verifier: Claude (subagent)*
```
---
## Guidelines
**Status values:**
- `passed` — All must-haves verified, no blockers
- `gaps_found` — One or more critical gaps found
- `human_needed` — Automated checks pass but human verification required
**Evidence types:**
- For EXISTS: "File at path, exports X"
- For SUBSTANTIVE: "N lines, has patterns X, Y, Z"
- For WIRED: "Line N: code that connects A to B"
- For FAILED: "Missing because X" or "Stub because Y"
**Severity levels:**
- 🛑 Blocker: Prevents goal achievement, must fix
- ⚠️ Warning: Indicates incomplete but doesn't block
- ℹ️ Info: Notable but not problematic
**Fix plan generation:**
- Only generate if gaps_found
- Group related fixes into single plans
- Keep to 2-3 tasks per plan
- Include verification task in each plan
---
## Example
```markdown
---
phase: 03-chat
verified: 2025-01-15T14:30:00Z
status: gaps_found
score: 2/5 must-haves verified
---
# Phase 3: Chat Interface Verification Report
**Phase Goal:** Working chat interface where users can send and receive messages
**Verified:** 2025-01-15T14:30:00Z
**Status:** gaps_found
## Goal Achievement
### Observable Truths
| # | Truth | Status | Evidence |
|---|-------|--------|----------|
| 1 | User can see existing messages | ✗ FAILED | Component renders placeholder, not message data |
| 2 | User can type a message | ✓ VERIFIED | Input field exists with onChange handler |
| 3 | User can send a message | ✗ FAILED | onSubmit handler is console.log only |
| 4 | Sent message appears in list | ✗ FAILED | No state update after send |
| 5 | Messages persist across refresh | ? UNCERTAIN | Can't verify - send doesn't work |
**Score:** 1/5 truths verified
### Required Artifacts
| Artifact | Expected | Status | Details |
|----------|----------|--------|---------|
| `src/components/Chat.tsx` | Message list component | ✗ STUB | Returns `<div>Chat will be here</div>` |
| `src/components/ChatInput.tsx` | Message input | ✓ EXISTS + SUBSTANTIVE | Form with input, submit button, handlers |
| `src/app/api/chat/route.ts` | Message CRUD | ✗ STUB | GET returns [], POST returns { ok: true } |
| `prisma/schema.prisma` | Message model | ✓ EXISTS + SUBSTANTIVE | Message model with id, content, userId, createdAt |
**Artifacts:** 2/4 verified
### Key Link Verification
| From | To | Via | Status | Details |
|------|----|----|--------|---------|
| Chat.tsx | /api/chat GET | fetch | ✗ NOT WIRED | No fetch call in component |
| ChatInput | /api/chat POST | onSubmit | ✗ NOT WIRED | Handler only logs, doesn't fetch |
| /api/chat GET | database | prisma.message.findMany | ✗ NOT WIRED | Returns hardcoded [] |
| /api/chat POST | database | prisma.message.create | ✗ NOT WIRED | Returns { ok: true }, no DB call |
**Wiring:** 0/4 connections verified
## Requirements Coverage
| Requirement | Status | Blocking Issue |
|-------------|--------|----------------|
| CHAT-01: User can send message | ✗ BLOCKED | API POST is stub |
| CHAT-02: User can view messages | ✗ BLOCKED | Component is placeholder |
| CHAT-03: Messages persist | ✗ BLOCKED | No database integration |
**Coverage:** 0/3 requirements satisfied
## Anti-Patterns Found
| File | Line | Pattern | Severity | Impact |
|------|------|---------|----------|--------|
| src/components/Chat.tsx | 8 | `<div>Chat will be here</div>` | 🛑 Blocker | No actual content |
| src/app/api/chat/route.ts | 5 | `return Response.json([])` | 🛑 Blocker | Hardcoded empty |
| src/app/api/chat/route.ts | 12 | `// TODO: save to database` | ⚠️ Warning | Incomplete |
**Anti-patterns:** 3 found (2 blockers, 1 warning)
## Human Verification Required
None needed until automated gaps are fixed.
## Gaps Summary
### Critical Gaps (Block Progress)
1. **Chat component is placeholder**
- Missing: Actual message list rendering
- Impact: Users see "Chat will be here" instead of messages
- Fix: Implement Chat.tsx to fetch and render messages
2. **API routes are stubs**
- Missing: Database integration in GET and POST
- Impact: No data persistence, no real functionality
- Fix: Wire prisma calls in route handlers
3. **No wiring between frontend and backend**
- Missing: fetch calls in components
- Impact: Even if API worked, UI wouldn't call it
- Fix: Add useEffect fetch in Chat, onSubmit fetch in ChatInput
## Recommended Fix Plans
### 03-04-PLAN.md: Implement Chat API
**Objective:** Wire API routes to database
**Tasks:**
1. Implement GET /api/chat with prisma.message.findMany
2. Implement POST /api/chat with prisma.message.create
3. Verify: API returns real data, POST creates records
**Estimated scope:** Small
---
### 03-05-PLAN.md: Implement Chat UI
**Objective:** Wire Chat component to API
**Tasks:**
1. Implement Chat.tsx with useEffect fetch and message rendering
2. Wire ChatInput onSubmit to POST /api/chat
3. Verify: Messages display, new messages appear after send
**Estimated scope:** Small
---
## Verification Metadata
**Verification approach:** Goal-backward (derived from phase goal)
**Must-haves source:** 03-01-PLAN.md frontmatter
**Automated checks:** 2 passed, 8 failed
**Human checks required:** 0 (blocked by automated failures)
**Total verification time:** 2 min
---
*Verified: 2025-01-15T14:30:00Z*
*Verifier: Claude (subagent)*
```

View File

@@ -0,0 +1,629 @@
<purpose>
Verify phase goal achievement through goal-backward analysis. Check that the codebase actually delivers what the phase promised, not just that tasks were completed.
This workflow is executed by a verification subagent spawned from execute-phase.md.
</purpose>
<core_principle>
**Task completion ≠ Goal achievement**
A task "create chat component" can be marked complete when the component is a placeholder. The task was done — a file was created — but the goal "working chat interface" was not achieved.
Goal-backward verification starts from the outcome and works backwards:
1. What must be TRUE for the goal to be achieved?
2. What must EXIST for those truths to hold?
3. What must be WIRED for those artifacts to function?
Then verify each level against the actual codebase.
</core_principle>
<required_reading>
**Load these references:**
- ~/.claude/get-shit-done/references/goal-backward.md (derivation process)
- ~/.claude/get-shit-done/references/verification-patterns.md (detection patterns)
- ~/.claude/get-shit-done/templates/verification-report.md (output format)
</required_reading>
<process>
<step name="load_context" priority="first">
**Gather all verification context:**
```bash
# Phase directory
PHASE_DIR=$(ls -d .planning/phases/${PHASE_ARG}* 2>/dev/null | head -1)
# Phase goal from ROADMAP
grep -A 5 "Phase ${PHASE_NUM}" .planning/ROADMAP.md
# Requirements mapped to this phase
grep -E "^| ${PHASE_NUM}" .planning/REQUIREMENTS.md 2>/dev/null
# All SUMMARY files (claims to verify)
ls "$PHASE_DIR"/*-SUMMARY.md 2>/dev/null
# All PLAN files (for must_haves in frontmatter)
ls "$PHASE_DIR"/*-PLAN.md 2>/dev/null
```
**Extract phase goal:** Parse ROADMAP.md for this phase's goal/description. This is the outcome to verify, not the tasks.
**Extract requirements:** If REQUIREMENTS.md exists, find requirements mapped to this phase. These become additional verification targets.
</step>
<step name="establish_must_haves">
**Determine what must be verified.**
**Option A: Must-haves in PLAN frontmatter**
Check if any PLAN.md has `must_haves` in frontmatter:
```bash
grep -l "must_haves:" "$PHASE_DIR"/*-PLAN.md 2>/dev/null
```
If found, extract and use:
```yaml
must_haves:
truths:
- "User can see existing messages"
- "User can send a message"
artifacts:
- path: "src/components/Chat.tsx"
provides: "Message list rendering"
key_links:
- from: "Chat.tsx"
to: "api/chat"
via: "fetch in useEffect"
```
**Option B: Derive from phase goal**
If no must_haves in frontmatter, derive using goal-backward process:
1. **State the goal:** Take phase goal from ROADMAP.md
2. **Derive truths:** Ask "What must be TRUE for this goal to be achieved?"
- List 3-7 observable behaviors from user perspective
- Each truth should be testable by a human using the app
3. **Derive artifacts:** For each truth, ask "What must EXIST?"
- Map truths to concrete files (components, routes, schemas)
- Be specific: `src/components/Chat.tsx`, not "chat component"
4. **Derive key links:** For each artifact, ask "What must be CONNECTED?"
- Identify critical wiring (component calls API, API queries DB)
- These are where stubs hide
5. **Document derived must-haves** before proceeding to verification.
See ~/.claude/get-shit-done/references/goal-backward.md for detailed derivation guidance.
</step>
<step name="verify_truths">
**For each observable truth, determine if codebase enables it.**
A truth is achievable if the supporting artifacts exist, are substantive, and are wired correctly.
**Verification status:**
- ✓ VERIFIED: All supporting artifacts pass all checks
- ✗ FAILED: One or more supporting artifacts missing, stub, or unwired
- ? UNCERTAIN: Can't verify programmatically (needs human)
**For each truth:**
1. Identify supporting artifacts (which files make this truth possible?)
2. Check artifact status (see verify_artifacts step)
3. Check wiring status (see verify_wiring step)
4. Determine truth status based on supporting infrastructure
**Example:**
Truth: "User can see existing messages"
Supporting artifacts:
- Chat.tsx (renders messages)
- /api/chat GET (provides messages)
- Message model (defines schema)
If Chat.tsx is a stub → Truth FAILED
If /api/chat GET returns hardcoded [] → Truth FAILED
If Chat.tsx exists, is substantive, calls API, renders response → Truth VERIFIED
</step>
<step name="verify_artifacts">
**For each required artifact, verify three levels:**
### Level 1: Existence
```bash
check_exists() {
local path="$1"
if [ -f "$path" ]; then
echo "EXISTS"
elif [ -d "$path" ]; then
echo "EXISTS (directory)"
else
echo "MISSING"
fi
}
```
If MISSING → artifact fails, record and continue to next artifact.
### Level 2: Substantive
Check that the file has real implementation, not a stub.
**Line count check:**
```bash
check_length() {
local path="$1"
local min_lines="$2"
local lines=$(wc -l < "$path" 2>/dev/null || echo 0)
[ "$lines" -ge "$min_lines" ] && echo "SUBSTANTIVE ($lines lines)" || echo "THIN ($lines lines)"
}
```
Minimum lines by type:
- Component: 15+ lines
- API route: 10+ lines
- Hook/util: 10+ lines
- Schema model: 5+ lines
**Stub pattern check:**
```bash
check_stubs() {
local path="$1"
# Universal stub patterns
local stubs=$(grep -c -E "TODO|FIXME|placeholder|not implemented|coming soon" "$path" 2>/dev/null || echo 0)
# Empty returns
local empty=$(grep -c -E "return null|return undefined|return \{\}|return \[\]" "$path" 2>/dev/null || echo 0)
# Placeholder content
local placeholder=$(grep -c -E "will be here|placeholder|lorem ipsum" "$path" 2>/dev/null || echo 0)
local total=$((stubs + empty + placeholder))
[ "$total" -gt 0 ] && echo "STUB_PATTERNS ($total found)" || echo "NO_STUBS"
}
```
**Export check (for components/hooks):**
```bash
check_exports() {
local path="$1"
grep -E "^export (default )?(function|const|class)" "$path" && echo "HAS_EXPORTS" || echo "NO_EXPORTS"
}
```
**Combine level 2 results:**
- SUBSTANTIVE: Adequate length + no stubs + has exports
- STUB: Too short OR has stub patterns OR no exports
- PARTIAL: Mixed signals (length OK but has some stubs)
### Level 3: Wired
Check that the artifact is connected to the system.
**Import check (is it used?):**
```bash
check_imported() {
local artifact_name="$1"
local search_path="${2:-src/}"
# Find imports of this artifact
local imports=$(grep -r "import.*$artifact_name" "$search_path" --include="*.ts" --include="*.tsx" 2>/dev/null | wc -l)
[ "$imports" -gt 0 ] && echo "IMPORTED ($imports times)" || echo "NOT_IMPORTED"
}
```
**Usage check (is it called?):**
```bash
check_used() {
local artifact_name="$1"
local search_path="${2:-src/}"
# Find usages (function calls, component renders, etc.)
local uses=$(grep -r "$artifact_name" "$search_path" --include="*.ts" --include="*.tsx" 2>/dev/null | grep -v "import" | wc -l)
[ "$uses" -gt 0 ] && echo "USED ($uses times)" || echo "NOT_USED"
}
```
**Combine level 3 results:**
- WIRED: Imported AND used
- ORPHANED: Exists but not imported/used
- PARTIAL: Imported but not used (or vice versa)
### Final artifact status
| Exists | Substantive | Wired | Status |
|--------|-------------|-------|--------|
| ✓ | ✓ | ✓ | ✓ VERIFIED |
| ✓ | ✓ | ✗ | ⚠️ ORPHANED |
| ✓ | ✗ | - | ✗ STUB |
| ✗ | - | - | ✗ MISSING |
Record status and evidence for each artifact.
</step>
<step name="verify_wiring">
**Verify key links between artifacts.**
Key links are critical connections. If broken, the goal fails even with all artifacts present.
### Pattern: Component → API
Check if component actually calls the API:
```bash
verify_component_api_link() {
local component="$1"
local api_path="$2"
# Check for fetch/axios call to the API
local has_call=$(grep -E "fetch\(['\"].*$api_path|axios\.(get|post).*$api_path" "$component" 2>/dev/null)
if [ -n "$has_call" ]; then
# Check if response is used
local uses_response=$(grep -A 5 "fetch\|axios" "$component" | grep -E "await|\.then|setData|setState" 2>/dev/null)
if [ -n "$uses_response" ]; then
echo "WIRED: $component → $api_path (call + response handling)"
else
echo "PARTIAL: $component → $api_path (call exists but response not used)"
fi
else
echo "NOT_WIRED: $component → $api_path (no call found)"
fi
}
```
### Pattern: API → Database
Check if API route queries database:
```bash
verify_api_db_link() {
local route="$1"
local model="$2"
# Check for Prisma/DB call
local has_query=$(grep -E "prisma\.$model|db\.$model|$model\.(find|create|update|delete)" "$route" 2>/dev/null)
if [ -n "$has_query" ]; then
# Check if result is returned
local returns_result=$(grep -E "return.*json.*\w+|res\.json\(\w+" "$route" 2>/dev/null)
if [ -n "$returns_result" ]; then
echo "WIRED: $route → database ($model)"
else
echo "PARTIAL: $route → database (query exists but result not returned)"
fi
else
echo "NOT_WIRED: $route → database (no query for $model)"
fi
}
```
### Pattern: Form → Handler
Check if form submission does something:
```bash
verify_form_handler_link() {
local component="$1"
# Find onSubmit handler
local has_handler=$(grep -E "onSubmit=\{|handleSubmit" "$component" 2>/dev/null)
if [ -n "$has_handler" ]; then
# Check if handler has real implementation
local handler_content=$(grep -A 10 "onSubmit.*=" "$component" | grep -E "fetch|axios|mutate|dispatch" 2>/dev/null)
if [ -n "$handler_content" ]; then
echo "WIRED: form → handler (has API call)"
else
# Check for stub patterns
local is_stub=$(grep -A 5 "onSubmit" "$component" | grep -E "console\.log|preventDefault\(\)$|\{\}" 2>/dev/null)
if [ -n "$is_stub" ]; then
echo "STUB: form → handler (only logs or empty)"
else
echo "PARTIAL: form → handler (exists but unclear implementation)"
fi
fi
else
echo "NOT_WIRED: form → handler (no onSubmit found)"
fi
}
```
### Pattern: State → Render
Check if state is actually rendered:
```bash
verify_state_render_link() {
local component="$1"
local state_var="$2"
# Check if state variable exists
local has_state=$(grep -E "useState.*$state_var|\[$state_var," "$component" 2>/dev/null)
if [ -n "$has_state" ]; then
# Check if state is used in JSX
local renders_state=$(grep -E "\{.*$state_var.*\}|\{$state_var\." "$component" 2>/dev/null)
if [ -n "$renders_state" ]; then
echo "WIRED: state → render ($state_var displayed)"
else
echo "NOT_WIRED: state → render ($state_var exists but not displayed)"
fi
else
echo "N/A: state → render (no state var $state_var)"
fi
}
```
### Aggregate key link results
For each key link in must_haves:
- Run appropriate verification function
- Record status and evidence
- WIRED / PARTIAL / STUB / NOT_WIRED
</step>
<step name="verify_requirements">
**Check requirements coverage if REQUIREMENTS.md exists.**
```bash
# Find requirements mapped to this phase
grep -E "Phase ${PHASE_NUM}" .planning/REQUIREMENTS.md 2>/dev/null
```
For each requirement:
1. Parse requirement description
2. Identify which truths/artifacts support it
3. Determine status based on supporting infrastructure
**Requirement status:**
- ✓ SATISFIED: All supporting truths verified
- ✗ BLOCKED: One or more supporting truths failed
- ? NEEDS HUMAN: Can't verify requirement programmatically
</step>
<step name="scan_antipatterns">
**Scan for anti-patterns across phase files.**
Identify files modified in this phase:
```bash
# Extract files from SUMMARY.md
grep -E "^\- \`" "$PHASE_DIR"/*-SUMMARY.md | sed 's/.*`\([^`]*\)`.*/\1/' | sort -u
```
Run anti-pattern detection:
```bash
scan_antipatterns() {
local files="$@"
echo "## Anti-Patterns Found"
echo ""
for file in $files; do
[ -f "$file" ] || continue
# TODO/FIXME comments
grep -n -E "TODO|FIXME|XXX|HACK" "$file" 2>/dev/null | while read line; do
echo "| $file | $(echo $line | cut -d: -f1) | TODO/FIXME | ⚠️ Warning |"
done
# Placeholder content
grep -n -E "placeholder|coming soon|will be here" "$file" -i 2>/dev/null | while read line; do
echo "| $file | $(echo $line | cut -d: -f1) | Placeholder | 🛑 Blocker |"
done
# Empty implementations
grep -n -E "return null|return \{\}|return \[\]|=> \{\}" "$file" 2>/dev/null | while read line; do
echo "| $file | $(echo $line | cut -d: -f1) | Empty return | ⚠️ Warning |"
done
# Console.log only implementations
grep -n -B 2 -A 2 "console\.log" "$file" 2>/dev/null | grep -E "^\s*(const|function|=>)" | while read line; do
echo "| $file | - | Log-only function | ⚠️ Warning |"
done
done
}
```
Categorize findings:
- 🛑 Blocker: Prevents goal achievement (placeholder renders, empty handlers)
- ⚠️ Warning: Indicates incomplete (TODO comments, console.log)
- ℹ️ Info: Notable but not problematic
</step>
<step name="identify_human_verification">
**Flag items that need human verification.**
Some things can't be verified programmatically:
**Always needs human:**
- Visual appearance (does it look right?)
- User flow completion (can you do the full task?)
- Real-time behavior (WebSocket, SSE updates)
- External service integration (payments, email)
- Performance feel (does it feel fast?)
- Error message clarity
**Needs human if uncertain:**
- Complex wiring that grep can't trace
- Dynamic behavior depending on state
- Edge cases and error states
**Format for human verification:**
```markdown
## Human Verification Required
### 1. {Test Name}
**Test:** {What to do}
**Expected:** {What should happen}
**Why human:** {Why can't verify programmatically}
```
</step>
<step name="determine_status">
**Calculate overall verification status.**
**Status: passed**
- All truths VERIFIED
- All artifacts pass level 1-3
- All key links WIRED
- No blocker anti-patterns
- (Human verification items are OK — will be prompted)
**Status: gaps_found**
- One or more truths FAILED
- OR one or more artifacts MISSING/STUB
- OR one or more key links NOT_WIRED
- OR blocker anti-patterns found
**Status: human_needed**
- All automated checks pass
- BUT items flagged for human verification
- Can't determine goal achievement without human
**Calculate score:**
```
score = (verified_truths / total_truths)
```
</step>
<step name="generate_fix_plans">
**If gaps_found, recommend fix plans.**
Group related gaps into fix plans:
1. **Identify gap clusters:**
- API stub + component not wired → "Wire frontend to backend"
- Multiple artifacts missing → "Complete core implementation"
- Wiring issues only → "Connect existing components"
2. **Generate plan recommendations:**
```markdown
### {phase}-{next}-PLAN.md: {Fix Name}
**Objective:** {What this fixes}
**Tasks:**
1. {Task to fix gap 1}
- Files: {files to modify}
- Action: {specific fix}
- Verify: {how to confirm fix}
2. {Task to fix gap 2}
- Files: {files to modify}
- Action: {specific fix}
- Verify: {how to confirm fix}
3. Re-verify phase goal
- Run verification again
- Confirm all must-haves pass
**Estimated scope:** {Small / Medium}
```
3. **Keep plans focused:**
- 2-3 tasks per plan
- Single concern per plan
- Include verification task
4. **Order by dependency:**
- Fix missing artifacts before wiring
- Fix stubs before integration
- Verify after all fixes
</step>
<step name="create_report">
**Generate VERIFICATION.md using template.**
```bash
REPORT_PATH="$PHASE_DIR/${PHASE_NUM}-VERIFICATION.md"
```
Fill template sections:
1. **Frontmatter:** phase, verified timestamp, status, score
2. **Goal Achievement:** Truth verification table
3. **Required Artifacts:** Artifact verification table
4. **Key Link Verification:** Wiring verification table
5. **Requirements Coverage:** If REQUIREMENTS.md exists
6. **Anti-Patterns Found:** Scan results table
7. **Human Verification Required:** Items needing human
8. **Gaps Summary:** Critical and non-critical gaps
9. **Recommended Fix Plans:** If gaps_found
10. **Verification Metadata:** Approach, timing, counts
See ~/.claude/get-shit-done/templates/verification-report.md for complete template.
</step>
<step name="return_to_orchestrator">
**Return results to execute-phase orchestrator.**
**Return format:**
```markdown
## Verification Complete
**Status:** {passed | gaps_found | human_needed}
**Score:** {N}/{M} must-haves verified
**Report:** .planning/phases/{phase_dir}/{phase}-VERIFICATION.md
{If passed:}
All must-haves verified. Phase goal achieved. Ready to proceed.
{If gaps_found:}
### Gaps Found
{N} critical gaps blocking goal achievement:
1. {Gap 1 summary}
2. {Gap 2 summary}
### Recommended Fixes
{N} fix plans recommended:
1. {phase}-{next}-PLAN.md: {name}
2. {phase}-{next+1}-PLAN.md: {name}
{If human_needed:}
### Human Verification Required
{N} items need human testing:
1. {Item 1}
2. {Item 2}
Automated checks passed. Awaiting human verification.
```
The orchestrator will:
- If `passed`: Continue to update_roadmap
- If `gaps_found`: Create and execute fix plans, then re-verify
- If `human_needed`: Present items to user, collect responses
</step>
</process>
<success_criteria>
- [ ] Must-haves established (from frontmatter or derived)
- [ ] All truths verified with status and evidence
- [ ] All artifacts checked at all three levels
- [ ] All key links verified
- [ ] Requirements coverage assessed (if applicable)
- [ ] Anti-patterns scanned and categorized
- [ ] Human verification items identified
- [ ] Overall status determined
- [ ] Fix plans generated (if gaps_found)
- [ ] VERIFICATION.md created with complete report
- [ ] Results returned to orchestrator
</success_criteria>