DEV Community

Cover image for Which AI coding assistants can see blast radius before they change code?
Daniel Westgaard
Daniel Westgaard

Posted on • Originally published at riftmap.dev

Which AI coding assistants can see blast radius before they change code?

I keep hitting the same moment, and if you run more than a handful of repositories you probably do too.

Claude Code is open in the platform repo. Cursor is open in a service two directories over. The base image both of them build on top of just shipped a CVE fix, so I want to bump the FROM line. Or a Terraform module half the stacks pull in through a source block needs one variable tightened. The edit itself is thirty seconds of work. The question that decides whether I make it before lunch or spend the afternoon in an incident channel is the one neither window will answer on its own: who else breaks.

So I went and checked what each of the assistants I actually drive can do about that question today. The honest finding is worth stating flat, because it is easy to lift and easy to misread.

As of July 2026, none of the three mainstream AI coding assistants, not Claude Code, not Cursor, not GitHub Copilot, resolves the cross-repo blast radius of a change, deterministically, completely, org-wide, on its own. The reason is not model quality, and it is not a feature any of them forgot to ship. The dependency edge that breaks the other repo was declared in a manifest none of them resolved into a graph, often in a repo the assistant never took in at all. Each of the three can answer the question. But only once you hand it a parsed dependency graph to query.

That is the whole post. The rest is why, and what "hand it a graph" actually means.

The question hides a conflation

The question "which assistant sees blast radius" smuggles in an assumption, and the assumption is the whole game: that an assistant which can see your repositories therefore knows how they depend on each other. Those are two different things, and the gap between them is where every one of these tools stops.

Access is not structure. Claude Code can read every file in seven repos you granted it and still not hold a single edge between them. A text match is not a resolved edge. Cursor can grep those repos and land on a FROM or a source line, and still not resolve it to the repo that produces the module, or walk the chain past the first hop. A curated context set is not a parsed graph. Copilot Spaces can hold exactly the repositories a task needs, but only if you already knew which ones to add.

The edge you actually care about is a specific, boring, declared thing. A Dockerfile FROM line in a downstream service. A go.mod require pinning a consumer to your module. A Terraform source block, a Helm value reference, a GitLab CI include. It was written down, in a manifest, in a repo. Just not the repo you happen to have open. The set of repositories on the far side of those edges is the blast radius of the change, and when an AI agent is the one making the change fast, that is AI-agent blast radius. It is exactly what a single repo's clone cannot show.

What each assistant can actually see today

Claude Code, Cursor, and GitHub Copilot have each shipped a real multi-repo capability in 2026, and being precise about what each one is matters, because they are three genuinely different mechanisms and none of them is a dependency graph. Capabilities in this space move fast, so treat everything below as re-checked on 13 July 2026 against each vendor's own current docs and roughly three months of changelog.

Claude Code: access, by design

Claude Code's cross-repo mechanism is directory access, and it is built to reach a dependency graph from somewhere else rather than construct one itself. The --add-dir flag grants Claude read and write access to directories outside the one it started in, and permissions.additionalDirectories makes that grant persistent. The /add-dir command does the same from inside a running session. Anthropic's own large-codebase guidance documents the cross-repo move under Grant access across packages or repositories: when a task spans multiple checkouts, you extend --add-dir or additionalDirectories to a separately-checked-out repository. All of it is genuinely useful. Point Claude Code at all seven repos and it can read and edit across them in one session.

What it gives you is access, and access is not the same as the answer. At a handful of repos the difference barely bites: grant Claude all of them and you can work out by hand which one breaks when you bump the base image, because the breaking edge is a real line in a real file, the FROM in a downstream service's Dockerfile, and once you have added that directory Claude can read it. The difference bites at scale. At an organisation's real size the repo on the far end of the edge is one you never added. Reconstructing the transitive closure across every manifest in the org, on demand, is the parser's deterministic job, not something the model does reliably or unprompted. Claude Code is the tool in this comparison best positioned to call an external dependency graph, and it is built to reach one: it connects to external services over MCP by design, and Anthropic's own guidance is to offload heavy search to an index exposed that way rather than read everything itself. That guidance names a search index, not a dependency graph, and the two are different objects. The architectural move is the same one, though, and a parsed dependency graph is exactly the kind of external service Claude Code is built to call. It is a consumer of the graph, not a rival to it.

Cursor: the agent can chase the chain, not resolve it

