Skip to content

Impact Analysis

Core feature since v5.1 | Enhanced in v7.5-v7.6 | Test mapping in v7.5

Impact Analysis answers three critical questions before every code change:

  1. "What downstream code might break?" — Blast radius analysis
  2. "Which tests should I run?" — Targeted test selection
  3. "Who needs to review this?" — Affected owners identification

This is something LLMs fundamentally cannot do without tooling — they can't reason about the full dependency graph, test mappings, or cross-file relationships at scale.


Table of Contents


Prerequisites

Impact analysis quality depends on your indexing setup. Here's what you need for each level of accuracy:

Minimum: Tree-sitter (Fast Tier)

Works out of the box with no additional setup.

  • Provides: Basic symbol detection, file-level analysis
  • Limitations: No cross-file references, confidence scores are low (0.3)
  • Best for: Quick checks, unsupported languages

Full semantic analysis with cross-file references.

# Install SCIP indexer for your language
go install github.com/sourcegraph/scip-go/cmd/scip-go@latest        # Go
npm install -g @anthropic/scip-typescript                           # TypeScript

# Generate index
ckb index

Provides:

  • Exact symbol definitions and references
  • Call graph traversal (callers and callees)
  • Transitive impact analysis (depth 2-4)
  • High confidence scores (0.85-1.0)

Language support for SCIP:

Language Indexer Quality
Go scip-go Tier 1 (full)
TypeScript/JS scip-typescript Tier 2 (full, minor edge cases)
Python scip-python Tier 2
Rust rust-analyzer Tier 3
Java/Kotlin scip-java Tier 3

See Language-Support for full compatibility matrix.

Enhanced: Telemetry Integration (Full Tier)

Add runtime observability for production-aware impact analysis.

{
  "telemetry": {
    "enabled": true,
    "serviceMap": {
      "my-api-service": "my-repo"
    }
  }
}

Provides:

  • Observed callers from production traffic
  • blendedConfidence combining static + runtime analysis
  • Detection of dynamic dispatch and reflection calls
  • "Observed only" callers that static analysis misses

See Telemetry for setup instructions.

Test Mapping: Coverage Files (v7.5)

For precise test selection, provide coverage data:

Go:

# Generate coverage file
go test -coverprofile=coverage.out ./...

# CKB will auto-detect coverage.out in the project root

JavaScript/TypeScript (Jest):

# Generate lcov coverage
jest --coverage --coverageReporters=lcov

# Coverage will be at coverage/lcov.info

Python (pytest):

# Generate coverage
pytest --cov=. --cov-report=lcov

# Coverage will be at coverage.lcov or lcov.info

Dart (flutter/dart test):

# Generate coverage (Flutter)
flutter test --coverage

# Coverage will be at coverage/lcov.info

Rust (cargo-tarpaulin):

# Install tarpaulin
cargo install cargo-tarpaulin

# Generate coverage
cargo tarpaulin --out Lcov

# Coverage will be at lcov.info

Java (JaCoCo):

# Maven with JaCoCo plugin
mvn test jacoco:report

# Coverage will be at target/site/jacoco/jacoco.xml
# Or configure for lcov output

Provides:

  • Precise line-level test mapping
  • affectedTests field in impact analysis
  • ckb affected-tests command

Fallback strategies (when no coverage file):

  1. Naming convention: foo.gofoo_test.go
  2. Import analysis: tests importing changed package
  3. Package-level: all tests in affected directories

See Configuration for custom coverage file locations.

Reviewer Suggestions: CODEOWNERS

For automated reviewer routing, add a CODEOWNERS file:

# .github/CODEOWNERS (GitHub) or CODEOWNERS (GitLab)

# Default owner
* @default-team

# Module-specific owners
/internal/api/       @api-team
/internal/auth/      @security-team
/internal/payments/  @payments-team @finance-team

# File-specific owners
/go.mod              @platform-team

Provides:

  • affectedOwners in impact analysis
  • ckb reviewers command
  • Suggested reviewers in ckb pr-summary

