← The ADLC library
Live debates · 33

Craft when typing is free

Craft has always been defended on moral grounds, and that argument loses every budget meeting. When generation costs almost nothing, the case for craft becomes a cost case, and it is much stronger than the aesthetic one ever was.

The argument in every engineering organisation right now goes roughly like this. One side says the codebase is turning into sludge and someone has to care about how it is written. The other side says the work is shipping, the customers are happy, and nobody has time for a taste debate.

The first side is right and is making the argument badly. My position: with roughly 41 percent of production code AI-generated by early 2026, craft has stopped being an aesthetic preference and become a cost input, and the moment you argue it on cost you stop losing.

What craft was actually buying

Strip out the romance and craft was a bet about future labour. You spent effort now on names, boundaries, and small surfaces so that the next person to touch this could work out what was going on quickly.

The return depended on two numbers: how much time you saved per future encounter, and how many future encounters there would be. Both were small and hard to observe, which is why craft was so easy to cut. The saving landed on somebody else’s sprint, months later, and never appeared as a line item anywhere.

That is the entire reason craft was argued morally. Nobody could show the money, so they appealed to pride instead.

The arithmetic changed underneath the argument

The saving per encounter did not change much. What changed is the number of encounters, and who is having them.

Every agent run against your repository is an encounter. It reads, forms a model, and acts on it. The number of those per week in a team with agents running is not comparable to the number of times a human opened the same file in 2019. And the reader has no memory between encounters. It cannot compensate for a bad name by remembering what happened last quarter, because there was no last quarter for it.

So the property that used to be a courtesy to colleagues is now the input quality for a process you run continuously. Legibility became a throughput variable.

The craft argument that loses

  • "This is not how we write code here"
  • Appeals to pride and standards
  • Benefit lands on nobody's quarter
  • Sounds like taste, so it is negotiable
  • Reliably cut when the deadline moves

The craft argument that wins

  • "Every run against this module loads four times the context it needs"
  • Appeals to spend and rework rate
  • Benefit lands this quarter, repeatedly
  • Sounds like unit economics, so it is defended
  • Survives the deadline because cutting it costs money now
Same practice, same code, different sentence. The second one belongs in a budget conversation, which is where these decisions are actually made.

Where the cost actually shows up

Three places, all of them measurable with what you already have.

Context loaded per change. A change to a module with clear boundaries needs the module. A change to a tangle needs the tangle, plus whatever the tangle reaches into. That difference is paid on every run, in tokens, in latency, and in the reviewer’s attention afterwards.

Rework rate by area. Some parts of your codebase produce changes that come back. If you attribute rework to the area rather than the ticket, the map you get is not a map of hard problems. It is mostly a map of places where the intent is not visible from the code, and something confidently guessed wrong. Context blindness, meaning output that is internally coherent but incompatible with the repository, concentrates exactly where local conventions are invisible.

Review time per change class. The review cost of a change is a function of how much a reader has to hold in their head to judge it. LinearB’s 2026 benchmarks put the increase in median review duration at 441.5 percent on agentic pull requests. Not all of that is legibility, but the fraction that is legibility is the fraction you can do something about this month.

Name the boundary, not the layerA module named for what it owns lets a reader load one thing. A module named for a technical layer forces it to load everything to find out what lives there.
Make the invariant localIf a rule holds across four files, every future change is a guess about the other three. Move the rule where it can be seen, and the guess disappears.
Delete dead paths aggressivelyDead code costs nothing to run and full price to read. It is now read constantly, by something that cannot tell it is dead.
Write the "why" at the point of the surpriseOne line above the non-obvious branch. This is the cheapest craft investment available and the only one that survives a rewrite of the code around it.
None of this is new advice. What is new is that each item now has a bill attached that you can put in front of a finance partner.

What is genuinely worth less now

I am not going to pretend everything that fell under craft survived the transition.

Hand-optimised cleverness has lost most of its value. So has stylistic consistency enforced by argument rather than by a formatter, and so has the deep personal knowledge of a codebase’s quirks that used to make a senior engineer irreplaceable in a particular corner. That was always a fragile asset and it is now close to worthless, because the thing doing most of the reading does not accumulate it.

What survived is the part that makes intent visible to a stranger with no memory. That part got more valuable, not less, and it is the part that was always hardest to defend in a sprint planning meeting.

Where this breaks down

Cost arguments cut both ways. If legibility is justified by spend, then any module cheap enough to regenerate wholesale does not need to be legible at all. That is a real conclusion and I accept it. There is a growing class of code that is genuinely disposable, and craft applied to it is waste.

The measurements I am leaning on are noisy. Context loaded per change moves with model behaviour, prompt strategy and caching, not just with your code. Attributing rework to areas is crude. I would not defend any single number from this in a hostile room; the direction is trustworthy, the precision is not.

Legible code can be shallow code. Small, clearly named units with obvious boundaries can still encode a wrong model of the domain, and legibility makes that error easier to propagate confidently. The most expensive mistakes I have seen were beautifully organised.

This can become a licence to spend a quarter tidying. The argument that craft pays is not the argument that any given cleanup pays. Most cleanups do not, because most code is barely touched. If you take this piece as authorisation for a general refactor programme, you will have used a cost argument to justify a cost.

Somebody has to hold the line, and that is a human job. Everything I have described requires people who know what good looks like reviewing what arrives. If the same volume pressure that made craft economic also removes the people who can recognise it, the argument wins and the practice still dies.

The takeaway

Craft was always an investment in future readers, and the number of future readers just went up by an order of magnitude while their memory went to zero. That turns a taste argument into a unit-cost argument.

Make it in that language. “Every run against this module loads four times what it needs, and the changes that come back come back from here” is a sentence that survives a budget review. “This is not how we write code” never has.

If you take one thing into next week: pick your three highest-change modules and work out what fraction of the context loaded to change them was actually relevant to the change. That ratio is the price you are paying for illegibility, weekly.