Skip to main content

blast: A Blast Radius Tool for Coding Agents

Overview

An agent about to change a symbol has one question, and it is not "where does this string appear". It is "what breaks". Those are different questions, and a grep answers only the first.

blast SYMBOL answers the second. It reports where the symbol is declared, which functions lean on it, what it leans on in turn, the comments that describe it and will be wrong once you edit it, and the files that historically move alongside it.

Every edge is derived on demand from the corpus as it is right now. There is no project model to configure and no graph to rebuild, so a file another agent saved a second ago is already in the answer, and a symbol in a language nobody taught the tool about still resolves.

That last part is the trade. A compiler front end would be more precise on the one language it was built for; blast is parser-free and reads byte shape, so it covers every language in a polyglot tree at once and pays for it with heuristics it is required to label rather than hide.

Why this over grep?

Use blast when you are about to change code and want the change's footprint before you make it. It is built for an agent editing an unfamiliar tree, and for a human doing the same thing at 2am.

Reach for gist instead when you know the pattern and want the matching lines. gist is a ripgrep-parity indexed search, and a blast report is a much more expensive thing to compute than the list of lines you actually asked for.

Reach for relate instead when the question is about similarity rather than a symbol - what resembles this file, what repeats across the tree, which files jointly explain a task.

Reach for a language server instead when you have one, the tree is one language, and the project builds. blast is what you use when any of those three is false.

Support

File a bug against this repository when a report is wrong: a call site blast missed, a row it invented, or a definition it failed to find. Paste the symbol and the --json report, which is the whole of what blast believes.

File it against irregex when the fault is in matching itself - a pattern that should match and does not, or a Unicode boundary that reads wrong. irregex is the engine underneath all three faces, and a matching bug reproduces there in isolation.

File it against relate when the fault is in similarity - a twin that is not a twin, or a provenance phrase attributed to the wrong file. The kinship and attribution kernels live there; blast only composes them.

Report a vulnerability through the process in SECURITY.md, never as a public issue.

Install

Install the Python package to get the bindings and the native CLI together:

pip install blast-search

Build from source with a Zig toolchain, or take the CLI from a release.

zig build            # blast → zig-out/bin/blast

On Windows, the installer builds blast.exe, places it in a per-user directory, and adds that directory to the user PATH without elevation:

.\install.ps1

The binary is standalone for the blast verb. provenance additionally reads the codex shelf that relate writes, so install relate if you want attribution.

The language bindings drive the same binary. The Python wheel bundles it; Rust and Go callers supply a CLI build:

Install You write
Python pip install blast-search import blast
Rust cargo add blast-search use blast::…
Go go get github.com/The-Billy-Company/blast/bindings/go import ".../bindings/go/compose"

The bare name blast was taken on both PyPI and crates.io and names there are permanent, so the distribution carries the -search suffix while the identifier you type stays blast — the bs4 / PIL split. All three pull the shared substrate, which is irregex on PyPI and irgx on crates.io. Per-language detail is in bindings/python, bindings/rust, and bindings/go.

Reading a Report

A report has six sections, and they are ordered by how likely you are to have to edit them. Run it on any symbol to see the shape.

blast runBlast

Every section is capped, so a report cannot flood a context window however popular the symbol is. Pass --budget N to cap it harder in approximate tokens; what gets trimmed is counted into stats.omitted rather than silently dropped.

Exact evidence and statistical evidence never mix. A line number and a def/use classification come from matching the bytes; a twin distance comes from compression kinship; they stay in separate fields and are never fused into one relevance score you cannot take apart.

Seed

The seed is where the symbol is declared, plus a guess at what kind of thing it is. A symbol declared in several places lists all of them, strongest declaration first.

Only a source file can declare anything. A definition list in prose and a key in a config file both wear shapes that read like declarations, so they are recorded as mentions and can never pose as the symbol's home.

Dependents

