Big Spec Up Front failed. Not because the people who practiced it were careless — many of them were meticulous. It failed because of something structural: the act of implementation always reveals things that specification missed. Users cannot fully articulate what they want before they see it. Complexity defeats even complete knowledge. External requirements shift before the system ships.
Agile was the response. Short loops. Working software over comprehensive documentation. Iterate toward understanding instead of specifying toward it.
That lesson got learned. And now AI is quietly unlearning it — not through argument, but through incentive.
The Mechanism
Here is the plain fact about how current AI coding tools work: the more complete your upfront specification, the better the output.
This is not a philosophy. Nobody designed it to push teams back toward waterfall thinking. It is simply an emergent property of how large language models process context. A well-specified prompt produces better code than a vague one. A detailed behavioral contract produces better tests than a rough sketch. Completeness is rewarded. Ambiguity is penalized.
The practical consequence is a pressure — quiet, consistent, invisible in any single decision — toward specifying more before you start. Not because you believe in BSUF. Just because the tool works better when you do.
The difference is immediately visible in the output. Ask an AI to implement a user notification system with “users should be able to manage their notifications” and you get something generic that handles the obvious case. Ask it with a two-page spec covering channel preferences, frequency caps, fallback behavior, opt-out scopes, and delivery guarantees — and the output is genuinely useful. The AI did not teach you this lesson through argument. It taught you through quality of output. Specify more, get more. The feedback loop is fast and consistent.
And that is exactly how methodological drift happens. Not through a decision to change approach. Through a sequence of individually reasonable choices that compound into something nobody chose.
What Drift Looks Like
It rarely announces itself. It looks like this:
You are starting a new feature. You sketch a rough spec. The AI output is mediocre — missing edge cases, unclear about boundaries. So you add detail. The output improves. You add more. The output improves again. By the time you have a version you trust, you have written four pages of requirements before a single test has run.
Each step was reasonable. The cumulative effect is that you are doing what your team explicitly abandoned five years ago.
The difference from the old BSUF era: you are moving faster. The spec is written in an afternoon instead of a quarter. The code is generated in an hour instead of a sprint. The velocity feels high. What you cannot see is that the loop has gotten shorter — not in duration, but in iteration count. And a faster loop with fewer iterations is still a process that skips what the missing iterations would have revealed.
The Worst Case Is the Important Case
There is a particular irony in where this pressure is strongest.
On well-understood problems — stable requirements, bounded scope, familiar domain — a thorough upfront spec is often genuinely achievable. The team knows what they need. The AI output is good. The pressure and the capability align. This works.
On problems that actually matter — new product territory, architectural unknowns, requirements that will shift under you — a complete upfront spec is impossible by definition. You cannot fully specify what you do not yet understand. The structural reasons BSUF fails are at their most acute.
And this is precisely where AI is simultaneously pulling you hardest toward the thing that will fail you. Because the output on a vague prompt for a hard problem is noticeably worse than the output on a detailed prompt for an easy problem. The tool is loudly telling you to specify more. The lesson it is teaching is wrong.
Consider what it looks like to build a recommendation engine for a new product — say, surfacing relevant content for users who have no history yet. You do not know what signals matter. You do not know what “relevant” means to this user population. You will only find out by shipping something, watching behavior, and iterating. That is not a gap in your preparation — it is the nature of the problem. No amount of upfront specification closes it.
But your AI tooling does not know that. The output on your first vague prompt is disappointing. So you add more detail to the spec. The output improves slightly. You add more. You are now writing user behavior models, cold-start heuristics, and fallback ranking strategies — all before you have a single data point on what your actual users do. You have front-loaded all the decisions that were supposed to emerge from iteration, because the tool gave you better output when you did.
The human tendency to over-specify before starting is not a new failure mode. AI gives it a tailwind.
The Counter-Move: Expectation-Driven Development
The instinct, when you notice this drift, is to specify less upfront. That is not quite right either. Vague prompts produce vague output. The goal is not to avoid specification — it is to avoid front-loading it.
The actual counter-move is to change what the specification is for — and what counts as proof that it was met.
This is what Expectation-Driven Development makes structural. Instead of a contract written before the first line of code, EDD works with expectations: plain-language statements of what the system must demonstrate, one behavior at a time. The AI implements against that expectation. The result is not “tests pass” — it is evidence: a demonstrated run of the real system proving the expectation was met. Then the next expectation.
The unit of specification is a single behavior. The proof is execution, not assertion. The spec grows through iteration rather than preceding it.
Applied to the notification system:
- Start with one expectation, not a system doc. “A user who opts out of email notifications does not receive an email when a new message arrives.” Not channel preferences, not frequency caps, not fallback behavior. One thing. What the implementation forces you to decide — where is opt-out stored? per-user or per-notification-type? — becomes the input to the next expectation.
- Require evidence, not confirmation. When the AI produces a notification preference model with a single boolean
email_enabled, run the real system against the expectation. If a user withemail_enabled = falsestill receives an email under certain conditions, the expectation is unmet — and you just learned something the spec never captured. That is valuable, and it cost you ten minutes instead of two weeks of BSUF. - Let the expectation author be different from the implementer. The person — or agent — who states what the system must do should not be the one who decides how it does it. That separation is what keeps the feedback loop honest. Without it, the spec and the implementation collapse into the same assumptions, and the evidence proves nothing.
Speed Is Not an Argument Against Iteration
The genuine advantage AI brings to iterative development is speed. Each cycle of specify → implement → observe → revise is faster. That is a real gain.
The trap is concluding that faster means fewer cycles needed. It does not. A faster loop is valuable because it lets you run more loops in the same time — which means more learning, more course correction, more contact with the actual problem.
Teams that use AI speed to skip iterations are trading that gain for the same class of failures that made BSUF fail in the first place. Just at higher velocity.
Nobody has to choose BSUF for it to come back. They just have to follow the path of least resistance long enough for the drift to compound.
Related: EDD Closes Half the Loop · AI + TDD: A Shortcut to the Goal or a Loss of Insight?
