Blast-radius engine — what breaks if I touch this? Reverse call graph + git co-change mining + ownership, judged by an LLM, run entirely on your machine.
Project description
Oneport Impact
"What breaks if I touch this?" — the blast-radius engine that reads your repo's own structure and history, on your machine.
Before you change a function, one command tells you who calls it, which tests
cover it, which files historically change with it, and who to ask — then an LLM
judges how load-bearing it is. grep finds text; Sourcegraph finds references.
Neither tells you that models.py and serializers.py change together 83% of
the time even though there's no import between them. That temporal coupling
lives only in git history — and Impact mines it locally, so nothing is uploaded
to learn it.
$ oneport-impact analyze billing/stripe.py
Blast radius: billing/stripe.py (file)
LOAD-BEARING · 128 call site(s) across 34 file(s) · 61 commits in history
This is core payment code exercised across the app; a signature change here
ripples into checkout, webhooks, and the admin refund flow.
Check first: billing/webhooks.py — changes with this file 83% of the time
Changes together with (temporal coupling)
83% billing/webhooks.py (51/61 commits)
44% tests/test_payments.py (27/61 commits)
Ask
@payments-team [CODEOWNER]
Priya Nair (22 commits, last 2026-05-30)
Why it's different
| Tool | What it gives you | The gap |
|---|---|---|
grep / IDE "find usages" |
text matches | no ranking, no history, no judgment |
| Sourcegraph | cross-repo references | search, not risk; needs your code on their servers |
| oneport-impact | callers + temporal coupling + ownership + risk verdict | local-first — your code never leaves the machine |
Every fact is deterministic (Python ast + git log); the model only judges
the facts. When a symbol's name is too common to attribute reliably (__init__,
get), Impact refuses to guess rather than report an inflated number — the
line between "structured, better than grep" and "confidently wrong."
Install
pip install oneport-impact
# optional, for the risk verdict — detection works without it:
export GEMINI_API_KEY=AIza... # free at https://aistudio.google.com/apikey
Use
# Query the blast radius of a symbol or file
oneport-impact analyze charge # by name
oneport-impact analyze billing.stripe.Client.charge # by qualname
oneport-impact analyze billing/stripe.py # by file
# Gate a change set (for pre-commit / CI)
oneport-impact check --staged # what you're about to commit
oneport-impact check --head # the last commit
oneport-impact check --staged --format json # machine-readable
oneport-impact analyze charge --no-llm # facts only, no API key
Exit code is 1 when a change trips a blocking finding (per --fail-on),
0 otherwise — drop check straight into CI.
What the gate flags
- IMP001 — wide blast radius: you're changing a symbol many places call.
- IMP010 — missing co-change companion: you changed a file but not the file
it historically changes with, e.g. "you changed
model.pybut notserializer.py, which changes with it 80% of the time."
Configure — .oneportrc
thresholds:
fan_in_warn: 8 # callers before a change is "wide"
fan_in_error: 25 # …before it's "very wide"
cochange_confidence: 0.5 # a companion must co-change this often to be flagged
cochange_min_together: 3 # …and at least this many times
max_commits: 1500 # history depth mined for co-change
The same .oneport/guidelines.md the rest of the suite reads is fed to the risk
verdict as context ("our payments module is business-critical").
In the Oneport gate
oneport-impact is an opt-in gate in op ship.
Enable it in .oneport/oneport.yaml:
enable:
- impact
It's advisory by default (warns, blocks only on critical) — it informs the ship decision without nagging.
Privacy
Serverless by design. The call graph, co-change mining, and ownership all run on
your machine from your repo's own .git. Only the optional one-paragraph risk
verdict calls a model, on your key. There is no Oneport server; your code never
leaves the building.
How it works
callgraph.py— reverse call graph via theastmodule, with an ambiguity guard so common names don't inflate fan-in.cochange.py— temporal-coupling miner overgit log, skipping mass-change commits that would couple everything.ownership.py— git authors + CODEOWNERS.advisor.py— the LLM risk verdict; judgment only, never invents facts.
MIT licensed.
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 oneport_impact-0.1.0.tar.gz.
File metadata
- Download URL: oneport_impact-0.1.0.tar.gz
- Upload date:
- Size: 25.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3007bd5dc157e716d2e96448b71e09a9657e8affe5f7a9b63bde4c0c3815c21d
|
|
| MD5 |
3039493af184651015ee82b0bfb16092
|
|
| BLAKE2b-256 |
77d21cd5ed90d1eb284e6edf107b193eb71488f3968952e54812b6a9456c10de
|
File details
Details for the file oneport_impact-0.1.0-py3-none-any.whl.
File metadata
- Download URL: oneport_impact-0.1.0-py3-none-any.whl
- Upload date:
- Size: 29.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6d4f298c43c30ccb05a2f54c40e15007f4f2565842e16a8acd79f041654b36e3
|
|
| MD5 |
e03e2d7a4913631f1baf8bf0f37ddba4
|
|
| BLAKE2b-256 |
1a8f24930a39be592393bf9ef32a5b21a9a31960062dacac9775c7a527dfae58
|