Let's talk
ai

AI in the delivery loop, described honestly

There are two prevailing accounts of AI in software delivery and both are wrong. One holds that engineering is nearly solved and teams can be a fraction of their size. The other holds that the output is unusable and serious work is untouched by it. Neither survives a few months of shipping production software with these tools in the loop.

What follows is what we actually observe, stated as plainly as we can, including the parts that are inconvenient.

Where it helps materially

Scaffolding and repetitive structure. A new endpoint that follows the shape of eleven existing endpoints, the data-access layer for a table you have just defined, a form bound to a schema, the fifteenth integration test that differs from the fourteenth in three values. This work is mechanical, the correct answer is obvious to a reviewer, and being able to verify it quickly is exactly what makes generation safe here.

Tests, especially the ones nobody writes. Given an implementation, models are good at enumerating cases a tired human skips: empty collections, boundary values, unicode in the name field, the timezone edge. Two cautions apply. Tests generated from an implementation assert what the code does, not what it should do, so they lock in bugs as faithfully as behaviour. And a suite that is mostly generated tends toward volume over meaning. Use them as a proposed list to prune, not as a body of work to accept.

Mechanical migrations. Moving a codebase across a framework version, replacing a deprecated library call in six hundred places, converting one test framework’s idioms to another’s. These are transformations with a checkable result: the build passes, the existing tests pass, the diff is reviewable in bulk because it is repetitive. This is one of the clearest wins available.

Comprehension of legacy code. This is where the value is largest and least discussed. Faced with a two-thousand-line stored procedure written by someone who left in 2011, a model will produce a readable summary of what it appears to do, trace the call graph, identify inputs and outputs, and flag branches that look unreachable. That is a starting hypothesis, not a finding, and every part of it has to be verified against the running system. But it replaces a week of reading with a day of checking, and it makes modernisation work tractable that otherwise stalls on nobody being willing to start.

The first draft of anything written. Commit messages, pull request descriptions, runbook entries, the documentation nobody has time for. Low risk, edited before use, and it raises the floor on artefacts that were previously skipped entirely.

Where it does not help

Deciding what to build. No model knows that the invoice logic has an exception for one customer because of a contract signed in 2019, or that the operations manager will not use a screen that takes more than four taps. Requirements come from talking to people who do the work.

Architecture with real trade-offs. Ask for an architecture and you will get a competent, generic one — the median of what is written about architecture on the internet. It will not know your team’s operational capacity, your compliance boundary, the system you must interoperate with, or which of your constraints is negotiable. Architecture is largely the art of choosing which problems to have, and that requires context the model does not have.

Subtle, domain-specific correctness. Code that compiles, reads well, passes review at a glance and is wrong about something only a domain expert would catch. This is the most dangerous output the tools produce, precisely because superficial quality is high. Financial rounding, tax rules, entitlement logic, anything where “looks right” and “is right” diverge.

Debugging genuinely novel failures. For a well-known error message, excellent. For an intermittent failure arising from your specific interaction of concurrency, caching and clock skew, it will confidently propose plausible causes, and confidence uncorrelated with correctness is worse than no answer for an inexperienced engineer.

Anything requiring accountability. A person has to be answerable for what ships. That cannot be delegated to a tool, and no serious client accepts otherwise.

Review discipline does not change

This is the point on which we will not move, and it is where teams get into trouble.

Generated code arrives fluent. It is well-formatted, plausibly named, idiomatic. Human code signals its own uncertainty — awkward naming, a hesitant comment, a slightly odd structure — and reviewers have spent years reading those signals. Generated code emits none of them, whether it is correct or badly wrong. The usual heuristics for where to look harder simply do not fire.

So the standard has to be explicit: every line that ships is reviewed by an engineer who understands it and can defend it, and who is accountable for it regardless of how it was produced. “The model wrote it” is not a mitigating explanation for a production incident.

Two practical consequences follow. Keep changes small, because the bottleneck moves to review and a two-thousand-line generated diff does not get reviewed properly by anyone, whatever the approval says. And be more careful, not less, in unfamiliar territory — the situation where generation is most tempting is exactly the one where you are least equipped to spot what is wrong with it.

The net effect

Delivery is faster, and the gain is real but uneven. It concentrates in the mechanical middle of the work and largely bypasses the parts that were always hard: understanding the problem, choosing among imperfect designs, and being sure the thing is correct.

The uncomfortable implication is that the ratio shifts. Less time typing code, more time reading it, reasoning about it and deciding whether it is right. That is a better use of an engineer, but it is not the same job, and teams that adopt the tools without adjusting how they review are shipping faster in a direction they have stopped checking.

Working on something like this?

We build this kind of software, and we staff the teams that do.

Get in touch