Dependents are the references, and they are the reason you ran the tool. Each row names the file, the line, the enclosing function when there is one, and whether that line uses the symbol or redefines it.

A reference outside a function body counts. Registries, dispatch tables, export lists, route maps, and dependency-injection wiring are exactly the edges that break a build when a name moves, and they live at file scope where a function-shaped search cannot see them.

A reference inside a string literal counts too, marked str. Names get wired by string in reflection, in SQL, and in route tables, so dropping them loses real edges - but a string is weaker evidence than a call, and the report says which it found rather than flattening the two.

Dependencies

Dependencies invert the question: what does the seed itself lean on. This is the list of things whose change would break it, which is what you want when the symbol is misbehaving rather than moving.

Resolution is deliberately conservative. The seed's own parameters and locals are excluded, a qualified head.member resolves only inside the module its head names, and a name that a whole package declares is treated as ambient rather than as a dependency.

Only a function has a body to lean on anything, so a type or a value reports no dependencies at all rather than reporting the neighboring words of its declaration.

Comments

Comments that mention the symbol are the documentation your edit is about to falsify. This is the stale-doc surface, and it is the part of a change that review catches last and users notice first.

A mention inside a comment is never counted as a dependent, and a mention inside a string is never counted as a comment. The same parser-free lexer decides both, so the two sections cannot disagree about where a comment ends.

Twins and Ripple

Twins are files that compress well against the seed's file - near-duplicates, forks, and parallel implementations. They are a co-edit signal rather than a dependency: nothing references anything, but historically these files move together, so a change here usually wants the same change there.

Ripple is the second hop. It names files that call the seed's dependents, so a change that propagates through one of them can reach here, and each row records which dependent bridges the two.

Both are statistical and both are labeled as such. A twin carries its distance so you can see how strong the claim is, and a ripple row carries its bridging name so you can dismiss it in one read.

What Outranks What

Authored code outranks generated code everywhere in the report. A generated file is regenerated from a contract, so it is almost never an agent's edit target - and left unranked it dominates, because codegen repeats a symbol in every stub, descriptor, and client shim it emits.

Generated rows are tagged gen and sorted last rather than deleted. Sometimes the generated call site is the evidence you wanted, and a tool that silently hid it would be lying about the radius.

Ranking runs before the caps, which is the part that matters. It means a symbol with six authored call sites and four hundred generated ones reports the six, where a first-come report would fill its entire budget with stubs and never mention the code you have to change.

Codegen is recognized from a generated-by header marker first and a filename convention second. Both are liberal by design: a false demotion only reorders a report, and no signal here can hide a match.

Recipes

Ask what a rename would touch, before you rename anything.

blast AcmeService

Narrow to one subtree when you already know the change is local. Scope is optional because a blast radius that stopped at a directory would lie, so narrowing is something you must ask for.

blast Session services/backend clients/web

Take the report as one JSON object when an agent is going to read it rather than a person. The schema is stable, every section is a named key, and nothing is truncated without being counted.

blast Session --json

Cap the report when context is tight. The seed, the stats, and the notes are the spine and are never trimmed; the tail goes first, cheapest evidence first.

blast Session --budget 800

Ask what the tool can do, in a form written for a machine reader with no other documentation.

blast --schema

Provenance

blast provenance TEXT answers a different question with the same discipline: where did this text come from, and does the tree still contain it. It is the verb for a snippet you were handed and are about to paste.

Attribution is relate's, verification is blast's. relate attributes each maximal verbatim phrase to one exemplar file on the codex shelf, then blast re-reads that file's current bytes and re-finds the phrase exactly.

A phrase surfaces only if the live file still holds it. That is the whole point of doing this here rather than in relate: an attribution against a shelf built yesterday can name a line that has since been deleted, and blast will not report one.

blast provenance 'const fd = std.posix.openat(std.posix.AT.FDCWD, path'

