AST call graph analyzer — what breaks if I change this file?
Project description
blast-radius
What breaks if I change this file?
blast-radius builds an incremental AST call graph for your Python project and
answers the question instantly. It indexes imports and symbol definitions into
SQLite (SHA-256 cached — only changed files are re-indexed) and resolves
transitive dependents in milliseconds.
pip install blast-radius
Quickstart
# Build the graph (incremental — only re-indexes changed files)
blast-radius --build
# What breaks if I change src/utils.py?
blast-radius --query src/utils.py
# Output a Mermaid diagram (renders in GitHub READMEs / PRs)
blast-radius --query src/utils.py --mermaid
# Watch mode — auto-rebuild on every save
blast-radius --watch
# Raw JSON output (pipe to jq, scripts, CI)
blast-radius --query src/utils.py --json
Terminal output (with Rich)
src/utils.py ⚡ GOD NODE
├── 📄 src/api/routes.py
├── 📄 src/models/user.py
├── 🧪 tests/test_utils.py
└── 🧪 tests/test_api.py
14 file(s) affected · in-degree 47 · 2 test file(s)
Install Rich for colored output:
pip install blast-radius[rich]
Mermaid diagram (renders in GitHub)
from blast_radius import build_graph, get_blast_radius, to_mermaid
build_graph()
result = get_blast_radius("src/utils.py")
print(to_mermaid(result))
Paste the output into any GitHub issue, PR, or README:
graph TD
utils_py["src/utils.py"]
utils_py --> routes_py["src/api/routes.py"]
utils_py --> user_py["src/models/user.py"]
utils_py --> test_utils_py["tests/test_utils.py"]
style test_utils_py fill:#22c55e,color:#fff
%% total affected: 3 | in-degree: 0
Python API
from blast_radius import build_graph, get_blast_radius, to_mermaid, watch
# Build the import graph (incremental — re-indexes only changed files)
n = build_graph()
print(f"{n} files indexed")
# Query blast radius
result = get_blast_radius("src/mymodule.py")
print(result["total_affected"]) # int
print(result["direct_dependents"]) # list of file paths
print(result["test_files"]) # files that start with tests/
# Mermaid output
diagram = to_mermaid(result)
# Watch mode (blocking — runs until Ctrl+C)
watch(interval=2.0)
Configuration
All paths are configurable — no hardcoded assumptions:
# Scan only specific directories
blast-radius --build --scan src tests
# Use a custom DB path (useful in CI)
blast-radius --build --db /tmp/my-graph.db
# Adjust watch poll interval
blast-radius --watch --interval 1.0
Or via Python API:
from pathlib import Path
build_graph(scan_dirs=["src", "tests"], db_path=Path("/tmp/my-graph.db"))
get_blast_radius("src/utils.py", db_path=Path("/tmp/my-graph.db"))
GitHub Action — comment blast radius on PRs
# .github/workflows/blast-radius.yml
name: Blast Radius
on: [pull_request]
jobs:
blast-radius:
runs-on: ubuntu-latest
permissions:
pull-requests: write
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with: {python-version: "3.11"}
- run: pip install blast-radius
- name: Compute blast radius
id: br
run: |
blast-radius --build
echo "mermaid<<EOF" >> $GITHUB_OUTPUT
blast-radius --query "${{ github.event.pull_request.head.sha }}" --mermaid >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT
- uses: marocchino/sticky-pull-request-comment@v2
with:
message: |
## Blast Radius
${{ steps.br.outputs.mermaid }}
Graphify god-node detection (optional)
If you have graphify installed and
have run graphify update . in your repo, blast-radius will enrich results with
transitive centrality data and flag god nodes (files imported by 30+ modules):
result = get_blast_radius("src/core.py")
if result.get("graphify", {}).get("god_node"):
print("WARNING: this is a god node — change it carefully")
Installation
# Core (no dependencies)
pip install blast-radius
# With Rich colored output
pip install blast-radius[rich]
# With watchdog file watching (faster than polling)
pip install blast-radius[watch]
# Everything
pip install blast-radius[all]
Part of the LexiPro Sovereign OS
blast-radius is extracted from LexiPro — a local-first
agentic OS where it powers the pre-edit safety gate: before any agent touches a
kernel file, get_blast_radius() checks if it's a god node. Agents touching files
with in-degree ≥ 30 must acquire a hard mutex first.
License
MIT — see LICENSE.
Built by Broken Arrow Entertainment LLC · Sovereign Intelligence Systems Group
OS Integration — God-Node Gate
blast-radius wires into pre-edit safety gates to enforce a hard stop before any
agent touches a high-centrality file. This is the v9.6 integration pattern used in
the LexiPro Sovereign OS:
# tool_hook_pipeline.py — _hook_guardian_path_guard (v9.6)
from blast_radius import get_blast_radius, rebuild_if_stale
async def pre_edit_gate(file_path: str) -> dict:
rebuild_if_stale(max_age_seconds=300)
br = get_blast_radius(file_path)
# Hard block — god-node writes require explicit mutex acquisition
if br.get("graphify", {}).get("god_node"):
in_deg = br["graphify"]["in_degree_sum"]
return {
"allowed": False,
"error": (
f"GOD_NODE_PROTECTED: {file_path} has in_degree_sum={in_deg}. "
f"Acquire hard mutex before editing god-node files."
),
}
# High blast radius — warn + emit contention pheromone
if br["total_affected"] >= 10:
emit_contention_pheromone(file_path, strength=br["total_affected"] / 50.0)
return {"allowed": True, "warning": f"{br['total_affected']} dependents affected"}
God-node threshold: files with in_degree_sum >= 30 (via Graphify) require
explicit mutex acquisition before any write. Without Graphify, the gate still warns
on total_affected >= 10.
Pheromone broadcast: high-blast-radius edits emit a WRITE_CONTENTION signal
to the NeuralBus so other agents observe the contested resource and can defer
non-critical writes.
Run graphify update . in your repo root to generate graphify-out/graph.json
and enable god-node detection.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file impact_radius-1.0.0.tar.gz.
File metadata
- Download URL: impact_radius-1.0.0.tar.gz
- Upload date:
- Size: 14.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0025416539a7329f28f3e42181b70a080c2a0de1aeb5206b758fdbd8c66a36d3
|
|
| MD5 |
03c77a7a79cfe3e363a2057a93093c6a
|
|
| BLAKE2b-256 |
4ed476b6a4968181269de3057cd383329b922c7fd9243500a6ad306a44a8fd9c
|
File details
Details for the file impact_radius-1.0.0-py3-none-any.whl.
File metadata
- Download URL: impact_radius-1.0.0-py3-none-any.whl
- Upload date:
- Size: 12.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
cbbbf429d25a1b257ce5f509fc3519f4d9c6ecac68df5ae04b96e74a93b7c8b2
|
|
| MD5 |
d3b70fc1e708d9a7da7dc71a1e07769d
|
|
| BLAKE2b-256 |
738cf9cb08830de4d4f77350079d8f0b05a6f8a808296e04a36c3f46e36e3399
|