Cursor's agent can attempt the cross-repo chain-walk itself, and being precise about how is what keeps this fair. Alongside the embeddings, Cursor ships Instant Grep, which its docs describe as a custom search engine that "outperforms ripgrep on large codebases," and the agent reaches for grep automatically when you reference a specific symbol. A declared dependency is a literal string, FROM myorg/base-image or source = "cloudposse/ssm-parameter-store/aws", and grep finds literal strings, so Cursor really can surface a FROM or a source line. With a model in the loop it can go further than a bare grep. It can map the Registry shorthand cloudposse/ssm-parameter-store/aws to the repository terraform-aws-ssm-parameter-store, because the model knows the Terraform Registry's terraform-<provider>-<name> convention, then grep for that repository and chain outward a hop at a time. For a coordinated edit across a frontend, a backend, and a shared library I already know are related, I use it and it is good.

Concede the whole of that. The agent can attempt the chain-walk. The line is not whether it can try, it is what the attempt is. Chaining greps with a model resolving each shorthand by convention is inference. Partial, non-deterministic, bounded to the repositories you added to the workspace, and an expensive multi-grep crawl that gets shakier every hop, this chain running six hops deep and fanning out into several repositories along the way. The model might resolve the shorthand correctly. It might miss the second literal form of the same edge, the explicit git:: URL written elsewhere in the org. It might stop at hop three. One resolved query against a graph that already parsed and resolved every edge is right by construction, complete, and org-wide. The model might get it right. A parsed graph is right.

GitHub Copilot: a context set you assemble by hand

GitHub Copilot reaches across repositories through a curated context set and a cloud agent, and each stops short of a dependency graph for the same underlying reason. Copilot Spaces let you assemble a set that can hold whole repositories alongside files, issues, PRs, and free-text notes, and share it across the org. GitHub's docs describe a Space's sources as "automatically updated as they change, making Copilot an evergreen expert in your project," which is a real strength: the set stays fresh without anyone re-uploading. The Copilot cloud agent, renamed from Copilot coding agent in GitHub's own changelog on 1 April 2026, will pick up a task and open a pull request for you.

Each has a real edge and the same wall. A Space is only ever as good as its curation, because you assemble it by hand: it holds exactly the repositories you decided to add. The cloud agent is scoped tighter still. GitHub's own documentation is blunt about the limit: Copilot "cannot make changes across multiple repositories in one run," works one branch at a time, and opens exactly one pull request per task. You can widen what it reads by naming sibling repositories, and I have written up how to wire that. But it reads the repositories you point it at, and no mechanism here tells you which those are.

The comparison, in one table

Put Claude Code, Cursor, and GitHub Copilot side by side on the one axis that matters here, cross-repo blast radius, and the pattern is not three different amounts of the same capability. It is three tools solving access and reasoning, and a fourth kind of thing solving structure. The last row is not a competing assistant. It is the parsed graph the other three can call.

How it reaches across repos What that answers well What it structurally cannot resolve
Claude Code Directory access: --add-dir, /add-dir, or permissions.additionalDirectories. You grant it the clones. Reading and editing across every repo you have checked out, in one session. Which of those repos breaks if a shared manifest edge changes, and which repo to add in the first place.
Cursor Instant Grep and an embeddings index across the folders in a multi-root workspace. Finding a declared line or a semantically related chunk across the folders you added. The agent can infer the chain hop by hop, but that stays non-deterministic and bounded to the workspace, never a resolved, deduplicated graph.
GitHub Copilot A curated Copilot Space and a cloud agent scoped to one repo per task. Answering over a context set you assembled by hand. Which repositories to put in that set. The cloud agent touches one repo and opens one PR.
A parsed artifact graph (e.g. Riftmap) Parses the declared manifest edges across the whole org from one read-only token. No clone needed. Which repositories transitively depend on a given repo, returned before you touch it. Which function or CI job inside a downstream repo breaks. It resolves repositories, not symbols.

Read down the last column. Every "cannot" in the first three rows is the same shape: an edge whose far end is in a repo the tool never took in, or never resolved past the string. Read the last row's "cannot" and it is a different shape entirely. A real limit, but a limit of resolution, repositories rather than functions, not a limit of reach.

Why none of them can resolve it

None of Claude Code, Cursor, or GitHub Copilot resolves cross-repo blast radius on its own, and the reason is structural. Two walls stand in the way, and each of the three hits both. The first is resolution. Reading a repo is not resolving its edges. An edge only enters a graph when something parses the manifest that declares it and resolves the shorthand back to the producing repository. Cursor's agent can chain greps and walk the composition outward, which is real, but a chain-walk is inference, partial, non-deterministic, stopping wherever the crawl runs out. None of the three parses and resolves on its own.

