--- description: Review story and create PR with all committed tasks argument-hint: "[STORY-ID or PATH]" allowed-tools: Read, Bash, Task model: claude-haiku-4-5-20251001 --- # Story Review Command Review entire user story implementation and create single PR if all tasks are approved. ## Introduction Senior Story Review Architect with expertise in user story validation, acceptance criteria verification, and pull request automation ## Prerequisites - Git repository with story start tag (e.g., `story/US-3.4-start`) - All tasks completed and tagged (e.g., `task/TASK-1.1-committed`) - GitHub CLI (`gh`) installed and authenticated - Story directory structure: `./project-management/US-STORY/US-X.Y-name/` - Valid US-story.md file with all task references - Clean working directory (no uncommitted changes) ## Input Variables $ARGUMENTS Default: "main" Can be overridden with: --base develop Default: "false" Set to "true" with: --draft true ## Memory Graph Usage (Auto) As you review a story, persist durable outcomes discovered in files and commit summaries: - Use `mcp__memory__search_nodes` → `create_entities`/`add_observations` → `create_relations` to record owners, endpoints, repo links, and key decisions (dated). The UserPromptSubmit and PostToolUse hooks auto-hint when these signals are detected. See `.claude/skills/memory-graph/`. ## Main Tasks **KEY REQUIREMENTS**: 1. Each completed US (user story) = 1 PR (not per task) 2. If review FAILS → Generate detailed REPORT file 3. Review against project standards AND enterprise guidelines 4. Use reviewer-story agent via Task tool 5. Parse agent JSON output programmatically 6. APPROVED → Auto-create PR with comprehensive body 7. CHANGES_REQUIRED → Generate US-X.Y-REVIEW-REPORT.md with fix guidance ### Step 1: Load and Validate Story File MUST validate story file exists and contains all required sections before proceeding. - [ ] Check USER-STORY.md exists at provided path - [ ] Verify file contains required sections: - ## User Story - ## Acceptance Criteria - ## Technical Requirements - ## Tasks - [ ] Parse all task references (TASK-X.Y format) - [ ] Collect story metadata (ID, title, description) #### Load Story File ```bash # Parse input - can be story ID (US-X.Y) or full path story_input="$ARGUMENTS" # Check if input is story ID format (US-X.Y) if [[ "$story_input" =~ ^US-[0-9]+\.[0-9]+$ ]]; then # Find story directory story_dir=$(find ./project-management/US-STORY -name "${story_input}-*" -type d 2>/dev/null | head -1) if [[ -z "$story_dir" ]]; then echo "❌ Error: Story ${story_input} not found" echo "" echo "Available stories:" ls -1d ./project-management/US-STORY/US-*/ 2>/dev/null || echo " (no stories found)" echo "" echo "Usage: /lazy story-review US-X.Y" echo " or: /lazy story-review ./project-management/US-STORY/US-X.Y-name/US-story.md" exit 1 fi story_file="${story_dir}/US-story.md" tasks_dir="${story_dir}/TASKS" story_id=$(basename "$story_dir" | grep -oP '^US-\d+\.\d+') else # Assume it's a full path to US-story.md story_file="$story_input" # Validate story file exists if [ ! -f "$story_file" ]; then echo "❌ Error: Story file not found: $story_file" echo "" echo "Usage: /lazy story-review US-X.Y" echo " or: /lazy story-review ./project-management/US-STORY/US-X.Y-name/US-story.md" exit 1 fi story_dir=$(dirname "$story_file") tasks_dir="${story_dir}/TASKS" story_id=$(basename "$story_dir" | grep -oP '^US-\d+\.\d+') fi # Validate tasks directory exists if [ ! -d "$tasks_dir" ]; then echo "❌ Error: Tasks directory not found: $tasks_dir" echo "Story directory may be corrupt" echo "Run /lazy create-feature to regenerate" exit 1 fi # Read story content story_content=$(cat "$story_file") story_title=$(grep -m1 "^# " "$story_file" | sed 's/^# //') # Extract GitHub issue number from story file story_github_issue=$(grep "GitHub Issue: #" "$story_file" | sed 's/.*#//' | head -1) ``` ### Step 2: Verify Story State with Git Tags Use git tags to track story and task completion state. All tasks must be committed before review. Story review uses git tags for state management: **Story Start Tag:** ```bash # Created by /lazy create-feature git tag story/oauth2-start ``` **Task Completion Tags:** ```bash # Created by /lazy task-exec after each task git tag task/TASK-1.1-committed git tag task/TASK-1.2-committed git tag task/TASK-1.3-committed ``` **Verification:** ```bash # Get all task tags task_tags=$(git tag -l 'task/*-committed') # Get story start tag story_start=$(git tag -l 'story/*-start' | tail -1) # Verify story start exists if [ -z "$story_start" ]; then echo "❌ Error: No story start tag found" echo "Expected: story/{story-id}-start" exit 1 fi ``` #### Collect Task Tags - [ ] Get all task files from TASKS directory - [ ] Get all task tags: `git tag -l 'task/*-committed'` - [ ] Parse task IDs from tags (extract TASK-X.Y) - [ ] Verify all tasks are committed - [ ] Extract GitHub issue numbers from task files - [ ] Block review if any task is incomplete ```bash # Collect all task files task_files=$(ls ${tasks_dir}/TASK-*.md 2>/dev/null) if [[ -z "$task_files" ]]; then echo "❌ Error: No task files found in ${tasks_dir}" echo "Story directory may be corrupt" exit 1 fi # Collect committed and pending tasks committed_tasks=() pending_tasks=() task_github_issues=() for task_file in $task_files; do task_id=$(basename "$task_file" .md) # e.g., TASK-1.1 # Check if task is committed (git tag) if git tag | grep -q "task/${task_id}-committed"; then committed_tasks+=("$task_id") # Extract GitHub issue number if present github_issue=$(grep "GitHub Issue: #" "$task_file" | sed 's/.*#//' | head -1) if [[ -n "$github_issue" ]]; then task_github_issues+=("$task_id:$github_issue") fi else pending_tasks+=("$task_id") fi done # Verify all tasks are committed if [[ ${#pending_tasks[@]} -gt 0 ]]; then echo "❌ Error: Not all tasks are committed" echo "" echo "Pending tasks:" for task in "${pending_tasks[@]}"; do echo " - $task" done echo "" echo "Next steps:" echo " 1. Complete missing tasks: /lazy task-exec " echo " 2. Re-run story review: /lazy story-review ${story_id}" exit 1 fi echo "✅ All ${#committed_tasks[@]} tasks are committed" ``` ### Step 3: Collect All Commits Since Story Start Get all commits between story start and current HEAD to include in PR. ```bash # Get commits since story start commits=$(git log "$story_start"..HEAD --oneline) commit_count=$(echo "$commits" | wc -l) # Verify there are commits if [ $commit_count -eq 0 ]; then echo "❌ Error: No commits found since story start" echo "Story start: $story_start" exit 1 fi echo "📊 Found $commit_count commits since $story_start" ``` ### Step 4: Collect Task Implementations For each completed task, collect: - Task file content from TASKS directory - Implementation files (from git diff) - Test results (if available) - GitHub issue links ```bash # For each task, collect implementation details all_tasks_summary="" for task_file in $task_files; do task_id=$(basename "$task_file" .md) task_title=$(grep -m1 "^# " "$task_file" | sed 's/^# //') task_gh_issue=$(grep "GitHub Issue: #" "$task_file" | sed 's/.*#//' | head -1) # Get files changed in task commits (approximate by commit messages) task_commits=$(git log "$story_start"..HEAD --oneline --grep="$task_id") commit_count=$(echo "$task_commits" | wc -l) # Collect for review all_tasks_summary="${all_tasks_summary}\n${task_id}: ${task_title}" if [[ -n "$task_gh_issue" ]]; then all_tasks_summary="${all_tasks_summary} (GH Issue #${task_gh_issue})" fi all_tasks_summary="${all_tasks_summary}\n Commits: ${commit_count}" done echo -e "📋 Task Summary:${all_tasks_summary}" ``` ### Step 5: Run Test Suite (if tests exist) Run project tests if test runner is available. ```bash # Detect test framework and run tests test_results="" if [ -f "pytest.ini" ] || [ -f "pyproject.toml" ]; then echo "🧪 Running pytest..." test_results=$(pytest --tb=short 2>&1 || true) elif [ -f "package.json" ]; then if grep -q '"test"' package.json; then echo "🧪 Running npm test..." test_results=$(npm test 2>&1 || true) fi fi ``` ### Step 6: Load Enterprise Standards Load project and enterprise standards for compliance checking. ```bash # Collect all applicable standards standards_content="" # 1. Load CLAUDE.md (project standards) if [ -f "CLAUDE.md" ]; then echo "📋 Loading project standards from CLAUDE.md..." standards_content="${standards_content}\n## Project Standards (CLAUDE.md)\n\n" standards_content="${standards_content}$(cat CLAUDE.md)" fi # 2. Load README.md (architecture decisions) if [ -f "README.md" ]; then echo "📋 Loading architecture decisions from README.md..." standards_content="${standards_content}\n## Architecture Decisions (README.md)\n\n" standards_content="${standards_content}$(cat README.md)" fi # 3. Load CONTRIBUTING.md (code standards) if [ -f ".github/CONTRIBUTING.md" ]; then echo "📋 Loading code standards from .github/CONTRIBUTING.md..." standards_content="${standards_content}\n## Code Standards (CONTRIBUTING.md)\n\n" standards_content="${standards_content}$(cat .github/CONTRIBUTING.md)" elif [ -f "CONTRIBUTING.md" ]; then echo "📋 Loading code standards from CONTRIBUTING.md..." standards_content="${standards_content}\n## Code Standards (CONTRIBUTING.md)\n\n" standards_content="${standards_content}$(cat CONTRIBUTING.md)" fi # 4. Load custom enterprise guidelines (if configured) enterprise_standards_path="${LAZY_DEV_ENTERPRISE_STANDARDS:-}" if [ -n "$enterprise_standards_path" ] && [ -f "$enterprise_standards_path" ]; then echo "📋 Loading enterprise standards from ${enterprise_standards_path}..." standards_content="${standards_content}\n## Enterprise Guidelines\n\n" standards_content="${standards_content}$(cat "$enterprise_standards_path")" fi # If no standards found, use defaults if [ -z "$standards_content" ]; then echo "⚠️ No standards files found - using LAZY-DEV defaults" standards_content="## Default Standards\n\n- Test coverage >80%\n- Type hints required\n- Documentation required for public APIs\n- OWASP Top 10 security compliance" fi echo "✅ Standards loaded successfully" ``` ### Step 7: Invoke Story Review Agent Invoke the Story Review Agent via Task tool with complete context including enterprise standards. The agent receives all story context, implementation details, and compliance standards. Agent output format is JSON for programmatic processing. ```bash # Prepare context for agent echo "🤖 Invoking Story Review Agent..." # Read full story content story_content_full=$(cat "$story_file") # Get all task file contents tasks_content="" for task_file in $task_files; do task_id=$(basename "$task_file" .md) tasks_content="${tasks_content}\n### ${task_id}\n\n$(cat "$task_file")\n" done # Get git diff stats files_changed=$(git diff --stat "$story_start"..HEAD) files_changed_list=$(git diff --name-only "$story_start"..HEAD) # Get test coverage if available coverage_result="" if command -v pytest &> /dev/null; then coverage_result=$(pytest --cov --cov-report=term-missing 2>&1 || true) fi # Store agent context in temporary file for Task tool cat > /tmp/story_review_context.md <80%) 6. Integration quality between all tasks Return JSON output as specified in reviewer-story.md agent template. EOF echo "📄 Context prepared: /tmp/story_review_context.md" ``` **Invoke reviewer-story agent now:** Use the Task tool to invoke `.claude/agents/reviewer-story.md` with the following variable substitutions: - `story_id`: ${story_id} - `story_file`: ${story_file} - `tasks_dir`: ${tasks_dir} - `branch_name`: $(git branch --show-current) - `standards`: ${standards_content} The agent will analyze all context and return JSON output with `status` field of either "APPROVED" or "REQUEST_CHANGES". ### Step 8: Process Review Results Parse JSON output from reviewer-story agent and take appropriate action. ```bash # Agent returns JSON - parse the status field agent_status=$(echo "$agent_output" | jq -r '.status' 2>/dev/null || echo "UNKNOWN") if [ "$agent_status" = "APPROVED" ]; then echo "✅ Story review APPROVED" echo "" # Extract summary from agent output agent_summary=$(echo "$agent_output" | jq -r '.summary' 2>/dev/null || echo "All checks passed") echo "📋 Summary: ${agent_summary}" echo "" # Proceed to Step 9 (PR creation) elif [ "$agent_status" = "REQUEST_CHANGES" ]; then echo "❌ Story review FAILED - Changes Required" echo "" # Generate detailed review report report_file="${story_dir}/${story_id}-review-report.md" echo "📝 Generating review report: ${report_file}" # Extract data from agent JSON output agent_summary=$(echo "$agent_output" | jq -r '.summary' 2>/dev/null || echo "Review found issues") # Count issues by severity critical_count=$(echo "$agent_output" | jq '[.issues[] | select(.severity == "CRITICAL")] | length' 2>/dev/null || echo "0") warning_count=$(echo "$agent_output" | jq '[.issues[] | select(.severity == "WARNING")] | length' 2>/dev/null || echo "0") suggestion_count=$(echo "$agent_output" | jq '[.issues[] | select(.severity == "SUGGESTION")] | length' 2>/dev/null || echo "0") total_issues=$((critical_count + warning_count + suggestion_count)) # Get task status summary tasks_passed=$(echo "$agent_output" | jq '[.tasks_status[] | select(.status == "passed")] | length' 2>/dev/null || echo "0") tasks_total=$(echo "$agent_output" | jq '.tasks_status | length' 2>/dev/null || echo "0") # Generate comprehensive report cat > "$report_file" < 0) then .issues | to_entries | map( "### " + ((.key + 1) | tostring) + ". " + (if .value.type then (.value.type | gsub("_"; " ") | ascii_upcase) else "Issue" end) + " (" + (.value.file // "N/A") + (if .value.line then ":" + (.value.line | tostring) else "" end) + ")\n" + "- **Type**: " + (.value.type // "unknown") + "\n" + "- **File**: " + (.value.file // "N/A") + (if .value.line then ":" + (.value.line | tostring) else "" end) + "\n" + "- **Issue**: " + .value.description + "\n" + "- **Fix**: " + .value.fix + "\n" ) | join("\n") else "No specific issues documented." end ') ## Tasks Status $(echo "$agent_output" | jq -r ' if .tasks_status and (.tasks_status | length > 0) then .tasks_status | map( "- " + .task_id + ": " + (if .status == "passed" then "✅ Passed" elif .status == "failed" then "❌ Failed (" + (.issues_count | tostring) + " issues)" elif .status == "warning" then "⚠️ Warning (" + (.issues_count | tostring) + " issues)" else "⚠️ " + .status end) ) | join("\n") else "- No task status available" end ') ## Next Steps Run: \`/lazy fix ${report_file}\` Or manually fix and re-run: \`/lazy review @${story_file}\` REPORT_EOF echo "✅ Review report generated: ${report_file}" echo "" echo "Found:" echo " - ${critical_count} CRITICAL issues" echo " - ${warning_count} WARNING issues" echo " - ${suggestion_count} SUGGESTIONS" echo "" echo "Next steps:" echo " 1. Review report: cat ${report_file}" echo " 2. Fix issues: /lazy fix ${report_file}" echo " 3. Re-run review: /lazy review ${story_id}" echo "" # Exit with status 1 to indicate failure exit 1 else echo "❌ Error: Unknown review status from agent: ${agent_status}" echo "Agent output:" echo "$agent_output" exit 1 fi ``` ### Step 9: Create Pull Request (If APPROVED) If review is approved, create a single PR containing all story commits with comprehensive summary. - One PR per user story (not per task) - Includes all commits since story start tag - References all task GitHub issues - Includes test results and quality metrics - Auto-closes related GitHub issues #### Prepare PR Body ```bash # Generate comprehensive PR body echo "📝 Generating PR body..." # Extract test coverage percentage test_coverage=$(echo "$coverage_result" | grep "^TOTAL" | awk '{print $NF}' || echo "N/A") # Get acceptance criteria status acceptance_criteria_list=$(cat "$story_file" | sed -n '/## Acceptance Criteria/,/##/p' | grep -E "^-.*" | sed 's/^- /✓ /') # Extract agent summary pr_summary=$(echo "$agent_output" | jq -r '.summary' 2>/dev/null || echo "Story implementation completed and reviewed") cat > pr_body.md <<'PR_BODY' # [FEATURE] ${story_title} **Story ID**: ${story_id} **Directory**: `${story_dir}` $(if [[ -n "$story_github_issue" ]]; then echo "**GitHub Issue**: Closes #${story_github_issue}"; fi) --- ## Summary ${pr_summary} --- ## User Story $(cat "${story_file}" | sed -n '/## User Story/,/##/p' | tail -n +2 | head -n -1) --- ## Acceptance Criteria $(echo "$acceptance_criteria_list" | sed 's/^/✓ /') --- ## Tasks Completed $(for task_file in ${tasks_dir}/TASK-*.md; do task_id=$(basename "$task_file" .md) task_title=$(grep "^# " "$task_file" | head -1 | sed 's/^# //') task_gh_issue=$(grep "GitHub Issue: #" "$task_file" | sed 's/.*#//' | head -1) if [[ -n "$task_gh_issue" ]]; then echo "✓ [${task_id}] ${task_title} - Closes #${task_gh_issue}" else echo "✓ [${task_id}] ${task_title}" fi done) --- ## Commits \`\`\` $(git log --oneline ${story_start}..HEAD) \`\`\` **Total Commits**: ${commit_count} --- ## Quality Metrics | Metric | Value | |--------|-------| | Files Changed | $(git diff --name-only "$story_start"..HEAD | wc -l) | | Lines Added | $(git diff --stat "$story_start"..HEAD | tail -1 | grep -oP '\d+(?= insertion)' || echo "0") | | Lines Removed | $(git diff --stat "$story_start"..HEAD | tail -1 | grep -oP '\d+(?= deletion)' || echo "0") | | Test Coverage | ${test_coverage} | | Tests Passing | $(echo "$test_results" | grep -oP '\d+(?= passed)' || echo "All") | --- ## Testing \`\`\` ${test_results:-No tests run} \`\`\` $(if [[ -n "$coverage_result" ]]; then echo "### Coverage Report" echo "\`\`\`" echo "$coverage_result" | head -20 echo "\`\`\`" fi) --- ## Compliance & Quality Checks ### Story Review ✅ **APPROVED** by reviewer-story agent ### Project Standards ✅ Compliant with CLAUDE.md requirements ✅ Follows project architecture patterns ### Enterprise Guidelines $(if [[ -n "$enterprise_standards_path" ]]; then echo "✅ Compliant with enterprise standards: \`${enterprise_standards_path}\`" else echo "✅ Compliant with LAZY-DEV framework defaults" fi) ### Security ✅ OWASP Top 10 compliance verified ✅ No security vulnerabilities detected ✅ Input validation implemented ✅ Authentication/authorization reviewed ### Code Quality ✅ Format: PASS (Black/Ruff) ✅ Lint: PASS (Ruff) ✅ Type: PASS (Mypy) ✅ Tests: PASS (Pytest) ### Documentation ✅ Public APIs documented ✅ README updated (if applicable) ✅ Inline comments for complex logic --- ## Integration Status ✅ All tasks integrate cohesively ✅ No conflicts between task implementations ✅ Data flows correctly between components ✅ No breaking changes to existing functionality --- ## Reviewer Notes **Review Method**: LAZY-DEV-FRAMEWORK automated story review **Review Agent**: `.claude/agents/reviewer-story.md` **Review Date**: $(date -u +"%Y-%m-%d %H:%M:%S UTC") **Summary**: ${pr_summary} **Strengths**: $(echo "$agent_output" | jq -r '.strengths // [] | if length > 0 then map("- " + .) | join("\n") else "- Comprehensive implementation\n- Strong test coverage\n- Clean code quality" end' 2>/dev/null || echo "- High-quality implementation") --- ## Related Issues $(if [[ -n "$story_github_issue" ]]; then echo "- Story: #${story_github_issue}" fi) $(for task_file in ${tasks_dir}/TASK-*.md; do task_gh_issue=$(grep "GitHub Issue: #" "$task_file" | sed 's/.*#//' | head -1) if [[ -n "$task_gh_issue" ]]; then task_id=$(basename "$task_file" .md) echo "- Task ${task_id}: #${task_gh_issue}" fi done) --- 🤖 Generated with [Claude Code](https://claude.com/claude-code) LAZY-DEV-FRAMEWORK **Story**: ${story_id} **Directory**: ${story_dir} **Framework**: LAZY-DEV v1.0.0-alpha PR_BODY # Expand variables in PR body eval "cat <<'EXPAND_PR_BODY' > pr_body_final.md $(cat pr_body.md) EXPAND_PR_BODY" echo "✅ PR body generated: pr_body_final.md" ``` #### Create PR with gh CLI ```bash # Determine if draft mode draft_flag="" if [ "$draft_mode" = "true" ]; then draft_flag="--draft" fi # Create PR echo "📦 Creating pull request..." pr_url=$(gh pr create \ --title "[FEATURE] $story_title" \ --body-file pr_body_final.md \ --base "$base_branch" \ --label "story,automated,reviewed,story:$story_id" \ $draft_flag) # Verify PR creation if [ $? -eq 0 ]; then # Get PR number pr_number=$(gh pr list --head "$(git branch --show-current)" --json number --jq '.[0].number') echo "✅ PR Created: $pr_url" echo "" echo "📁 Story: ${story_id}" echo " Directory: ${story_dir}" echo "" echo "📦 PR Details:" echo " Number: #${pr_number}" echo " Title: [STORY] $story_title" echo " Base: $base_branch" echo " Commits: $commit_count" echo "" # Close GitHub issues echo "🔗 Closing GitHub Issues:" # Close main story issue if [[ -n "$story_github_issue" ]]; then gh issue close $story_github_issue --reason completed \ --comment "Completed in PR #${pr_number}" 2>/dev/null if [ $? -eq 0 ]; then echo " ✅ #${story_github_issue} - [STORY] ${story_title}" fi fi # Close all task issues for task_file in ${tasks_dir}/TASK-*.md; do task_id=$(basename "$task_file" .md) task_title=$(grep "^# " "$task_file" | head -1 | sed 's/^# //') task_gh_issue=$(grep "GitHub Issue: #" "$task_file" | sed 's/.*#//' | head -1) if [[ -n "$task_gh_issue" ]]; then gh issue close $task_gh_issue --reason completed \ --comment "Completed in PR #${pr_number}" 2>/dev/null if [ $? -eq 0 ]; then echo " ✅ #${task_gh_issue} - [${task_id}] ${task_title}" fi fi done echo "" echo "✅ All related issues closed" echo "✅ Ready for merge" else echo "❌ Error: Failed to create PR" echo "Check: gh auth status" exit 1 fi ``` ## Parallelization During Review While the story review is running or after it completes, you can run other commands in parallel if they are independent. ### Commands That Can Run in Parallel **During Review (While Waiting for Agent)**: ```bash # 1. Cleanup unused code (runs on current branch) /lazy cleanup --scope feature/US-X.Y # 2. Generate documentation for the story /lazy documentation --scope US-X.Y # 3. Check memory graph for this story's entities /lazy memory-check US-X.Y ``` **After Review Approval (Before PR Merge)**: ```bash # 1. Start work on next independent story /lazy create-feature "Next feature brief" # 2. Update project documentation /lazy documentation --scope project # 3. Run refactoring on completed work /lazy refactor --scope US-X.Y ``` ### Commands That CANNOT Run in Parallel **Blocked Until Review Completes**: ```bash # ❌ Cannot run another story review simultaneously /lazy story-review US-Y.Z # Wait for current review to finish # ❌ Cannot re-execute tasks in the story being reviewed /lazy task-exec TASK-X.Y # Wait until review fails or make changes after PR # ❌ Cannot fix review issues until report is generated /lazy story-fix-review US-X.Y-REVIEW-REPORT.md # Only after review fails ``` ### Recommended Workflow **Optimal Parallelization**: ```bash # Terminal 1: Run story review /lazy story-review US-3.4 # Terminal 2: While review is running, cleanup and document in parallel /lazy cleanup --scope feature/US-3.4 /lazy documentation --scope US-3.4 # If review APPROVED: # - PR is created automatically # - GitHub issues are closed # - Ready to start next story # If review FAILED: # - Fix issues: /lazy story-fix-review US-3.4-REVIEW-REPORT.md # - Re-run: /lazy story-review US-3.4 ``` ## Integration with Other Commands ### Workflow Integration **Complete Story Lifecycle**: ``` 1. /lazy create-feature "Brief" ↓ Creates: US-X.Y-name/US-story.md Creates: TASKS/TASK-*.md Creates: GitHub issues Sets tag: story/US-X.Y-start 2. /lazy task-exec TASK-1.1 /lazy task-exec TASK-1.2 /lazy task-exec TASK-1.3 ↓ Each sets tag: task/TASK-X.Y-committed Each implements and tests feature 3. /lazy story-review US-X.Y ← THIS COMMAND ↓ Loads: All tasks, commits, standards Invokes: reviewer-story agent If APPROVED: ↓ Creates: PR with full context Closes: All GitHub issues If CHANGES_REQUIRED: ↓ Creates: US-X.Y-REVIEW-REPORT.md Outputs: Fix guidance 4. If changes needed: /lazy story-fix-review US-X.Y-REVIEW-REPORT.md ↓ Routes issues to appropriate agents Fixes critical/warning issues Then re-run: /lazy story-review US-X.Y 5. After PR merge: /lazy cleanup --scope US-X.Y /lazy documentation --scope US-X.Y ``` ### Command Dependencies **story-review depends on**: - `/lazy create-feature` (creates story structure) - `/lazy task-exec` (completes all tasks) - Git tags: `story/*-start`, `task/*-committed` - GitHub CLI: `gh` authenticated **Commands that depend on story-review**: - `/lazy story-fix-review` (processes review report) - Subsequent `/lazy story-review` runs (after fixes) **Independent parallel commands**: - `/lazy cleanup` (code cleanup) - `/lazy documentation` (docs generation) - `/lazy memory-check` (graph queries) - `/lazy create-feature` (new independent story) ## Error Handling & Recovery ### Error: Story file not found ``` ❌ Error: Story US-3.4 not found Available stories: ./project-management/US-STORY/US-1.1-user-authentication/ ./project-management/US-STORY/US-2.3-payment-integration/ Usage: /lazy story-review US-X.Y or: /lazy story-review ./project-management/US-STORY/US-X.Y-name/US-story.md Recovery: 1. Check story ID: ls ./project-management/US-STORY/ 2. Use correct story ID: /lazy story-review US-1.1 3. Or use full path to US-story.md ``` ### Error: Task tags missing ``` ❌ Error: Not all tasks are committed Pending tasks: - TASK-1.2 - TASK-1.3 Next steps: 1. Run git tag -l 'task/*' to see completed tasks 2. Execute missing tasks: /lazy task-exec TASK-1.2 3. Retry: /lazy story-review US-3.4 ``` ### Error: Story start tag missing ``` ❌ Error: No story start tag found Expected: story/US-X.Y-start Recovery: 1. Check if create-feature was run: git tag -l 'story/*' 2. Create tag manually: git tag story/US-3.4-start $(git log --reverse --oneline | head -1 | cut -d' ' -f1) 3. Retry: /lazy story-review US-3.4 ``` ### Error: No commits found ``` ❌ Error: No commits found since story start Story start: story/oauth2-start Recovery: 1. Verify story tag: git log story/oauth2-start 2. Check current branch: git branch --show-current 3. Ensure tasks were committed (not just completed) ``` ### Error: Review changes needed ``` ⚠️ Story review needs changes: Critical Issues: - TASK-1.3 validation: Missing edge case for declined cards Location: src/payments/validator.py:45 Impact: Invalid cards may be processed Next steps: 1. Fix validation in TASK-1.3 2. Re-run: /lazy task-exec TASK-1.3 3. Re-review: /lazy story-review US-3.4 ``` ### Error: Tasks directory not found ``` ❌ Error: Tasks directory not found: ./project-management/US-STORY/US-3.4-oauth2/TASKS Story directory may be corrupt Run /lazy create-feature to regenerate Recovery: 1. Verify story structure: ls -la ./project-management/US-STORY/US-3.4-*/ 2. Check if TASKS directory exists 3. If missing, regenerate with /lazy create-feature ``` ### Error: GitHub issue numbers missing ``` ⚠️ Warning: Some task files don't have GitHub issue numbers This may happen with older stories Recovery: 1. Manually add GitHub issues 2. Or regenerate story with /lazy create-feature (includes gh issue creation) 3. Issues without numbers won't be auto-closed ``` ### Error: gh CLI not found ``` ❌ Error: gh command not found Recovery: 1. Install GitHub CLI: https://cli.github.com 2. Authenticate: gh auth login 3. Verify: gh auth status 4. Retry: /lazy story-review US-3.4 ``` ### Error: gh auth failed ``` ❌ Error: Not authenticated to GitHub Recovery: 1. Run: gh auth login 2. Follow prompts to authorize 3. Verify: gh auth status 4. Retry: /lazy story-review US-3.4 ``` ### Error: Base branch doesn't exist ``` ❌ Error: Base branch 'develop' not found Recovery: 1. Check branches: git branch -a 2. Use correct base: /lazy story-review US-3.4 --base main 3. Or create branch: git branch develop ``` ## Success Criteria Story review is successful when: - ✅ Story file is valid with all required sections - ✅ Story directory structure is correct: `./project-management/US-STORY/US-X.Y-name/` - ✅ All task files found in TASKS directory - ✅ All task tags present: `git tag -l 'task/TASK-*-committed'` - ✅ All commits collected since story start - ✅ Review agent approved entire implementation - ✅ All acceptance criteria validated - ✅ Architecture, security, and testing validated - ✅ PR created with title `[STORY] {story-name}` - ✅ PR body contains full story + all tasks + test results + GitHub issues - ✅ All commits included in PR history - ✅ PR is on correct base branch - ✅ All related GitHub issues closed (story + tasks) ## Example Usage ### Basic story review with story ID ```bash /lazy story-review US-3.4 ``` ### Review with full path (backward compatible) ```bash /lazy story-review ./project-management/US-STORY/US-3.4-oauth2-authentication/US-story.md ``` ### Review on specific base branch ```bash /lazy story-review US-3.4 --base develop ``` ### Create as draft PR ```bash /lazy story-review US-3.4 --draft true ``` ### Verify story state before review ```bash # List available stories ls -1d ./project-management/US-STORY/US-*/ # Check what tasks are completed git tag -l 'task/*' # Check story commits git log story/US-3.4-start..HEAD --oneline # Then run review /lazy story-review US-3.4 ``` ## Session Logging All activities logged to `logs//story-review.json`: ```json { "story_file": "USER-STORY.md", "story_id": "oauth2-auth", "base_branch": "main", "draft_mode": false, "timestamp": "2025-10-25T15:45:00Z", "stages": [ { "stage": "load_story", "status": "completed", "story_title": "Build OAuth2 Authentication" }, { "stage": "verify_tags", "status": "completed", "all_present": true, "task_count": 4 }, { "stage": "collect_commits", "status": "completed", "commit_count": 7 }, { "stage": "collect_implementations", "status": "completed", "files_changed": 15 }, { "stage": "run_tests", "status": "completed", "test_result": "passed" }, { "stage": "review", "status": "approved", "agent": "story-review-agent" }, { "stage": "pr_creation", "status": "completed", "pr_url": "https://github.com/org/repo/pull/42", "pr_number": 42 } ], "result": { "approved": true, "pr_url": "https://github.com/org/repo/pull/42", "tasks_included": ["TASK-1.1", "TASK-1.2", "TASK-1.3", "TASK-1.4"], "commits_included": 7, "files_changed": 15 } } ``` ## Integration with Other Commands ### After /lazy create-feature ```bash # create-feature creates story directory and sets start tag /lazy create-feature "Add OAuth2 authentication" # Creates: ./project-management/US-STORY/US-3.4-oauth2-authentication/ # US-story.md, TASKS/TASK-*.md files # GitHub issues for story and tasks # Sets tag: story/US-3.4-start # Execute all tasks /lazy task-exec TASK-1.1 /lazy task-exec TASK-1.2 /lazy task-exec TASK-1.3 # Review and create PR (using story ID) /lazy story-review US-3.4 ``` ### After /lazy task-exec ```bash # Each task-exec sets a completion tag /lazy task-exec TASK-1.1 # Sets tag: task/TASK-1.1-committed # story-review uses these tags to verify completion /lazy story-review US-3.4 ``` ### Workflow Summary ``` /lazy create-feature ↓ Creates ./project-management/US-STORY/US-X.Y-name/ story/US-X.Y-start tag created GitHub issues created ↓ /lazy task-exec TASK-1.1 → task/TASK-1.1-committed /lazy task-exec TASK-1.2 → task/TASK-1.2-committed /lazy task-exec TASK-1.3 → task/TASK-1.3-committed ↓ /lazy story-review US-X.Y ↓ Verify all tags present ↓ Collect all commits ↓ Review Agent validation ↓ Create PR (if approved) ↓ Close GitHub issues (story + tasks) ``` ## Notes - Story review is **read-only** - no file modifications during review - All validation happens through git tags (immutable markers) - Review agent has complete context (story + tasks + implementations + tests) - PR creation is automatic only if review is approved - Draft mode allows additional manual review before merge - Story state tracking enables iterative review (fix tasks, re-review) - Accepts both story ID (US-X.Y) and full path for backward compatibility - Automatically closes all related GitHub issues (story + all tasks) - Works with new directory structure: `./project-management/US-STORY/US-X.Y-name/` - Task files are individual TASK-*.md files in TASKS subdirectory - GitHub issue numbers extracted from story and task files