Without CODEOWNERS, CKB falls back to git blame for ownership signals.

Keeping the Index Fresh

Impact analysis is only as accurate as your index. Stale indexes produce stale results.

# Check freshness
ckb status

# Manual refresh
ckb index

# Watch mode (auto-refresh on file changes)
ckb index --watch

# MCP with watch mode
ckb mcp --watch

Use --strict mode to fail when the index is stale:

ckb impact diff --strict  # Fails if index is behind HEAD

Checking Your Setup

Use ckb status to verify impact analysis prerequisites:

$ ckb status

Repository: /Users/lisa/code/myproject
Index:      ✓ Fresh (indexed 5 minutes ago, 8,432 symbols)
Language:   Go

Change Impact Analysis:
  Coverage:   ✓ Found (coverage.out, 2 hours old)
  CODEOWNERS: ✓ Found (.github/CODEOWNERS, 15 patterns)

Missing components show actionable guidance:

Change Impact Analysis:
  Coverage:   ⚠ Not found (test mapping will use heuristics)
              Generate: go test -coverprofile=coverage.out ./...
  CODEOWNERS: ⚠ Not found (reviewer suggestions unavailable)
              Create: .github/CODEOWNERS

Quick Start

# 1. Initialize and index
cd /your/project
ckb init
ckb index

# 2. (Optional) Generate coverage for test mapping
go test -coverprofile=coverage.out ./...

# 3. Analyze impact of your changes
ckb impact diff                    # Uncommitted changes
ckb impact diff --staged           # Staged changes only
ckb impact diff --base=main        # Compare to branch

# 4. Get affected tests
ckb affected-tests                 # Tests to run for your changes
ckb affected-tests --output=command # Ready-to-run command

# 5. Get suggested reviewers
ckb reviewers                      # Who should review this?

Single Symbol Impact Analysis

Analyze what depends on a specific symbol before changing it.

CLI

# Basic impact analysis
ckb impact "UserService.Authenticate"

# With transitive callers (depth 2-4)
ckb impact "Engine.Start" --depth=3

# Include telemetry data
ckb impact "HandleRequest" --include-telemetry

MCP Tool: analyzeImpact

{
  "name": "analyzeImpact",
  "arguments": {
    "symbolId": "scip-go gomod example.com/api internal/auth/user.go/UserService#Authenticate",
    "depth": 2,
    "includeTelemetry": true,
    "telemetryPeriod": "90d"
  }
}

Parameters

Parameter Type Default Description
symbolId string required Symbol ID or qualified name
depth number 2 Transitive depth (1-4). Depth 1 = direct callers only
includeTelemetry boolean true Include runtime observability data
telemetryPeriod string "90d" Telemetry window: "7d", "30d", "90d", "all"

Response

{
  "symbol": {
    "stableId": "scip-go gomod example.com/api ...",
    "name": "Authenticate",
    "kind": "function"
  },
  "visibility": {
    "visibility": "public",
    "confidence": 0.9
  },
  "riskScore": {
    "score": 0.72,
    "level": "high",
    "explanation": "High risk: 15 direct caller(s) across 4 module(s).",
    "factors": [
      { "name": "visibility", "value": 0.9, "weight": 0.3 },
      { "name": "direct-callers", "value": 0.8, "weight": 0.35 },
      { "name": "module-spread", "value": 0.6, "weight": 0.25 },
      { "name": "impact-kind", "value": 0.7, "weight": 0.1 }
    ]
  },
  "blastRadius": {
    "moduleCount": 4,
    "fileCount": 12,
    "uniqueCallerCount": 18,
    "riskLevel": "medium"
  },
  "directImpact": [
    {
      "stableId": "...",
      "name": "LoginHandler",
      "kind": "direct-caller",
      "distance": 1,
      "confidence": 0.95
    }
  ],
  "transitiveImpact": [
    {
      "stableId": "...",
      "name": "ServeHTTP",
      "kind": "transitive-caller",
      "distance": 2,
      "confidence": 0.85
    }
  ],
  "modulesAffected": [
    { "moduleId": "internal/api", "name": "api", "impactCount": 8 },
    { "moduleId": "internal/auth", "name": "auth", "impactCount": 5 }
  ],
  "observedUsage": {
    "hasTelemetry": true,
    "totalCalls": 1250,
    "trend": "stable"
  },
  "blendedConfidence": 0.89,
  "relatedDecisions": [...],
  "docsToUpdate": [...]
}

