---
# Stage identity per spec Section 6.1
stage: 2
stage_id: "02"
title: "Remediation"
workflow: review
estimated_tokens: 2000

# Context specification
context:
  static:
    persona: "careful engineer fixing review findings with minimal changes"
    purpose: "Fix all issues from review, run gates, then return to Stage 1 for re-review"
  dynamic:
    - key: feature_dir
      source: cli_arg
    - key: review_scope
      source: cli_arg
      default: ""
    - key: review_focus
      source: cli_arg
      default: ""
    - key: scope_files
      source: cli_arg
      default: ""
    - key: iterations
      source: cli_arg
    - key: max_agents
      source: cli_arg
      default: 5

# Sub-agent architecture for context efficiency (informational metadata, not parsed by engine)
# Actual sub-agent instructions are in the prompt body below
sub_agent:
  enabled: true
  purpose: "Fix files in parallel, preserving main agent context"
  max_concurrent: "{max_agents}"
  checkpoint_after_batch: true
  sub_agent_receives:
    - file_path: "The file to fix"
    - issues: "List of issues to fix in this file"
    - review_focus: "Focus area: security | correctness | integration | full"
    - scope_boundary: "Files allowed to modify"
  sub_agent_returns:
    - file_path: "Fixed file path"
    - issues_fixed: "Number of issues fixed"
    - issues_skipped: "Number of issues skipped with reasons"
    - issues_deferred: "Number of issues requiring out-of-scope changes"
    - status: "success | partial | failed"
    - error: "Error message if failed"

# Execution flow with step types
execution_flow:
  - step: 1
    type: action
    name: load_scope
    instruction: "Load scope and findings from CLI args"
    output_variable: scope_config
  - step: 2
    type: action
    name: create_todo
    instruction: "Create TODO list from findings organized by severity"
    output_variable: todo_list
  - step: 3
    type: action
    name: recall_cache
    instruction: "Recall cached understanding for each file being fixed"
  - step: 3.5
    type: action
    name: pre_flight_checks
    instruction: "Impact analysis and test planning before making edits"
    actions:
      - "quality(action=\"impact\") for each symbol being changed"
      - "tests(action=\"for_file\") to identify test coverage"
      - "tests(action=\"recommended\") to plan verification"
      - "Check repo_guidelines for project-specific patterns"
      - "Group fixes by testability and blast radius"
    output_variable: impact_plan
  - step: 4
    type: parallel
    name: fix_issues
    instruction: "Spawn sub-agents to fix files in parallel (max {max_agents} concurrent)"
    max_concurrent: "{max_agents}"
    checkpoint: true
  - step: 5
    type: action
    name: aggregate_results
    instruction: "Collect results from sub-agents, report progress"
  - step: 6
    type: action
    name: run_gates
    instruction: "Run quality gates (lint, types, build, tests)"
    output_variable: gates_passed
  - step: 7
    type: action
    name: learning_loop
    instruction: "Update memory/review-patterns.md with discovered patterns and learnings"
    actions:
      - "Capture discovered patterns (what to check in future reviews)"
      - "Document remediation gotchas (what broke during fixes)"
      - "Record repo-specific rules (project conventions discovered)"
    output_variable: learning_summary
  - step: 8
    type: action
    name: commit_fixes
    instruction: "Commit fixed files with appropriate message"
  - step: 9
    type: action
    name: generate_summary
    instruction: "Generate remediation summary"
    output_variable: summary

# Guardrails
guardrails:
  enforcement: active
  allowed_tools:
    - civyk-repoix
    - Read
    - Edit
    - Write
    - Grep
    - Glob
    - Bash
  forbidden_actions:
    - "Delete production source files"
    - "Make changes outside SCOPE_FILES"
    - "Push to remote without user confirmation"
    - "Add features beyond what's needed to fix issues"
  file_restrictions:
    allowed_paths:
      - "{scope_files}"
    forbidden_paths:
      - ".env"
      - "**/*.key"
      - "**/credentials*"
  read_only: false