Raise --min-phrase above its twelve-byte floor to drop trivial quotes, and -C to widen the context lines around each located phrase. The shelf comes from relate index --shelf, and provenance says so plainly when it is missing rather than reporting an empty answer.

Note the two verbs shape their JSON differently, because their answers are different objects. A blast report is one JSON object; provenance emits NDJSON, one row per attributed phrase.

Contracts

Results go to stdout and diagnostics go to stderr, always. A run you piped and a run you watched produce the same bytes on stdout, so a captured report and a read one can never disagree.

Exit codes are ripgrep-shaped. Zero means the verb ran, two means a usage, parse, or missing-shelf error, and a report with no rows is still a zero.

A name that used to be a verb is a diagnostic, never a silent alias. blast context and blast family folded into relate's --matching modifier, and invoking either prints the invocation that replaced it and exits two - so a pinned script fails loudly instead of drifting onto semantics that moved.

blast --schema is the machine-readable contract: every verb, every flag, its type and default, the exit codes, and the notes. Read it rather than parsing --help, which is written for a person, and note that --version reports this package's own number rather than the engine's.

Build and Test

Build, test, and typecheck with the Zig toolchain.

zig build          # the blast binary → zig-out/bin/blast
zig build test     # the unit suite
zig build check    # compile-only

Builds are ReleaseFast unless -Dcli-optimize says otherwise. The suite here is deliberately small: this package is a face over engines that carry their own much larger suites, so most of blast's behavior is proven underneath it.

The package's import topology is machine-checked by charter.zone, which allows two hops of reach and no more. The face lives in src/surface/face/blast/ and imports everything else: irregex for engines, corpus, and argv; relate for kinship, the shelf, and the composition kernels; gist for the CLI chassis.

Where This Came From

blast was extracted from a package path inside a private monorepo, cut at ce430bbaab. It was briefly named irregex, which is why that name now belongs to the engine package rather than to a binary.

Development uses sibling checkouts wired by build.zig.zon path dependencies; releases pin a url and a hash. The license is Apache-2.0, matching every package underneath it.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

blast_search-1.2.1-py3-none-win_arm64.whl (3.2 MB view details)

Uploaded Python 3Windows ARM64

blast_search-1.2.1-py3-none-win_amd64.whl (3.4 MB view details)

Uploaded Python 3Windows x86-64

blast_search-1.2.1-py3-none-manylinux_2_17_x86_64.whl (3.3 MB view details)

Uploaded Python 3manylinux: glibc 2.17+ x86-64

blast_search-1.2.1-py3-none-manylinux_2_17_aarch64.whl (3.1 MB view details)

Uploaded Python 3manylinux: glibc 2.17+ ARM64

blast_search-1.2.1-py3-none-macosx_11_0_x86_64.whl (2.3 MB view details)

Uploaded Python 3macOS 11.0+ x86-64

blast_search-1.2.1-py3-none-macosx_11_0_arm64.whl (2.2 MB view details)

Uploaded Python 3macOS 11.0+ ARM64

File details

Details for the file blast_search-1.2.1-py3-none-win_arm64.whl.

File metadata

  • Download URL: blast_search-1.2.1-py3-none-win_arm64.whl
  • Upload date:
  • Size: 3.2 MB
  • Tags: Python 3, Windows ARM64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for blast_search-1.2.1-py3-none-win_arm64.whl
Algorithm Hash digest
SHA256 f4bec90342b61dbe312dc0cbe0d52240f04e1f7a91d9c6bbcfd86ad4b634b311
MD5 a08f9f9a26e43deffe6db73e0eb3bca5
BLAKE2b-256 e043c53ee835f2c69dfc4bcab5a6c243b2f70e7f2382d6f78c0c426bc28f3aae

See more details on using hashes here.

Provenance

The following attestation bundles were made for blast_search-1.2.1-py3-none-win_arm64.whl:

Publisher: release.yml on The-Billy-Company/blast

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file blast_search-1.2.1-py3-none-win_amd64.whl.