Blast Radius (v7.6)

The blastRadius field provides a quick summary of impact spread:

Risk Level Criteria
Low ≤2 modules AND ≤5 callers
Medium 3-5 modules OR 6-20 callers
High >5 modules OR >20 callers

Transitive Impact (v7.6)

When depth > 1 and SCIP is available, CKB traces callers-of-callers:

Depth Confidence Use Case
1 0.95 Direct callers only
2 0.85 Default, catches most impact
3 0.75 For high-risk refactors
4 0.65 Maximum coverage, more noise

Risk Score Calculation

Risk is computed from 4 weighted factors:

Factor Weight Description
visibility 30% Public symbols are riskier
direct-callers 35% More callers = higher risk
module-spread 25% Cross-module impact is riskier
impact-kind 10% Breaking changes vs additive

Risk levels:

  • Low < 0.4
  • Medium 0.4-0.6
  • High 0.6-0.8
  • Critical > 0.8

Git Diff Impact Analysis

Analyze the impact of pending code changes from git diffs.

CLI

# Analyze current working tree changes
ckb impact diff

# Analyze only staged changes
ckb impact diff --staged

# Compare against a different branch
ckb impact diff --base=main

# Analyze a commit range (for CI)
ckb impact --range=main..HEAD

# Deeper transitive analysis
ckb impact diff --depth=3

# Strict mode (fail if index is stale)
ckb impact diff --strict

# Output formats
ckb impact diff --format=json       # Machine-readable JSON
ckb impact diff --format=markdown   # PR comment-ready markdown

Output Formats

Format Use Case
text Human-readable terminal output (default)
json Machine-readable, for scripting and CI
markdown PR comments, GitHub/GitLab integration

Markdown Output (--format=markdown)

Generates formatted markdown suitable for PR comments:

ckb impact --range=origin/main..HEAD --format=markdown > comment.md

Example output:

## 🟡 Change Impact Analysis

| Metric | Value |
|--------|------:|
| Risk Level | **medium** |
| Symbols Changed | 12 |
| Directly Affected | 28 |
| Transitively Affected | 45 |
| Modules in Blast Radius | 3 |

### Changed Symbols
- `UserService.Authenticate` (internal/auth/user.go)
- `LoginHandler` (internal/api/login.go)

### Affected Modules
| Module | Impact Count |
|--------|-------------:|
| internal/api | 15 |
| internal/auth | 8 |
| internal/session | 5 |

### Recommendations
- ⚠️ High-risk change affecting 3 modules. Consider additional code review.
- ⚠️ Run tests for affected modules before merging.

This output is designed for the sticky-pull-request-comment GitHub Action pattern.

MCP Tool: analyzeChange

{
  "name": "analyzeChange",
  "arguments": {
    "staged": false,
    "baseBranch": "HEAD",
    "depth": 2,
    "includeTests": false,
    "strict": false
  }
}

Parameters

Parameter Type Default Description
diffContent string - Raw diff (if empty, uses git diff)
staged boolean false Analyze staged changes only
baseBranch string HEAD Base for comparison
depth number 2 Transitive depth (1-4)
includeTests boolean false Include test files
strict boolean false Fail if index is stale

How It Works

Git Diff → Parse Hunks → Map to Symbols → Analyze Impact → Aggregate Results
  1. Parse Diff: Uses sourcegraph/go-diff to parse unified diffs
  2. Map to Symbols: Matches changed lines to SCIP symbol definitions
  3. Analyze Impact: Runs single-symbol impact analysis on each changed symbol
  4. Aggregate Results: Deduplicates, computes module spread, calculates risk

