How Blast-Radius Analysis Works in code-review-graph to Trace Callers and Dependents

Blast-radius analysis in code-review-graph traces callers and dependents by executing a weighted breadth-first search (BFS) through an SQLite knowledge graph, scoring each reachable node based on relationship types and depth decay to quantify the impact of modified files.

The code-review-graph repository provides a blast-radius analysis engine that maps how changes in specific files propagate through a codebase's call hierarchy. By treating functions, classes, and modules as interconnected nodes in a persistent graph, the system identifies every upstream caller and downstream dependent that could be affected by a code change.

The Two-Layer Architecture

Public Interface: get_impact_radius

In code_review_graph/tools/query.py, the get_impact_radius function (lines 105-122) serves as the primary entry point. It accepts an explicit list of changed files or discovers them automatically via git diff, then delegates the computational heavy lifting to the graph store. The function returns a structured report containing counts of changed nodes, impacted nodes, affected files, and a computed risk rating.

Core Engine: get_impact_radius_sql

The actual graph traversal resides in code_review_graph/graph.py within the GraphStore.get_impact_radius_sql method (starting at line 742). This implementation uses temporary SQLite tables to perform an iterative frontier expansion entirely within the database engine, ensuring linear performance even on cyclic graphs.

Step-by-Step Algorithm Execution

1. Seed Preparation with Qualified Names

The algorithm begins by identifying every graph node residing within the changed files. For each modified file, the system calls self.get_nodes_by_file and inserts the nodes' qualified names into a temporary table named _impact_seeds (lines 996-1000 in graph.py). These seeds represent the origin points of the impact analysis.

2. Edge Weight Configuration

Before traversal begins, the system loads relationship weights from the IMPACT_EDGE_WEIGHTS map defined in code_review_graph/constants.py (lines 421-429) into a temporary table _impact_weights (lines 383-390). This configuration allows different relationship types—such as CALLS or IMPORTS_FROM—to contribute varying levels of impact to the final score.

3. Frontier Initialization and Iterative Expansion

The algorithm initializes two critical temporary tables: _impact_best tracking the highest score for each visited node, and _impact_frontier containing nodes to expand in the current iteration. Both tables are seeded with the changed nodes at a score of 1.0 (lines 511-518).

The BFS loop (lines 886-904) executes up to max_depth times. In each iteration, the system generates candidates by joining the current frontier with the edges table in both directions, applying the formula:

candidate_score = parent_score × edge_weight × IMPACT_DEPTH_DECAY

Only candidates exceeding both their current best score and the IMPACT_SCORE_FLOOR threshold survive (lines 585-618).

4. Result Extraction and Truncation Detection

After the frontier stabilizes or reaches the maximum depth, the algorithm selects the top max_nodes + 1 rows from _impact_best to detect truncation. It joins these results back to the nodes table (lines 909-923), filtering out seed nodes and internal "verilog-kind" nodes to produce the final set of impacted callers and dependents.

Practical Usage Examples

Command Line Interface

The crg impact command provides immediate blast-radius analysis for uncommitted changes:


# Analyze changes in the current branch

crg impact

This command maps to code_review_graph/main.py → get_impact_radius_tool, which internally invokes the full analysis pipeline described above.

Python API Integration

For programmatic access, import the get_impact_radius function from the query tools:

from code_review_graph.tools.query import get_impact_radius

# Analyze the last commit with detailed output

report = get_impact_radius(
    changed_files=None,      # Auto-detect via git diff

    max_depth=2,
    max_results=500,
    detail_level="standard"
)

print(report["summary"])

# Output: Blast radius for 3 changed file(s):

#   - 5 nodes directly changed

#   - 27 nodes impacted (within 2 hops)

#   - 4 additional files affected

Direct Graph Store Access

Advanced users can bypass the wrapper and interact directly with the GraphStore class:

from code_review_graph.graph import GraphStore

store = GraphStore("/tmp/crg.db")
changed = ["src/foo/bar.py", "src/baz/qux.ts"]
impact = store.get_impact_radius(
    changed_files=changed,
    max_depth=3,
    max_nodes=200
)

print(f"Total impacted nodes: {len(impact['impacted_nodes'])}")

Configuration and Tuning

Impact Scoring Constants

The behavior of the blast-radius algorithm is governed by constants in code_review_graph/constants.py:

  • IMPACT_EDGE_WEIGHTS: Maps relationship types (e.g., CALLS, IMPORTS_FROM) to decimal multipliers that determine how strongly a connection transmits impact.
  • IMPACT_DEPTH_DECAY: A decay factor applied at each hop to represent diminishing relevance as distance from the change increases.
  • IMPACT_SCORE_FLOOR: A global threshold below which nodes are discarded to prevent noise from distant, weakly-connected dependents.

Summary

  • Blast-radius analysis performs a weighted BFS through the knowledge graph to identify callers and dependents affected by file changes.
  • The public get_impact_radius tool in code_review_graph/tools/query.py handles input validation and result formatting while delegating computation to GraphStore.
  • The core SQL-based engine in code_review_graph/graph.py uses temporary tables (_impact_seeds, _impact_frontier, _impact_best) to track traversal state and scores.
  • Edge weights and depth decay constants in code_review_graph/constants.py allow fine-tuning of how different relationship types contribute to impact scores.
  • The algorithm stops at max_depth hops or when scores fall below IMPACT_SCORE_FLOOR, ensuring predictable performance on large codebases.

Frequently Asked Questions

How does code-review-graph handle cyclic dependencies during blast-radius analysis?

The algorithm prevents infinite loops by maintaining the _impact_best table, which stores only the highest score encountered for each node. If a cycle is detected, subsequent visits with lower scores are discarded, ensuring the query terminates in linear time relative to the number of edges.

What types of relationships does the blast-radius algorithm consider?

According to the IMPACT_EDGE_WEIGHTS configuration in code_review_graph/constants.py, the system weights various relationship types including CALLS, IMPORTS_FROM, and other code dependencies. Each type receives a specific multiplier that determines how strongly the connection propagates impact scores through the graph.

Can I adjust the sensitivity of the blast-radius calculation?

Yes. You can tune the analysis by modifying max_depth to control search depth, max_nodes to limit result set size, or by adjusting the IMPACT_DEPTH_DECAY and IMPACT_SCORE_FLOOR constants in code_review_graph/constants.py to change how quickly impact diminishes across multiple hops.

How does the system detect when results are truncated?

The engine retrieves max_nodes + 1 rows from the final results table. If the extra row exists, the system marks the results as truncated, indicating that the blast radius extends beyond the configured max_nodes limit and additional callers or dependents may exist.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →