What AI actually made better

  • engineering-practice
  • exploration
  • prototyping

Most careful writing about what AI did to engineering work has been, in effect, a loss column. The rituals went out of calibration, the handoffs leak, the debt hides, the apprenticeship thinned, the dashboard decoupled from the thing it measured. The accounting is honest and the entries are real. It is also half a ledger. A team that reads only the loss column comes away believing AI was a net subtraction from the craft, which is not what the careful version of the argument says and not what the teams who adopted well have experienced.

The gains are real. They are also specific — not a diffuse “productivity,” which is the word vendors reach for precisely because it commits to nothing. Three things genuinely got better, in ways that survive scrutiny. Each one is a real asset. Each one also has a condition attached, and the condition is the part most teams skip, which is how a real gain quietly converts into a wash.

This is the other half of the ledger. It is not a rebuttal of the loss column. Both columns are true at once; that is what makes the accounting hard.

1. Exploration got cheap

The change everyone notices is that implementation got cheap — the chosen thing gets built faster. The more interesting change is upstream of the choice: exploration got cheap. The cost of finding out what a direction would even look like, before committing to it, collapsed.

This is a different cost than implementation cost, and it was always the more quietly limiting one. Pre-AI, a team facing a fork — two data models, three ways to structure a service, an unfamiliar approach nobody had used — had to choose mostly on argument, because trying each branch was too expensive to do more than once. The spike was a luxury. The team budgeted one exploratory build, ran it, and from then on defended the sunk investment. Whichever branch got the spike had an unearned advantage: it was the one that existed.

Cheap exploration removes the rationing. A team can now build enough of two or three branches to compare them as artifacts rather than as positions. The unfamiliar approach — a different concurrency model, a storage engine nobody has production experience with, a library the team has only read about — can be tried at the cost of an afternoon instead of a sprint. The question shifts from which option can we afford to investigate to which option does the investigation actually favor. That is a real upgrade in how engineering decisions get made, and it is the gain in this corpus that compounds the most, because better forks compound for years.

The catch. Cheap exploration only pays if exploration still closes. The discipline that the old expense enforced for free was a forcing function: you could afford to explore once, so you were obliged to decide. Remove the expense and you remove the obligation. The failure mode is a team that explores three branches, finds the comparison genuinely informative, and then does not pick — because picking forecloses options and exploring is pleasant and cheap. Call it exploration that never closes. The branches sit there, half-built, each a plausible direction, none of them the direction. The team has bought itself better information and spent it on indecision.

Exploration is an input to a decision, not a substitute for one. Cheap exploration raises the ceiling on decision quality only for teams that still treat the decision as the deliverable and the exploration as the means. A team that has not noticed the difference will explore beautifully and ship nothing, and will mistake the motion for progress because the motion is, genuinely, better-informed than it used to be.

2. The throwaway prototype got honest

Throwaway code was always supposed to be thrown away. It almost never was. The prototype built to answer a question — will this approach work, does this API behave the way the docs imply, what does the UI feel like — had a strong tendency to survive its own purpose. It answered the question, and then, because rebuilding it properly was expensive and it mostly worked, it quietly became the production version. The team inherited a load-bearing system whose architecture was a first draft nobody had intended to keep.

The mechanism was sunk cost, and the sunk cost was real: the prototype represented days of work, and throwing it away to rebuild deliberately meant spending those days again. Faced with that bill, teams rationalized. The prototype “wasn’t that bad.” It “just needed cleanup.” The cleanup never fully happened, and the field accumulated a vast inventory of production systems that were structurally prototypes wearing maintenance.

Cheap implementation broke the mechanism, and this is the gain: the prototype can finally be honest about being a prototype. When rebuilding the proper version costs an afternoon rather than a week, the sunk cost that used to trap the prototype in production is small enough to absorb. The team can build the prototype to answer the question, get the answer, and then actually discard it and build the real thing — because the real thing is no longer prohibitively more expensive than keeping the draft. The throwaway prototype, for the first time, can do the job its name always promised: be genuinely disposable. That makes it a far more useful instrument. You can prototype more aggressively, more speculatively, more often, because the prototype is no longer a commitment in disguise.

The catch. A prototype is only an asset if it stays labeled and walled. The same cheapness that lets a team discard the prototype also lets the prototype reach production-shaped completeness — tests, error handling, a clean surface — fast enough that it stops looking like a prototype. The old prototype announced itself: it was visibly rough, and the roughness was a warning. The new prototype can be stylistically indistinguishable from deliberate work within a day. The failure mode is prototype leakage: the exploratory build looks finished, someone wires it into the real path, and the team has shipped a draft again — not because rebuilding was too expensive this time, but because nobody noticed it was a draft.

The gain requires a discipline the old expense supplied automatically. A prototype has to be marked as one — in the branch, in the description, in the team’s shared understanding of what this code is — and walled off from the production path until a deliberate decision promotes it. Teams that build the prototype, take the answer, and explicitly discard or rebuild it get a genuinely better instrument. Teams that let the prototype’s polish stand in for a promotion decision have reproduced the old failure with a faster clock.

3. A category of toil collapsed

Some engineering work was never developmental. The framework version bump across two hundred call sites. The format migration. The mechanical rename that the type system could almost, but not quite, do alone. The test backfill for a module that shipped without coverage. This work had a specific character: it required attention but almost no judgment, it did not get more interesting the tenth time, and it taught the engineer doing it close to nothing. It was toil — and toil, on most teams, was not distributed as work. It was levied as a tax.

The tax fell on whoever was junior enough, new enough, or unlucky enough to draw it. It was the work that filled a sprint without advancing a career, and the resentment around it was structural, not personal: an engineer could spend a quarter on toil and emerge with nothing to show that a promotion committee or their own sense of progress could recognize. Worse, the toil that got deferred — because someone, reasonably, did not want to spend a quarter that way — turned into a particular kind of debt: the migration nobody ran, the version everyone stayed three behind on.

This category genuinely collapsed. Not “got faster” — collapsed, in the sense that it stopped being a meaningful claim on a person’s time and attention. The bulk migration is now bounded by review time, not execution time. The test backfill is a session, not a sprint. The deferred mechanical debt that used to compound because nobody would volunteer for it can now be cleared by someone who decides it should be. This is the cleanest gain of the three, because almost nothing was lost when it went: the work was not teaching anyone anything, and the people who used to absorb it got that time back. Toil collapse is the rare change in this whole accounting that has a short catch and a long benefit.

The catch — shorter, but real. Two things hid inside the toil, and a team that scythes all of it without noticing loses them. The first is slack. Low-judgment work was where engineers recovered — the task you could do while tired, while half-thinking about a harder problem, in the first week of a new job before the hard work was safe to hand you. A codebase with no toil left in it has no gentle on-ramp; the gradient from “new here” to “trusted with judgment” got steeper, and onboarding has to supply deliberately what the toil used to supply by accident. The second is that not all apparent toil was toil. Some of the mechanical-looking work was quietly building familiarity — the engineer who did the two-hundred-call-site migration came out the other side knowing where two hundred call sites were. That map was a side effect nobody valued until it stopped being produced. The discipline is small: notice which of the collapsed work was carrying a second job, and assign that job somewhere on purpose.

What the second column is for

The loss column and the gain column are both honest, and a team’s experience of AI adoption is mostly determined by which errors it makes about each. Two errors are common and opposite.

The first is over-fearing the losses — treating the calibration problems and the hidden debt and the thinned apprenticeship as reasons the whole change was a mistake, and adopting grudgingly, defensively, in a way that forfeits the gains without avoiding the losses. The second is under-claiming the gains — taking cheap exploration, the honest prototype, and toil collapse as ambient “productivity,” never naming them, and therefore never building the conditions that convert them from potential into realized value. The first team is paying the costs and refusing the dividend. The second team has the dividend sitting in an account it never learned to draw on.

The gains are real and they are conditional. Cheap exploration pays only for teams that still close decisions. The honest prototype pays only for teams that wall it off and discard it on purpose. Toil collapse pays cleanly, as long as the team notices what the toil was quietly carrying. None of these conditions is expensive. All of them are easy to skip, because each gain looks complete on the surface — the exploration happened, the prototype works, the toil is gone — and the missing condition is invisible until the gain has already leaked away.

Teams that read only the loss column adopt AI as damage control and get a smaller version of the loss anyway. Teams that read only the gain column adopt it as a free lift and watch the lift dissipate into motion. The teams that come out ahead are the ones holding both columns open at once — claiming the gains deliberately enough to keep them, and accounting for the losses honestly enough to bound them. The ledger has two sides. An adoption story that quotes only one of them is not optimism or caution. It is just bad bookkeeping.