Response

{
  "summary": {
    "filesChanged": 5,
    "symbolsChanged": 23,
    "directlyAffected": 12,
    "transitivelyAffected": 45,
    "estimatedRisk": "medium"
  },
  "changedSymbols": [
    {
      "symbolId": "scip-go gomod example.com/api Handler().",
      "name": "Handler",
      "file": "internal/api/handler.go",
      "changeType": "modified",
      "lines": [45, 46, 47],
      "confidence": 1.0
    }
  ],
  "affectedSymbols": [
    {
      "stableId": "...",
      "name": "ServeHTTP",
      "kind": "direct-caller",
      "distance": 1,
      "moduleId": "internal/server",
      "confidence": 0.9
    }
  ],
  "blastRadius": {
    "moduleCount": 3,
    "fileCount": 8,
    "uniqueCallerCount": 15,
    "riskLevel": "medium"
  },
  "recommendations": [
    {
      "type": "review",
      "severity": "warning",
      "message": "High-risk change affecting 5 modules. Consider additional code review.",
      "action": "Request review from module owners"
    },
    {
      "type": "test",
      "severity": "warning",
      "message": "Significant transitive impact (45 symbols). Run comprehensive test suite.",
      "action": "Run full test suite before merging"
    }
  ],
  "indexStaleness": {
    "isStale": false,
    "commitsBehind": 0,
    "indexedCommit": "abc123",
    "headCommit": "abc123"
  }
}

Confidence Scoring

Symbol mapping confidence based on match precision:

Confidence Meaning
1.0 Exact definition line match
0.8 Change within symbol body
0.7 Reference on changed line
0.3 File-level only (no SCIP data)

Aggregated Risk Scoring

Four weighted factors determine overall risk:

Factor Weight Thresholds
symbols_changed 20% >5 = 0.5, >10 = 0.7, >20 = 1.0
direct_impact 30% >10 = 0.5, >20 = 0.7, >50 = 1.0
transitive_impact 20% >20 = 0.5, >50 = 0.7, >100 = 1.0
module_spread 30% >1 = 0.4, >3 = 0.7, >5 = 1.0

Risk levels: low (<0.4), medium (0.4-0.6), high (0.6-0.8), critical (>0.8)


Affected Tests (v7.5)

Get a list of tests to run based on your code changes. Dramatically reduces CI time by running only relevant tests.

CLI

# Get tests for uncommitted changes
ckb affected-tests

# Output as runnable command
ckb affected-tests --output=command
# → go test -run 'TestAuth|TestLogin|TestSession' ./...

# Output as simple list (one test per line)
ckb affected-tests --format=list
# → TestAuth
# → TestLogin
# → TestSession

# Specify coverage file location
ckb affected-tests --coverage=./coverage/lcov.info

# Strategy options
ckb affected-tests --strategy=precise  # Only tests directly covering changes
ckb affected-tests --strategy=safe     # Include transitive tests (default)
ckb affected-tests --strategy=full     # All tests in affected packages

MCP Tool: getAffectedTests

{
  "name": "getAffectedTests",
  "arguments": {
    "commit": "HEAD",
    "strategy": "safe"
  }
}

Parameters

Parameter Type Default Description
files string[] - Changed file paths
symbols string[] - Changed symbol IDs
commit string - Git commit SHA
commitRange string - "base..head" format
strategy string "safe" Test selection strategy

Test Selection Strategies

Strategy Description Use Case
precise Only tests that directly cover changed lines Fast feedback, may miss edge cases
safe Include tests for transitive callers (1 level) Default, good balance
full All tests in affected packages Pre-merge, paranoid mode

Response