File metadata

  • Download URL: blast_search-1.2.1-py3-none-win_amd64.whl
  • Upload date:
  • Size: 3.4 MB
  • Tags: Python 3, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for blast_search-1.2.1-py3-none-win_amd64.whl
Algorithm Hash digest
SHA256 bda565d80469105e0acb0b9a8c31f83efeda2746dc6593a8f25ae0f89e2fe952
MD5 68de5b11bfa1185adc3b2af244d74490
BLAKE2b-256 a37b004d6f45a0d102c6eec579c03cd1f1c142d266baf512fe717cc2ee3259b0

See more details on using hashes here.

Provenance

The following attestation bundles were made for blast_search-1.2.1-py3-none-win_amd64.whl:

Publisher: release.yml on The-Billy-Company/blast

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file blast_search-1.2.1-py3-none-manylinux_2_17_x86_64.whl.

File metadata

File hashes

Hashes for blast_search-1.2.1-py3-none-manylinux_2_17_x86_64.whl
Algorithm Hash digest
SHA256 f0bf1574dd5f60632d3f2f04d46384e75a08d4292e8635f8f8498d1297ccc6dd
MD5 34d1ebd2082654009f0e2ff1b4fff5b9
BLAKE2b-256 a9900b4d9de58b4066c67b2d6122a1c4bbc7b969b57ec90819acc1f54148f7eb

See more details on using hashes here.

Provenance

The following attestation bundles were made for blast_search-1.2.1-py3-none-manylinux_2_17_x86_64.whl:

Publisher: release.yml on The-Billy-Company/blast

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file blast_search-1.2.1-py3-none-manylinux_2_17_aarch64.whl.

File metadata

File hashes

Hashes for blast_search-1.2.1-py3-none-manylinux_2_17_aarch64.whl
Algorithm Hash digest
SHA256 2939f639dc9404dc410e7d137ad98825c3a1844ba37a09c7bba155a2ad7bcbe5
MD5 b58700cbdc212113ffa6e89c2aebfbb5
BLAKE2b-256 a982c604cc9ace8f7abd49eddc4d73234fe8b3ee32ba9340557c17238fc77286

See more details on using hashes here.

Provenance

The following attestation bundles were made for blast_search-1.2.1-py3-none-manylinux_2_17_aarch64.whl:

Publisher: release.yml on The-Billy-Company/blast

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file blast_search-1.2.1-py3-none-macosx_11_0_x86_64.whl.

File metadata

File hashes

Hashes for blast_search-1.2.1-py3-none-macosx_11_0_x86_64.whl
Algorithm Hash digest
SHA256 23f7869643b5ba4412311a6e9ef1c9298b57359e3bd009c08b322d283389caf6
MD5 d0d6211b48fa0b8ce4dc50fe0a4f9ead
BLAKE2b-256 907c78859e35f9522f998c9155d758432bba53b43ebc41b53c3f3c8b299f5c0b

See more details on using hashes here.

Provenance

The following attestation bundles were made for blast_search-1.2.1-py3-none-macosx_11_0_x86_64.whl:

Publisher: release.yml on The-Billy-Company/blast

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file blast_search-1.2.1-py3-none-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for blast_search-1.2.1-py3-none-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 56a3514b23e49f37eba5076e0d963bc7dc9faf88354534b5c3f95081d37b0e56
MD5 f73feb1ba7b362c9a1c76daf942ec5f3
BLAKE2b-256 e77d529e4a306f087571b8f4bd4277a08bb21a8b9f13983e04d5fa9689376bb3

See more details on using hashes here.

Provenance

The following attestation bundles were made for blast_search-1.2.1-py3-none-macosx_11_0_arm64.whl:

Publisher: release.yml on The-Billy-Company/blast

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

This release

1.2.1 This release

6 files

1.1.2

2 files

1.1.1

2 files

1.1.0

2 files

1.0.0

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page