Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Prodigy Integration

Debtmap integrates with Prodigy to provide fully automated technical debt reduction through AI-driven workflows. This chapter explains how to set up and use Prodigy workflows to automatically refactor code, add tests, and improve codebase quality.

Prerequisites Checklist

Before using Prodigy with Debtmap, ensure you have:

  • Rust 1.70 or later installed
  • Debtmap installed (cargo install debtmap)
  • Prodigy installed (cargo install --git https://github.com/iepathos/prodigy prodigy)
  • Anthropic API key for Claude access
  • Git (for worktree management)
  • Optional: just command runner (a command runner like make), or use direct cargo commands as alternatives

What is Prodigy?

Note: Prodigy is a separate open-source tool (https://github.com/iepathos/prodigy). You need to install both Debtmap and Prodigy to use this integration.

Prodigy is an AI-powered workflow automation system that uses Claude to execute complex multi-step tasks. When integrated with Debtmap, it can:

  • Automatically refactor high-complexity functions identified by Debtmap
  • Add unit tests for untested code
  • Fix code duplication by extracting shared logic
  • Improve code organization by addressing architectural issues
  • Validate improvements with automated testing

All changes are made in isolated git worktrees, validated with tests and linting, and only committed if all checks pass.

Benefits

Automated Debt Reduction

Instead of manually addressing each technical debt item, Prodigy can:

  1. Analyze Debtmap’s output
  2. Select high-priority items
  3. Generate refactoring plans
  4. Execute refactorings automatically
  5. Validate with tests
  6. Commit clean changes

Iterative Improvement

Prodigy supports iterative workflows:

  • Run analysis → fix top items → re-analyze → fix more
  • Configurable iteration count (default: 5 iterations)
  • Each iteration focuses on highest-priority remaining items

Safe Experimentation

All changes happen in isolated git worktrees:

  • Original branch remains untouched
  • Failed attempts don’t affect main codebase
  • Easy to review before merging
  • Automatic cleanup after workflow

Prerequisites

Install Prodigy

# Install Prodigy from GitHub repository
cargo install --git https://github.com/iepathos/prodigy prodigy

# Verify installation
prodigy --version

Note: Currently, Prodigy must be installed from GitHub. Check the Prodigy repository for the latest installation instructions.

Requirements:

  • Rust 1.70 or later
  • Git (for worktree management)
  • Anthropic API key for Claude access

Configure Claude API

# Set Claude API key
export ANTHROPIC_API_KEY="your-api-key-here"

# Or in ~/.prodigy/config.toml:
[api]
anthropic_key = "your-api-key-here"

Ensure Debtmap is Installed

# Install Debtmap
cargo install debtmap

# Verify installation
debtmap --version

Quick Start

1. Initialize Workflow

Create a workflow file workflows/debtmap.yml:

# Sequential workflow. Fix top technical debt item

# Phase 1: Generate coverage data
- shell: "just coverage-lcov"  # or: cargo tarpaulin --out lcov --output-dir target/coverage

# Phase 2: Analyze tech debt and capture baseline
- shell: "debtmap analyze . --lcov target/coverage/lcov.info --output .prodigy/debtmap-before.json --format json"

# Phase 3: Create implementation plan (PLANNING PHASE)
- claude: "/prodigy-debtmap-plan --before .prodigy/debtmap-before.json --output .prodigy/IMPLEMENTATION_PLAN.md"
  capture_output: true
  validate:
    commands:
      - claude: "/prodigy-validate-debtmap-plan --before .prodigy/debtmap-before.json --plan .prodigy/IMPLEMENTATION_PLAN.md --output .prodigy/plan-validation.json"
    result_file: ".prodigy/plan-validation.json"
    threshold: 75
    on_incomplete:
      commands:
        - claude: "/prodigy-revise-debtmap-plan --gaps ${validation.gaps} --plan .prodigy/IMPLEMENTATION_PLAN.md"
      max_attempts: 3
      fail_workflow: false

# Phase 4: Execute the plan (IMPLEMENTATION PHASE)
- claude: "/prodigy-debtmap-implement --plan .prodigy/IMPLEMENTATION_PLAN.md"
  commit_required: true
  validate:
    commands:
      - shell: "debtmap analyze . --lcov target/coverage/lcov.info --output .prodigy/debtmap-after.json --format json"
      - shell: "debtmap compare --before .prodigy/debtmap-before.json --after .prodigy/debtmap-after.json --plan .prodigy/IMPLEMENTATION_PLAN.md --output .prodigy/comparison.json --format json"
      - shell: "debtmap validate-improvement --comparison .prodigy/comparison.json --output .prodigy/debtmap-validation.json"
    result_file: ".prodigy/debtmap-validation.json"
    threshold: 75
    on_incomplete:
      commands:
        - claude: "/prodigy-complete-debtmap-fix --gaps ${validation.gaps} --plan .prodigy/IMPLEMENTATION_PLAN.md --attempt ${validation.attempt_number}"
          commit_required: true
        - shell: "just coverage-lcov"
        - shell: "debtmap analyze . --lcov target/coverage/lcov.info --output .prodigy/debtmap-after.json --format json"
        - shell: "debtmap compare --before .prodigy/debtmap-before.json --after .prodigy/debtmap-after.json --plan .prodigy/IMPLEMENTATION_PLAN.md --output .prodigy/comparison.json --format json"
      max_attempts: 5
      fail_workflow: true

# Phase 5: Run tests with automatic fixing
- shell: "just test"
  on_failure:
    claude: "/prodigy-debug-test-failure --output ${shell.output}"
    max_attempts: 5
    fail_workflow: true

# Phase 6: Run linting and formatting
- shell: "just fmt-check && just lint"
  on_failure:
    claude: "/prodigy-lint ${shell.output}"
    max_attempts: 5
    fail_workflow: true

Note about just: This example uses just (a command runner like make). If you don’t have a justfile, replace just coverage-lcov with cargo tarpaulin --out lcov --output-dir target/coverage, just test with cargo test, and just fmt-check && just lint with cargo fmt --check && cargo clippy -- -D warnings.

2. Run Workflow

# Run with auto-confirm, 5 iterations
prodigy run workflows/debtmap.yml -yn 5

# Run with custom iteration count
prodigy run workflows/debtmap.yml -yn 10

# Run single iteration for testing
prodigy run workflows/debtmap.yml -yn 1

Command Flags:

  • -y (--yes) - Auto-confirm workflow steps (skip prompts)
  • -n 5 (--max-iterations 5) - Run workflow for up to 5 iterations

Note: Worktrees are managed separately via the prodigy worktree command. In MapReduce mode, Prodigy automatically creates isolated worktrees for each parallel agent.

3. Review Results

Prodigy creates a detailed report:

📊 WORKFLOW SUMMARY
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

Iterations: 5
Items Fixed: 12
Tests Added: 8
Complexity Reduced: 145 → 78 (-46%)
Coverage Improved: 45% → 72% (+27%)

✅ All validations passed

Useful Prodigy Commands

Beyond prodigy run, several commands help manage workflows and sessions:

Resume Interrupted Workflows

# Resume an interrupted sequential workflow
prodigy resume <SESSION_ID>

# Resume an interrupted MapReduce job
prodigy resume-job <JOB_ID>

# List all sessions to find the SESSION_ID
prodigy sessions

When to use: If a workflow is interrupted (Ctrl-C, system crash, network issues), you can resume from the last checkpoint rather than starting over.

View Checkpoints

# List all available checkpoints
prodigy checkpoints

# List checkpoints for specific session
prodigy checkpoints --session <SESSION_ID>

When to use: To see available restore points for interrupted workflows.

Manage Worktrees

# List all Prodigy worktrees
prodigy worktree list

# Clean up old worktrees
prodigy worktree clean

# Remove specific worktree
prodigy worktree remove <SESSION_ID>

When to use: MapReduce workflows create many worktrees. Clean them up periodically to save disk space.

Monitor MapReduce Progress

# View progress of running MapReduce job
prodigy progress <JOB_ID>

# View events and logs from MapReduce job
prodigy events <JOB_ID>

# Filter events by type
prodigy events <JOB_ID> --type agent_started
prodigy events <JOB_ID> --type agent_completed
prodigy events <JOB_ID> --type agent_failed

When to use: Monitor long-running MapReduce jobs to see how many agents have completed, which are still running, and which have failed.

Manage Dead Letter Queue

# View failed MapReduce items in DLQ
prodigy dlq list <JOB_ID>

# Retry failed items from DLQ
prodigy dlq retry <JOB_ID> <ITEM_ID>

# Remove items from DLQ
prodigy dlq remove <JOB_ID> <ITEM_ID>

When to use: When some MapReduce agents fail, their items go to the Dead Letter Queue. You can retry them individually or investigate why they failed.

Session Management

# List all workflow sessions
prodigy sessions

# Clean up old sessions
prodigy clean

When to use: View history of workflow runs and clean up old data.

Workflow Configuration

Prodigy workflows are defined as YAML lists of steps. Each step can be either a shell command or a claude slash command.

Workflow Step Types

Shell Commands

Execute shell commands directly:

# Simple shell command
- shell: "cargo test"

# With timeout (in seconds)
- shell: "just coverage-lcov"
  timeout: 900  # 15 minutes

# With error handling
- shell: "just test"
  on_failure:
    claude: "/prodigy-debug-test-failure --output ${shell.output}"
    max_attempts: 5
    fail_workflow: true

Shell Command Fields:

  • shell: Command to execute (string)
  • timeout: Maximum execution time in seconds (optional)
  • on_failure: Error handler configuration (optional)
    • claude: Slash command to run on failure
    • max_attempts: Maximum retry attempts
    • fail_workflow: If true, fail entire workflow after max attempts

Claude Commands

Execute Claude Code slash commands:

# Simple Claude command
- claude: "/prodigy-debtmap-plan --before .prodigy/debtmap-before.json --output .prodigy/IMPLEMENTATION_PLAN.md"

# With output capture (makes command output available in ${shell.output})
- claude: "/prodigy-debtmap-plan --before .prodigy/debtmap-before.json --output .prodigy/IMPLEMENTATION_PLAN.md"
  capture_output: true

# With commit requirement (workflow fails if no git commit made)
- claude: "/prodigy-debtmap-implement --plan .prodigy/IMPLEMENTATION_PLAN.md"
  commit_required: true

# With timeout and validation
- claude: "/prodigy-debtmap-implement --plan .prodigy/IMPLEMENTATION_PLAN.md"
  commit_required: true
  timeout: 1800  # 30 minutes
  validate:
    commands:
      - shell: "cargo test"
    result_file: ".prodigy/validation.json"
    threshold: 75

Claude Command Fields:

  • claude: Slash command to execute (string)
  • capture_output: If true, command output is available in ${shell.output} variable (optional)
  • commit_required: If true, workflow fails if command doesn’t create a git commit (optional)
  • timeout: Maximum execution time in seconds (optional)
  • validate: Validation configuration (optional, see Step-Level Validation below)

Step-Level Validation

Steps can include validation that must pass:

- claude: "/prodigy-debtmap-implement --plan .prodigy/IMPLEMENTATION_PLAN.md"
  commit_required: true
  validate:
    commands:
      - shell: "cargo test"
      - shell: "cargo clippy -- -D warnings"
    result_file: ".prodigy/validation.json"
    threshold: 75
    on_incomplete:
      commands:
        - claude: "/prodigy-complete-debtmap-fix --gaps ${validation.gaps} --plan .prodigy/IMPLEMENTATION_PLAN.md"
          commit_required: true
      max_attempts: 5
      fail_workflow: true

Validation Options:

  • commands: List of commands to run for validation
  • result_file: JSON file containing validation results
  • threshold: Minimum score (0-100) required to pass
  • on_incomplete: Actions to take if validation score < threshold
  • max_attempts: Maximum retry attempts
  • fail_workflow: Whether to fail entire workflow if validation never passes

Error Handling

Use on_failure to handle command failures:

- shell: "just fmt-check && just lint"
  on_failure:
    claude: "/prodigy-lint ${shell.output}"
    max_attempts: 5
    fail_workflow: true

Error Handling Options:

  • claude: Slash command to fix the failure
  • max_attempts: Maximum fix attempts
  • fail_workflow: If true, workflow fails after max_attempts; if false, continues to next step

Coverage Integration

Generate and use coverage data in workflows. See Coverage Integration for details on generating LCOV files and understanding coverage metrics.

# Generate coverage
- shell: "just coverage-lcov"

# Use coverage in analysis
- shell: "debtmap analyze . --lcov target/coverage/lcov.info --output .prodigy/debtmap-before.json --format json"

Claude Slash Commands

Important: The slash commands documented below are custom commands provided in Debtmap’s .claude/commands/ directory. They are included in the Debtmap repository as working examples. You can use them as-is or create your own based on these patterns.

Note on workflow styles: The sequential workflow (workflows/debtmap.yml) uses shell: commands directly, while the MapReduce workflow (workflows/debtmap-reduce.yml) uses claude: wrapper commands for some operations like validate-improvement. Both approaches are valid - use whichever fits your workflow style.

Prodigy workflows use Claude Code slash commands to perform analysis, planning, and implementation. The key commands used in the debtmap workflow are:

Planning Commands

/prodigy-debtmap-plan

Creates an implementation plan for the top priority debt item.

- claude: "/prodigy-debtmap-plan --before .prodigy/debtmap-before.json --output .prodigy/IMPLEMENTATION_PLAN.md"
  capture_output: true

Parameters:

  • --before: Path to debtmap analysis JSON file
  • --output: Path to write implementation plan

/prodigy-validate-debtmap-plan

Validates that the implementation plan is complete and addresses the debt item.

- claude: "/prodigy-validate-debtmap-plan --before .prodigy/debtmap-before.json --plan .prodigy/IMPLEMENTATION_PLAN.md --output .prodigy/plan-validation.json"

Parameters:

  • --before: Original debtmap analysis
  • --plan: Implementation plan to validate
  • --output: Validation results JSON (with score 0-100)

/prodigy-revise-debtmap-plan

Revises an incomplete plan based on validation gaps.

- claude: "/prodigy-revise-debtmap-plan --gaps ${validation.gaps} --plan .prodigy/IMPLEMENTATION_PLAN.md"

Parameters:

  • --gaps: List of missing items from validation
  • --plan: Plan file to update

Implementation Commands

/prodigy-debtmap-implement

Executes the implementation plan.

- claude: "/prodigy-debtmap-implement --plan .prodigy/IMPLEMENTATION_PLAN.md"
  commit_required: true

Parameters:

  • --plan: Path to implementation plan

/prodigy-validate-debtmap-improvement

Validates that the implementation successfully addressed the debt item.

Note: In practice, workflows use the debtmap validate-improvement shell command directly. While a Claude slash command wrapper exists, both the sequential workflow (workflows/debtmap.yml:31) and MapReduce workflow (workflows/debtmap-reduce.yml:44) use the shell command for consistency.

# Standard approach (used in actual workflows)
- shell: "debtmap validate-improvement --comparison .prodigy/comparison.json --output .prodigy/debtmap-validation.json"

Parameters:

  • --comparison: Debtmap comparison results (before vs after)
  • --output: Validation results JSON (with score 0-100)
  • --previous-validation: (Optional) Previous validation result for trend tracking
  • --threshold: (Optional) Improvement threshold percentage (default: 75.0)

/prodigy-complete-debtmap-fix

Completes a partial fix based on validation gaps.

- claude: "/prodigy-complete-debtmap-fix --gaps ${validation.gaps} --plan .prodigy/IMPLEMENTATION_PLAN.md --attempt ${validation.attempt_number}"
  commit_required: true

Parameters:

  • --gaps: Validation gaps to address
  • --plan: Original implementation plan
  • --attempt: Current retry attempt number (from ${validation.attempt_number})

Testing and Quality Commands

/prodigy-debug-test-failure

Automatically fixes failing tests.

- shell: "just test"
  on_failure:
    claude: "/prodigy-debug-test-failure --output ${shell.output}"
    max_attempts: 5

Parameters:

  • --output: Test failure output from shell command

/prodigy-lint

Fixes linting and formatting issues.

- shell: "just fmt-check && just lint"
  on_failure:
    claude: "/prodigy-lint ${shell.output}"
    max_attempts: 5

Parameters:

  • Shell output with linting errors

Target Selection

Target selection happens through the debtmap analysis and slash commands, not through workflow configuration:

How Targets Are Selected

  1. Debtmap analyzes the codebase and scores all items by complexity, coverage, and risk
  2. Planning command (/prodigy-debtmap-plan) selects the highest priority item
  3. Implementation command (/prodigy-debtmap-implement) fixes that specific item
  4. Next iteration re-analyzes and selects the next highest priority item

Factors in Prioritization

  • Complexity score: Functions with cyclomatic complexity > 10
  • Coverage percentage: Lower coverage increases priority
  • Risk score: Complexity × (100 - coverage%)
  • Debt type: Complexity, TestGap, Duplication, GodObject, DeepNesting

Customizing Target Selection

To focus on specific debt types or modules, modify the slash commands or create custom commands in .claude/commands/

MapReduce Workflows

Prodigy supports MapReduce workflows for processing multiple items in parallel. This is powerful for large-scale refactoring where you want to fix many debt items simultaneously.

When to Use MapReduce

  • Processing multiple independent debt items simultaneously (e.g., refactor 10 high-complexity functions in parallel)
  • Applying the same fix pattern across many files
  • Large-scale codebase cleanup tasks
  • Situations where sequential iteration would be too slow

MapReduce vs Sequential Workflows

Sequential Workflow (-n 5):

  • Runs entire workflow N times in sequence
  • Fixes one item per iteration
  • Each iteration re-analyzes the codebase
  • Total time: N × workflow_duration

MapReduce Workflow:

  • Processes multiple items in parallel in a single run
  • Setup phase runs once
  • Map phase spawns N parallel agents (each in isolated worktree)
  • Reduce phase aggregates results
  • Total time: setup + max(map_agent_durations) + reduce

Complete MapReduce Example

Create workflows/debtmap-reduce.yml:

name: debtmap-parallel-elimination
mode: mapreduce

# Setup phase: Analyze the codebase and generate debt items
setup:
  timeout: 900  # 15 minutes for coverage generation
  commands:
    # Generate coverage data with tarpaulin
    - shell: "just coverage-lcov"

    # Run debtmap with coverage data to establish baseline
    - shell: "debtmap analyze src --lcov target/coverage/lcov.info --output .prodigy/debtmap-before.json --format json"

# Map phase: Process each debt item in parallel with planning and validation
map:
  # Input configuration - debtmap-before.json contains items array
  input: .prodigy/debtmap-before.json
  json_path: "$.items[*]"

  # Commands to execute for each debt item
  agent_template:
    # Phase 1: Create implementation plan
    - claude: "/prodigy-debtmap-plan --item '${item}' --output .prodigy/plan-${item_id}.md"
      capture_output: true
      validate:
        commands:
          - claude: "/prodigy-validate-debtmap-plan --item '${item}' --plan .prodigy/plan-${item_id}.md --output .prodigy/validation-${item_id}.json"
        result_file: ".prodigy/validation-${item_id}.json"
        threshold: 75
        on_incomplete:
          commands:
            - claude: "/prodigy-revise-debtmap-plan --gaps ${validation.gaps} --plan .prodigy/plan-${item_id}.md"
          max_attempts: 3
          fail_workflow: false

    # Phase 2: Execute the plan
    - claude: "/prodigy-debtmap-implement --plan .prodigy/plan-${item_id}.md"
      commit_required: true
      validate:
        commands:
          - shell: "just coverage-lcov"
          - shell: "debtmap analyze src --lcov target/coverage/lcov.info --output .prodigy/debtmap-after-${item_id}.json --format json"
          - shell: "debtmap compare --before .prodigy/debtmap-before.json --after .prodigy/debtmap-after-${item_id}.json --plan .prodigy/plan-${item_id}.md --output .prodigy/comparison-${item_id}.json --format json"
          - shell: "debtmap validate-improvement --comparison .prodigy/comparison-${item_id}.json --output .prodigy/debtmap-validation-${item_id}.json"
        result_file: ".prodigy/debtmap-validation-${item_id}.json"
        threshold: 75
        on_incomplete:
          commands:
            - claude: "/prodigy-complete-debtmap-fix --gaps ${validation.gaps} --plan .prodigy/plan-${item_id}.md --attempt ${validation.attempt_number}"
              commit_required: true
            - shell: "just coverage-lcov"
            - shell: "debtmap analyze src --lcov target/coverage/lcov.info --output .prodigy/debtmap-after-${item_id}.json --format json"
            - shell: "debtmap compare --before .prodigy/debtmap-before.json --after .prodigy/debtmap-after-${item_id}.json --plan .prodigy/plan-${item_id}.md --output .prodigy/comparison-${item_id}.json --format json"
          max_attempts: 5
          fail_workflow: true

    # Phase 3: Verify tests pass
    - shell: "just test"
      on_failure:
        claude: "/prodigy-debug-test-failure --output ${shell.output}"
        max_attempts: 5
        fail_workflow: true

    # Phase 4: Check formatting and linting
    - shell: "just fmt-check && just lint"
      on_failure:
        claude: "/prodigy-lint ${shell.output}"
        max_attempts: 5
        fail_workflow: true

  # Parallelization settings
  max_parallel: 5  # Run up to 5 agents in parallel

  # Filter and sort items
  # Note: NULLS LAST ensures File items (with null Function.unified_score.final_score)
  # and Function items (with null File.score) sort correctly
  filter: "File.score >= 10 OR Function.unified_score.final_score >= 10"
  sort_by: "File.score DESC NULLS LAST, Function.unified_score.final_score DESC NULLS LAST"
  max_items: 10  # Limit to 10 items per run

# Reduce phase: Aggregate results and verify overall improvements
reduce:
  # Phase 1: Run final tests across all changes
  - shell: "just test"
    on_failure:
      claude: "/prodigy-debug-test-failure --output ${shell.output}"
      max_attempts: 5
      fail_workflow: true

  # Phase 2: Check formatting and linting
  - shell: "just fmt-check && just lint"
    on_failure:
      claude: "/prodigy-lint ${shell.output}"
      max_attempts: 5
      fail_workflow: true

  # Phase 3: Re-run debtmap to measure cumulative improvements
  - shell: "just coverage-lcov"
  - shell: "debtmap analyze src --lcov target/coverage/lcov.info --output .prodigy/debtmap-after.json --format json"

  # Phase 4: Create final commit with summary
  - write_file:
      path: ".prodigy/map-results.json"
      content: "${map.results}"
      format: json
      create_dirs: true

  - claude: |
      /prodigy-compare-debt-results \
        --before .prodigy/debtmap-before.json \
        --after .prodigy/debtmap-after.json \
        --map-results-file .prodigy/map-results.json \
        --successful ${map.successful} \
        --failed ${map.failed} \
        --total ${map.total}
    commit_required: true

Running MapReduce Workflows

# Run MapReduce workflow (single execution processes multiple items in parallel)
prodigy run workflows/debtmap-reduce.yml

# Run with auto-confirm
prodigy run workflows/debtmap-reduce.yml -y

Note: MapReduce workflows don’t typically use -n for iterations. Instead, they process multiple items in a single run through parallel map agents.

MapReduce Configuration Options

Top-Level Fields

  • name: Workflow name (string)
  • mode: mapreduce: Enables MapReduce mode (required)
  • setup: Commands to run once before map phase
  • map: Map phase configuration
  • reduce: Commands to run after all map agents complete

Setup Phase Fields

  • timeout: Maximum time in seconds for setup phase
  • commands: List of shell or claude commands to run

Map Phase Fields

  • input: Path to JSON file containing items to process
  • json_path: JSONPath expression to extract items array (e.g., $.items[*])
  • agent_template: List of commands to run for each item (each item gets its own agent in an isolated worktree)
  • max_parallel: Maximum number of agents to run concurrently
  • filter: Expression to filter which items to process (e.g., "score >= 10")
  • sort_by: Expression to sort items (e.g., "score DESC")
  • max_items: Limit total items processed

MapReduce-Specific Variables

VariableAvailable InTypeDescription
${item}map phaseJSONThe full JSON object for current item (File or Function type)
${item_id}map phasestringUnique ID for current item (auto-generated)
${validation.gaps}map phasearrayList of validation gaps from failed validation
${validation.attempt_number}map phasenumberCurrent retry attempt number (1, 2, 3, etc.)
${shell.output}both phasesstringOutput from previous shell command
${map.results}reduce phasearrayAll map agent results as JSON
${map.successful}reduce phasenumberCount of successful map agents
${map.failed}reduce phasenumberCount of failed map agents
${map.total}reduce phasenumberTotal number of map agents

Understanding ${item} Structure:

The ${item} variable contains different fields depending on whether it’s a File or Function debt item:

  • File items: Have a File.score field (non-null) and Function.unified_score.final_score is null
  • Function items: Have a Function.unified_score.final_score field (non-null) and File.score is null

This distinction matters when filtering and sorting items in MapReduce workflows. See the filter/sort_by examples below for proper handling of both types.

MapReduce Architecture

┌─────────────────────────────────────────────────────────┐
│ Setup Phase (main worktree)                            │
│ - Generate coverage data                               │
│ - Run debtmap analysis                                 │
│ - Output: .prodigy/debtmap-before.json                 │
└─────────────────────────────────────────────────────────┘
                           │
                           ▼
┌─────────────────────────────────────────────────────────┐
│ Map Phase (parallel worktrees)                         │
│                                                         │
│  ┌──────────────┐  ┌──────────────┐  ┌──────────────┐ │
│  │ Agent 1      │  │ Agent 2      │  │ Agent 3      │ │
│  │ Item #1      │  │ Item #2      │  │ Item #3      │ │
│  │ Worktree A   │  │ Worktree B   │  │ Worktree C   │ │
│  │              │  │              │  │              │ │
│  │ Plan → Fix   │  │ Plan → Fix   │  │ Plan → Fix   │ │
│  │ → Validate   │  │ → Validate   │  │ → Validate   │ │
│  │ → Test       │  │ → Test       │  │ → Test       │ │
│  │ → Commit     │  │ → Commit     │  │ → Commit     │ │
│  └──────────────┘  └──────────────┘  └──────────────┘ │
│                                                         │
│  ┌──────────────┐  ┌──────────────┐                   │
│  │ Agent 4      │  │ Agent 5      │                   │
│  │ Item #4      │  │ Item #5      │                   │
│  │ Worktree D   │  │ Worktree E   │                   │
│  │              │  │              │                   │
│  │ Plan → Fix   │  │ Plan → Fix   │                   │
│  │ → Validate   │  │ → Validate   │                   │
│  │ → Test       │  │ → Test       │                   │
│  │ → Commit     │  │ → Commit     │                   │
│  └──────────────┘  └──────────────┘                   │
└─────────────────────────────────────────────────────────┘
                           │
                           ▼
┌─────────────────────────────────────────────────────────┐
│ Reduce Phase (main worktree)                           │
│ - Merge all agent worktrees                            │
│ - Run final tests on merged code                       │
│ - Run final linting                                    │
│ - Re-analyze with debtmap                              │
│ - Generate summary commit                              │
└─────────────────────────────────────────────────────────┘

Key Concepts:

  • Isolation: Each map agent works in its own git worktree
  • Parallelism: Multiple agents process different items simultaneously
  • Validation: Each agent validates its changes independently
  • Merging: Reduce phase merges all successful agent worktrees
  • Final Validation: Reduce phase ensures merged code passes all tests

Iteration Strategy

How Iterations Work

When you run prodigy run workflows/debtmap.yml -yn 5, the workflow executes up to 5 times:

  1. Iteration 1:

    • Analyze codebase with debtmap
    • Select highest priority item
    • Create implementation plan
    • Execute plan and validate
    • Run tests and linting
  2. Iteration 2:

    • Re-analyze codebase (scores updated based on Iteration 1 changes)
    • Select next highest priority item
    • Repeat plan/implement/validate cycle
  3. Continue until iteration limit reached or workflow completes without finding issues

Controlling Iterations

Iterations are controlled via the -n flag:

# Single iteration (testing)
prodigy run workflows/debtmap.yml -yn 1

# Standard run (5 iterations)
prodigy run workflows/debtmap.yml -yn 5

# Deep cleanup (10+ iterations)
prodigy run workflows/debtmap.yml -yn 20

What Happens Each Iteration

Each iteration runs the entire workflow from start to finish:

  1. Generate coverage data
  2. Analyze technical debt
  3. Create implementation plan
  4. Execute plan
  5. Validate improvement
  6. Run tests (with auto-fixing)
  7. Run linting (with auto-fixing)

The workflow continues to the next iteration automatically if all steps succeed.

Example Output

Iteration 1:
  - Fixed: parse_expression() (9.2 → 5.1)
  - Fixed: calculate_score() (8.8 → 4.2)
  - Fixed: apply_weights() (8.5 → 5.8)
  ✓ Tests pass

Iteration 2:
  - Fixed: normalize_results() (7.5 → 3.9)
  - Fixed: aggregate_data() (7.2 → 4.1)
  ✓ Tests pass

Iteration 3:
  - No items above threshold (6.0)
  ✓ Early stop

Final Results:
  Items fixed: 5
  Average complexity: 15.2 → 8.6

Validation

Prodigy validates changes at the workflow step level, not as a standalone configuration.

Step-Level Validation

Validation is attached to specific workflow steps:

- claude: "/prodigy-debtmap-implement --plan .prodigy/IMPLEMENTATION_PLAN.md"
  commit_required: true
  validate:
    commands:
      - shell: "debtmap analyze . --lcov target/coverage/lcov.info --output .prodigy/debtmap-after.json --format json"
      - shell: "debtmap compare --before .prodigy/debtmap-before.json --after .prodigy/debtmap-after.json --plan .prodigy/IMPLEMENTATION_PLAN.md --output .prodigy/comparison.json --format json"
      - shell: "debtmap validate-improvement --comparison .prodigy/comparison.json --output .prodigy/debtmap-validation.json"
    result_file: ".prodigy/debtmap-validation.json"
    threshold: 75
    on_incomplete:
      commands:
        - claude: "/prodigy-complete-debtmap-fix --gaps ${validation.gaps} --plan .prodigy/IMPLEMENTATION_PLAN.md --attempt ${validation.attempt_number}"
          commit_required: true
        - shell: "just coverage-lcov"
        - shell: "debtmap analyze . --lcov target/coverage/lcov.info --output .prodigy/debtmap-after.json --format json"
        - shell: "debtmap compare --before .prodigy/debtmap-before.json --after .prodigy/debtmap-after.json --plan .prodigy/IMPLEMENTATION_PLAN.md --output .prodigy/comparison.json --format json"
      max_attempts: 5
      fail_workflow: true

Validation Process

  1. Commands run: Execute validation commands (shell or claude)
  2. Check result file: Read JSON file specified in result_file
  3. Compare to threshold: Score must be >= threshold (0-100 scale)
  4. On incomplete: If score < threshold, run on_incomplete commands
  5. Retry: Repeat up to max_attempts times
  6. Fail or continue: If fail_workflow: true, stop workflow; otherwise continue

Validation Result Format

The result_file JSON should contain:

{
  "score": 85,
  "passed": true,
  "gaps": [],
  "details": "All debt improvement criteria met"
}

Test Validation with Auto-Fix

Tests are validated with automatic fixing on failure:

- shell: "just test"
  on_failure:
    claude: "/prodigy-debug-test-failure --output ${shell.output}"
    max_attempts: 5
    fail_workflow: true

If tests fail, Prodigy automatically attempts to fix them up to 5 times before failing the workflow.

Output and Metrics

Workflow Report

{
  "workflow": "debtmap-debt-reduction",
  "iterations": 5,
  "items_processed": 12,
  "items_fixed": 10,
  "items_failed": 2,
  "metrics": {
    "complexity_before": 145,
    "complexity_after": 78,
    "complexity_reduction": -46.2,
    "coverage_before": 45.3,
    "coverage_after": 72.1,
    "coverage_improvement": 26.8
  },
  "changes": [
    {
      "file": "src/parser.rs",
      "function": "parse_expression",
      "before_score": 9.2,
      "after_score": 5.1,
      "improvements": ["Reduced complexity", "Added tests"]
    }
  ]
}

Commit Messages

Prodigy generates descriptive commit messages:

refactor(parser): reduce complexity in parse_expression

- Extract nested conditionals to helper functions
- Add unit tests for edge cases
- Coverage: 0% → 85%
- Complexity: 22 → 8

Generated by Prodigy workflow: debtmap-debt-reduction
Iteration: 1/5

Integration with CI/CD

GitHub Actions

name: Prodigy Debt Reduction

on:
  schedule:
    - cron: '0 0 * * 0'  # Weekly on Sunday
  workflow_dispatch:

jobs:
  reduce-debt:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Setup Rust
        uses: actions-rs/toolchain@v1
        with:
          toolchain: stable

      - name: Install Prodigy
        run: cargo install prodigy

      - name: Install dependencies
        run: |
          cargo install debtmap
          cargo install just

      - name: Run Prodigy workflow
        env:
          ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
        run: prodigy run workflows/debtmap.yml -yn 5

      - name: Create PR
        uses: peter-evans/create-pull-request@v5
        with:
          title: "chore: automated debt reduction via Prodigy"
          body: |
            Automated technical debt reduction using Prodigy workflow.

            This PR was generated by the weekly debt reduction workflow.
            Review changes carefully before merging.
          branch: prodigy-debt-reduction

GitLab CI

prodigy-debt-reduction:
  stage: quality
  rules:
    - if: '$CI_PIPELINE_SOURCE == "schedule"'
  script:
    - cargo install prodigy
    - cargo install debtmap
    - cargo install just
    - prodigy run workflows/debtmap.yml -yn 5
  artifacts:
    paths:
      - .prodigy/debtmap-*.json
      - .prodigy/comparison.json

Important CI Considerations

  • API Keys: Store ANTHROPIC_API_KEY as a secret
  • Worktrees: MapReduce mode creates isolated worktrees automatically for parallel processing
  • Dependencies: Install prodigy, debtmap, and just (or your build tool)
  • Timeout: CI jobs may need extended timeout for multiple iterations
  • Review: Always create a PR for human review before merging automated changes

Best Practices

1. Start Small

Begin with low iteration counts:

# First run: 1 iteration to test workflow
prodigy run workflows/debtmap.yml -yn 1

# Standard run: 3-5 iterations
prodigy run workflows/debtmap.yml -yn 5

2. Focus on High-Priority Items

The debtmap analysis automatically prioritizes by:

  • Complexity score (cyclomatic complexity)
  • Coverage percentage (lower coverage = higher priority)
  • Risk score (complexity × (100 - coverage%))

To focus on specific areas, create custom slash commands in .claude/commands/ that filter by:

  • Module/file patterns
  • Specific debt types (Complexity, TestGap, Duplication)
  • Score thresholds

3. Validate Thoroughly

Use comprehensive validation in your workflow:

- shell: "just test"
  on_failure:
    claude: "/prodigy-debug-test-failure --output ${shell.output}"
    max_attempts: 5
    fail_workflow: true

- shell: "just fmt-check && just lint"
  on_failure:
    claude: "/prodigy-lint ${shell.output}"
    max_attempts: 5
    fail_workflow: true

4. Review Before Merging

Always review Prodigy’s changes:

# Find your worktree
ls ~/.prodigy/worktrees/

# Check changes
cd ~/.prodigy/worktrees/session-xxx
git diff main

# Review commit history
git log --oneline

# Run full test suite
cargo test --all-features

5. Monitor Progress

Track debt reduction over iterations:

# Compare before and after
debtmap compare --before .prodigy/debtmap-before.json --after .prodigy/debtmap-after.json

# View detailed metrics
cat .prodigy/comparison.json | jq

Troubleshooting

Workflow Fails to Start

Issue: “Prodigy not found” or “API key missing”

Solution:

# Install Prodigy
cargo install prodigy

# Set API key
export ANTHROPIC_API_KEY="your-key"

# Verify installation
prodigy --version

Validation Failures

Issue: Validation score below threshold

Solution: Check validation results:

# View validation details
cat .prodigy/debtmap-validation.json

# Check what gaps remain
cat .prodigy/debtmap-validation.json | jq '.gaps'

# Review comparison results
cat .prodigy/comparison.json

The workflow will automatically retry up to max_attempts times with /prodigy-complete-debtmap-fix.

Test Failures

Issue: Tests fail after implementation

Solution: The workflow includes automatic test fixing:

- shell: "just test"
  on_failure:
    claude: "/prodigy-debug-test-failure --output ${shell.output}"
    max_attempts: 5
    fail_workflow: true

If tests still fail after 5 attempts, review manually:

# Check test output
just test

# Review recent changes
git diff HEAD~1

No Items Processed

Issue: Workflow completes but doesn’t find debt to fix

Possible Causes:

  1. Codebase has very low debt scores (below selection threshold)
  2. Coverage data not generated properly
  3. Debtmap analysis found no high-priority items

Solution:

# Check debtmap analysis results
cat .prodigy/debtmap-before.json | jq '.items | sort_by(-.unified_score.final_score) | .[0:5]'

# Verify coverage was generated
ls -lh target/coverage/lcov.info

# Run debtmap manually to see what's detected
debtmap analyze . --lcov target/coverage/lcov.info

Workflow Hangs or Times Out

Issue: Workflow takes too long or appears stuck

Possible Causes:

  • Large codebase with many files
  • Complex refactoring requiring extensive analysis
  • Network issues with Claude API

Solution:

  • Reduce iteration count for testing (-n 1)
  • Check Claude API connectivity
  • Monitor worktree for progress: cd ~/.prodigy/worktrees/session-xxx && git log

MapReduce-Specific Troubleshooting

Resuming Failed MapReduce Jobs

Issue: MapReduce job was interrupted or failed

Solution:

# Find the job ID from recent sessions
prodigy sessions

# Resume the MapReduce job from checkpoint
prodigy resume-job <JOB_ID>

The job will resume from where it left off, skipping already-completed items.

Checking MapReduce Progress

Issue: Want to monitor long-running MapReduce job

Solution:

# View overall progress
prodigy progress <JOB_ID>

# View detailed events
prodigy events <JOB_ID>

# Filter for specific event types
prodigy events <JOB_ID> --type agent_completed
prodigy events <JOB_ID> --type agent_failed

Output example:

MapReduce Job: job-abc123
Status: running
Progress: 7/10 items (70%)
- Completed: 5
- Running: 2
- Failed: 3

Managing Failed MapReduce Items

Issue: Some agents failed, items in Dead Letter Queue

Solution:

# View failed items
prodigy dlq list <JOB_ID>

# Review why an item failed (check events)
prodigy events <JOB_ID> --item <ITEM_ID>

# Retry specific failed item
prodigy dlq retry <JOB_ID> <ITEM_ID>

# Remove unfixable items from DLQ
prodigy dlq remove <JOB_ID> <ITEM_ID>

Common failure reasons:

  • Validation threshold not met after max_attempts
  • Tests fail and can’t be fixed automatically
  • Merge conflicts with other agents’ changes
  • Timeout exceeded for complex refactoring

Cleaning Up MapReduce Worktrees

Issue: Disk space consumed by many MapReduce worktrees

Solution:

# List all worktrees
prodigy worktree list

# Clean up completed job worktrees
prodigy worktree clean

# Remove specific session's worktrees
prodigy worktree remove <SESSION_ID>

# Manual cleanup (if Prodigy commands don't work)
rm -rf ~/.prodigy/worktrees/session-xxx

When to clean:

  • After successful job completion and merge
  • When disk space is low
  • After abandoned or failed jobs

MapReduce Merge Conflicts

Issue: Reduce phase fails due to merge conflicts between agent worktrees

Possible Causes:

  • Multiple agents modified overlapping code
  • Agents made conflicting architectural changes
  • Shared dependencies updated differently

Solution:

# Review which agents succeeded
prodigy events <JOB_ID> --type agent_completed

# Check merge conflicts
cd ~/.prodigy/worktrees/session-xxx
git status

# Manually resolve conflicts
# Edit conflicting files
git add .
git commit -m "Resolve MapReduce merge conflicts"

# Resume the job
prodigy resume-job <JOB_ID>

Prevention:

  • Use filter to ensure agents work on independent items
  • Reduce max_parallel to minimize conflicts
  • Design debt items to be truly independent

Understanding MapReduce Variables

If you’re debugging workflow files, these variables are available:

In map phase (agent_template):

  • ${item}: Full JSON of current item being processed
  • ${item_id}: Unique ID for current item
  • ${validation.gaps}: Validation gaps from validation result
  • ${validation.attempt_number}: Current retry attempt (1, 2, 3…)
  • ${shell.output}: Output from previous shell command

In reduce phase:

  • ${map.results}: All map agent results as JSON
  • ${map.successful}: Count of successful agents
  • ${map.failed}: Count of failed agents
  • ${map.total}: Total number of agents

Example debug command:

# In agent_template, log the item being processed
- shell: "echo 'Processing item: ${item_id}' >> .prodigy/debug.log"

Example Workflows

Full Repository Cleanup

For comprehensive debt reduction, use a higher iteration count:

# Run 10 iterations for deeper cleanup
prodigy run workflows/debtmap.yml -yn 10

# Run 20 iterations for major refactoring
prodigy run workflows/debtmap.yml -yn 20

The workflow automatically:

  1. Selects highest priority items each iteration
  2. Addresses different debt types (Complexity, TestGap, Duplication)
  3. Validates all changes with tests and linting
  4. Commits only successful improvements

Custom Workflow for Specific Focus

Create a custom workflow file for focused improvements:

workflows/add-tests.yml - Focus on test coverage:

# Generate coverage
- shell: "just coverage-lcov"

# Analyze with focus on test gaps
- shell: "debtmap analyze . --lcov target/coverage/lcov.info --output .prodigy/debtmap-before.json --format json"

# Create plan (slash command will prioritize TestGap items)
- claude: "/prodigy-debtmap-plan --before .prodigy/debtmap-before.json --output .prodigy/IMPLEMENTATION_PLAN.md"

# ... rest of standard workflow steps

Run with:

prodigy run workflows/add-tests.yml -yn 5

Targeted Module Cleanup

Create a custom slash command to focus on specific modules:

.claude/commands/refactor-module.md:

# /refactor-module

Refactor the highest complexity item in the specified module.

Arguments: --module <module_name>

... implementation details ...

Then create a workflow using this command for targeted refactoring.

See Also