Files
Claude-Code-Workflow/.claude/skills/team-review/roles/reviewer/commands/deep-analyze.md
catlog22 a859698c7d chore: move 3 skills to ccw-skill-hub repository
Migrated to D:/ccw-skill-hub/skills/:
- project-analyze
- copyright-docs
- software-manual
2026-02-24 12:23:41 +08:00

6.8 KiB

Command: deep-analyze

CLI Fan-out deep analysis. Splits findings into 2 domain groups, runs parallel CLI agents for root cause / impact / optimization enrichment.

When to Use

  • Phase 3 of Reviewer, when deep_analysis.length > 0
  • Requires deep_analysis[] array and sessionFolder from Phase 2

Trigger conditions:

  • REV-* task in Phase 3 with at least 1 finding triaged for deep analysis

Strategy

Delegation Mode

Mode: CLI Fan-out (max 2 parallel agents, analysis only)

Tool Fallback Chain

gemini (primary) -> qwen (fallback) -> codex (fallback)

Group Split

Group A: Security + Correctness findings -> 1 CLI agent
Group B: Performance + Maintainability findings -> 1 CLI agent
If either group empty -> skip that agent (run single agent only)

Execution Steps

Step 1: Split Findings into Groups

const groupA = deep_analysis.filter(f =>
  f.dimension === 'security' || f.dimension === 'correctness'
)
const groupB = deep_analysis.filter(f =>
  f.dimension === 'performance' || f.dimension === 'maintainability'
)

// Collect all affected files for CLI context
const collectFiles = (group) => [...new Set(
  group.map(f => f.location?.file).filter(Boolean)
)]
const filesA = collectFiles(groupA)
const filesB = collectFiles(groupB)

Step 2: Build CLI Prompts

function buildPrompt(group, groupLabel, affectedFiles) {
  const findingsJson = JSON.stringify(group, null, 2)
  const filePattern = affectedFiles.length <= 20
    ? affectedFiles.map(f => `@${f}`).join(' ')
    : '@**/*.{ts,tsx,js,jsx,py,go,java,rs}'

  return `PURPOSE: Deep analysis of ${groupLabel} code findings -- root cause, impact, optimization suggestions.
TASK:
- For each finding: trace root cause (independent issue or symptom of another finding?)
- Identify findings sharing the same root cause -> mark related_findings with their IDs
- Assess impact scope and affected files (blast_radius: function/module/system)
- Propose fix strategy (minimal fix vs refactor) with tradeoff analysis
- Identify fix dependencies (which findings must be fixed first?)
- For each finding add these enrichment fields:
  root_cause: { description: string, related_findings: string[], is_symptom: boolean }
  impact: { scope: "low"|"medium"|"high", affected_files: string[], blast_radius: string }
  optimization: { approach: string, alternative: string, tradeoff: string }
  fix_strategy: "minimal" | "refactor" | "skip"
  fix_complexity: "low" | "medium" | "high"
  fix_dependencies: string[] (finding IDs that must be fixed first)
MODE: analysis
CONTEXT: ${filePattern}
Findings to analyze:
${findingsJson}
EXPECTED: Respond with ONLY a JSON array. Each element is the original finding object with the 6 enrichment fields added. Preserve ALL original fields exactly.
CONSTRAINTS: Preserve original finding fields | Only add enrichment fields | Return raw JSON array only | No markdown wrapping`
}

const promptA = groupA.length > 0
  ? buildPrompt(groupA, 'Security + Correctness', filesA) : null
const promptB = groupB.length > 0
  ? buildPrompt(groupB, 'Performance + Maintainability', filesB) : null

Step 3: Execute CLI Agents (Parallel)

function runCli(prompt) {
  const tools = ['gemini', 'qwen', 'codex']
  for (const tool of tools) {
    try {
      const out = Bash(
        `ccw cli -p "${prompt.replace(/"/g, '\\"')}" --tool ${tool} --mode analysis --rule analysis-diagnose-bug-root-cause`,
        { timeout: 300000 }
      )
      return out
    } catch { continue }
  }
  return null  // All tools failed
}

// Run both groups -- if both present, execute via Bash run_in_background for parallelism
let resultA = null, resultB = null

if (promptA && promptB) {
  // Both groups: run in parallel
  // Group A in background
  Bash(`ccw cli -p "${promptA.replace(/"/g, '\\"')}" --tool gemini --mode analysis --rule analysis-diagnose-bug-root-cause > "${sessionFolder}/review/_groupA.txt" 2>&1`,
    { run_in_background: true, timeout: 300000 })
  // Group B synchronous (blocks until done)
  resultB = runCli(promptB)
  // Wait for Group A to finish, then read output
  Bash(`sleep 5`)  // Brief wait if B finished faster
  try { resultA = Read(`${sessionFolder}/review/_groupA.txt`) } catch {}
  // If background failed, try synchronous fallback
  if (!resultA) resultA = runCli(promptA)
} else if (promptA) {
  resultA = runCli(promptA)
} else if (promptB) {
  resultB = runCli(promptB)
}

Step 4: Parse & Merge Results

function parseCliOutput(output) {
  if (!output) return []
  try {
    const match = output.match(/\[[\s\S]*\]/)
    if (!match) return []
    const parsed = JSON.parse(match[0])
    // Validate enrichment fields exist
    return parsed.filter(f => f.id && f.dimension).map(f => ({
      ...f,
      root_cause: f.root_cause || { description: 'Unknown', related_findings: [], is_symptom: false },
      impact: f.impact || { scope: 'medium', affected_files: [f.location?.file].filter(Boolean), blast_radius: 'module' },
      optimization: f.optimization || { approach: f.suggested_fix || '', alternative: '', tradeoff: '' },
      fix_strategy: ['minimal', 'refactor', 'skip'].includes(f.fix_strategy) ? f.fix_strategy : 'minimal',
      fix_complexity: ['low', 'medium', 'high'].includes(f.fix_complexity) ? f.fix_complexity : 'medium',
      fix_dependencies: Array.isArray(f.fix_dependencies) ? f.fix_dependencies : []
    }))
  } catch { return [] }
}

const enrichedA = parseCliOutput(resultA)
const enrichedB = parseCliOutput(resultB)

// Merge: CLI-enriched findings replace originals, unenriched originals kept as fallback
const enrichedMap = new Map()
for (const f of [...enrichedA, ...enrichedB]) enrichedMap.set(f.id, f)

const enrichedFindings = deep_analysis.map(f =>
  enrichedMap.get(f.id) || {
    ...f,
    root_cause: { description: 'Analysis unavailable', related_findings: [], is_symptom: false },
    impact: { scope: 'medium', affected_files: [f.location?.file].filter(Boolean), blast_radius: 'unknown' },
    optimization: { approach: f.suggested_fix || '', alternative: '', tradeoff: '' },
    fix_strategy: 'minimal',
    fix_complexity: 'medium',
    fix_dependencies: []
  }
)

// Write output
Write(`${sessionFolder}/review/enriched-findings.json`, JSON.stringify(enrichedFindings, null, 2))

// Cleanup temp files
Bash(`rm -f "${sessionFolder}/review/_groupA.txt" "${sessionFolder}/review/_groupB.txt"`)

Error Handling

Scenario Resolution
gemini CLI fails Fallback to qwen, then codex
All CLI tools fail for a group Use original findings with default enrichment
CLI output not valid JSON Attempt regex extraction, else use defaults
Background task hangs Synchronous fallback after timeout
One group fails, other succeeds Merge partial results with defaults
Invalid enrichment fields Apply defaults for missing/invalid fields