Skip to content
All writing

The doorman fallacy in software engineering

A hotel replaces its doorman with a doorstop and revenue quietly falls. The same reasoning is now being applied to engineering teams, and it rests on believing that writing code was the job.

In Alchemy, Rory Sutherland describes a hotel that works out its doorman is an expensive way to open a door. A doorstop costs almost nothing. The doorman costs a salary. The arithmetic is not in dispute, so the hotel automates the door.

Revenue declines over the following year and nobody can explain it. Nothing changed except the door.

What the hotel had been buying, without ever writing it down, was someone who hailed taxis, recognised returning guests, discouraged people who should not be in the lobby, carried bags, and signalled by standing there that this was a hotel with a doorman. Opening the door was the only part visible in the accounts. It was close to the least valuable thing he did.

That is the doorman fallacy: define a role by its most legible function, automate that function, and discover afterwards that the function was never the point.

It is now being applied to software engineering, and the argument runs like this. Engineers write code. AI writes code. Therefore fewer engineers, or cheaper ones, or none.

Every step of that is sound except the first.

Writing code is the last step, and the cheapest

By the time an engineer types anything, the decisions that determine whether the software survives have already been made.

Somebody worked out what the thing actually needs to do, which is rarely what the request said. Somebody decided what not to build. Somebody chose which parts to buy rather than write, and which third party is safe to depend on. Somebody worked out the data model, which is the decision that is hardest to reverse and most expensive to get wrong. Somebody decided how it fails.

Writing code is the act of expressing those decisions in a form a computer will accept. It is the visible output, it is the part with a measurable volume, and it is the part that looks like the job to everyone who has never done it.

This is not a new confusion. Organisations have measured lines of code as a productivity metric for decades, and the metric has always been worse than useless, because more code is more to maintain. An engineer who solves a problem in fifty lines has usually done better work than one who takes five hundred. The measurement rewards the opposite.

Tokens are the current version of the same mistake. Volume of generated output is once again standing in for value, for the same reason it did last time: it is the only thing that is easy to count.

What the role contains that is not in the output

Five things, none of which appear in a diff.

Deciding what not to build. The most valuable engineering decision is usually a refusal. A feature that does not exist has no bugs, no maintenance cost and no security surface. Somebody has to be able to say that a request should not be met the way it was made, and be listened to.

Knowing which approach survives contact with production. There are always several designs that work in a demonstration. Knowing which one still works when the data is malformed, the third party is down, two users click at once and the volume is forty times higher than anyone forecast is not a knowledge problem. It is a scar-tissue problem.

Carrying the reasons. Every system contains decisions that look wrong and are not. A duplicated field that exists because an upstream system sends the same value in two formats. A retry that looks excessive and prevents a known failure. This context lives in people. Remove them and the next person removes the safeguard, because to them it looks like a mistake.

Noticing the problem is wrong. The most expensive projects are the ones that were built correctly and should not have been built at all. That failure happens at the requirements stage, and it is caught by someone with enough context to say the thing nobody in the room wants to hear.

Being accountable. When a system produces a wrong answer at scale, an organisation needs a person who understands why and can be held responsible for the fix. Generated code has no author in that sense. Something still has to.

The failure is deferred, which is what makes it dangerous

If removing engineering judgement broke things immediately, nobody would do it twice. It does not.

The code gets written. It compiles. The tests pass, including the ones generated alongside it. The feature ships and the demonstration goes well. On any measure available in the first quarter the decision looks correct, and the saving is real and bankable now.

The cost arrives later, as a slope rather than an event. Changes take longer than they used to. Bugs recur in the same areas. Nobody is confident what a change will affect, so estimates inflate to cover the uncertainty. New engineers take months rather than weeks to become useful. Eventually somebody proposes a rewrite, and the rewrite is quoted at more than the entire saving.

At no point does anything obviously break. That is exactly the hotel’s experience. Revenue declined and nobody could point at the door.

The distinction that actually matters

None of this is an argument that AI-assisted engineering is a mistake. Generated code is genuinely faster for a large class of work, and refusing it is its own kind of expensive.

The distinction is between compressing the expression and removing the judgement.

An experienced engineer using generation to produce in an hour what previously took a day has compressed the expression. Every decision that mattered is still being made by someone who understands the consequences. That is a straightforward gain, and it is what most competent teams are already doing.

An organisation that concludes it needs fewer people making decisions, because the typing is now cheap, has removed the judgement. The output looks similar for a while. It is not the same thing, and the difference does not appear on any dashboard until it is structural.

How to tell which one you are doing

Three questions, and they are uncomfortable on purpose.

When something ships, can anyone explain why it was built that way? Not what it does. Why that approach rather than the alternatives. If the honest answer is that it was generated and it worked, then no decision was made, and there is nothing to revisit when the assumptions change.

Who is allowed to say no? If nobody in the process has both the standing and the context to reject a request, you do not have engineering. You have order-taking with better tooling.

When it breaks at 6pm, who understands it? If the answer is that somebody will read the code and work it out, an owned system has become an archaeology problem. That is a real cost and it arrives at the worst possible moment.

Sometimes it is just a door

The doorman fallacy is not an argument against automation. Sutherland’s hotel could have automated the door and kept the man, and been better off for it.

The point is narrower and harder. Value is frequently invisible in the accounts, and the things easiest to measure are rarely the things that matter. Lines of code were easy to count and meant nothing. Tokens are easy to count and mean nothing. Whether the right thing got built, in a form the organisation can still change in three years, is difficult to count and is the entire job.

Some tasks genuinely are what they appear to be. Plenty of code is boilerplate and generating it is an unambiguous improvement. The failure is not in automating the typing. It is in concluding that the typing was what you were paying for.

Recognise any of this?

We have built five AI systems that reached production. Twenty minutes will tell you whether yours can.

Book a call