get_blast_radius β
Answers the question "what breaks if I change this?" Returns every symbol that could be affected by modifying the target, graded across three confidence tiers so you know what is certain vs speculative.
See the mandatory sequence before editing.
Parameters β
| Name | Type | Required | Description |
|---|---|---|---|
symbolId | string | yes | Fully-qualified symbol id (<file>::<name>::<kind>) |
confidence | "confirmed" | "likely" | "potential" | no | Restrict results to a single tier |
intent | string | no | Keyword filter on impacted symbols (e.g. "test", "adapter") |
Confidence tiers β
Results are grouped into 3 confidence tiers β see Blast Radius tiers.
Example β
{
"symbolId": "packages/cli/src/adapters/storage/sqlite.ts::SqliteStorageAdapter::class"
}Filter to high-confidence only:
{
"symbolId": "packages/cli/src/adapters/storage/sqlite.ts::SqliteStorageAdapter::class",
"confidence": "confirmed"
}Response β
{
"symbolId": "packages/cli/src/adapters/storage/sqlite.ts::SqliteStorageAdapter::class",
"impactScore": 27,
"directDependentsCount": 6,
"confirmedCount": 6,
"likelyCount": 14,
"potentialCount": 7,
"overallRiskScore": 0.82,
"impactedSymbols": [
{
"symbolId": "packages/cli/src/index.ts::main::function",
"name": "main",
"kind": "function",
"confidence": "confirmed",
"riskScore": 0.91
}
],
"byCluster": {
"packages/cli/src/adapters/storage": 12,
"packages/cli/src/core/graph": 3,
"packages/cli/src/adapters/mcp": 8,
"packages/cli/src/cli": 4
},
"crossClusterEdges": 15,
"multiClusterHint": "Change impacts 4 clusters β multi-team review recommended.",
"_meta": { "totalItems": 27, "returnedItems": 27, "truncated": false }
}If the symbol is missing from the index:
{ "found": false, "hint": "Symbol not found. Run \"ctxo index\" to build the codebase index." }v0.8 cluster fields β
| Field | When present | Meaning |
|---|---|---|
byCluster | A community snapshot exists (ctxo index after v0.8) | Map of clusterLabel β count of impacted symbols in that cluster |
crossClusterEdges | Same | Count of impacted-set edges that cross the target's own cluster |
multiClusterHint | byCluster touches β₯ 3 clusters | Human-readable nudge for multi-team review |
Killer example: same impactScore, different risk β
Two candidate refactors both report impactScore: 10. Before v0.8, they look identical.
| Change | byCluster (v0.8) | Verdict |
|---|---|---|
| A β rename a private method | { "src/billing": 10 } | One cluster, one team; proceed. |
| B β tweak a shared DTO | { "src/billing": 4, "src/auth": 3, "src/reporting": 3 } + multiClusterHint | Three clusters, three teams; needs coordination. |
The raw numbers are identical. The cluster breakdown is the difference between "go" and "stop".
Interpreting overallRiskScore β
| Score | Risk level | Action |
|---|---|---|
> 0.7 | high | Plan carefully, write tests first, review with a teammate |
0.3 - 0.7 | medium | Read get_why_context before editing |
< 0.3 | low | Safe to edit, still verify imports via find_importers if unsure |
See it in action β
See a worked comparison of blind edits vs blast-radius-aware edits: Blast Radius comparison.
Common pitfalls β
Skipping this tool
Editing a symbol without calling get_blast_radius first is the #1 cause of broken dependencies. The static graph catches couplings that grep and manual reading will miss, especially through re-exports and dynamic dispatch.
- Treating
potentialas noise β the tier comes from git co-change history; two files that always change together are coupled even when the parser sees no edge. - Ignoring
_meta.truncatedβ large impact sets are capped byCTXO_RESPONSE_LIMIT. If truncated, narrow withconfidenceorintent. - Using the symbol name instead of id β always pass the full
<file>::<name>::<kind>id. Look it up withsearch_symbolsif you only know the name.
Related tools β
get_why_contextβ required follow-up before editingget_logic_sliceβ forward deps (what this symbol needs)find_importersβ direct reverse lookup onlyget_pr_impactβ blast radius across every changed symbol in a diff