Blast Scope

io.github.Atharva-Jayappa由 GitHub 账号 Atharva-Jayappa 发布v0.6.1更新于 Oct 24, 2026

Contextual blast-radius scoring for shell commands an AI agent is about to run

发布方自己的服务:Scope (AEC) - Preview

已验证STDIO仅桌面开发者工具安全与监控

概览

AI 生成的概览

在 AI 代理执行 shell 命令前评估其破坏性影响范围,返回严重程度、证据和撤销快照。

可以做什么
Blast Scope 是一个针对 shell 命令的后果评估引擎。它解析命令,先判断是否为潜在破坏性命令,再通过安全的只读探测(git status/reflog、docker inspect、读取锁文件、SQLite SELECT 计数)估算命令实际会影响什么。它返回评分、严重等级、理由、证据、可恢复性、受影响的依赖图节点以及按段拆分的链式分析。工具包括 assess_command、index_project、list_snapshots 和 restore_snapshot;PreToolUse 钩子可对高危命令给出建议并创建快照。
适用场景
当代理或开发者要执行可能删除文件、重写 git 历史、移除 Docker 卷、卸载软件包或删除 SQL 表的 shell 命令,并希望在执行前获得建议性风险评分时使用。在具有依赖图的项目中尤其有用,因为同一条命令可能因上下文不同而处于低风险或严重风险。
运行要求
通过 stdio 在本地运行,通常使用 uvx blast-scope 或固定版本的本地检出配合 uv。未声明认证、环境变量或请求头。部分探测需要本地工具或状态(git 仓库、Docker 守护进程、SQLite 文件、锁文件);无法探测时会退回到带标注的估算。
安装前请注意
它仅提供建议,从不阻止命令执行。严重路径可能创建 tar 包撤销快照,会写入磁盘文件。restore_snapshot 会恢复文件并可能覆盖当前状态。评分范围刻意限定为破坏性后果;网络外泄和持久化不在范围内。无法进行只读探测时会明确标注为估算。

安装

在 SourceWeft 中

  1. 打开 控制台中的 Blast Scope,将其添加到工作区。
  2. 为需要使用其工具的对话启用该服务。

Desktop only,通过 STDIO。 STDIO 服务会启动本地进程,因此需要 SourceWeft 桌面宿主。

其他 MCP 客户端

参照 仓库 中的启动说明。

README

Blast Scope

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:

COMMAND                            SEVERITY   WHY                                          ADVICE─────────────────────────────────  ────────   ──────────────────────────────────────────  ───────rm -rf ./logs                      LOW        0 importers · regenerable · outside src      proceedrm -rf ./config                    CRITICAL   8 modules import it · high PageRank hub      blockgit reset --hard   (clean tree)    LOW        nothing uncommitted to discard               proceedgit reset --hard   (4 dirty files) HIGH       would throw away 4 files of uncommitted work confirmgit push --force   (protected)     CRITICAL   would orphan commits on a protected branch   blockdocker volume rm cache  (absent)   LOW        volume doesn't exist — nothing to remove     proceeddocker volume rm pgdata (in use)   CRITICAL   holds data · in use · no image to rebuild    blockpip uninstall flask     (uv.lock)  LOW        regenerable — exact version pinned in lock   proceedDROP TABLE users        (42 rows)  CRITICAL   schema + 42 rows · irreversible              blockDELETE FROM logs        (in txn)   HIGH       no WHERE — but inside a txn, ROLLBACK-able    confirm

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.


