dobbe

Resolve Pipeline Deep Dive

The vuln resolve pipeline orchestrates four AI agents in an iterative feedback loop to scan, fix, verify, and report on vulnerable dependencies.

Full Pipeline Flowchart

                    ┌──────────────────────┐
                    │  run_pipeline(cfg)    │
                    └──────────┬───────────┘
                               │
                               v
                    ┌──────────────────────┐
                    │  ensure_local_clone   │
                    │  - Auto-detect CWD?   │
                    │  - Configured paths?  │
                    │  - Common dirs?       │
                    │  - CWD remote match?  │
                    │  - Clone to tempdir   │
                    └──────────┬───────────┘
                               │
                               v
                    ┌──────────────────────┐
                    │  setup_branch         │
                    │  git checkout -b      │
                    │  <branch> <base>      │
                    └──────────┬───────────┘
                               │
                               v
              ┌────────────────────────────────────┐
              │  scan_summary_override set?         │
              └────────────────┬───────────────────┘
                         yes | │ no
                             │ v
                             │ ┌────────────────────────────────┐
                             │ │  SCAN AGENT                     │
                             │ │  prompt: build_scan_prompt()     │
                             │ │  tools:  BASE_TOOLS + MCP        │
                             │ │  output: JSON -> AlertGroups     │
                             │ │  post:   build_scan_summary()    │
                             │ └────────────────┬───────────────┘
                             │                  │
                             v                  v
              ┌────────────────────────────────────┐
              │  scan_summary ready                  │
              └────────────────┬───────────────────┘
                               │
                         ┌─────┴──────┐
                         │  dry_run?  │
                         └─────┬──────┘
                       yes |       | no
                           v       │
                     Return scan   │
                     report only   │
                                   │
                    ┌──────────────┘
                    │ iteration = 1
                    │ feedback = ""
                    v
        ┌───> ┌────────────────────────────────────┐
        │     │  FIX AGENT                          │
        │     │  prompt: build_fix_prompt(           │
        │     │    local_path, scan_summary,         │
        │     │    feedback)                         │
        │     │  tools:  FIX_TOOLS + MCP             │
        │     │  rules:  PATCH/MINOR only,           │
        │     │          update lockfiles,            │
        │     │          skip if no safe fix          │
        │     │  output: JSON -> FixResult            │
        │     └────────────────┬───────────────────┘
        │                      │
        │                      v
        │     ┌────────────────────────────────────┐
        │     │  commit_fixes                       │
        │     │  git add -A && git commit           │
        │     └────────────────┬───────────────────┘
        │                      │
        │                ┌─────┴──────┐
        │                │  Commit    │
        │                │  created?  │
        │                └─────┬──────┘
        │              yes |       | no
        │                  │       v
        │                  │  converged = true
        │                  │  (no changes to fix)
        │                  │  skip to REPORT
        │                  │
        │            ┌─────┴──────┐
        │            │ skip_      │
        │            │ verify?    │
        │            └─────┬──────┘
        │          yes |       | no
        │              v       │
        │        converged     │
        │        = true        │
        │        skip to       │
        │        REPORT        │
        │                      v
        │     ┌────────────────────────────────────┐
        │     │  VERIFY AGENT                       │
        │     │  prompt: build_verify_prompt(        │
        │     │    local_path, branch, base_branch)  │
        │     │  tools:  VERIFY_TOOLS                │
        │     │  checks: git diff, breaking changes, │
        │     │          test suite, lockfile sync    │
        │     │  output: JSON -> VerifyResult         │
        │     └────────────────┬───────────────────┘
        │                      │
        │                ┌─────┴──────┐
        │                │  passed?   │
        │                └─────┬──────┘
        │              yes |       | no
        │                  │       │
        │                  │       │
        │                  │  ┌────┴────────────────┐
        │                  │  │  iteration <         │
        │                  │  │  max_iterations?     │
        │                  │  └────┬────────────────┘
        │                  │  yes |       | no
        │                  │      │       │
        │                  │      v       │
        │                  │  ┌──────────────────┐
        │                  │  │  revert_to_base  │
        │                  │  │  git reset       │
        │                  │  │  --hard <base>   │
        │                  │  │  on <branch>     │
        │                  │  └────────┬─────────┘
        │                  │           │
        │                  │  feedback = verify.feedback
        │                  │  iteration += 1
        │     converged    │           │
        │     = true       │           │
        │                  │           │
        │                  v           │
        │           skip to REPORT     │
        │                              │
        └──────────────────────────────┘

                    ┌──────────────────────┐
                    │  REPORT AGENT         │
                    │  prompt:              │
                    │   build_report_prompt │
                    │  tools: [Read]        │
                    │  output: text summary │
                    │  (< 500 words)        │
                    └──────────┬───────────┘
                               │
                         ┌─────┴────────────┐
                         │  converged AND    │
                         │  not cfg.no_pr?   │
                         └─────┬────────────┘
                       yes |         | no
                           v         v
                    ┌────────────┐  Return
                    │  create_pr │  report
                    │  gh pr     │  only
                    │  create    │
                    └────────────┘

