The full upstream README, mirrored here for reference. Install config, tool schemas, adoption signals, and an original overview live on the Blast Scope listing page.
A consequence engine for shell commands. Blast Scope scores what a command would actually do — before an AI agent (or you) runs it. It doesn't pattern-match syntax into a blocklist; it figures out the command's real target, observes that target with a safe, read-only probe, and returns a structured risk score with evidence.
The whole point is contextual blast radius. The same command gets a completely different score depending on what it would actually hit:
Two commands can be byte-identical and score four bands apart. That gap is the product.
Not a blocklist. Not a replacement for Shellfirm. Not a syscall monitor. It scores structural consequence — advisory, never blocking — and for the rare critical command it captures an undo snapshot first.
A command flows through a cheap funnel: almost everything is recognized as non-destructive in microseconds and exits silent. Only a flagged destructive candidate pays for a probe.
The eligibility filter is the design boundary. A command class earns a live probe only when both hold: (1) its impact is observable by a strictly side-effect-free read (HTTP-GET sense — never mutate state to assess state), and (2) its undo story is well-known enough to encode in a static table. When a probe can't run here and now (no docker daemon, no DB driver, no creds), the tool degrades to a labeled estimate — it never guesses silently, and it never blocks.
See docs/heuristics.md for the per-class tables, the exact filesystem formula, and calibration.
| Class | Destructive ops it scores | Safe (read-only) probe | Reversibility signal |
|---|---|---|---|
| Filesystem | rm -rf, mv, > truncate | dependency graph + git status | git-tracked? regenerable? secret? precious? |
| Git | reset --hard, push --force, branch -D, clean -fdx | status · reflog · rev-list · rev-parse @{u} | reflog window · remote ahead · protected branch |
| Docker | volume rm, system prune -a, rm -f | volume inspect · ps -a · volume ls | volume → none · container → recreatable from image |
| pip / uv | pip uninstall, uv pip uninstall | read lockfile / manifest (no subprocess) | lockfile present → fully regenerable |
| SQL | DROP, TRUNCATE, DELETE without WHERE | SQLite: SELECT count(*) mode=ro; transaction check | inside a transaction? backup posture? |
New classes drop in behind one protocol (triage / assess)
in src/blast_scope/classes/; each class confines
assess to strictly side-effect-free reads.
Calibrated multi-class guardrail with command resolution and a precise dependency graph.
| Capability | Module |
|---|---|
| Flag/operand-sensitive command model (POSIX and PowerShell) | command_effects.py, command_parser.py |
Command resolution — env/tilde/brace/glob expansion, unset-var hazards, script transparency (sh -c, npm run + pre/post hooks, script files, Makefile targets), read-only $(...) substitution | resolution.py |
Dry-run oracles — git clean -n exact lists, reset divergence, checkout clobber preview, find -delete→-print rewrite, sqlite scoped-DELETE counts, rsync --dry-run; oracle targets feed the undo snapshot | classes/git.py, classes/find.py, classes/rsync.py, classes/sql.py |
| Recoverability classification (git state, secrets, regenerable, precious data) | recoverability.py |
| Dependency graph + weighted PageRank centrality, incremental indexing | graph_resolver.py, centrality.py |
| Two-axis, evidence-based filesystem scoring | risk_scorer.py |
| Command-class probes — git / docker / pip·uv / SQL, behind one protocol | classes/ |
| Out-of-graph path analyzers (infra / config-by-path) + git base | consequences.py, vcs.py, infra.py, config_refs.py |
| PreToolUse hook + tarball snapshot/undo | hook.py, snapshot.py |
| Eval harness + labeled corpus + calibration | eval.py, tests/fixtures/eval_corpus.jsonl |
Calibration. Two harnesses, both run-it-yourself:
tests/fixtures/eval_corpus.jsonl, 58 cases spanning every
recoverability category, git working-tree state, infra/config, rm -rf .git,
a graph-indexed central module, the git/docker/pip/SQL classes, and the
resolution layer — unset-var collapses, glob/env-var targets, sh -c
payloads, npm pre-hooks, opaque wrappers, mass destruction of tracked
source) — 58/58 exact severity, gate F1 1.00, pinned by
tests/test_eval.py with headroom so changes can't silently regress.data_destruction) it catches 82.4% of
injected attacks on realistic workspaces — on the fast hook path, no graph
required, thanks to command resolution (env/glob binding + script
transparency). Wrapper transparency also lifts code_tampering from ~0% to
50%. The per-category recall is deliberately uneven, and the table says so:
blast-scope scores destructive consequence — filesystem/data loss plus
git/docker/pip/SQL state. Network exfiltration and persistence are a different
threat model, out of scope by design — not an unfinished corner. That's the
boundary, drawn on purpose. See bench/.The fastest path for any MCP client is zero-install via uvx (no clone, no venv):
Claude Code users — one line wires up both the MCP tools and the advisory hook:
For development, or to pin a checkout:
Add to your MCP client config (e.g. Claude Code settings.json):
Tools exposed:
| Tool | Purpose |
|---|---|
assess_command(command, cwd?, project_root?) | Score a (possibly chained) command. Returns score, severity, rationale, evidence, recoverability, affected nodes, and a per-segment chain breakdown. |
index_project(project_root) | Force a dependency-graph rebuild (auto-built on first use otherwise). |
list_snapshots(project_root) | List undo snapshots, newest first. |
restore_snapshot(snapshot_id, project_root) | Undo a risky command by restoring its snapshot. |
Intercept Bash commands before they run — advisory, never blocking. Volume scales with stakes: silent on low/medium, advise on high, advise + snapshot on critical. The snapshot skips what's already recoverable (git-clean, regenerable) and warns rather than tars anything over a hard size cap, so the undo net stays fast and trustworthy.
The hooks also keep the dependency graph alive on their own — no MCP call
needed: SessionStart cold-builds it in a detached background process, and
every PreToolUse refreshes it incrementally before scoring (a ~20 ms stat
sweep when nothing changed), so verdicts track the current tree even after a
burst of agent edits. Add to .claude/settings.json:
Full details and the undo flow: docs/hook.md.
A filesystem command, scored against the dependency graph:
A command class that couldn't probe — note the labeled estimate (no Postgres driver, server possibly remote, so the tool refuses to guess silently):
find-based deletion variants) — the SABER per-category table is the worklist.See CLAUDE.md for the full spec, contracts, and design rules.
Apache 2.0 (versions ≤ 0.3.1 were MIT). The vendored code-review-graph sources remain MIT under their upstream notice — see NOTICE.