
AI coding agents have changed the rate at which code arrives for review. It is now common for an engineer to pilot one or more agent sessions at a time, each one producing a merge request (MR) of its own, and for a team’s review queue to grow in both volume and density as a result. On my team, since engineers started piloting agents, the number of open MRs and the size of each one have both gone up and the humans have become the bottleneck of catching up with what’s going on.
One common response is to label MRs by severity or impact and decide per label whether a human gate is required. This helps, but regardless of how liberal a team chooses to be with that gating, the people on the team still need some level of understanding of the work being merged. Skipping the review does not remove the need to know what changed, it only defers it.
In this article, we’ll look at this gap as a form of debt, explain why the line-by-line code diff is the wrong unit for paying it down, introduce the idea of a shape diff, and cover the options a team has for putting one in place.
What is Understanding Debt?
Technical debt is the gap between the code a team has and the code it would have if it had taken the time to do things right. Understanding debt is the gap between the code a team has and the code the team can explain. At any given moment in a project with heavy AI usage, a given engineer’s understanding of what’s going on can sit anywhere on a wide range. At one end they have the same intimacy with the code they had prior to the AI era, having typed most of it themselves. At the other end it feels as if AI is moving faster than they are able to catch up with, and large parts of the system are code nobody on the team has read.
(The terms comprehension debt and cognitive debt are being used for close relatives of this idea, the first at the level of an individual engineer and the second at the level of a team’s shared understanding. Understanding debt as used here covers both, since in practice they accrue together.)
Like technical debt, understanding debt compounds. Every MR merged on top of code nobody understood makes the next MR in that area harder to review, and the engineer debugging an incident there later pays the interest. And like technical debt, it does not go away by being ignored. It has to be managed.
Why the Line Diff Isn’t Enough
The unified diff has been the unit of code review for a long time. When a human wrote every line it worked, because the author had already formed an understanding of the change and the reviewer only had to reconstruct it. With agent-written code the diff is the wrong depth for three different readers:
- The pilot: the engineer who directed the agent approved a plan and a result, not every line. Reading the diff line by line is a cold read for them too.
- The teammate: anyone who wasn’t in the back-and-forth between the pilot and the agent has none of that context, and a dense MR gives them no way in.
- The team with no pilot: when agents open MRs on their own (dependency bumps, scheduled refactors, generated fixes) every human on the team is in the second position.
Moreover, the diff is not only too detailed, it’s incomplete. It shows the lines that changed and leaves out the lines that didn’t, and the unchanged callers of a changed function are exactly what a reviewer needs in order to see where the change lands. A signature change touching two lines in one file can affect six call paths in files the diff never mentions.
Reviewing the Shape of a Change
Here’s where the shape diff comes in. Instead of presenting a change as a set of line edits, a shape diff presents the difference between the structure of the code before and after the change, leaving the lines themselves for later. The aspects worth comparing are the ones a reviewer would otherwise have to reconstruct by hand:
- Call paths: which entry points now reach the changed code, and through which functions.
- Signatures: which function or method signatures changed, and how many callers each one has.
- Components: which packages or modules are new, and which existing ones the change touches.
- Data flow: which paths from an entry point down to a database table, queue, or outbound call were added, removed, or rerouted.
- Endpoints: which HTTP routes, gRPC methods, commands, or workers were added or changed.
Consider a scenario where an agent is asked to add a bulk order endpoint to a Go service. It adds a handler, a CreateMany method, and, to support per-request options, widens the signature of the existing Create method. The MR comes in at around 140 changed lines across six files. The part of the diff a reviewer is most likely to skim past looks like this:
diff
-func (s *OrderService) Create(ctx context.Context, o Order) (Order, error) {+func (s *OrderService) Create(ctx context.Context, o Order, opts CreateOptions) (Order, error) {
Two lines. Nothing about them says what else they reach. Here’s the same MR as a shape diff:
Signatures changed (1) (*OrderService).Create +opts CreateOptions callers: 3 (2 outside this MR)Endpoints added (1) POST /orders/bulk -> Handler.CreateBulk -> OrderService.CreateMany -> OrderService.Create -> orders (table)Call paths affected (3) POST /orders -> Handler.Create -> OrderService.Create (signature) worker import_orders -> Importer.Run -> OrderService.Create (signature) POST /orders/bulk -> Handler.CreateBulk -> OrderService.CreateMany (new)Packages touched: api, orders Packages added: none
In this example the shape view answers the questions a reviewer actually has before they read a single line. The signature change reaches Importer.Run, a worker the MR did not touch and the pilot may not have thought about. The new endpoint writes to the same orders table through the same Create method, so there is no second write path to worry about. Nothing was added at the package level. From here the reviewer can decide what deserves a close read (probably Importer.Run and CreateMany) and what can be skimmed, going into the line diff by choice rather than by default.
In other words, the review happens at a higher level first, against several aspects of the code at once, and the line-by-line pass becomes a second step the reader takes when the shape tells them to.
Putting It Into Practice
The shape diff is a way of reviewing, not a product, and teams can get there by a few routes:
- An AI aid on demand: ask the agent that made the change, or a separate one, to produce a diagram of the call paths, signatures, and endpoints the MR affects. Cheapest to start with, and the output quality depends entirely on what the agent was given. Skills such as archify tighten this up: the agent writes a typed description of components and edges, the tool checks each component against the source and fails on anything invented, and a local renderer draws it. It can also diff two of those snapshots and label what was added, removed, moved, or rerouted, which is most of a shape diff already.
- A CI job: generate the shape view automatically when the MR is opened and post it as a note on the MR. Every MR then arrives with one and nobody has to remember to ask. This is the route that keeps up with volume, since it costs the pilot nothing per MR, and any of the tools in this list can sit behind it.
- Existing graph tools: most ecosystems have a call-graph or dependency-graph tool already (go-callvis for Go, dependency-cruiser for JavaScript and TypeScript, and so on). These draw one commit. The diff between base and head is on you, but running one at each commit and comparing the output is a reasonable first version.
- Home-grown tooling: most languages have a way to build a call graph programmatically (
go/packagesand SSA in Go, for example). A script that extracts the graph at the base commit and the head commit and diffs the two is a modest amount of work for one language, and the team gets to decide exactly what the view shows.
Which route fits depends on the volume and density a team is dealing with. A team with many small agent MRs needs the CI route. A team with a few dense ones may get by with on-demand diagrams. The point is not the tool. The point is that the team decides on something, tries more than one way of knowing what’s going on in its code, and measures whether the people on it are catching up or falling further behind.
Things to Consider
While reviewing at the level of shape is a real improvement for dense MRs, there are some factors to consider:
- A shape view is a summary: it cannot show a wrong line. It complements the diff, it does not replace it, and the human gate for high-severity changes should still include reading the code.
- Budget the diagram: a dense MR can produce a graph nobody can read. Whatever generates the view has to trim it to what fits in a note and say what it left out, otherwise the reviewer trusts a picture that is quietly incomplete.
- Check generated narration: if a model writes the prose beside the diagram, validate every sentence against the actual change. A confident summary nobody checked is a new form of understanding debt, not a payment on the old one!
- Interest still accrues: a shape diff lowers the cost of catching up, it does not remove the need to. Teams that merge without anyone looking at either view are still taking on debt, just more quietly.
Conclusion
As agents take on more of the typing, the scarce resource on a team shifts from the ability to produce code to the ability to understand it. Understanding debt is a way of naming that shift so it can be managed the way technical debt is: made visible, budgeted for, and paid down on purpose rather than discovered during an incident.
Reviewing the shape of a change is one way to pay it down. A view of what changed in the call paths, signatures, components, data flow, and endpoints lets a reader see where a change lands before deciding how deep to go, which is exactly the decision the line diff never helped with.
For a bare-bones example of what’s possible, I wrote a small tool called shapediff that extracts a typed code graph at the base and head of an MR, diffs the two, and posts the result as a single note with Mermaid diagrams. It’s one approach among several, and the idea above stands on its own.
Cheers!
Leave a Reply