Agent Roles

Scan Agent

Purpose: Fetch and triage Dependabot alerts.

Prompt template: SCAN_PROMPT_TEMPLATE - instructs Claude to fetch alerts for the repo, analyze each one for actual code path usage, and return structured JSON with risk levels.

Tool allowlist: [Bash, Read, Grep, Glob] + GitHub MCP if available. The scan agent can read files to check import paths but cannot modify anything.

Output: JSON parsed into AlertGroup objects containing TriageResult entries. Post-processed by _build_scan_summary() into a human-readable summary passed to the fix agent.

Pre-computed scan override: When PipelineConfig.scan_summary_override is set (via --from-scan), the scan agent is bypassed entirely. The pre-computed summary string is injected at the same point where _build_scan_summary() would produce it, so all downstream agents (fix, verify, report) receive identical input. This is produced by scan_summary_from_repo_result() which converts a RepoResult model to the same text format.

Fix Agent

Purpose: Apply safe dependency upgrades.

Prompt template: FIX_PROMPT_TEMPLATE - receives the scan summary and any feedback from a prior failed verification. Rules: only PATCH/MINOR bumps, update lockfiles, skip if no safe fix, don’t modify application code.

Tool allowlist: [Bash, Read, Grep, Glob, Edit, Write] + GitHub MCP. The fix agent is the only agent with write permissions.

Output: JSON parsed into FixResult with per-package fix actions and skipped packages with reasons.

Verify Agent

Purpose: Validate that the fixes don’t break anything.

Prompt template: VERIFY_PROMPT_TEMPLATE - instructs Claude to review the git diff, check for breaking changes, run the test suite, and verify lockfile consistency.

Tool allowlist: [Bash, Read, Grep, Glob]. The verify agent can run tests via Bash but cannot edit files, ensuring independence from the fix agent.

Output: JSON parsed into VerifyResult with passed boolean, categorized issues, test output, and a feedback string that gets fed to the next fix iteration.

Report Agent

Purpose: Summarize the pipeline run.

Prompt template: REPORT_PROMPT_TEMPLATE - receives repo name, iteration count, convergence status, scan summary, and iteration details.

Tool allowlist: [Read]. Minimal permissions - report agent only needs to read to produce its summary.

Output: Plain text executive summary (< 500 words).

Convergence Logic

The pipeline uses feedback propagation to converge:

Iteration 1: fix_agent(scan_summary, feedback="")
             verify_agent -> fails with feedback
Iteration 2: fix_agent(scan_summary, feedback=verify.feedback)
             verify_agent -> fails with new feedback
Iteration 3: fix_agent(scan_summary, feedback=verify.feedback)
             verify_agent -> passes
             -> converged!

The verify agent’s feedback field contains specific instructions for the fix agent: which tests failed, what broke, and suggested approaches. This creates a conversation-like loop where each iteration benefits from prior failures.

Git Operations

Operation Implementation When
CWD detect git remote get-url origin No flags given, or –repo slug match
Clone git clone --depth 1 Repo not found locally
Branch git checkout -b <branch> <base> Start of pipeline
Commit git add -A && git commit -m <msg> After fix agent
Revert git reset --hard <base> on branch After failed verify
Push git push -u origin <branch> Before PR creation
PR gh pr create --title --body If converged

All git operations use a 60-second timeout. Failures raise GitError.

Batch Resolve

When running with --org or --user, batch_resolve.py orchestrates:

  1. List all repos for the owner
  2. Run run_pipeline() sequentially for each repo
  3. Fire progress callbacks between repos
  4. Aggregate into BatchResolveReport

Sequential execution (not parallel) is intentional - each pipeline run creates branches and PRs, and parallel execution could cause rate limiting or resource contention.

See Also