# Post-validation checks
post_validation:
  - check: issues_fixed
    description: "All critical/high issues from review report remediated"
    severity: error
  - check: gates_passed
    description: "Quality gates (lint, types, build, tests) pass after fixes"
    severity: error
  - check: fixes_committed
    description: "Fixed files committed with descriptive message"
    severity: error

# Output specification
output:
  state_update:
    review.current_stage: "02-remediation"
  completion_command: "civyk-hatch update-stage review 02 --status completed"

# Next stage - loops back to 01 until review passes
next:
  stage: 1
  stage_id: "01"
  command: "civyk-hatch review --stage=1"
  auto_continue: true
  is_terminal: false
  condition: "review did not pass"
version: 1.0.0
---
{{include:strict-execution-mode-lite.md}}

{{include:ai-cache-enforcement.md}}

# Remediation

Fix all issues from review, run gates, then return to Stage 1 for re-review.

---

## Rules

- Fix all issues before running gates
- Read file before modifying (no blind edits)
- Always return to Stage 1 after fixes (loop ends when review passes)
- Stay within scope (only fix files in `SCOPE_FILES`)

---

## Step 1: Load Scope and Findings

Load from CLI args:

- `REVIEW_SCOPE`: branch | staged | commits | files | uncommitted
- `REVIEW_FOCUS`: full | security | correctness | integration
- `SCOPE_FILES`: list of files in scope

---

## Step 2: Create TODO from Findings

```text
TODO (Iteration {iterations})
=============================
Focus: {REVIEW_FOCUS}
Scope: {REVIEW_SCOPE} ({file_count} files)

CRITICAL: [ ] Issue - file:line
HIGH:     [ ] Issue - file:line
MEDIUM:   [ ] Issue - file:line
LOW:      [ ] Issue - file:line
```

If findings were truncated: re-run Stage 1 first.

---

## Step 3: Recall Cache

```text
understand(action="recall", target="<file_path>")
# Use cached understanding to inform fixes
```

---

## Step 3.5: Pre-Flight Checks

**Before making ANY edits, perform impact analysis to prevent cascading failures.**

This step identifies:

- All call sites that will be affected
- Tests that need updating
- Repo-specific patterns to follow
- Optimal fix grouping strategy

### 3.5.1 Impact Analysis for Each Change

**For each significant symbol being modified:**

```text
# MCP mode:
quality(action="impact", fqn="path.to.function", depth=3, include_tests=true)
symbol(action="callers", fqn="path.to.function", depth=2)
symbol(action="references", fqn="path.to.symbol")

# CLI mode:
civyk-repoix query quality --action impact --fqn "path.to.function" --depth 3 --include-tests true
civyk-repoix query symbol --action callers --fqn "path.to.function" --depth 2
civyk-repoix query symbol --action references --fqn "path.to.symbol"
```

**Document the blast radius:**

```text
File: src/auth/login.py
Symbol: authenticate(username, password)
Issue: [HIGH] Missing timeout parameter

Impact Analysis:
- Callers: 12 functions across 8 files
- Tests: 8 test functions
- Blast radius: HIGH
- Breaking change: Adding required parameter will break all callers
- Mitigation: Add optional parameter with default value
```

### 3.5.2 Test Planning

**Identify existing test coverage:**

```text
# MCP mode:
tests(action="for_file", path="src/auth/login.py", include_indirect=true)
tests(action="recommended", changed_files=["src/auth/login.py", "src/api/routes.py"])

# CLI mode:
civyk-repoix query tests --action for_file --path "src/auth/login.py" --include-indirect true
civyk-repoix query tests --action recommended --changed-files "src/auth/login.py" "src/api/routes.py"
```

**Plan verification strategy:**