The second wall is reach, and it is where every cross-repo mechanism the three ship bottoms out. Granting Claude Code the clones. Adding folders to a Cursor workspace. Curating a Copilot Space. Configuring one of Cursor's new cloud multi-repo environments. Fanning Copilot tasks across repositories over the new agent-tasks API. Each terminates in a list of repositories a human chose, and choosing that list is the blast-radius question itself. The agent can try to extend that list by discovery, grepping outward and cloning what it finds. But discovery is bounded to what the agent already reached, it is non-deterministic, and it cannot add the repo that breaks until it already knows it breaks. That last constraint is the resolution wall in the reach wall's clothing, and it is the thing you were trying to find out.

This is why "just use a bigger context window" and "just embed everything" do not close the gap. Embeddings retrieve by resemblance, and a declared dependency is not a resemblance; that is the argument I make at length in inferred context is not a dependency graph. Symbol graphs, the Sourcegraph-style index of where a function is defined and called, are genuinely excellent and also the wrong layer here: they resolve code symbols, not the infrastructure edges declared in Terraform, Docker, Helm, and CI, which is a different category of graph entirely. And this is not a hypothetical failure mode. It is the mechanism behind a measurable rise in change-failure rate as AI-accelerated changes outrun anyone's ability to see their consequences, which I have written up with the 2026 data.

One honest caveat, because a sharp reader will have it ready. Step one category over from the daily-driver assistants and a tool did ship real cross-repo awareness on this exact layer: Qodo's Cross Repo Review, announced in June 2026. It is not a lightweight player and I want to be fair to it. Its docs define a relationship type where, in their words, "One repository depends on a build artifact, container image, or pipeline output produced by the other." That is the artifact layer, named explicitly. Qodo reaches it, it is well funded, and it belongs in this conversation. And it is worth being precise about how Qodo comes to know those relationships: its docs say a relationship can be discovered automatically or defined by hand, which puts it across inferred and registered both, not one clean regime. The line I draw is not capability, it is mechanism and moment. Where a relationship feeds the impact call, Qodo's docs disclose the mechanism: "The agent reads the related repositories and traces the impact in both directions: code that depends on the change, and code in the PR that may conflict with the other repository." That is an LLM tracing at review time, which is inference, not a deterministic parser resolving a declared source = edge the build already executes. And the moment is the other half. Qodo acts on pull requests already opened, and "By default, Qodo targets the main branch of each connected repository," not at the point a developer is deciding what to change in an interactive session. Qodo does not break the argument here. It sharpens it. Hand a tool the cross-repo relationships and it will reason over them. The whole question is where those relationships come from and how they are resolved.

What changes the answer: hand it the graph

What changes the answer is not a smarter assistant but a parsed dependency graph the assistant can query, and the effect is the same for all three. Here is the shape of it, with a receipt from a real scan rather than an adjective.

Take one repository an assistant might plausibly have open. Cloud Posse's terraform-aws-ssm-parameter-store, a thin wrapper around AWS SSM Parameter Store, the kind of small shared module nobody thinks about until it changes. On its own, any of the three sees one repo. Point a parsed cross-repo graph at the same repo and ask what depends on it, and the answer comes back as a set of repositories.

# 1. resolve the one repo the assistant already has
curl -s -H "X-API-Key: $RIFTMAP_API_KEY" \
  "https://api.riftmap.dev/api/v1/repositories/lookup?url=https://github.com/cloudposse/terraform-aws-ssm-parameter-store"
# → { "id": "54052e08-b43f-4b67-975b-d869e9cdc62a", ... }

# 2. ask the graph what transitively depends on it
curl -s -H "X-API-Key: $RIFTMAP_API_KEY" \
  "https://api.riftmap.dev/api/v1/repositories/54052e08-b43f-4b67-975b-d869e9cdc62a/impact"
# → { "total_affected": 22, "max_depth_reached": 6, ... }
Enter fullscreen mode Exit fullscreen mode