How it works

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.

  shell command      │   split chains (&& || ; |) · de-alias PowerShell · parse flags/targets      ▼  ┌──────────────────────────────────────────────────────────────────────┐  │  STAGE 1 · triage  (near-free regex — runs on every command)          │  │     which class?   git · docker · pip/uv · sql · else filesystem       │  │     destructive?   `git status` → no.   `git reset --hard` → yes ↓     │  └───────────────────────────────┬──────────────────────────────────────┘                    destructive candidate │   (everything else exits here, silent)                                          ▼  ┌──────────────────────────────────────────────────────────────────────┐  │  ELIGIBILITY FILTER   safe read-only probe?   AND   undo authorable?   │  └──────────────┬──────────────────────────────────────┬─────────────────┘         yes, probe it │                       no probe here / now │                       ▼                                           ▼   STAGE 2 · safe probe (read-only)                    heuristic estimate     git  status · reflog · rev-list                   from a static per-class     docker  inspect · ps · ls                          table — and LABELED     sqlite  SELECT count(*)  [mode=ro]                  "(estimated)" so you     pip/uv  read lockfiles                              know it wasn't probed                       │                                           │                       └─────────────────────┬─────────────────────┘                                              ▼        blast radius  ×  reversibility   (combined PER CLASS — no global formula)        filesystem also folds in: dependency-graph centrality + recoverability                                              ▼              score 0.0–1.0  →  severity (low / medium / high / critical)                                              ▼        PreToolUse hook:  silent (low/med) · advise (high) · advise + snapshot (critical)

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.

The five command classes

ClassDestructive ops it scoresSafe (read-only) probeReversibility signal
Filesystemrm -rf, mv, > truncatedependency graph + git statusgit-tracked? regenerable? secret? precious?
Gitreset --hard, push --force, branch -D, clean -fdxstatus · reflog · rev-list · rev-parse @{u}reflog window · remote ahead · protected branch
Dockervolume rm, system prune -a, rm -fvolume inspect · ps -a · volume lsvolume → none · container → recreatable from image
pip / uvpip uninstall, uv pip uninstallread lockfile / manifest (no subprocess)lockfile present → fully regenerable
SQLDROP, TRUNCATE, DELETE without WHERESQLite: SELECT count(*) mode=ro; transaction checkinside 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.


Status

Calibrated multi-class guardrail with command resolution and a precise dependency graph.

CapabilityModule
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 $(...) substitutionresolution.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 snapshotclasses/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 indexinggraph_resolver.py, centrality.py
Two-axis, evidence-based filesystem scoringrisk_scorer.py
Command-class probes — git / docker / pip·uv / SQL, behind one protocolclasses/
Out-of-graph path analyzers (infra / config-by-path) + git baseconsequences.py, vcs.py, infra.py, config_refs.py
PreToolUse hook + tarball snapshot/undohook.py, snapshot.py
Eval harness + labeled corpus + calibrationeval.py, tests/fixtures/eval_corpus.jsonl