{
  "strategy": "safe",
  "confidence": 0.92,
  "tests": [
    {
      "name": "TestUserAuthenticate",
      "path": "internal/auth/user_test.go",
      "reason": "Directly covers changed symbol UserService.Authenticate",
      "priority": 1
    },
    {
      "name": "TestLoginHandler",
      "path": "internal/api/login_test.go",
      "reason": "Tests caller of changed symbol",
      "priority": 2
    }
  ],
  "commands": {
    "go": "go test -run 'TestUserAuthenticate|TestLoginHandler' ./internal/..."
  },
  "warnings": {
    "uncoveredSymbols": ["internal/legacy/handler.go:OldFunc"],
    "staleData": false
  }
}

Confidence Scoring

Confidence reflects data quality:

Confidence Data Source
0.95+ Coverage file with line-level mapping
0.80-0.94 Naming convention + import analysis
0.60-0.79 Package-level mapping only
< 0.60 Heuristics, consider running full suite

CI Integration Example

- name: Run Affected Tests
  run: |
    # Get test command
    CMD=$(ckb affected-tests --output=command --strategy=safe)
    CONFIDENCE=$(ckb affected-tests --format=json | jq '.confidence')

    if (( $(echo "$CONFIDENCE < 0.7" | bc -l) )); then
      echo "Low confidence, running full suite"
      go test ./...
    else
      echo "Running: $CMD"
      eval "$CMD"
    fi

Reviewer Suggestions

Identify who should review changes based on CODEOWNERS and git history.

CLI

# Get reviewers for uncommitted changes
ckb reviewers

# Include owners of affected (not just changed) code
ckb reviewers --include-affected

# JSON output for scripting
ckb reviewers --format=json

MCP Tool: getChangeOwners

{
  "name": "getChangeOwners",
  "arguments": {
    "commit": "HEAD",
    "includeSecondary": true
  }
}

Parameters

Parameter Type Default Description
files string[] - Changed file paths
symbols string[] - Changed symbol IDs
commit string - Git commit SHA
includeSecondary boolean false Include owners of affected (not changed) code

Response

{
  "primary": [
    {
      "owner": "@security-team",
      "source": "codeowners",
      "pattern": "/internal/auth/*",
      "confidence": 1.0
    },
    {
      "owner": "@alice",
      "source": "git-blame",
      "files": ["internal/auth/user.go"],
      "confidence": 0.85
    }
  ],
  "secondary": [
    {
      "owner": "@api-team",
      "source": "codeowners",
      "reason": "Owns caller of changed symbol",
      "confidence": 0.7
    }
  ],
  "reviewStrategy": {
    "minimum": ["@security-team"],
    "recommended": ["@security-team", "@alice", "@api-team"]
  }
}

Review Strategy

Category Description
minimum Must approve — CODEOWNERS with full match
recommended Should approve — includes secondary owners and git contributors

CI Integration Example

- name: Request Reviews
  run: |
    REVIEWERS=$(ckb reviewers --format=json | jq -r '.reviewStrategy.recommended | join(",")')
    gh pr edit --add-reviewer "$REVIEWERS"

Configuration

Configure impact analysis behavior in .ckb/config.json:

{
  "coverage": {
    "paths": [
      "coverage.out",
      "coverage/lcov.info",
      "coverage.lcov"
    ],
    "autoDetect": true,
    "maxAge": "168h"
  },
  "ownership": {
    "paths": [
      ".github/CODEOWNERS",
      "CODEOWNERS"
    ]
  },
  "impact": {
    "defaultDepth": 2,
    "strict": false,
    "includeTests": true
  }
}
Field Description
coverage.paths Checked in order, first found wins
coverage.autoDetect Also check common locations (default: true)
coverage.maxAge Warn if older than this (default: 168h / 7 days)
ownership.paths CODEOWNERS file locations
impact.defaultDepth Transitive depth 1-4 (default: 2)
impact.strict Fail on stale index (default: false)
impact.includeTests Include test files in analysis (default: true)

Environment Variables

Variable Description
CKB_COVERAGE_PATH Override coverage file location
CKB_IMPACT_DEPTH Default transitive depth
CKB_IMPACT_STRICT Set to 1 to fail on stale index

CI/CD Integration

