* feat: add /gsd:code-review and /gsd:code-review-fix commands Closes #1636 Add two new slash commands that close the gap between phase execution and verification. After /gsd:execute-phase completes, /gsd:code-review reviews produced code for bugs, security issues, and quality problems. /gsd:code-review-fix then auto-fixes issues found by the review. ## New Files - agents/gsd-code-reviewer.md — Review agent with 3 depth levels (quick/standard/deep) and structured REVIEW.md output - agents/gsd-code-fixer.md — Fix agent with atomic git rollback, 3-tier verification, per-finding atomic commits, logic-bug flagging - commands/gsd/code-review.md — Slash command definition - commands/gsd/code-review-fix.md — Slash command definition - get-shit-done/workflows/code-review.md — Review orchestration: 3-tier file scoping, repo-boundary path validation, config gate - get-shit-done/workflows/code-review-fix.md — Fix orchestration: --all/--auto flags, 3-iteration cap, artifact backup across iterations - tests/code-review.test.cjs — 35 tests covering agents, commands, workflows, config, integration, rollback strategy, and logic-bug flagging ## Modified Files - get-shit-done/bin/lib/config.cjs — Register workflow.code_review and workflow.code_review_depth with defaults and typo suggestions - get-shit-done/workflows/execute-phase.md — Add code_review_gate step (PIPE-01): runs after aggregate_results, advisory only, non-blocking - get-shit-done/workflows/quick.md — Add Step 6.25 code review (PIPE-03): scopes via git diff, uses gsd-code-reviewer, advisory only - get-shit-done/workflows/autonomous.md — Add Step 3c.5 review+fix chain (PIPE-02): auto-chains code-review-fix --auto when issues found ## Design Decisions - Rollback uses git checkout -- {file} (atomic) not Write tool (partial write risk) - Logic-bug fixes flagged "requires human verification" (syntax check cannot verify semantics) - Path traversal guard rejects --files paths outside repo root - Fail-closed scoping: no HEAD~N heuristics when scope is ambiguous Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * feat: add /gsd:code-review and /gsd:code-review-fix commands Closes #1636 Add two new slash commands that close the gap between phase execution and verification. After /gsd:execute-phase completes, /gsd:code-review reviews produced code for bugs, security issues, and quality problems. /gsd:code-review-fix then auto-fixes issues found by the review. ## New Files - agents/gsd-code-reviewer.md — Review agent: 3 depth levels, REVIEW.md - agents/gsd-code-fixer.md — Fix agent: git rollback, 3-tier verification, logic-bug flagging, per-finding atomic commits - commands/gsd/code-review.md, code-review-fix.md — Slash command definitions - get-shit-done/workflows/code-review.md — Review orchestration: 3-tier file scoping, path traversal guard, config gate - get-shit-done/workflows/code-review-fix.md — Fix orchestration: --all/--auto flags, 3-iteration cap, artifact backup - tests/code-review.test.cjs — 35 tests: agents, commands, workflows, config, integration, rollback, logic-bug flagging ## Modified Files - get-shit-done/bin/lib/config.cjs — Register workflow.code_review and workflow.code_review_depth config keys - get-shit-done/workflows/execute-phase.md — Add code_review_gate step (PIPE-01): after aggregate_results, advisory, non-blocking - get-shit-done/workflows/quick.md — Add Step 6.25 code review (PIPE-03): git diff scoping, gsd-code-reviewer, advisory - get-shit-done/workflows/autonomous.md — Add Step 3c.5 review+fix chain (PIPE-02): auto-chains code-review-fix --auto when issues found ## Design decisions - Rollback uses git checkout -- {file} (atomic) not Write tool - Logic-bug fixes flagged requires human verification (syntax != semantics) - --files paths validated within repo root (path traversal guard) - Fail-closed: no HEAD~N heuristics when scope ambiguous Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: resolve contradictory rollback instructions in gsd-code-fixer rollback_strategy said git checkout, critical_rules said Write tool. Align all three sections (rollback_strategy, execution_flow step b, critical_rules) to use git checkout -- {file} consistently. Also remove in-memory PRE_FIX_CONTENT capture — no longer needed since git checkout is the rollback mechanism. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: address all review feedback from rounds 3-4 Blocking (bash compatibility): - Replace mapfile -t with portable while IFS= read -r loops in both workflows (mapfile is bash 4+; macOS ships bash 3.2 by default) - Add macOS bash version note to platform_notes Blocking (quick.md scope heuristic): - Replace fragile HEAD~$(wc -l SUMMARY.md) with git log --grep based diff, matching the more robust approach in code-review.md Security (path traversal): - Document realpath -m macOS behavior in platform_notes; guard remains fail-closed on macOS without coreutils Logic / correctness: - Fix REVIEW_PATH / FIX_REPORT_PATH interpolation in node -e strings; use process.env.REVIEW_PATH via env var prefix to avoid single-quote path injection risk - Add iteration semantics comment clarifying off-by-one behavior - Remove duplicate "3. Determine changed files" heading in gsd-code-reviewer.md Agent: - Add logic-bug limitation section to gsd-code-fixer verification_strategy Tests (39 total, up from 32): - Add rollback uses git checkout test - Add success_criteria consistency test (must not say Write tool) - Add logic-bug flagging test - Add files_reviewed_list spec test - Add path traversal guard structural test - Add mapfile-in-bash-blocks tests (bash 3.2 compatibility) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: add gsd-code-reviewer to quick.md available_agent_types and copilot install test - quick.md Step 6.25 spawns gsd-code-reviewer but the workflow's <available_agent_types> block did not list it, failing the spawn consistency CI check (#1357) - copilot-install.test.cjs hardcoded agent list was missing gsd-code-fixer.agent.md and gsd-code-reviewer.agent.md, failing the Copilot full install verification test Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: replace /gsd: colon refs with /gsd- hyphen format in new files Fixes stale-colon-refs CI test (#1748). All 19 violations replaced: - agents/gsd-code-fixer.md (2): description + role spawned-by text - agents/gsd-code-reviewer.md (4): description + role + fallback note + error msg - get-shit-done/workflows/code-review-fix.md (7): error msgs + retry suggestions - get-shit-done/workflows/code-review.md (5): error msgs + retry suggestions - get-shit-done/workflows/execute-phase.md (1): code_review_gate suggestion Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
498 lines
18 KiB
Markdown
498 lines
18 KiB
Markdown
<purpose>
|
|
Auto-fix issues from REVIEW.md. Validates phase, checks config gate, verifies REVIEW.md exists and has fixable issues, spawns gsd-code-fixer agent, handles --auto iteration loop (capped at 3), commits REVIEW-FIX.md once at the end, and presents results.
|
|
</purpose>
|
|
|
|
<required_reading>
|
|
Read all files referenced by the invoking prompt's execution_context before starting.
|
|
</required_reading>
|
|
|
|
<available_agent_types>
|
|
- gsd-code-fixer: Applies fixes to code review findings
|
|
- gsd-code-reviewer: Reviews source files for bugs and issues
|
|
</available_agent_types>
|
|
|
|
<process>
|
|
|
|
<step name="initialize">
|
|
Parse arguments and load project state:
|
|
|
|
```bash
|
|
PHASE_ARG="${1}"
|
|
INIT=$(node "$HOME/.claude/get-shit-done/bin/gsd-tools.cjs" init phase-op "${PHASE_ARG}")
|
|
if [[ "$INIT" == @file:* ]]; then INIT=$(cat "${INIT#@file:}"); fi
|
|
```
|
|
|
|
Parse from init JSON: `phase_found`, `phase_dir`, `phase_number`, `phase_name`, `padded_phase`, `commit_docs`.
|
|
|
|
**Input sanitization (defense-in-depth):**
|
|
```bash
|
|
# Validate PADDED_PHASE contains only digits and optional dot (e.g., "02", "03.1")
|
|
if ! [[ "$PADDED_PHASE" =~ ^[0-9]+(\.[0-9]+)?$ ]]; then
|
|
echo "Error: Invalid phase number format: '${PADDED_PHASE}'. Expected digits (e.g., 02, 03.1)."
|
|
# Exit workflow
|
|
fi
|
|
```
|
|
|
|
**Phase validation (before config gate):**
|
|
If `phase_found` is false, report error and exit:
|
|
```
|
|
Error: Phase ${PHASE_ARG} not found. Run /gsd-status to see available phases.
|
|
```
|
|
|
|
This runs BEFORE config gate check so user errors are surfaced immediately regardless of config state.
|
|
|
|
Parse optional flags from $ARGUMENTS:
|
|
|
|
```bash
|
|
FIX_ALL=false
|
|
AUTO_MODE=false
|
|
for arg in "$@"; do
|
|
if [[ "$arg" == "--all" ]]; then FIX_ALL=true; fi
|
|
if [[ "$arg" == "--auto" ]]; then AUTO_MODE=true; fi
|
|
done
|
|
```
|
|
|
|
Compute scope variable:
|
|
|
|
```bash
|
|
if [ "$FIX_ALL" = "true" ]; then
|
|
FIX_SCOPE="all"
|
|
else
|
|
FIX_SCOPE="critical_warning"
|
|
fi
|
|
```
|
|
|
|
Compute review and fix report paths:
|
|
|
|
```bash
|
|
REVIEW_PATH="${PHASE_DIR}/${PADDED_PHASE}-REVIEW.md"
|
|
FIX_REPORT_PATH="${PHASE_DIR}/${PADDED_PHASE}-REVIEW-FIX.md"
|
|
```
|
|
</step>
|
|
|
|
<step name="check_config_gate">
|
|
Check if code review is enabled via config:
|
|
|
|
```bash
|
|
CODE_REVIEW_ENABLED=$(node "$HOME/.claude/get-shit-done/bin/gsd-tools.cjs" config-get workflow.code_review 2>/dev/null || echo "true")
|
|
```
|
|
|
|
If CODE_REVIEW_ENABLED is "false":
|
|
```
|
|
Code review fix skipped (workflow.code_review=false in config)
|
|
```
|
|
Exit workflow.
|
|
|
|
Default is true — only skip on explicit false. This check runs AFTER phase validation so invalid phase errors are shown first.
|
|
|
|
Note: This reuses the `workflow.code_review` config key rather than introducing a separate `workflow.code_review_fix` key. Rationale: fixes are meaningless without review, so a single toggle makes sense. If independent control is needed later, a separate key can be added in v2.
|
|
</step>
|
|
|
|
<step name="check_review_exists">
|
|
Verify that REVIEW.md exists:
|
|
|
|
```bash
|
|
if [ ! -f "${REVIEW_PATH}" ]; then
|
|
echo "Error: No REVIEW.md found for Phase ${PHASE_ARG}. Run /gsd-code-review ${PHASE_ARG} first."
|
|
exit 1
|
|
fi
|
|
```
|
|
|
|
Do NOT auto-run code-review. Require explicit user action to ensure review intent is clear.
|
|
</step>
|
|
|
|
<step name="check_review_status">
|
|
Parse REVIEW.md frontmatter to check status and extract context for --auto loop:
|
|
|
|
```bash
|
|
# Parse status field
|
|
REVIEW_STATUS=$(REVIEW_PATH="${REVIEW_PATH}" node -e "
|
|
const fs = require('fs');
|
|
const content = fs.readFileSync(process.env.REVIEW_PATH, 'utf-8');
|
|
const match = content.match(/^---\n([\s\S]*?)\n---/);
|
|
if (match && /status:\s*(\S+)/.test(match[1])) {
|
|
console.log(match[1].match(/status:\s*(\S+)/)[1]);
|
|
} else {
|
|
console.log('unknown');
|
|
}
|
|
" 2>/dev/null)
|
|
```
|
|
|
|
If status is "clean" or "skipped":
|
|
```
|
|
No issues to fix in Phase ${PHASE_ARG} REVIEW.md (status: ${REVIEW_STATUS}).
|
|
```
|
|
Exit workflow.
|
|
|
|
If status is "unknown":
|
|
```
|
|
Warning: Could not parse REVIEW.md status. Proceeding with fix attempt.
|
|
```
|
|
|
|
Extract review depth for --auto re-review:
|
|
|
|
```bash
|
|
REVIEW_DEPTH=$(REVIEW_PATH="${REVIEW_PATH}" node -e "
|
|
const fs = require('fs');
|
|
const content = fs.readFileSync(process.env.REVIEW_PATH, 'utf-8');
|
|
const match = content.match(/^---\n([\s\S]*?)\n---/);
|
|
if (match && /depth:\s*(\S+)/.test(match[1])) {
|
|
console.log(match[1].match(/depth:\s*(\S+)/)[1]);
|
|
} else {
|
|
console.log('standard');
|
|
}
|
|
" 2>/dev/null)
|
|
```
|
|
|
|
Extract original review file list for --auto re-review scope persistence:
|
|
|
|
```bash
|
|
# Extract review file list — portable bash 3.2+ (no mapfile, handles spaces in paths)
|
|
REVIEW_FILES_ARRAY=()
|
|
while IFS= read -r line; do
|
|
[ -n "$line" ] && REVIEW_FILES_ARRAY+=("$line")
|
|
done < <(REVIEW_PATH="${REVIEW_PATH}" node -e "
|
|
const fs = require('fs');
|
|
const content = fs.readFileSync(process.env.REVIEW_PATH, 'utf-8');
|
|
const match = content.match(/^---\n([\s\S]*?)\n---/);
|
|
if (match) {
|
|
const fm = match[1];
|
|
// Try YAML array format: files_reviewed_list: [file1, file2]
|
|
const bracketMatch = fm.match(/files_reviewed_list:\s*\[([^\]]+)\]/);
|
|
if (bracketMatch) {
|
|
bracketMatch[1].split(',').map(f => f.trim()).filter(Boolean).forEach(f => console.log(f));
|
|
} else {
|
|
// Try YAML list format: files_reviewed_list:\n - file1\n - file2
|
|
let inList = false;
|
|
for (const line of fm.split('\n')) {
|
|
if (/files_reviewed_list:/.test(line)) { inList = true; continue; }
|
|
if (inList && /^\s+-\s+(.+)/.test(line)) { console.log(line.match(/^\s+-\s+(.+)/)[1].trim()); }
|
|
else if (inList && /^\S/.test(line)) { break; }
|
|
}
|
|
}
|
|
}
|
|
" 2>/dev/null)
|
|
```
|
|
|
|
If REVIEW.md contains a `files_reviewed_list` frontmatter field, use that as the re-review scope. If not present, fall back to re-reviewing the full phase (same behavior as initial code-review).
|
|
</step>
|
|
|
|
<step name="spawn_fixer">
|
|
Spawn the gsd-code-fixer agent with config:
|
|
|
|
```bash
|
|
# Build config for agent
|
|
echo "Applying fixes from ${REVIEW_PATH}..."
|
|
echo "Fix scope: ${FIX_SCOPE}"
|
|
```
|
|
|
|
Use Task() to spawn agent:
|
|
|
|
```
|
|
Task(subagent_type="gsd-code-fixer", prompt="
|
|
<files_to_read>
|
|
${REVIEW_PATH}
|
|
</files_to_read>
|
|
|
|
<config>
|
|
phase_dir: ${PHASE_DIR}
|
|
padded_phase: ${PADDED_PHASE}
|
|
review_path: ${REVIEW_PATH}
|
|
fix_scope: ${FIX_SCOPE}
|
|
fix_report_path: ${FIX_REPORT_PATH}
|
|
iteration: 1
|
|
</config>
|
|
|
|
Read REVIEW.md findings, apply fixes, commit each atomically, write REVIEW-FIX.md. Do NOT commit REVIEW-FIX.md (orchestrator handles that).
|
|
")
|
|
```
|
|
|
|
**Agent failure handling:**
|
|
|
|
If Task() fails:
|
|
```
|
|
Error: Code fix agent failed: ${error_message}
|
|
```
|
|
|
|
Check if FIX_REPORT_PATH exists:
|
|
- If yes: "Partial success — some fixes may have been committed."
|
|
- If no: "No fixes applied."
|
|
|
|
Either way:
|
|
```
|
|
Some fix commits may already exist in git history — check git log for fix(${PADDED_PHASE}) commits.
|
|
You can retry with /gsd-code-review-fix ${PHASE_ARG}.
|
|
```
|
|
|
|
Exit workflow (skip auto loop).
|
|
</step>
|
|
|
|
<step name="auto_iteration_loop">
|
|
Only runs if AUTO_MODE is true. If AUTO_MODE is false, skip this step entirely.
|
|
|
|
```bash
|
|
if [ "$AUTO_MODE" = "true" ]; then
|
|
# Iteration semantics: the initial fix pass (step 5) is iteration 1.
|
|
# This loop runs iterations 2..MAX_ITERATIONS (re-review + re-fix cycles).
|
|
# Total fix passes = MAX_ITERATIONS. Loop uses -lt (not -le) intentionally.
|
|
ITERATION=1
|
|
MAX_ITERATIONS=3
|
|
|
|
while [ $ITERATION -lt $MAX_ITERATIONS ]; do
|
|
ITERATION=$((ITERATION + 1))
|
|
|
|
echo ""
|
|
echo "═══════════════════════════════════════════════════════"
|
|
echo " --auto: Starting iteration ${ITERATION}/${MAX_ITERATIONS}"
|
|
echo "═══════════════════════════════════════════════════════"
|
|
echo ""
|
|
|
|
# Re-review using same depth and file scope as original review
|
|
echo "Re-reviewing phase ${PHASE_ARG} at ${REVIEW_DEPTH} depth..."
|
|
|
|
# Backup previous REVIEW.md and REVIEW-FIX.md before overwriting
|
|
if [ -f "${REVIEW_PATH}" ]; then
|
|
cp "${REVIEW_PATH}" "${REVIEW_PATH%.md}.iter${ITERATION}.md" 2>/dev/null || true
|
|
fi
|
|
if [ -f "${FIX_REPORT_PATH}" ]; then
|
|
cp "${FIX_REPORT_PATH}" "${FIX_REPORT_PATH%.md}.iter${ITERATION}.md" 2>/dev/null || true
|
|
fi
|
|
|
|
# If original review had explicit file list, pass it safely to re-review agent
|
|
FILES_CONFIG=""
|
|
if [ ${#REVIEW_FILES_ARRAY[@]} -gt 0 ]; then
|
|
FILES_CONFIG="files:"
|
|
for f in "${REVIEW_FILES_ARRAY[@]}"; do
|
|
FILES_CONFIG="${FILES_CONFIG}
|
|
- ${f}"
|
|
done
|
|
fi
|
|
|
|
# Spawn gsd-code-reviewer agent to re-review
|
|
# (This overwrites REVIEW_PATH with latest review state)
|
|
Task(subagent_type="gsd-code-reviewer", prompt="
|
|
<config>
|
|
depth: ${REVIEW_DEPTH}
|
|
phase_dir: ${PHASE_DIR}
|
|
review_path: ${REVIEW_PATH}
|
|
${FILES_CONFIG}
|
|
</config>
|
|
|
|
Re-review the phase at ${REVIEW_DEPTH} depth. Write findings to ${REVIEW_PATH}.
|
|
Do NOT commit the output — the orchestrator handles that.
|
|
")
|
|
|
|
# Check new REVIEW.md status
|
|
NEW_STATUS=$(REVIEW_PATH="${REVIEW_PATH}" node -e "
|
|
const fs = require('fs');
|
|
const content = fs.readFileSync(process.env.REVIEW_PATH, 'utf-8');
|
|
const match = content.match(/^---\n([\s\S]*?)\n---/);
|
|
if (match && /status:\s*(\S+)/.test(match[1])) {
|
|
console.log(match[1].match(/status:\s*(\S+)/)[1]);
|
|
} else {
|
|
console.log('unknown');
|
|
}
|
|
" 2>/dev/null)
|
|
|
|
if [ "$NEW_STATUS" = "clean" ]; then
|
|
echo ""
|
|
echo "✓ All issues resolved after iteration ${ITERATION}."
|
|
break
|
|
fi
|
|
|
|
# Still has issues — spawn fixer again
|
|
echo "Issues remain. Applying fixes for iteration ${ITERATION}..."
|
|
|
|
Task(subagent_type="gsd-code-fixer", prompt="
|
|
<files_to_read>
|
|
${REVIEW_PATH}
|
|
</files_to_read>
|
|
|
|
<config>
|
|
phase_dir: ${PHASE_DIR}
|
|
padded_phase: ${PADDED_PHASE}
|
|
review_path: ${REVIEW_PATH}
|
|
fix_scope: ${FIX_SCOPE}
|
|
fix_report_path: ${FIX_REPORT_PATH}
|
|
iteration: ${ITERATION}
|
|
</config>
|
|
|
|
Read REVIEW.md findings, apply fixes, commit each atomically, write REVIEW-FIX.md (overwrite previous). Do NOT commit REVIEW-FIX.md.
|
|
")
|
|
|
|
# Check if fixer succeeded
|
|
if [ ! -f "${FIX_REPORT_PATH}" ]; then
|
|
echo "Warning: Iteration ${ITERATION} fixer failed to produce fix report. Stopping auto-loop."
|
|
break
|
|
fi
|
|
done
|
|
|
|
# After loop completes
|
|
if [ $ITERATION -ge $MAX_ITERATIONS ]; then
|
|
echo ""
|
|
echo "⚠ Reached maximum iterations (${MAX_ITERATIONS}). Remaining issues documented in REVIEW-FIX.md."
|
|
fi
|
|
fi
|
|
```
|
|
|
|
Key design decisions for --auto (addresses ALL review HIGH concerns):
|
|
1. **Re-review scope**: Uses REVIEW_FILES_ARRAY from original REVIEW.md frontmatter, falling back to full phase scope. Scope is NOT lost between iterations. Uses portable while-read loop (bash 3.2+ compatible, handles spaces in paths).
|
|
2. **Artifact semantics**: REVIEW.md is overwritten by each re-review (latest review state). REVIEW-FIX.md is overwritten by each fixer iteration (latest fix state with iteration count). There is ONE final version of each artifact, not per-iteration copies.
|
|
Backup files (.iterN.md) preserve history for post-mortem analysis if iterations degrade.
|
|
3. **Commit timing**: Fix commits happen per-finding inside the agent. REVIEW-FIX.md is NOT committed until step 7 (after ALL iterations complete). Only ONE docs commit for REVIEW-FIX.md, not one per iteration.
|
|
</step>
|
|
|
|
<step name="commit_fix_report">
|
|
After ALL iterations complete (or single pass in non-auto mode), validate and commit REVIEW-FIX.md:
|
|
|
|
```bash
|
|
if [ -f "${FIX_REPORT_PATH}" ]; then
|
|
# Validate REVIEW-FIX.md has valid YAML frontmatter with status field
|
|
HAS_STATUS=$(REVIEW_PATH="${REVIEW_PATH}" node -e "
|
|
const fs = require('fs');
|
|
const content = fs.readFileSync(process.env.FIX_REPORT_PATH, 'utf-8');
|
|
const match = content.match(/^---\n([\s\S]*?)\n---/);
|
|
if (match && /status:/.test(match[1])) { console.log('valid'); } else { console.log('invalid'); }
|
|
" 2>/dev/null)
|
|
|
|
if [ "$HAS_STATUS" = "valid" ]; then
|
|
echo "REVIEW-FIX.md created at ${FIX_REPORT_PATH}"
|
|
|
|
if [ "$COMMIT_DOCS" = "true" ]; then
|
|
node "$HOME/.claude/get-shit-done/bin/gsd-tools.cjs" commit \
|
|
"docs(${PADDED_PHASE}): add code review fix report" \
|
|
--files "${FIX_REPORT_PATH}"
|
|
fi
|
|
else
|
|
echo "Warning: REVIEW-FIX.md has invalid frontmatter (no status field). Not committing."
|
|
echo "Agent may have produced malformed output. Review manually: ${FIX_REPORT_PATH}"
|
|
fi
|
|
else
|
|
echo "Warning: REVIEW-FIX.md not found at ${FIX_REPORT_PATH}."
|
|
echo "Agent may have failed before writing report."
|
|
echo "Check git log for any fix(${PADDED_PHASE}) commits that were applied."
|
|
fi
|
|
```
|
|
|
|
This commit happens ONCE at the end of the workflow, after all iterations (if --auto) complete. Not per-iteration.
|
|
</step>
|
|
|
|
<step name="present_results">
|
|
Parse REVIEW-FIX.md frontmatter and present formatted summary to user.
|
|
|
|
First check if fix report exists:
|
|
|
|
```bash
|
|
if [ ! -f "${FIX_REPORT_PATH}" ]; then
|
|
echo ""
|
|
echo "═══════════════════════════════════════════════════════════════"
|
|
echo ""
|
|
echo " ⚠ No fix report generated"
|
|
echo ""
|
|
echo "───────────────────────────────────────────────────────────────"
|
|
echo ""
|
|
echo "The fixer agent may have failed before completing."
|
|
echo "Check git log for any fix(${PADDED_PHASE}) commits."
|
|
echo ""
|
|
echo "Retry: /gsd-code-review-fix ${PHASE_ARG}"
|
|
echo ""
|
|
echo "═══════════════════════════════════════════════════════════════"
|
|
exit 1
|
|
fi
|
|
```
|
|
|
|
Extract frontmatter fields:
|
|
|
|
```bash
|
|
# Extract only the YAML frontmatter block (between first two --- lines)
|
|
FIX_FRONTMATTER=$(REVIEW_PATH="${REVIEW_PATH}" node -e "
|
|
const fs = require('fs');
|
|
const content = fs.readFileSync(process.env.FIX_REPORT_PATH, 'utf-8');
|
|
const match = content.match(/^---\n([\s\S]*?)\n---/);
|
|
if (match) process.stdout.write(match[1]);
|
|
" 2>/dev/null)
|
|
|
|
# Parse fields from frontmatter only (not full file)
|
|
FIX_STATUS=$(echo "$FIX_FRONTMATTER" | grep "^status:" | cut -d: -f2 | xargs)
|
|
FINDINGS_IN_SCOPE=$(echo "$FIX_FRONTMATTER" | grep "^findings_in_scope:" | cut -d: -f2 | xargs)
|
|
FIXED_COUNT=$(echo "$FIX_FRONTMATTER" | grep "^fixed:" | cut -d: -f2 | xargs)
|
|
SKIPPED_COUNT=$(echo "$FIX_FRONTMATTER" | grep "^skipped:" | cut -d: -f2 | xargs)
|
|
ITERATION_COUNT=$(echo "$FIX_FRONTMATTER" | grep "^iteration:" | cut -d: -f2 | xargs)
|
|
```
|
|
|
|
Display formatted inline summary:
|
|
|
|
```bash
|
|
echo ""
|
|
echo "═══════════════════════════════════════════════════════════════"
|
|
echo ""
|
|
echo " Code Review Fix Complete: Phase ${PHASE_NUMBER} (${PHASE_NAME})"
|
|
echo ""
|
|
echo "───────────────────────────────────────────────────────────────"
|
|
echo ""
|
|
echo " Fix Scope: ${FIX_SCOPE}"
|
|
echo " Findings: ${FINDINGS_IN_SCOPE}"
|
|
echo " Fixed: ${FIXED_COUNT}"
|
|
echo " Skipped: ${SKIPPED_COUNT}"
|
|
if [ "$AUTO_MODE" = "true" ]; then
|
|
echo " Iterations: ${ITERATION_COUNT}"
|
|
fi
|
|
echo " Status: ${FIX_STATUS}"
|
|
echo ""
|
|
echo "───────────────────────────────────────────────────────────────"
|
|
echo ""
|
|
```
|
|
|
|
If status is "all_fixed":
|
|
```bash
|
|
if [ "$FIX_STATUS" = "all_fixed" ]; then
|
|
echo "✓ All issues resolved."
|
|
echo ""
|
|
echo "Full report: ${FIX_REPORT_PATH}"
|
|
echo ""
|
|
echo "Next step:"
|
|
echo " /gsd-verify-work — Verify phase completion"
|
|
echo ""
|
|
fi
|
|
```
|
|
|
|
If status is "partial" or "none_fixed":
|
|
```bash
|
|
if [ "$FIX_STATUS" = "partial" ] || [ "$FIX_STATUS" = "none_fixed" ]; then
|
|
echo "⚠ Some issues could not be fixed automatically."
|
|
echo ""
|
|
echo "Full report: ${FIX_REPORT_PATH}"
|
|
echo ""
|
|
echo "Next steps:"
|
|
echo " cat ${FIX_REPORT_PATH} — View fix report"
|
|
echo " /gsd-code-review ${PHASE_NUMBER} — Re-review code"
|
|
echo " /gsd-verify-work — Verify phase completion"
|
|
echo ""
|
|
fi
|
|
```
|
|
|
|
```bash
|
|
echo "═══════════════════════════════════════════════════════════════"
|
|
```
|
|
</step>
|
|
|
|
</process>
|
|
|
|
<platform_notes>
|
|
**Windows:** This workflow uses bash features (arrays, variable expansion, while loops). On Windows, it requires Git Bash or WSL. Native PowerShell is not supported. The CI matrix (Ubuntu/macOS/Windows) runs under Git Bash on Windows runners, which provides bash compatibility.
|
|
</platform_notes>
|
|
|
|
<success_criteria>
|
|
- [ ] Phase validated before config gate check
|
|
- [ ] Config gate checked (workflow.code_review)
|
|
- [ ] REVIEW.md existence verified (error if missing)
|
|
- [ ] REVIEW.md status checked (skip if clean/skipped)
|
|
- [ ] Agent spawned with correct config (review_path, fix_scope, fix_report_path)
|
|
- [ ] Agent failure handled with partial-success awareness (some fix commits may exist)
|
|
- [ ] --auto iteration loop respects 3-iteration cap
|
|
- [ ] --auto re-review uses persisted file scope (not lost between iterations)
|
|
- [ ] REVIEW-FIX.md committed ONCE after all iterations (not per-iteration)
|
|
- [ ] Missing fix report handled with explicit error message in present_results
|
|
- [ ] Results presented inline with next step suggestion
|
|
</success_criteria>
|