```text
After fixes, run these tests to verify:
- test_auth_login.py::test_authenticate_success
- test_auth_login.py::test_authenticate_timeout
- test_api_routes.py::test_login_endpoint
(+ 5 more tests)

Estimated test time: 3-5 seconds
```

### 3.5.3 Follow Repo Standards

**Check repo guidelines from context:**

```text
# From context (loaded by context_loader.py):
{repo_guidelines}

# If repo_guidelines exists, extract relevant patterns:
# - Disposal: Check standard pattern for IDisposable/IAsyncDisposable
# - Null checks: Use ArgumentNullException.ThrowIfNull() if available
# - Error handling: Follow repo's exception handling convention
# - Naming: Follow repo's naming conventions

Example from pyproject.toml:
[tool.ruff]
line-length = 100

# Action: Ensure all edits respect 100-char line length
```

### 3.5.4 Atomic Change Grouping

**Group fixes by testability and independence:**

```text
Group 1 (Independent fixes - can run tests after each):
- File: src/auth/login.py
  - [CRITICAL] SQL injection fix
  - [HIGH] Missing null check
  Tests: test_auth_login.py

Group 2 (Coordinated fixes - must fix together):
- Files: src/api/routes.py, src/api/handlers.py
  - [HIGH] Inconsistent error handling
  - [MEDIUM] Missing timeout in related calls
  Tests: test_api_integration.py

Group 3 (Low-risk fixes - batch together):
- Multiple files with magic numbers
  Tests: None needed (linter will catch issues)
```

**Benefits:**

- Easier to debug if build/test fails
- Clear checkpoint after each group
- Prevents mixing unrelated changes

### 3.5.5 Consolidate Impact Plan

```text
impact_plan = {
  "high_impact_changes": [
    {
      "file": "src/auth/login.py",
      "symbol": "authenticate",
      "callers": 12,
      "tests": 8,
      "mitigation": "Use optional parameter with default"
    }
  ],
  "test_strategy": {
    "tests_to_run": ["test_auth_login.py", "test_api_routes.py"],
    "estimated_time": "5s"
  },
  "repo_standards": {
    "line_length": 100,
    "disposal_pattern": "using statement",
    "null_check_pattern": "ArgumentNullException.ThrowIfNull()"
  },
  "fix_groups": [
    {"files": ["src/auth/login.py"], "independent": true},
    {"files": ["src/api/routes.py", "src/api/handlers.py"], "coordinated": true}
  ]
}
```

---

## Step 4: Fix Each Issue (Sub-Agent Pattern)

**CRITICAL: Use sub-agents to preserve main orchestrator context.**

The orchestrator (you) spawns sub-agents for each file with issues. This saves context because:

- Main agent only tracks high-level progress
- Sub-agents handle the detailed fix implementation
- Results are aggregated back to main agent

### 4.1 Group Issues by File

From the TODO list, group issues by file:

```text
File: src/auth/login.py
  - [CRITICAL] F-001: SQL injection risk
  - [HIGH] F-002: Missing null check

File: src/api/routes.py
  - [MEDIUM] F-003: Inconsistent error handling
```

### 4.2 Spawn Sub-Agents in Parallel

For each file with issues, spawn a sub-agent:

```text
# Orchestrator spawns sub-agents (max {max_agents} concurrent)
PARALLEL FOR file_group in issues_by_file:
    spawn_sub_agent(
        prompt="""
        Fix issues in: {file_group.file_path}
        Issues to fix: {file_group.issues}
        Review focus: {REVIEW_FOCUS}

        Instructions:
        1. Read the file content
        2. Implement minimal fix for each issue
        3. Verify fix (single test or linter if applicable)
        4. Return: issues_fixed, issues_skipped, issues_deferred

        Rules:
        - Minimal changes only (no refactoring)
        - Stay within scope (only {SCOPE_FILES})
        - Skip with evidence if not an issue
        - Defer if requires out-of-scope changes
        """,
        tools=[Read, Edit, Write, Bash]
    )
```