As scanned on 7 July 2026, terraform-aws-ssm-parameter-store sits upstream of 22 other repositories inside the same Cloud Posse GitHub org, reached across six hops of Terraform module composition. Every edge on the path is a Terraform source = reference, parsed out of the manifest and resolved back to the repository that produces the module, never a go.mod or package.json require. The chain is legible if you walk it. The source in terraform-aws-iam-system-user, at main.tf line 63, points back at the parameter-store module. That module is pulled in by iam-s3-user, which is pulled in by s3-bucket, then s3-log-storage, then lb-s3-bucket, and six hops out you reach the org's load-balancer modules: terraform-aws-alb, terraform-aws-nlb, and terraform-aws-elastic-beanstalk-environment. None of those load balancers names the parameter-store module anywhere in its own files. The edge is real, declared, and six hops removed from anything a human editing that module would think to grep for.

That is the number none of the three produces on its own, and the one all three can retrieve in a single call once the graph exists. Two things keep it honest. The call is repo-level, so it tells you which repositories are downstream, not which function or job inside them; for the pre-change question, which repos do I need to think about, that is exactly the resolution you want. And the 22 is a transitive closure, not 22 breaks at once.

The reason is the pin, and there is a further distinction hiding in it. Cloud Posse pins every one of these edges, this chain's first hop at 0.13.0, the far-end terraform-aws-alb at 0.19.0, so a bump to the shared module is a migration you schedule, not an outage you wake up to. Each hop propagates only as it bumps its own pin. That pinned case is what this receipt demonstrates. The estate that actually needs this graph is the other one, the source that is a bare git:: URL with no ?ref=, the FROM pinned to :latest, the CI include that tracks main. Those edges do not wait for a coordinated bump. They break on the next apply. And the same graph tells the two apart, because Riftmap carries the version constraint and its pin state on every edge, a version_constraint_state of pinned, floating, or branch. Point Riftmap at your own estate and it splits the affected set in two: the consumers you coordinate an upgrade across, and the ones that break unannounced. That second set is the afternoon in an incident channel this post opened on. That split is Riftmap's to make and hard for the others to reach. Grep finds the string but not the pin semantics behind it. An agent chain-walk has to read and correctly interpret a version constraint at every single hop. Qodo's LLM traces the impact at review time and never reads the pin semantics that decide which case an edge is in.

What 22 gives you is the set you must consider and coordinate a fix across, which for the kind of shared-module change that opened this post is exactly the right set, four of them direct dependents and the rest transitive, the chain necking through one repository mid-way before it fans out to the load balancers. And 22 is the count inside the one org Riftmap has connected here, the 242-repo Cloud Posse org. Anyone vendoring these modules into their own private infrastructure is invisible to that scan, so the honest figure is at least 22, not exactly 22. The assistant, meanwhile, is only ever one caller of that graph: when I am the one bumping the module, those same two calls run from my own terminal, no agent in the loop at all.

It matters that the graph is parsed rather than guessed, and the confidence floor is where that shows. In the depth-six graph around this module there are 254 edges, and 79 of them sit below the default 0.8 confidence floor and are excluded from the answer. Every one of those 79 is a git_url_reference, a heuristic text match at confidence 0.6 to 0.7, a script mentioning a repo URL in passing rather than a manifest declaring a dependency. The eight edges on the spine all resolve at 0.9, the deterministic score for a Terraform Registry shorthand matched against the Registry's naming convention, the same transform the Cursor agent runs hop by hop, here applied mechanically across the whole org and comfortably above the floor. Parsed, not inferred, is not a slogan here. It is the line between the edge the build actually executes and a string that happened to look like one.

There is no first-party Riftmap MCP server yet, and I would rather say that plainly than dress it up. What exists today is not a workaround, it is the path I actually run. Riftmap publishes an OpenAPI schema, so you point a generic OpenAPI-to-MCP bridge at it and each endpoint becomes a tool the assistant can call, no bespoke server to build. The one thing worth doing is scoping it: the --tag flags below hand the agent only the read-only graph endpoints (the repositories and impact tags — lookup, dependencies, dependents, impact), so it gets the tools it needs to answer "who else breaks" and nothing else, no billing or workspace-admin surface from the rest of the schema. One config block, your key in an X-API-Key header:

{
  "mcpServers": {
    "riftmap": {
      "command": "npx",
      "args": [
        "-y", "@ivotoby/openapi-mcp-server",
        "--tag", "repositories", "--tag", "impact"
      ],
      "env": {
        "OPENAPI_SPEC_PATH": "https://app.riftmap.dev/openapi.json",
        "API_BASE_URL": "https://api.riftmap.dev/api/v1",
        "API_HEADERS": "X-API-Key:${RIFTMAP_API_KEY}"
      }
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

That is the setup I walk through for Claude Code and Cursor, against the endpoints an agent calls. The same graph answers at merge time, not just at planning time, and checking a PR's blast radius as a gate is its own piece, organised by graph layer.

Other parsed graphs an agent can call over MCP already exist. The line Riftmap draws is narrower and, I think, more durable. It is the artifact layer, resolved. Dockerfile FROM, Terraform source, Helm value references, GitLab CI include, each edge followed back to the repository that actually produces the image or the module, and served across an entire GitHub or GitLab org from one read-only, org-level token, not a per-developer index of the repos you happened to clone. The receipt above walks one Terraform source chain; the same parse-and-resolve step runs across the parser suite, so a Dockerfile FROM line, a Helm value reference, or a GitLab CI include resolves back to its producing repository the same deterministic way. That is the layer an assistant structurally cannot rebuild from a single repo's checkout, which is the whole reason the answer to who else breaks was never in the box to begin with.

This is all Riftmap is. It parses the edges your manifests already declare, a dozen ecosystems in all, across an entire GitHub or GitLab org from one read-only token, and serves the graph over an API. It is not a fourth assistant competing with the three. It is the substrate they were always going to have to call. The map of the dependency that used to live only in the head of the engineer who wired that shared module in last time and has since left. If you want that map for your own org rather than Cloud Posse's, that is what Riftmap is for.

The assistant was never the limitation

The race between Claude Code, Cursor, and Copilot is real, and it is a race about access and reasoning, and both of those keep getting better every month. Neither is the thing standing between you and the answer to "who else breaks." The edge that breaks the other repo was declared in a manifest, in a repo none of them opened, and no amount of model improvement puts it back in the box. Give any of the three that parsed graph and all three can answer. The assistant was never the limitation. The missing graph was.

Questions I get asked

Which AI coding assistants can see blast radius before they change code?

As of July 2026, none of the three mainstream assistants resolves cross-repo blast radius on its own: not Claude Code, not Cursor, not GitHub Copilot. Each has a real multi-repo mechanism (directory access, grep plus a semantic index, curated context sets), but none reads and resolves the declared manifest edges that decide which repositories break when a shared base image, module, or CI template changes. Hand one a parsed graph and it can: pointed at Cloud Posse's terraform-aws-ssm-parameter-store, that graph returned 22 downstream repositories across the org, six hops out along Terraform source references resolved back to the producing repo, as scanned on 7 July 2026. The honest answer is whichever assistant you give the graph to.

Are there AI assistants that show blast radius before code changes?

Not among the daily-driver assistants, on their own. The closest is one category over: Qodo's Cross Repo Review, a PR-review feature, has an LLM read the related repositories and trace cross-repo impact on already-opened pull requests, on the main branch by default, which is inference at review time rather than a parsed graph queried at planning time. It reaches the artifact layer, which is real, but through tracing, not a deterministic parser resolving the source = and FROM edges a build already executes. For an interactive assistant to show blast radius before it opens a PR, you point it at a parsed cross-repo graph, and the affected repositories come back before the change is made.

Can Claude Code, Cursor, or Copilot analyse the blast radius of a change on their own?

No. Claude Code sees the directories you grant it, Cursor greps and embeds the folders you added to the workspace, and Copilot reasons over a context set you curate, and none of the three resolves a dependency edge whose far end lives in a repo the tool never took in. The limit is structural, not a matter of model quality: a stronger model reading the same single repo still cannot recover an edge that was declared in a manifest somewhere else. They can all answer the question once you hand them a parsed cross-repo dependency graph to query. On their own, they cannot build one.

How do you give an AI coding assistant cross-repo blast-radius awareness?

You give it a queryable dependency graph, let it resolve the repository it is about to change, and ask which repositories transitively depend on that one. Riftmap builds that graph by parsing the declared edges (Dockerfile FROM, Terraform source, go.mod requires, Helm, CI) across an entire org from one read-only token, and serves it over an HTTP API any assistant can call; there is no first-party MCP server yet, so you point the assistant at the API directly or through a generic OpenAPI-to-MCP bridge pointed at the published schema. Pointed at cloudposse/terraform-aws-ssm-parameter-store, that graph returned 22 repositories across the org that depend on it, six hops out through Terraform source references, as scanned on 7 July 2026.

About Riftmap

Riftmap maps cross-repo dependencies across your entire GitLab or GitHub organisation — Terraform, Docker, CI templates, Helm, and more. One read-only token. No YAML to maintain.

Top comments (0)