Impact analysis integrates with CI pipelines for automated risk assessment and PR comments.

GitHub Actions: PR Comment Widget

The simplest integration — post impact analysis as a PR comment:

# .github/workflows/impact-comment.yml
name: Impact Comment

on:
  pull_request:
    types: [opened, synchronize]

permissions:
  contents: read
  pull-requests: write

jobs:
  comment:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Setup CKB
        run: npm install -g @tastehub/ckb

      - name: Generate Impact Report
        run: |
          ckb index --if-stale=24h
          ckb impact \
            --range="${{ github.event.pull_request.base.sha }}..${{ github.sha }}" \
            --format=markdown \
            > impact.md

      - name: Post Comment
        uses: marocchino/sticky-pull-request-comment@v2
        with:
          header: ckb-impact
          path: impact.md

The sticky-pull-request-comment action updates the same comment on each push (via header: ckb-impact) instead of creating duplicates.

GitHub Actions: Full Workflow

Complete workflow with risk gates, reviewer assignment, and affected tests:

# .github/workflows/impact-analysis.yml
name: Change Impact Analysis

on:
  pull_request:
    types: [opened, synchronize, reopened]

permissions:
  contents: read
  pull-requests: write
  checks: write

jobs:
  impact:
    name: Analyze Impact
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0  # Full history for commit range analysis

      - name: Setup CKB
        run: npm install -g @tastehub/ckb

      - name: Index Repository
        run: ckb index --if-stale=24h

      - name: Analyze PR Impact
        id: impact
        run: |
          ckb impact \
            --range="${{ github.event.pull_request.base.sha }}..${{ github.sha }}" \
            --format=json \
            > impact.json

          echo "risk=$(jq -r '.summary.estimatedRisk' impact.json)" >> $GITHUB_OUTPUT
          echo "affected=$(jq -r '.summary.transitivelyAffected' impact.json)" >> $GITHUB_OUTPUT
          echo "files=$(jq -r '.summary.filesChanged' impact.json)" >> $GITHUB_OUTPUT

      - name: Generate PR Comment
        run: |
          ckb impact \
            --range="${{ github.event.pull_request.base.sha }}..${{ github.sha }}" \
            --format=markdown \
            > comment.md

      - name: Post Impact Summary
        uses: marocchino/sticky-pull-request-comment@v2
        with:
          header: impact-analysis
          path: comment.md

      - name: Get Suggested Reviewers
        id: reviewers
        run: |
          reviewers=$(ckb reviewers \
            --range="${{ github.event.pull_request.base.sha }}..${{ github.sha }}" \
            --format=gh)
          echo "list=$reviewers" >> $GITHUB_OUTPUT

      - name: Request Reviewers
        if: steps.reviewers.outputs.list != ''
        run: |
          gh pr edit ${{ github.event.pull_request.number }} \
            --add-reviewer "${{ steps.reviewers.outputs.list }}"
        env:
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}

      - name: Risk Gate
        if: steps.impact.outputs.risk == 'critical'
        run: |
          echo "::error::Critical risk detected. Manual review required."
          echo "## ⛔ Critical Risk Detected" >> $GITHUB_STEP_SUMMARY
          echo "This PR affects critical paths. Please review carefully." >> $GITHUB_STEP_SUMMARY
          exit 1

    outputs:
      risk: ${{ steps.impact.outputs.risk }}
      affected: ${{ steps.impact.outputs.affected }}

Risk-Based Test Strategy

Run different test suites based on impact risk:

- name: Determine Test Strategy
  run: |
    RISK=$(jq -r '.summary.estimatedRisk' impact.json)
    MODULES=$(jq '.blastRadius.moduleCount' impact.json)

    if [ "$RISK" = "critical" ] || [ "$MODULES" -gt 5 ]; then
      echo "Running full test suite"
      go test ./...
    else
      echo "Running affected tests only"
      ckb affected-tests --strategy=safe --output=command | bash
    fi

Pre-commit Hook

Block critical-risk commits locally:

#!/bin/bash
# .git/hooks/pre-commit

# Check if CKB is installed
if ! command -v ckb &> /dev/null; then
    exit 0
fi

RESULT=$(ckb impact diff --staged --format=json 2>/dev/null || echo '{}')
RISK=$(echo "$RESULT" | jq -r '.summary.estimatedRisk // "unknown"')

if [ "$RISK" = "critical" ]; then
    echo ""
    echo "⛔ CRITICAL RISK DETECTED"
    echo "   Review the impact before committing:"
    echo "   $ ckb impact diff --staged"
    echo ""
    echo "   To bypass: git commit --no-verify"
    exit 1
elif [ "$RISK" = "high" ]; then
    echo "⚠️  HIGH RISK CHANGE - consider running full test suite"
fi

exit 0

Make executable: chmod +x .git/hooks/pre-commit

Ready-to-Use Templates

Template Description
examples/github-actions/impact-comment.yml Simple PR comment widget
examples/github-actions/impact-analysis.yml Full workflow with risk gates
examples/gitlab-ci/ckb.yml GitLab CI template
examples/hooks/pre-commit Git pre-commit hook
examples/hooks/husky/ Husky integration for JS/TS

See CI-CD-Integration for more CI templates and examples/README for installation instructions.


Best Practices

When to Use Each Tool

Scenario Tool Flags
"What breaks if I change this function?" ckb impact <symbol> --depth=2
"Is this refactor safe?" ckb impact diff --staged
"Should I merge this PR?" ckb impact diff --base=main
"What tests should I run?" ckb affected-tests --strategy=safe
"Who needs to review this?" ckb reviewers --include-affected

Keeping Coverage Fresh

Coverage data can become stale as tests change. Regenerate periodically:

# In CI: regenerate before impact analysis
- name: Generate Coverage
  run: go test -coverprofile=coverage.out ./...

- name: Analyze Impact
  run: ckb affected-tests --strategy=safe

CKB warns when coverage is older than max_age (default: 7 days).

Handling Large Diffs

For changes with >20 symbols changed:

  1. Break into smaller PRs: Use the split recommendation
  2. Use shallow depth: --depth=1 for faster analysis
  3. Focus on high confidence: Filter by confidence >= 0.7
  4. Check staleness: Ensure index is fresh with --strict

Interpreting Low Confidence

Low confidence (< 0.7) means:

  • The changed file isn't in the SCIP index
  • The language isn't fully supported
  • The index is stale

Actions:

  1. Regenerate index: ckb index
  2. Check language support: ckb doctor --tier=standard
  3. For unsupported languages, use file-level analysis

Limitations

  1. Go has best support: Full SCIP with incremental indexing
  2. Static analysis only: Can't detect runtime-only dependencies (use telemetry)
  3. New files: Added files not in the index get low-confidence entries
  4. Deleted symbols: Deletion detection limited to what was indexed
  5. Dynamic dispatch: Interface implementations may be missed
  6. Single-repo only: Cross-repo impact requires federation (planned for future)
  7. Local coverage files: CKB uses local coverage files, not Codecov/Coveralls APIs

For dynamic dispatch and reflection, use --depth=3 or enable telemetry for observed callers.

Why Local Coverage, Not Codecov API?

CKB uses local coverage files (coverage.out, lcov.info) rather than cloud coverage APIs because:

  1. No API tokens required — Works immediately without setup
  2. Precise line-level mapping — Local files contain exact line coverage
  3. Offline capable — No network dependency for test mapping
  4. Codecov's "Impact Analysis" is different — Codecov's feature uses OpenTelemetry production telemetry, not test coverage

Generate coverage locally in your CI pipeline before running CKB impact analysis.


Example Prompts

"What will break if I rename UserService?"

"Analyze the risk of my current changes"

"Is it safe to refactor LegacyHandler?"

"Show me the blast radius of changing ProcessPayment"

"What tests should I run for my changes?"

"Who should review this PR?"

"Give me the affected tests as a runnable command"