DEV Community

Paul Grimshaw | bounded.dev
Paul Grimshaw | bounded.dev

Posted on • Originally published at bounded.dev on

Understanding Is the New Luxury Good

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. 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, not because it started anything, but because it put a clean shape on something I have been circling for a long time in my own work with agents. The interesting part is not the failure. It is the knowing.

The knowing

My friend's 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 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 exact 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 underneath all of it, 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 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.

None of it is 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 looks like the answer, and rules like "do not repeat business logic" are the fix I see recommended again and again. Anyone who has leaned on them 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 tick the box, 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 expressed it is by being present while the code was written.

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. At the other end, the full black box: you specify, you discuss, you never look inside. Between them sit the positions most 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.

On my own projects I have mostly settled on that last position. 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. The logic behind them I steer by spec and verify by test, and I do not read most of the code that lands there.

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 hard 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 toward coarse, 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.

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.

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.

Some of the static cases can be caught today, and I do bother: an ESLint rule like no-restricted-imports (or dependency-cruiser if you want more structure) will fail the build the moment anything in src/domain imports from src/adapters. That is worth having. But notice what it is: a tripwire I laid in advance, at a boundary I already predicted, expressed as a file path. It knows one rule. It does not know what I care about.

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 sharply each part of the system is rendered for my attention. 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 at all, 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.

None of this is 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. 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.

Top comments (0)