Coding agents got cross-repo access this year. They still cannot see the blast radius of a base-image bump — because that edge was never a function call, and it lives in a repo they never opened.
Last spring someone posted a small VS Code extension to Hacker News. The pitch was one sentence from their own week. They had added a single field to a shared struct, and found out in CI, twenty minutes later, that 417 files depended on it. So they built a tool that shows you that tree the moment you save, files colour-coded by how far downstream they sit. It is a good tool. Underneath it is a Rust CLI and tree-sitter, parsing your code into a graph of which file references which.
Read that story again and notice what kind of dependency it actually is. A field on a struct. Files that reference the struct. Functions that call those functions. It is a symbol graph, it lives inside one repository, and tree-sitter can see all of it. This is the version of blast radius the industry has largely tooled. Sourcegraph indexes it. CodeLayers draws it on save. GitLab’s new Knowledge Graph answers it over MCP. The most-quoted blast-radius anecdote on the internet is a within-repo, symbol-level story, answered by within-repo, symbol-level tools.
Now hand the same engineer their next task, and hand it to an agent. Bump the base image three services are built on. Tighten a variable on a Terraform module that six repositories source. Rename a value key in a Helm chart that nine deployments inherit. The thing that breaks is real, and it is downstream, and it is not 417 files in this repository. It is eleven services in eleven other repositories, owned by teams who never read the changelog. And the edge that connects the change to the breakage was never a function call. tree-sitter will never find it. It was never in the code. It only ever existed in a manifest, in a repository the agent did not clone.
So here is the claim this whole post is built on. An AI coding agent can see the repository it cloned. The edges that break when a shared base image, Terraform module, or Helm chart changes live in other repositories, declared as a Dockerfile FROM line or a Terraform source block, which means they sit outside the agent’s context by construction, not by oversight. You cannot prompt your way past it. You have to give the agent the graph.
The agents’ own users have already asked for this
The clearest evidence that this is the live problem is that the people running these agents are filing the feature request themselves, in the agents’ own issue trackers, in their own words. In February someone opened a request on the Claude Code repository for multi-repository sessions. The interesting part was not the ask. It was the reasoning. The author wanted the agent to discover additional repositories as it works, “via dependency analysis, import tracing, or configuration references”, because, in their words, “I don’t always know which repos are affected when I start the task.” Their example stack was a shared API-contracts library, a Node backend, a React frontend, and a Kubernetes infrastructure repository.
It is not one request. There is a second one that wants the agent to see the API handlers in backend/, the types they share with frontend/, and the Terraform definitions in infra/, and to trace a payment flow end to end across all of them. There is a third asking for a --workspace flag so a single session can coordinate a change to an API in one repository and its client in another. And over on the GitHub side there is the Copilot request I have written about before, the web-app and orders-service pair where Copilot cannot detect that the frontend is calling an endpoint the backend just renamed, because the contract lives in a repository outside its scope.
Four requests, three agents, one shape. None of these people are asking for a better model. They are asking for the thing the model cannot hold in its head: a map of how the repositories depend on each other. Claude Code is not broken here, and neither is Copilot. They are consumers waiting for a graph that nobody has handed them yet. The rest of this post is about why the workarounds they reach for in the meantime all stop in the same place, and what the graph would have to parse to actually answer the question.
The workarounds, and where each one stops
Spend an hour in the support forums for any of the big coding agents and you will see the same three families of workaround, reached for in roughly this order. Each one solves a real problem. Each one stops at the same wall.
Widen the window
The first instinct is access. Open more repositories so the agent can read them. Claude Code ships /add-dir, and the multi-repo feature requests above are mostly asking for the remote and team version of it. VS Code has multi-root workspaces, a .code-workspace file listing several repository folders that open together. Copilot has Spaces, the one genuinely multi-repo surface GitHub ships, where you assemble a curated set of repositories and chat against it. These are the right first move, and at a handful of repositories they are often enough.
But access is not structure. The agent can now read orders-service while it edits web-app. Nothing tells it that it should, or that a third repository consumes the same contract and is not in scope at all. Widening the window shows the agent more rooms. It does not hand it the floor plan. I made the longer version of this argument in Repo access was never the hard part, and it is the limit underneath this entire category.
Write the map by hand
The second instinct is to write the structure down. This is the CLAUDE.md and AGENTS.md era, files that more than sixty thousand repositories now carry, READMEs for agents that describe how the system fits together. Some teams go further and build a dedicated repository to hold it, an agents meta-repository that serves as the agent’s orientation and working memory. The most documented version is Mabl’s, an 850-line repo coordination graph their agents query at planning time, which they credit with cutting context drift from roughly forty per cent of agent failures to under five. It works.
It also decays, and the people writing these files know it. The most useful line I have read on the pattern comes from an engineer who layered the files org, team, and repo deep and concluded: “I learned not to list repos here. Lists go stale. Instead, tell Claude where to look.” That is the trap in one sentence. A hand-written map has to be kept current by humans at the same throughput the agents are changing the repositories, and the agent navigating by a stale map does not feel stale. It feels fast, right up until the change lands. A map that decays is the developer-portal catalogue problem wearing new clothes, and it loses to the same thing: a graph parsed from the source, which cannot drift from the source because it is read from it.
Hand the agent a hosted index
The third instinct is the most sophisticated, and the closest to right. Stop writing the map by hand and serve a real index over a tool call. Augment exposes its context engine to other agents over MCP. There are custom MCP servers with trace_dependency and load_symbol tools that follow the call chain across repository boundaries. CodeLayers does it from tree-sitter. GitLab Orbit does it at GitLab scale, a property graph of code and the whole software lifecycle, queryable over MCP. These are real graphs, and an agent that calls one is genuinely better off than one navigating by a markdown file.
But look at what every one of them indexes. Functions. Classes. Imports. Call edges. They are symbol graphs, and a symbol graph answers “who calls this function” beautifully. It does not answer “what breaks if I change this base image,” because the answer to that question is not made of function calls. I want to be fair to Orbit in particular, because it is the most serious graph anyone has shipped in this space and a very large, very well-funded proof that the category is real. I read everything they shipped before saying a word about it. And it still does not parse a single FROM line.
That is the wall all three families hit. Widen the window and you have access without structure. Write the map and you have structure that rots. Serve a symbol index and you have a real graph that stops at the language boundary. None of them parse the layer where a platform team’s worst change actually lives.
The edge that was never a function call
Blast radius is two questions wearing one phrase, and almost every tool in this space answers the wrong one for infrastructure. Ask “what breaks if I change this” at the symbol layer and you get a graph of functions and their callers. Ask it at the infrastructure layer and you get a completely different graph, with completely different nodes and edges, built by a completely different parser.
The nodes of that second graph are the things your repositories are actually made of and share between each other. A base image. A Terraform module. A Helm chart. A reusable CI template. The edges are the references that bind those things across repositories: a Dockerfile FROM line pinning the image, a Terraform source block pointing at the module repo, a terraform_remote_state lookup, a Helm dependencies entry or a value reference, a GitLab CI include:project, a reusable Actions uses:. These are not function calls and they are not in the code for a symbol graph to find. They are declared in manifests, deterministically, and they point at repositories the agent never opened.
Side by side, the two graphs look like this.
| Symbol graph | Artifact graph | |
|---|---|---|
| Nodes | functions, classes, files | base images, Terraform modules, Helm charts, CI templates |
| Edges | calls and imports between symbols | FROM lines, source blocks, include:project, chart dependencies |
| Where the edge lives | in the code, in the repo you cloned | in a manifest, in a repo you didn’t clone |
| Answers | who calls this function | what breaks if I change this base image |
A symbol graph and an artifact graph are different categories, built by different parsers, and blast radius on an infrastructure change needs the second one.
This is why the agent’s blindness is structural rather than a gap a smarter model closes. When an agent edits a Terraform module’s output variable, the breakage is in the six repositories that source that module, and the only record that those six repositories exist is six source blocks sitting in six manifests across the org. The agent cloned one repository. It has one of the seven facts it needs. No amount of reasoning recovers the other six, because they were never text it could read. They are edges in a graph it was never given.
And the fix has a specific shape, the same one Mabl reached and the same one the feature requests are circling. Parse the manifests that already declare these edges. Resolve each reference to the repository that owns the artifact. Build the cross-repo graph once, keep it current by re-reading the source, and let the agent query it during planning. Parsed, not inferred. The graph that should be answering the agent’s question already exists in your org’s manifests, unassembled.
What this looks like on a real org
The transitive reach of a shared artifact is almost always larger than anyone eyeballs, and it is invisible from the place people go to check. I ran the open-telemetry GitHub organisation through Riftmap to put a number on it. 105 repositories. A change to opentelemetry-collector reaches twenty-one of them, across three levels of the dependency graph, every edge a go.mod require resolved to the repository that owns the module. An engineer editing the collector sees the collector. They do not see the twenty-one. GitHub’s own dependency graph will not show it to them either, because it works per repository and does not traverse the org transitively.
Two details from that scan are worth holding onto, because they say something about what counting gets you versus what parsing gets you. The most-referenced repository in the entire org is opentelemetry-specification, cited fifty-one times. Change it and you break no one’s build, because those fifty-one references are documentation links, not dependencies. The collector is referenced far less and ripples through twenty-one repositories. Counting mentions and resolving dependencies are different operations, and only one of them tells you what will actually break.
Now hold that example up against the infrastructure layer, because it is the gentle version of the problem. A go.mod require at least lives in a file inside the repository the agent cloned. The dependency is in scope even if its transitive reach is not. Move to the base image built by a separate platform repository, or the Terraform module sourced from a third, and the dependency is not in the agent’s repository at all. It is in another repo entirely, reached by a reference the agent’s tools do not resolve. If the package layer is already bigger than anyone tracks, the artifact layer is the part no one can see at all. That is the gap, and it is the one Riftmap was built for.
Why this gets worse as agents get better
The faster and more confident agents get, the wider this gap opens, which is the uncomfortable part. A human making a base-image bump at least pauses, half-remembers that the payments team is downstream, and sends a Slack message. An agent makes the change cleanly, passes the same local tests the repository has always been reviewed against, and opens the pull request in ninety seconds. Each change looks correct in isolation because each change is correct in isolation. The defect is at the seam between repositories, and the seam is exactly what neither the agent nor its local tests can see.
This is why the aggregate numbers move in the wrong direction as AI adoption climbs, and I have walked that data, Cortex and DORA and Amazon’s own high-blast-radius memo, in its own post rather than repeat it here. The short version is that local correctness went up and system stability went down, and the two are not in tension. They are the same fact seen from inside one repository and from across the org.
The dependency that walked out the door
There is a more human version of this, and in every conversation I have had about Riftmap it is the one that lands hardest. The base image that nine services inherit from, or the shared module six repositories source, is very often a dependency nobody wrote down, set up years ago by the senior engineer who has since moved teams or left. The graph lived in their head. When they walked out the door, the org did not lose the dependency. It lost the only copy of the map.
An agent inherits that amnesia and runs at speed on top of it. It will confidently change the artifact the departed engineer quietly wired into half the estate, because nothing in the repository it cloned records that the wiring exists. This is the highest-stakes edge precisely because it is the least documented one, and it is the strongest reason the map cannot be a thing humans maintain by hand. The dependency that broke production is the one nobody remembered. A parser does not forget, and it does not resign.
The graph you don’t have to build
Give an agent every repository in your organisation and you have given it access. You have not given it the map. The record of what breaks when it bumps a base image was never in any of those repositories’ code, and no symbol graph, however good, will reconstruct an edge that was only ever a source block in a manifest. Those are different gifts, and only one of them tells the agent what it is about to break.
Riftmap is the version of that map you do not have to build by hand. One read-only token across your GitHub or GitLab organisation. It parses the manifests that already declare these edges, Terraform source blocks, Dockerfile FROM lines, Helm chart dependencies, CI includes, go.mod requires, across twelve ecosystems, resolves each reference to the repository that owns it, and serves the result two ways. An interactive blast-radius view for the engineer who owns the estate and holds the pager, and an HTTP API the agent calls during planning, to ask which repositories a change affects before it opens the pull request. Auto-discovered, never declared. Parsed, not inferred.
Questions teams ask
The same handful of questions comes up every time I walk an engineer through this, so here they are, answered straight.
Can an AI coding agent see which other repos a change will affect? Not on its own. An agent’s context is the repository it has cloned, and the edges that break when a shared base image, Terraform module, or Helm chart changes live in other repositories, declared in manifests the agent never reads. It can see the change. It cannot see the consumers, unless it is given a cross-repo dependency graph to query.
Why doesn’t Claude Code or Cursor know about my Terraform or Helm dependencies?
Because those dependencies are not function calls. A Dockerfile FROM line, a Terraform source block, or a Helm value reference is a manifest declaration that points at another repository, and code-aware tooling indexes symbols and imports, not artifact references across repos. The dependency only exists in a file the agent did not clone, so it sits outside the agent’s context by construction.
How do I give a coding agent cross-repo blast radius? Parse the manifests across your org that already declare the dependencies, resolve each reference to the repository that owns the artifact, and expose the resulting graph as a tool the agent calls during planning. Riftmap does this from one read-only token and serves it over an HTTP API, so the agent can ask which repositories a change affects before it opens a pull request.
Isn’t this just a token-saving optimisation for agents? No. Saving tokens is a side effect, and a declining one as context windows grow. The point is that the artifact-layer dependency graph is information the agent structurally cannot reconstruct from the single repository it cloned, no matter how large its context window gets. It is missing context, not expensive context.