Understanding Is the New Luxury Good
Working with agents, how much of your own codebase you understand has become a choice, and each step up costs multiples. Engineers still know exactly what they want from their code; what is missing is a medium for expressing it, and a way to see drift before it is expensive. On the resolution gap.
A friend told me recently about a side project he had vibe coded. It works, mostly. What struck me was not the state of the project but the precision of his complaints about it. Even without looking, he knew that one provider’s implementation had leaked all the way through the core of the application. He knew there was a growing list of edge cases the agent had never properly handled. He was not confused about what good looks like, and he was not wrong about where his project falls short of it. He knew exactly where it was wrong. He just had not been in the room when it went wrong, and nothing in his toolchain considered that worth an interruption.
That exchange stuck with me. It put a clean shape on something I have been circling for a long time in my own work with agents.
The spectrum, and what a step costs
How much of what gets built do you actually need to understand? Working with agents, that has quietly become a choice, and the range of available answers is wider than we usually admit. At one end, AI as autocomplete: you are still the author, slightly faster, every line of the system lit. At the other end, the full black box: you specify, you discuss, you never look inside. The code runs dark. Manufacturing already has a name for that end, the dark factory, running lights out because nobody needs to watch. Between the two ends sit the positions many of us actually occupy. Review everything the agent writes. Review only the key code. Dictate the architecture, review the interfaces, and let specs and tests carry the interiors.
The part that took me longer to see: movement along this spectrum is not priced in increments. One step toward more understanding, from black box to reviewing even the important changes, can turn a weekend project into weeks. Still far faster than the pre-agent world, but these are multiples, not percentages, in both calendar time and cognitive effort.
Understanding has become a luxury good, and every engineer working this way is quietly deciding how much of it they can afford.
Sizing the black boxes
Where the bar sits is not only taste. It is the project. A personal finance app for myself I will vibe code completely dark and feel fine about it. Work for a client, or anything where somebody else carries the consequences, moves the dial the other way, because reviewing most of what lands is part of what is expected of me. And I notice that on production projects, when I do turn the dial towards the dark, I want the sponsors of the project to know and agree that this is how we are working.
The level of understanding is not a private choice. It is part of the accountability structure, and right now we negotiate it informally or not at all. The cost of that informality is visible in most engineering organisations at the moment: the pressure to adopt agents and move faster arrives from above, while accountability for what ships stays exactly where it has always been, on the developers. Asked to turn the dial down while carrying the consequences alone, they hold it finer than anyone above them would like. That is not conservatism, it is a fair reading of where the risk sits. A lot of the speed agents promise is locked behind this, and I suspect it stays locked until the choice of resolution is something a team and its sponsors visibly share.
Which is why I have stopped thinking of the choice as whether to black box. The real decisions are the sizes of the black boxes, where their edges sit, and what the outside of each one looks like: which surfaces get full scrutiny while the interiors run dark.
On my own projects the setting I might choose looks like this: I decide the module structure, I say what belongs in the domain, I read the ports, the public interfaces the domain offers, with real attention, and I let spec and tests carry the logic behind them. But that is one position among many, and the trouble is the same wherever you set the dial. The tooling does not know a line has been drawn. A new method on a port arrives in the same grey diff as a hundred routine edits, so whether a part of the system is meant to run light or dark, keeping your attention on the surfaces you chose is a discipline held by hand, against the grain of every tool. That difficulty is the thread running through the rest of this piece.
The knowing
The interesting part of my friend’s story is not the failure. It is the knowing. His complaints were precise, and that is the norm rather than the exception. Give an experienced engineer time to study a vibe coded app in depth and they will commonly list the headline problems off the top of their head: this piece of business logic recurs in three places; the SQL for the filter has leaked into the domain; the list of categories is hard coded in the UI as well as being driven from the database. Given enough time with the code they can see everywhere the agent went off piste, and yes, this still happens with well guardrailed apps.
What strikes me is the gap this reveals, and it has two halves. We know what well engineered code looks like, but we lack a way of telling an agent to build in that style and having it hold. And we can see where an application has gone off piste, but only by studying it in depth, at a cost we do not want to pay until it is too late. Expressing the intent, and seeing where reality has drifted from it: both halves look solvable to me, which is why none of this is an argument against vibe coding. It is an argument about what we should be building next.
Most engineers I speak to carry this kind of intent about how their application should be built, whatever they have chosen to delegate. I know my domain should expose a repository port and that the Postgres code should live in an adapter that fits it. I know findById takes an id and returns a single item. I know the filter method on that port should have no knowledge of SQL. I know the adapter earns an integration test against a real database while the domain is tested on pure logic alone. I know which public interfaces I consider load-bearing.
And crucially, I know what things are called. I suspect my team think I obsess over naming too much, but so much of the rest comes down to it. If you cannot name the result of a function that fetches yesterday’s outlying reading across a portfolio of meters, what chance do you have of architecting the thing it belongs to? The name is the first piece of architecture, and a wrong one propagates through the module structure, into the interfaces, and eventually into the product itself. Naming and boundaries are rarely separate problems: if you cannot name a thing, you probably do not know where its boundary sits, and if you do not know where the boundaries sit, you are headed for a mess.
Much of this is not written down in any form a machine could act on. The specification does not hold it: a spec describes what the application does, not how it should be built. The code holds the outcome but not the intent. The agent instructions file may look like the answer with rules like “do not repeat business logic” - a fix I see recommended often enough. But anyone who has tried to lean on these knows they do not hold, for two reasons. An agent works in a narrow window of the codebase at a time, and a rule that can only be checked across the whole application has no purchase on any single change. And today’s frontier agents are intensely goal focused: in the drive to complete the task, standing rules are exactly what falls by the wayside.
The rule is written down, and it still is not expressed anywhere that matters. So the intent lives where it has always lived, mainly in my head, and the only way I have ever successfully expressed it is by being present while the code was written.
Yesterday’s tools
Being present used to be enough, because understanding accrued as a byproduct of construction. When you build a system piece by piece, the mental model and the codebase grow together; the slowness was doing quiet work for us. Agents removed the slowness, the byproduct went with it, and nothing has replaced it.
Now look at the surfaces we are left doing the work on.
We speak, through voice to text, into terminals: a device designed for short typed commands, now hosting long free-flowing conversations about architecture. We assess the structure of an application by reading its lowest-level artifact, verbose implementation text, because that is the only complete view on offer. We review change through diffs, and a diff measures the size of a change when what we care about is its significance. A big rename is an enormous diff and a non-event; a new port on the domain is twenty lines and an architectural moment. The diff sorts them exactly backwards. We write specification documents in editors built for writing code, and read them back in whatever happens to render markdown.
Every one of these tools is optimised for a world where the human reads, writes and reviews code from scratch, at low level, slowly enough that understanding takes care of itself. Not one of them is optimised for the job that actually now fills my day: aligning my understanding of what is being built with the agent’s, and catching the places where the two have diverged while the divergence is still cheap to correct. Misalignment is the real pain. It is nearly invisible in the current toolset, and it stays invisible until it surfaces as my friend’s leaked provider, at which point the correction costs more than the feature did.
The developer who knows what to flag
Imagine instead a very experienced developer looking after this codebase on your behalf. They would not forward you every commit. They would know, from working with you, that you want to see any change to a public interface, any new port on the domain, any fundamental shift in how a core algorithm behaves. They would equally know not to bring you the diff of a rename, however many files it touched, or the internals of one adapter method. And they would know the difference between that diff and the rename itself. A concept in the domain changing its name, or a new term entering the ubiquitous language at all, is exactly the kind of event that should reach you, even though the text of the change is the least interesting part of it. The language is load-bearing; the find-and-replace is not. They carry a model of what rises to your attention and what does not.
That model is the thing I want to give the agent, and I have no medium for it. It is not a spec, because it is about construction rather than behaviour. It is not a lint rule, because most of it is judgement about significance rather than a path predicate. It is something closer to an escalation contract: a declaration, per project, per module, per interface, of what reaches me and at what level of detail. A dial I would call resolution, because that is what it is: how brightly each part of the system is rendered for my attention. Not the light switch, but the dimmer behind the light and dark: some parts of the codebase I want at full resolution, every change surfaced. Most of it I want compressed to almost nothing, with an agreed list of events that always break through.
I do not know yet what this looks like concretely. Richer views over code graphs, maybe. Interfaces marked as load-bearing so change there is always an event. Directory structures that carry review policy the way they already carry lint scope. I can see pieces; I cannot yet see the tool.
Everything downstream of this
I have written before that boundaries are what make delegation to agents work best, and this is that argument wearing different clothes: a boundary is exactly the place where an escalation contract can attach. But code review is only the surface where I feel the gap most sharply. Testing has the same shape, deciding what the human needs to see proven versus what passing quietly is enough. So do permissions, migrations, and monitoring what agents change in production. Each of these is an interface between human intent and machine construction, and each of them is still built for the old flow of work.
Most of the conversation about agentic development is about the writing: how much of it agents can take on, how good they are at it. I think the writing was always the small half. The tools we use to understand, steer, and correct what gets built were designed for a pace and a division of labour that no longer exist, and they are going to be reinvented nearly wholesale. It is rare to be around while the basic instruments of a craft get redesigned. That is where we are.
This is not a claim that nobody is working on it. Pieces are appearing everywhere: deterministic checks, richer diff tooling, code maps, agents reviewing agents, and I am exploring the space myself. Much of what I have written here is simply the pain that drives that exploration, written down.
When we picture the future of building software we tend to reach for the Minority Report image: hands sweeping through the air, the whole system rendered in glowing glass. Maybe. The version I keep imagining is quieter. I describe what I care about once, the way I would to a trusted senior engineer, and the system holds it. Construction runs fast and dark where I have chosen dark, and my attention is called only when something that matters moves. Free-flowing and fast-moving, with the critical points held to full scrutiny.
What I have not yet seen is the whole: a way of working where the resolution is explicit, agreed with the people who carry the risk, and cheap to change. The teams that get there first will not just have better oversight. They will be the ones free to spend the speed others may leave on the table. So this is an articulation of what I have started calling the resolution gap. I think it is solvable, and this is an open invitation. If you have seen something that gets genuinely close, I would like to hear about it.
Get new posts by email
Occasional posts on software architecture and AI-assisted development. No spam, unsubscribe anytime.