Calibration. Two harnesses, both run-it-yourself:

  • In-repo corpus (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.
  • SABER — 716 real coding-agent workspaces. Against ~1725 safe commands, blast-scope's false-positive rate is 0.58%; on its core competency (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/.
bash
uv run python -m blast_scope.eval                 # in-repo corpuspython bench/saber_eval.py --tasks <saber>/dataset/data/tasks.jsonl   # SABER

Installation

The fastest path for any MCP client is zero-install via uvx (no clone, no venv):

bash
uvx blast-scope        # runs the MCP server on stdio

Claude Code users — one line wires up both the MCP tools and the advisory hook:

bash
/plugin marketplace add Atharva-Jayappa/blast-scope/plugin install blast-scope

For development, or to pin a checkout:

bash
git clone https://github.com/Atharva-Jayappa/blast-scope.gitcd blast-scope && uv sync --all-extras

Usage

As an MCP server

Add to your MCP client config (e.g. Claude Code settings.json):

json
{  "mcpServers": {    "blast-scope": { "command": "uvx", "args": ["blast-scope"], "type": "stdio" }  }}

Tools exposed:

ToolPurpose
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.

As a hook (tiered advice + auto-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:

json
{  "hooks": {    "SessionStart": [      { "hooks": [{ "type": "command", "command": "python -m blast_scope.hook" }] }    ],    "PreToolUse": [      { "matcher": "Bash",        "hooks": [{ "type": "command", "command": "python -m blast_scope.hook" }] }    ]  }}

Full details and the undo flow: docs/hook.md.


Example output

A filesystem command, scored against the dependency graph:

jsonc
// assess_command("rm -rf ./config", project_root="/proj"){  "score": 0.93,  "severity": "critical",  "recommendation": "block",  "recoverability": "untracked",  "rationale": "rm targets config. 8 direct importer(s), 14 total affected. not git-tracked. recursive deletion. CRITICAL risk.",  "evidence": [    "8 importer(s), 14 affected node(s)",    "high centrality (PageRank 0.91) — a hub other code routes through",    "untracked — not in git history",    "recursive — applies to every file underneath"  ],  "affected_nodes": [ /* ... */ ],  "chain": [ /* per-segment breakdown */ ]}

A command class that couldn't probe — note the labeled estimate (no Postgres driver, server possibly remote, so the tool refuses to guess silently):

jsonc
// assess_command('psql -c "DROP TABLE users"'){  "score": 0.9,  "severity": "critical",  "recommendation": "block",  "evidence": [    "drops users — its schema and all rows, irreversible (estimated — no read-only probe for postgres)"  ]}// the same DROP against a local SQLite file probes for real://   "drops users — its schema and 42 row(s), irreversible"   (estimated: false)

Development

bash
uv sync --all-extrasuv run pytest -q              # full suiteuv run python -m blast_scope.eval   # scoring accuracy report

Project structure

blast-scope/├── src/blast_scope/│   ├── server.py            # MCP server + tools (assess, index, snapshots)│   ├── command_parser.py    # shell → structured intent (POSIX + PowerShell)│   ├── command_effects.py   # command/flag/operand → intent + weight│   ├── recoverability.py    # path → how recoverable if destroyed│   ├── graph_resolver.py    # paths → dependency-graph impact (+ PageRank)│   ├── centrality.py        # pure-Python weighted PageRank│   ├── risk_scorer.py       # signals → score + severity + evidence│   ├── classes/             # command-class probes behind one protocol│   │   ├── __init__.py      #   Candidate · ConsequenceClass · registry│   │   ├── git.py           #   reflog / upstream-divergence / protected branch│   │   ├── docker.py        #   volume / container / system-prune probes│   │   ├── packages.py      #   pip·uv uninstall vs. lockfile presence│   │   └── sql.py           #   DROP/TRUNCATE/DELETE — SQLite probe + estimates│   ├── consequences.py      # coordinator: class probes + path analyzers│   ├── vcs.py / infra.py / config_refs.py   # git base + path analyzers│   ├── hook.py              # PreToolUse advisory hook│   ├── snapshot.py          # tarball snapshot / restore / list│   ├── eval.py              # evaluation harness + metrics│   └── vendor/crg/          # vendored from code-review-graph (MIT)├── tests/                   # 298 tests incl. eval regression guard│   └── fixtures/eval_corpus.jsonl   # labeled calibration corpus└── docs/    ├── heuristics.md        # scoring model + per-class tables + calibration    └── hook.md              # hook registration + undo

Roadmap

  • Lift recall on the destruction classes (glob targets over tracked files, find-based deletion variants) — the SABER per-category table is the worklist.
  • Optional live probes for Postgres/MySQL (in-process, read-only) once a driver policy is settled — today those engines degrade to labeled estimates.
  • PowerShell-shell awareness in the hook path (the MCP tool already supports it).
  • Optional richer interception modes beyond advisory.

See CLAUDE.md for the full spec, contracts, and design rules.


License

Apache 2.0 (versions ≤ 0.3.1 were MIT). The vendored code-review-graph sources remain MIT under their upstream notice — see NOTICE.

来源:README.md,提交 c73f4b5

工具

0
SourceWeft 尚未在沙箱中启动过该软件包,因此其工具未知。

版本历史

1
  1. v0.6.1最新Sep 16, 2026

评分

已满足适用检查项的 50%

该评分衡量此收录条目的完整程度,依据注册中心条目、端点与公开来源计算得出。它不是对服务器本身的评价,也不表示服务器安全或当前可用:可连通性是带日期的检查结果,评分也不包含安装量或用户评价。

  • 近 30 天内可连通25 分

    请保持端点能够响应 MCP 握手;SourceWeft 每 30 天探测一次。

  • 已声明认证方式10 分

    请在注册中心条目中声明凭据请求头,或保持端点能够响应探测,以便判定其认证方式。

  • 已列出工具15 分

    请让服务器在无凭据时响应 tools/list,或发布可在沙箱中无凭据启动的软件包。

  • 描述必需15 分
  • 图标10 分
  • 文档15 分
  • 许可证10 分

其他 Scope 集成