Rapid Product Development: RAD Without the Requirements Phase
by Simon Lehmann
I build products as rapid application development with the requirements phase taken out. That phase was insurance against expensive rework. Rework is cheap now, so I stopped paying for it.
RAD’s reputation is “the fast one”, which is unfair to it. Its first two phases are requirements planning and user design, and they are the heavy part: get users and stakeholders in a room, run workshops, leave with an agreed specification. Only then does construction start, timeboxed and small. RAD didn’t skip the specification. It bought one and then protected it.
That was a good trade. Construction ran for months and took a team. Finding out in month four that the model was wrong cost you months two and three as well. Three weeks of workshops to avoid that is cheap insurance: a bounded cost against an unbounded one.
The premium hasn’t changed. The risk has. When rebuilding a subsystem is an afternoon, buying certainty up front stops paying for itself. You are spending attention and other people’s time to avoid a cost that isn’t there any more.
The premium may also have been wrong all along. Everyone reaches for the same number to justify it, that a defect costs a hundred times more to fix in production than in requirements, and it turns out to have no study under it. Laurent Bossavit chased the citations. They run back to internal IBM course notes from 1981, and the institute credited with the research was a staff training program. The shape was plausible when construction took months. The multiplier was folklore.
So requirements gathering didn’t become wrong. It became overpriced. That’s how process usually outlives its reason, because the reason is rarely written down next to the practice. Brooks did this to himself and then said so. “Plan to throw one away, you will anyhow” was the 1975 advice. Twenty years later he called it too simplistic, because it assumed the waterfall it was written inside. His reason wasn’t mine, he was worried about how long waterfall makes you wait for user feedback, but the shape is the same. Advice quietly inherits the cost structure it was written under.
There’s a second cost people miss. A document several people agreed to acquires authority. Changing it means arguing against a consensus instead of against a guess. You pay once to manufacture certainty and again every time reality disagrees with it.
The phase bought one more thing, and this one I’m not paying for either. It was how you found out what people who aren’t you need. One person, greenfield, no stakeholders, no regulator, nothing legacy to keep alive, and I’m the user. So I get that part free. Everything below is bounded by it, and I don’t know what the method looks like when the requirements have to come from someone else.
What goes in instead
A rough idea. Not a thin specification, an actual rough idea, the kind you can say out loud in two minutes.
I hand that to an agent and get back, an hour later, the artifact those two phases used to produce: purpose, principles, an architecture, a list of things the product will not be. The difference is what I take it to be. It is not knowledge. It is guesses in a good format, and that’s fine, because nothing is staked on it.
Hanip is the Korean app I’ve been building this way. Its day-one design named a cloud pronunciation API in the architecture diagram. That was gone before lunch, replaced by something self-hosted, because first contact with the problem said it wouldn’t work. A capability the same document ruled out for v1 shipped anyway. That’s what a document written before you’ve built anything is worth, and the only mistake available is treating it as worth more.
The decisions get smaller
The requirements still have to come from somewhere. They arrive during, and they arrive in a particular order.
First you decide what the product is. Not features, identity: what loop it’s built around, what it refuses to be. Then a size down, what its parts are and what each owns. Then how one feature should behave. Then which of two reasonable designs for a screen is better. Then things that are barely engineering, like which examples go in the third batch of content.
Nobody hands you that sequence. You answer whatever the biggest open question is, and in hindsight they were shrinking. Which makes decision size a progress signal. Still making identity-sized calls on the ninth iteration and the product isn’t converging, it’s thrashing. When the biggest question left is a matter of taste, you’re done.
Requirements gathering didn’t get skipped. It got spread across the build and sorted by size, and every decision got made by someone who had used the thing that evening.
Why it converges
Big decisions do arrive late. A few days into Hanip I reopened the entire visual design, which is an identity-sized question showing up well after identity was settled.
It didn’t reset everything. The early decisions were written down as constraints, each with the reason behind it. The overhaul had to argue with them before any code moved, and most of them won.
That’s the mechanism. A later decision has to beat an earlier one on the merits rather than by being more recent. Without it, iterations don’t get smaller. They take turns being big.
Which is just an architecture decision record, written up by Michael Nygard in 2011 for the same reason. Nobody reads a big document, and once the reason behind a decision is gone, later decisions overturn it without ever arguing with it. Building this fast only means there are more later decisions.
Engineering comes second
Engineering follows the product here. I read maybe a tenth of the code. What keeps that from rotting is workflows: passes that go back over what the agents built, check it against standards I’ve set, and rewrite it to meet them. Quality applied in a sweep, not supervised line by line.
Except anything that can lie to you
A layout bug announces itself when you look at the screen, so it can wait. A model returning a confident wrong answer looks exactly like one that works, and using the product will never surface it. On Hanip the graded evals for every model interaction went in near the start, before almost any product iteration, and caught things using the app wouldn’t have.
This is the one piece of the method that doesn’t follow from rework being cheap. It follows from a component being stochastic, which is why evals are their own discipline, with or without any of this. Anything that fails silently needs its harness before you iterate, because iterating is what carries a silent failure forward.
What it still costs
You can’t reliably tell which decisions are the big ones while you’re making them. Some look tiny. How one piece of data is modelled can be a product decision in a technical costume, and you feel it everywhere, later. An agent builds whatever structure you describe, quickly and well, and won’t stop to tell you the structure was the decision.
There’s an older way to say this. Architecture is whatever people think is hard to change, which is a fact about your tools more than about the thing itself. On one of Martin Fowler’s projects, Pramod Sadalage made schema changes and data migration cheap, and the database schema stopped being architectural at all. So the architect’s real job, Fowler argues, is to remove architecture by eliminating irreversibility.
That points somewhere other than getting better at spotting the big decision. It says to have fewer of them. Make the thing easy to undo and it matters less whether you called it right.
Which is the same trade as the rest of this, one level down, and it’s where I have the least to show. A structure that’s expensive to undo takes no longer to describe to an agent than one that isn’t. Nothing slows you down at the point where it counts.