How Blast Radius Analysis Works in code-review-graph: A Deep Dive into the SQLite-Powered Graph Algorithm

Blast radius analysis in code-review-graph measures the scope of a code change by performing a weighted breadth-first search through a SQLite knowledge graph, calculating impact scores based on edge types and depth decay to identify all affected nodes within a configurable hop limit.

The code-review-graph repository provides a sophisticated blast radius analysis tool that quantifies how far-reaching a code change might be by traversing relationships between code entities. This analysis helps developers and reviewers understand the potential risk and scope of modifications before they reach production. At its core, the system uses a custom SQLite-based graph traversal algorithm to compute precise impact scores for every affected node.

Core Components of the Blast Radius Engine

The Public Interface: get_impact_radius

Located in code_review_graph/tools/query.py, the get_impact_radius function serves as the primary entry point for blast radius analysis. It accepts either an explicit list of changed files or automatically discovers them via git diff, then coordinates with the graph store to compute and format the results. This wrapper builds human-readable summaries including counts of changed nodes, impacted nodes, additional affected files, and generates risk ratings (low/medium/high) when using detail_level="minimal".

The Graph Engine: get_impact_radius_sql

The heavy lifting occurs in code_review_graph/graph.py within the GraphStore.get_impact_radius_sql method (starting at line 742). This implementation performs the actual graph traversal using temporary SQLite tables and a frontier-based expansion algorithm. It seeds the search with nodes from changed files, then iteratively expands the frontier while maintaining best-known scores for each node, ensuring the query remains efficient even on cyclic graphs.

Step-by-Step Algorithm Execution

1. Seed Preparation and Edge Weight Configuration

The algorithm begins by identifying all nodes residing in the changed files through self.get_nodes_by_file and storing their qualified names in the _impact_seeds temporary table (lines 996-1000 in graph.py). Simultaneously, it loads the IMPACT_EDGE_WEIGHTS mapping from code_review_graph/constants.py (lines 421-429) into the _impact_weights table, assigning specific weights to relationship types such as CALLS or IMPORTS_FROM.

2. Frontier Initialization

Two critical temporary tables are created: _impact_best tracks the highest impact score for each node, while _impact_frontier contains nodes awaiting expansion in the current iteration. Both tables are initialized with the seed nodes at a score of 1.0 (lines 511-518).

3. Iterative Weighted Expansion

For each depth iteration up to max_depth, the algorithm joins the current frontier with the edges table in both directions to generate candidates. Each candidate receives a score calculated as score = parent_score × edge_weight × depth_decay, where IMPACT_DEPTH_DECAY reduces the score as distance from the source increases (lines 585-618). Only candidates exceeding both the node's current best score and the global IMPACT_SCORE_FLOOR threshold survive and become the next frontier (loop at lines 886-904).

4. Result Extraction and Truncation Detection

After the BFS completes, the system selects the top max_nodes + 1 rows from _impact_best—the extra row serves solely to detect if results were truncated. It joins these results back to the nodes table to retrieve full entity data, filtering out seed nodes and internal "verilog-kind" nodes (lines 909-923).

Practical Implementation Examples

Command-Line Usage

The simplest way to run blast radius analysis is through the CLI:


# Analyze the blast radius of changes in the current branch

crg impact

This command maps to code_review_graph/main.py in the get_impact_radius_tool function, which internally invokes the full analysis pipeline.

Python API Integration

For programmatic access, import the query tool directly:

from code_review_graph.tools.query import get_impact_radius

# Generate a detailed report for the last commit

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 example:

# 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 interact with the underlying GraphStore class:

from code_review_graph.graph import GraphStore

store = GraphStore("/tmp/crg.db")
changed_files = ["src/foo/bar.py", "src/baz/qux.ts"]

impact = store.get_impact_radius_sql(
    changed_files, 
    max_depth=3, 
    max_nodes=200
)

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

Configuration Constants and Tuning

Edge Weights and Scoring Parameters

The behavior of blast radius analysis is controlled by constants defined in code_review_graph/constants.py:

  • IMPACT_EDGE_WEIGHTS: Dictionary mapping relationship types (e.g., CALLS, IMPORTS_FROM) to multipliers that amplify or reduce the propagation of impact scores
  • IMPACT_DEPTH_DECAY: Factor applied at each hop to simulate diminishing influence as distance from the change increases
  • IMPACT_SCORE_FLOOR: Minimum threshold below which nodes are excluded from results, preventing infinite expansion through weak connections

Summary

  • Blast radius analysis in code-review-graph uses a custom SQLite-based BFS algorithm to measure code change impact through relationship traversal.
  • The get_impact_radius function in code_review_graph/tools/query.py provides the public API, while get_impact_radius_sql in code_review_graph/graph.py handles the low-level graph computation.
  • The algorithm employs weighted scoring (parent_score × edge_weight × depth_decay) with configurable thresholds to ensure relevant results while maintaining linear performance on cyclic graphs.
  • Results include counts of changed nodes, impacted nodes, affected files, and risk ratings to guide code review prioritization.

Frequently Asked Questions

How does code-review-graph prevent infinite loops during blast radius analysis?

The algorithm uses the _impact_best temporary table to track the highest score achieved for each node, only updating the frontier when a new path yields a strictly better score. Combined with the IMPACT_SCORE_FLOOR threshold and max_depth limit, this ensures termination even when encountering cyclic dependencies in the graph.

What determines the impact score of a node in the blast radius calculation?

According to the source code in code_review_graph/graph.py, each node's impact score is calculated as the product of three factors: the parent node's score, the specific edge weight from IMPACT_EDGE_WEIGHTS based on relationship type, and the IMPACT_DEPTH_DECAY factor. This multiplication ensures that influence diminishes appropriately with both relationship strength and graph distance.

Can I customize which types of relationships affect the blast radius?

Yes, by modifying the IMPACT_EDGE_WEIGHTS dictionary in code_review_graph/constants.py (lines 421-429), you can adjust how different edge types (such as CALLS, IMPORTS_FROM, or INHERITS_FROM) contribute to the score. Setting a weight to 0.0 effectively excludes that relationship type from the analysis.

What is the difference between max_depth and max_nodes in the blast radius API?

The max_depth parameter controls how many hops the algorithm performs from the seed nodes, limiting the search radius in the graph, while max_nodes caps the total number of results returned after scoring. The system actually fetches max_nodes + 1 internally to detect when truncation occurs, allowing it to report whether additional impacted nodes exist beyond the returned set.

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 →