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:
- "What downstream code might break?" — Blast radius analysis
- "Which tests should I run?" — Targeted test selection
- "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
- Quick Start
- Single Symbol Impact Analysis
- Git Diff Impact Analysis
- Affected Tests (v7.5)
- Reviewer Suggestions
- Configuration
- CI/CD Integration
- Best Practices
- Limitations
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
Recommended: SCIP Index (Standard Tier)
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
blendedConfidencecombining 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
affectedTestsfield in impact analysisckb affected-testscommand
Fallback strategies (when no coverage file):
- Naming convention:
foo.go→foo_test.go - Import analysis: tests importing changed package
- 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:
affectedOwnersin impact analysisckb reviewerscommand- 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
- Parse Diff: Uses
sourcegraph/go-diffto parse unified diffs - Map to Symbols: Matches changed lines to SCIP symbol definitions
- Analyze Impact: Runs single-symbol impact analysis on each changed symbol
- 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:
- Break into smaller PRs: Use the
splitrecommendation - Use shallow depth:
--depth=1for faster analysis - Focus on high confidence: Filter by
confidence >= 0.7 - 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:
- Regenerate index:
ckb index - Check language support:
ckb doctor --tier=standard - For unsupported languages, use file-level analysis
Limitations
- Go has best support: Full SCIP with incremental indexing
- Static analysis only: Can't detect runtime-only dependencies (use telemetry)
- New files: Added files not in the index get low-confidence entries
- Deleted symbols: Deletion detection limited to what was indexed
- Dynamic dispatch: Interface implementations may be missed
- Single-repo only: Cross-repo impact requires federation (planned for future)
- 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:
- No API tokens required — Works immediately without setup
- Precise line-level mapping — Local files contain exact line coverage
- Offline capable — No network dependency for test mapping
- 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"
Related Pages
- MCP-Tools#analyzeImpact - MCP tool reference
- MCP-Tools#analyzeChange - MCP tool reference
- CI-CD-Integration - Full CI/CD workflows
- Telemetry - Runtime observability setup
- Language-Support - SCIP indexer compatibility
- Features#impact-analysis--safety - Feature overview