No LLM. No API key. No config. Nothing leaves your runner.
Ever LGTM'd a 12-line diff that took down half the codebase? The diff looked harmless — because the danger wasn't in the diff. It was in the 54 files downstream that nobody checked.
Blastr is a free code review action that catches exactly that. On every pull request it indexes your repo's dependency graph, intersects it with the diff, and posts a deterministic risk report: which files can break the most, which public APIs just changed, which "unrelated" files historically change together, and which hot spots have no tests watching them. Every number is traceable to a structural signal — not a vibe from a model.
# .github/workflows/blastr.yml
name: Blastr
on:
pull_request:
permissions:
contents: read
pull-requests: write
jobs:
risk:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0 # full history unlocks the co-change signal
- uses: Bidbogs-prog/blastr@v1That's the whole setup. ~30 seconds from now, every PR gets this — and this one is real, posted by Blastr on the PR that shipped this very action:
And when a PR is safe, Blastr says so at a glance — a 🟢 badge, and for signal-free changes just a single line. It's loud exactly as often as your repo is dangerous, so a 🔴 still means something on PR #400. One find-or-update comment per PR, edited on every push — never a wall of stacked bot noise.
| Signal | Question it answers | Weight |
|---|---|---|
| Blast radius | If this file breaks, how many files break with it? | 30 |
| Public API churn | Did the diff touch exported symbols other code depends on? | 25 |
| Surprising coupling | Which files historically change with this one but aren't imports? | 15 |
| Centrality | Is this a hub file (PageRank over the import graph)? | 15 |
| Untested hub | Is anything watching this file? (amplifies hubs, ignores leaves) | 10 |
| Churn | Raw size of the change | 5 |
Per-file score 0–100; the PR tier is the riskiest file, escalated one level when
risk is broad (3+ elevated files). Signals only fire where they mean something:
"untested" never flags docs or config, and coupling ignores lockfiles, changelogs,
and generated files. The model is versioned (v1.1) and deterministic: same diff,
same score, every time.
Your reviewer sees the diff. They don't see the 54 files that import it — and neither does an LLM bot reading the same diff. The risk that ships isn't in the lines that changed; it's in the graph around them:
| LLM-over-diff bots | Blastr | |
|---|---|---|
| Sees code around the diff | rarely | the whole import graph |
| "This change breaks 54 downstream files" | can't know | measured |
| Explainable verdicts | prose, unverifiable | every point traceable to a signal |
| Deterministic / reproducible | no | yes |
| Your code sent to a third party | yes | never leaves the runner |
| Cost per PR | $$ | free |
| Noise per PR | comment walls | one comment, updated in place |
They're complementary: Blastr tells you where the risk is; a human (or an agent — see below) tells you whether it's realized. Blastr is the cheap, always-on floor.
- Index — a tree-sitter pass builds a symbol/import graph of the repo (25+ languages: TypeScript, JavaScript, Python, Go, Rust, Java, C/C++, C#, Ruby, PHP, Swift, Kotlin, and more), plus a co-change matrix from git history.
- Intersect — the PR diff is mapped to graph nodes: changed line ranges ∩ exported symbol spans, changed files ∩ dependents, diff ∩ co-change pairs.
- Score — the weighted model above, rendered as one PR comment + a job summary, with per-file driver breakdowns.
First run on a large repo pays a one-time indexing cost (scan time scales with repo size); typical repos review in well under a minute.
- uses: Bidbogs-prog/blastr@v1
with:
github-token: ${{ github.token }} # default; needs pull-requests: write
comment: "true" # "false" → job summary only
fail-on: "never" # never | elevated | high
base: "" # override diff base (non-PR runs)| Output | Value |
|---|---|
tier |
low | elevated | high |
score |
0–100 |
Use it as a gate (optional — by default Blastr reports and never blocks):
- uses: Bidbogs-prog/blastr@v1
with:
fail-on: high # block merges only on high structural riskOr route the outputs yourself — require an extra approval on high, page the
code owner, label the PR:
- uses: Bidbogs-prog/blastr@v1
id: blastr
- if: steps.blastr.outputs.tier == 'high'
run: gh pr edit ${{ github.event.number }} --add-label "high-blast-radius"
env:
GH_TOKEN: ${{ github.token }}- History matters. Check out with
fetch-depth: 0(or ≥300) — the co-change signal reads git history. Blastr self-heals shallow checkouts by fetching what it needs, and warns when history is too thin. - Fork PRs get GitHub's read-only token, so the comment can't post — the report still lands in the job summary, and the outputs still work.
- Monorepos work fine; scores are per-file and the graph spans the checkout.
- Privacy: analysis runs entirely inside your Action runner. Blastr makes exactly one kind of network call: the GitHub API request that posts the comment.
- License: BUSL-1.1 — free to run in your CI, personal or commercial. The only thing you can't do is resell or rehost Blastr itself. Converts to Apache 2.0 in 2030.
The deterministic report tells you where the blast radius is. The next tier sends a graph-aware review agent in after it: grounded in these same signals, it walks the actual dependents, reads the callers, and reviews the PR with the structural map in hand — BYOK (your model, your key), sparse and justified instead of a comment wall. It ships as a GitHub App: hosted, zero CI config.
Two clicks, two optional questions. Early installs get the agent tier free during beta — and the deterministic tier you just installed stays free, forever.
(A ⭐ star helps other teams find Blastr, too.)
Licensed under BUSL-1.1. Built on a commercially licensed subset of SoulForge's code-intelligence engine (see THIRD_PARTY_NOTICES.md). Contributor docs: docs/DEVELOPMENT.md.
