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

> Understand blast radius analysis in code-review-graph. Learn how a SQLite graph and BFS algorithm reveal code change impact scores and affected nodes. Optimize your impact assessment.

- Repository: [Tirth Kanani/code-review-graph](https://github.com/tirth8205/code-review-graph)
- Tags: deep-dive
- Published: 2026-07-19

---

**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`](https://github.com/tirth8205/code-review-graph/blob/main/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`](https://github.com/tirth8205/code-review-graph/blob/main/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`](https://github.com/tirth8205/code-review-graph/blob/main/graph.py)). Simultaneously, it loads the `IMPACT_EDGE_WEIGHTS` mapping from [`code_review_graph/constants.py`](https://github.com/tirth8205/code-review-graph/blob/main/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:

```bash

# Analyze the blast radius of changes in the current branch

crg impact

```

This command maps to [`code_review_graph/main.py`](https://github.com/tirth8205/code-review-graph/blob/main/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:

```python
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:

```python
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`](https://github.com/tirth8205/code-review-graph/blob/main/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`](https://github.com/tirth8205/code-review-graph/blob/main/code_review_graph/tools/query.py) provides the public API, while **`get_impact_radius_sql`** in [`code_review_graph/graph.py`](https://github.com/tirth8205/code-review-graph/blob/main/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`](https://github.com/tirth8205/code-review-graph/blob/main/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`](https://github.com/tirth8205/code-review-graph/blob/main/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.