### 4.3 Real-Time Progress (Orchestrator)

**After EACH sub-agent completes:**

```text
OUTPUT: "[{completed}/{total}] [ok] {file_path} - {status}"

# Example outputs:
"[1/4] [ok] src/auth/login.py - fixed 2/2 issues"
"[2/4] [ok] src/api/routes.py - fixed 1/1 issues"
"[3/4] [warn] src/services/user.py - fixed 1, skipped 1 (not an issue)"
"[4/4] [err] src/handlers/auth.py - failed: parse error"
```

**Update TODO for visual progress:**

```text
TodoWrite: "Fixing issues: {completed}/{total} files ({pct}%)"
```

### 4.4 Checkpoint After Each Batch

```text
understand(action="store",
    scope="project",
    target="remediation-checkpoint",
    purpose="Remediation workflow checkpoint",
    importance="high",
    key_points=[
        "files_done: {completed}",
        "files_remaining: {remaining}",
        "issues_fixed: {total_fixed}",
        "issues_skipped: {total_skipped}"
    ],
    gotchas=["Resume with: civyk-hatch review --stage=2 --resume"]
)
```

### 4.5 Handle Sub-Agent Failures

```text
IF sub_agent.status == "failed":
    errors.append({file: sub_agent.file_path, error: sub_agent.error})
    CONTINUE  # Don't fail entire workflow

# After all agents complete:
IF errors:
    OUTPUT: "=== ERRORS (will retry on next iteration) ==="
    FOR error in errors:
        OUTPUT: "  - {error.file}: {error.error}"
```

### 4.6 Sub-Agent Fix Criteria

For each issue:

1. Read the code (understand context)
2. Implement minimal fix (smallest change needed)
3. Verify fix (single test or linter check)
4. Mark complete: `[X] Fixed: {description}`

Skip with evidence: `[SKIP] Not an issue - {proof/reason}`

**Fix quality:**

- No features beyond what's needed
- No refactoring surrounding code
- Delete unused code completely

**Scope boundary:**

- Only fix files in `SCOPE_FILES`
- If fix requires changes outside scope, note as: `[DEFER] Requires changes to {file} (out of scope)`

---

## Step 5: Aggregate Results

The orchestrator collects and aggregates results from all sub-agents:

```text
=== REMEDIATION PROGRESS ===

Files processed: {total_files}
Issues fixed: {total_fixed}
Issues skipped: {total_skipped} (with evidence)
Issues deferred: {total_deferred} (out of scope)
Errors: {error_count}

{IF errors:}
Errors will be retried on next iteration.
{END IF}
```

---

## Step 6: Quality Gates

**Run once after all fixes. ALL gates must pass before proceeding.**

### 6.1 Build Verification

**Language-specific build commands:**

```bash
# .NET:
dotnet build {solution_file} -c Release

# Node.js:
npm run build
# OR: pnpm build
# OR: yarn build

# Python:
python -m compileall {changed_files}
# OR: poetry build (if package)

# Go:
go build ./...

# Rust:
cargo build --release
```

**Gate Requirement:** Build MUST pass with zero errors and zero warnings.

**If build fails:**

- Read error message carefully
- Fix the root cause (don't just suppress warnings)
- Re-run build to verify
- DO NOT proceed if build fails

### 6.2 Test Verification

**Run tests for changed files:**

```bash
# .NET:
dotnet test --filter "FullyQualifiedName~{changed_namespace}"

# Node.js:
npm test -- --testPathPattern={file_pattern}
# OR: jest --testPathPattern={pattern}

# Python:
pytest {test_files}
# OR: pytest -k {pattern}

# Go:
go test ./path/to/changed/package/...

# Rust:
cargo test --package {package_name}
```

**Gate Requirement:** Tests MUST pass with no failures.

**If tests fail:**

- Analyze the failure - don't just update test expectations
- Determine if fix broke logic or if test needs updating
- If logic is correct: Fix the implementation
- If test is outdated: Update test (with evidence)
- Re-run tests to verify
- DO NOT proceed if tests fail

### 6.3 Lint Verification

**Language-specific linters:**

```bash
# .NET:
dotnet format verify {solution_file}
# Auto-fix: dotnet format {solution_file}

# TypeScript/JavaScript:
npm run lint
# Auto-fix: npm run lint -- --fix
# OR: eslint {files} --fix

# Python:
ruff check {files}
# Auto-fix: ruff check --fix {files}
# OR: pylint {files}

# Markdown:
markdownlint **/*.md
# Auto-fix: markdownlint --fix **/*.md

# Go:
golangci-lint run ./...

# Rust:
cargo clippy -- -D warnings
```

**Gate Requirement:** Linters MUST pass with zero issues.

**Process:**

1. Run linter with auto-fix first (if available)
2. Commit auto-fix changes
3. Run linter again to verify
4. Fix remaining issues manually if needed
5. DO NOT proceed if linter fails

### 6.4 Type Check Verification (if applicable)

**Language-specific type checkers:**

```bash
# TypeScript:
tsc --noEmit

# Python:
mypy {files}
# OR: pyright {files}

# Flow (JavaScript):
flow check
```

**Gate Requirement:** Type checker MUST pass with zero errors.

**If type check fails:**

- Add missing type annotations
- Fix type mismatches
- DO NOT use type: ignore unless absolutely necessary (with comment explaining why)

### 6.5 Gate Failure Handling

**CRITICAL: If ANY gate fails, BLOCK remediation completion.**

```text
IF build_failed OR test_failed OR lint_failed OR typecheck_failed:
    OUTPUT: "=== GATE FAILURE ==="
    OUTPUT: "Gate: {gate_name}"
    OUTPUT: "Error: {error_message}"
    OUTPUT: ""
    OUTPUT: "Remediation BLOCKED until gates pass."
    OUTPUT: "Fix the issue and re-run this step."
    STOP  # Do not proceed to commit
```

### 6.6 All Gates Passed

**Only if all gates pass:**

```text
=== ALL GATES PASSED ===
[PASS] Build
[PASS] Tests ({N} tests)
[PASS] Lint
[PASS] Types

Proceeding to commit...
```

---

## Step 7: Learning Loop

**After workflow completion, update learning memory for continuous improvement.**

This step captures patterns discovered during review and remediation, making future reviews more effective.

### 7.1 Discovered Patterns

**Capture patterns found during review that should be checked in all future reviews:**

```text
# Patterns discovered this iteration:
patterns = [
  "Always check timeout on HttpClient.GetAsync()",
  "CancellationTokenSource must be disposed (use using statement)",
  "Magic numbers in retry logic (should be constants)",
  "Missing null checks on public API parameters"
]

# Add to memory/review-patterns.md under "Patterns to Watch"
```

**Format:**

```markdown
## Patterns to Watch

- [ ] Always check: HTTP calls have timeout parameter
- [ ] Always check: IDisposable/CancellationTokenSource properly disposed
- [ ] Always check: Magic numbers in retry/timeout logic
- [ ] Always check: Null checks on public API parameters
```

### 7.2 Remediation Gotchas

**Document what broke during remediation and how to avoid it:**

```text
# Gotchas discovered this iteration:
gotchas = [
  "Adding ILogger parameter breaks test constructors - plan test updates first",
  "Changing method signature affects 10+ callers - use optional params with defaults",
  "Disposal using statement changes indentation - re-run formatter after",
  "Adding timeout to HttpClient breaks existing mocks - update mocks first"
]

# Add to memory/review-patterns.md under "Remediation Gotchas"
```

**Format:**

```markdown
## Remediation Gotchas

- **Adding ILogger to constructors**: Breaks all test constructors. Plan test updates before implementation.
- **Changing method signatures**: High blast radius. Use optional parameters with defaults to minimize impact.
- **Disposal patterns**: Using statement changes indentation. Run formatter after implementation.
- **HttpClient timeout**: Breaks mocks. Update test mocks first, then implementation.
```

### 7.3 Repo-Specific Rules

**Capture project-specific conventions discovered:**

```text
# Repo rules discovered this iteration:
rules = [
  "Repo uses custom RetryPolicy wrapper - don't add raw Polly",
  "Error handling: Use Result<T> pattern, not exceptions",
  "Logging: Use structured logging with semantic properties",
  "Timeout defaults: API calls = 30s, DB queries = 5s, external services = 60s"
]

# Add to memory/review-patterns.md under "Repo-Specific Rules"
```

**Format:**

```markdown
## Repo-Specific Rules

- **Retry logic**: Use custom RetryPolicy wrapper (located in src/common/retry.py), NOT raw Polly
- **Error handling**: Prefer Result<T> pattern over exceptions (see src/common/result.py)
- **Logging**: Structured logging with semantic properties (logger.info("event", {"key": "value"}))
- **Timeout defaults**: API=30s, DB=5s, External=60s (see src/config/timeouts.py)
```

### 7.4 Update Memory File

**Write or append to memory/review-patterns.md:**

```bash
# Create file if it doesn't exist
if [ ! -f memory/review-patterns.md ]; then
  cat > memory/review-patterns.md <<'EOF'
# Review Patterns - Learned from Code Reviews

This file captures patterns, gotchas, and repo-specific rules discovered during code reviews.
Used to improve future review accuracy and reduce iteration count.

## Patterns to Watch

## Remediation Gotchas

## Repo-Specific Rules

EOF
fi

# Append discoveries (with timestamp)
echo "" >> memory/review-patterns.md
echo "## Discovered on $(date +%Y-%m-%d)" >> memory/review-patterns.md
echo "" >> memory/review-patterns.md
# ... append patterns, gotchas, rules ...
```

**File Location:** `memory/review-patterns.md` (repo root)

### 7.5 Consolidate Learning Summary

```text
learning_summary = {
  "patterns_discovered": {patterns},
  "remediation_gotchas": {gotchas},
  "repo_rules": {rules},
  "memory_file_updated": "memory/review-patterns.md",
  "next_review_benefit": "These patterns will be pre-loaded in Step 3.5 of next review"
}
```

**Benefit for Next Review:**

- Pre-review context (Step 3.5 in 01-review.md) will load this file
- Domain agents will check these patterns proactively
- Reduces "discovered in review N, missed in review N-1" issues
- Continuous improvement cycle

---

## Step 8: Commit

```bash
git status --porcelain | grep '^ M\|^M ' | cut -c4- | xargs git add

git commit -m "$(cat <<'EOF'
fix({focus}): review findings (iteration {iterations})

Scope: {REVIEW_SCOPE}
Focus: {REVIEW_FOCUS}
Fixed:
- [CRITICAL] description
- [HIGH] description
EOF
)"
```

Commit message prefix by focus:

- Security: `fix(security):`
- Correctness: `fix:`
- Integration: `fix(api):` or `fix(integration):`
- Full: `fix:`

Avoid `git add -A` (may include .env, credentials).

---

## Step 9: Summary

```text
Remediation Complete (Iteration {iterations})
Scope: {REVIEW_SCOPE} | Focus: {REVIEW_FOCUS}
Critical: [N] | High: [N] | Medium: [N] | Low: [N]
Fixed: [N] | Skipped: [N] | Deferred: [N]
```

---

## [AUTO-CONTINUE]

After remediation, automatically return to Stage 1 to re-review (loop until all issues resolved).

## NEXT

```bash
civyk-hatch review --stage=1 --iterations={next_iteration} \
  --review-scope={REVIEW_SCOPE} \
  --review-focus={REVIEW_FOCUS} \
  --scope-files="{SCOPE_FILES}"
```
