Freeze Three Constraints First
An agent will rewrite your architecture to ship a feature, unless something in the build fails when it does.
Ibrahim AbuAlhaol, PhD, P.Eng., SMIEEE
AI Technical Lead
An unclear requirement used to cost you once. Someone built the wrong thing, review caught it, and the fix was cheap. After that the misunderstanding was settled for good, in code a person had read. You paid for it one time.
That math has stopped working. When a coding agent rebuilds a module, it reads the requirement again and decides again what it means. Nothing forces it to decide the same way twice. Birgitta Böckeler found this while testing the Tessl framework in October 2025: the same specification gave different results run after run. What used to be a one-time cost is now charged every time you generate, and teams running agents generate all day.
This is why specification engineering became a real practice in 2026 instead of a slogan. Writing things down did not suddenly become a virtue. The costs flipped. Building fell close to zero, and being unclear started to add up.
A specification is not a faster way to say what you want. It is the only place where a decision gets made once instead of once per run.
The half of the spec that nobody writes
Most specs written for agents describe behavior: what the feature does, what the user sees, which edge cases matter. Tools handle this part well. AWS Kiro walks you from requirements to design to tasks across three markdown files. GitHub Spec Kit gives you specify, plan, and tasks.
Kiro also pulled EARS notation into the loop, a strict way of writing requirements that Alistair Mavin and colleagues published in 2009 after studying jet engine control requirements at Rolls-Royce. They found eight problems that kept showing up in ordinary written requirements, from unclear wording to rules nobody could test, and cut all eight by forcing every requirement into one of five sentence patterns. Airbus, NASA and Bosch adopted it long before agents existed.
But behavior is only half of a specification. It answers one question: does the system do the right thing? You buy that half with clear acceptance criteria. It says nothing about what has to stay true while forty other features are being built next to it.
The other half is about structure: the line that may not be crossed, the data that may not leave a country, the interface three other teams already build on, the failure that has to stay small instead of spreading. David Parnas argued in 1972 that a module should be defined by the decision it hides, not by the steps it runs. What a module refuses to expose is its real specification.
Write only the behavior half and you get working features sitting on a system you have to rebuild before real users can touch it. That is the efficiency half, and efficiency here just means how little you rebuild on the way. It never shows up in a demo.
Architecture is the part of the spec you freeze
Here is a definition worth keeping. Architecture is the part of the specification that nobody is allowed to reopen just to ship a feature.
That part used to be protected by cost. Rewriting the database layer to add one form field was too expensive to suggest, so nobody suggested it. The rule held because breaking it was slow, not because anyone had written it down.
Agents removed that protection. Ask one to add a field and it will rebuild the schema if that is the shortest path to passing tests, and the change will look fine in review. Nothing in your request said the schema was holding the building up, because nobody ever had to say it. Breaking an architectural decision now costs about the same as any other change. So it quietly stopped being an architectural decision, while everyone kept treating it as one.
Fred Brooks split complexity in two in 1987. Some of it is accidental, created by our own tools. The rest is essential, built into the problem itself, and he argued that no single advance would make that part ten times easier. Agents are the best attack on the accidental half anyone has shipped. They do nothing for the essential half, which is deciding what a system must be and must never become. That work moved. It did not go away, and specification engineering is where it landed.
Why most spec tools stop short of production
Böckeler's survey gave the field its words by naming three levels. At spec-first, you write a spec before the task and drop it once the feature ships. At spec-anchored, the spec stays alive and guides how that feature changes later. At spec-as-source, people edit only the spec and never touch the generated code.
Her finding is uncomfortable. Almost everything shipping today is spec-first while selling itself as more. Spec Kit makes a branch for every spec, which ties the spec's life to one change request instead of to the feature it describes. Kiro's own examples cover a single story and say nothing about reusing it. Only Tessl, then in private beta, aimed past the first step.
Production systems live in exactly that gap. A spec you throw away after the first build cannot guide the second. Hartwig Grabowski named the failure that follows silent spec-code drift: the code changes, the spec does not, and nobody sees the gap until closing it is expensive. His fix is a drift gate that blocks the merge when the two disagree. It is the same idea as a fitness function in evolutionary architecture: an automatic check that fails the build when something you said would stay true stops being true.
One warning before anyone builds a business case. The success numbers going around for these tools come from vendors and early users, not from controlled studies, and Grabowski's paper has no measurements at all. The argument here does not rest on those numbers. It rests on the cost, which you can check against your own rework rate without trusting anyone's marketing.
A specification nobody enforces is just a comment. Enforcing it is what turns a document into a contract, and only a contract survives an agent that is trying to make the tests pass.
The three worth freezing first
A rule in a wiki is advice. The same rule in the test suite is a specification. Nobody has time to turn a whole architecture into tests at once, and you do not need to. Three rules cover most of what agents actually break, and each one takes a few lines to check.
- A data line: which records may not leave a country, a customer, or a service. The test looks at what crosses the line and fails when something does. Write this one first, because this is the one with a regulator behind it.
- A rule about which module may call which. Agents break this one constantly, because reaching across a line is usually the fastest way to make a test pass.
- A rule for what happens when something breaks. Turn a service off inside the test and check that the system slows down or drops one feature, instead of taking everything down with it.
The second one looks like this.
# spec/invariants/test_boundaries.py
FORBIDDEN = {"billing": {"reporting", "marketing"}}
def test_module_boundaries():
for package, banned in FORBIDDEN.items():
for module in imports_of(package):
assert module.root not in banned, (
f"{package} imported {module.root}. "
"See spec/architecture.md, boundary B-04."
)
That test is now part of the specification. Every agent that runs the suite reads it, and it fails loudly instead of drifting away quietly. It also points back to the written rule, which is what lets a person decide the rule was wrong instead of just deleting the check.
Three checks is an afternoon of work. After that, every generated change is measured against them before it merges, and the agent that would have quietly rebuilt your schema has to fail a build to do it. The number three matters less than the idea: pick the rules that cost the most to undo, and make breaking them loud.
Two more things cost almost nothing to add. Give your interfaces clear version numbers, because they are promises other teams already build on. And write down what you are not building, since the cheapest rule you will ever write is the one that stops an agent from helpfully adding more.
You have to buy both halves
Most companies adopting these tools have bought the first half and assumed the second came with it. They see faster first drafts and decide the method works. The bill for the other half arrives later, when a system has to survive its own pace of change instead of impressing people in a review. Every feature works, and the fourth one meant rewriting the first three.
Specification engineering is not documentation with a new name. It is deciding, once and in writing, which parts of a system may be rebuilt and which may not. The parts that may not are your architecture, whether or not anyone wrote them down. Writing them down is the only thing that makes them hold.
What leaders should do
- Ask your teams to show you the other half of a spec, the part about structure, not the acceptance criteria. If all they have is a list of behaviors, your architecture is not written down anywhere and every agent is free to redesign it. Give it an owner and a date.
- Give one engineer an afternoon this quarter to move the three rules above into the test suite. That is the whole fix, and it outlives whichever tool you buy next.
- Find out which of the three levels your tools actually work at, not which one the vendor claims. If specs are created on a branch and merged away, you are at level 1 and your specs are temporary.
- Change what you measure. Track rework rate, meaning how much generated code gets replaced within thirty days, next to how much you ship. Counting output alone rewards the exact failure you are trying to prevent.
Related Articles
References & Extended Literature
- Böckeler, B. "Understanding Spec-Driven-Development: Kiro, spec-kit, and Tessl." Exploring Gen AI, martinfowler.com, 15 October 2025. martinfowler.com/articles/exploring-gen-ai/sdd-3-tools.html
- Grabowski, H. "The Spec Growth Engine: Spec-Anchored, Code-Coupled, Drift-Enforced Architecture for AI-Assisted Software Development." arXiv:2606.27045 [cs.SE], 25 June 2026. arxiv.org/abs/2606.27045
- Mavin, A., Wilkinson, P., Harwood, A., and Novak, M. "Easy Approach to Requirements Syntax (EARS)." 17th IEEE International Requirements Engineering Conference (RE 2009), pp. 317-322. DOI 10.1109/RE.2009.9
- Parnas, D. L. "On the Criteria To Be Used in Decomposing Systems into Modules." Communications of the ACM, 15(12), December 1972, pp. 1053-1058. DOI 10.1145/361598.361623
- Brooks, F. P. "No Silver Bullet: Essence and Accidents of Software Engineering." IEEE Computer, 20(4), April 1987, pp. 10-19. DOI 10.1109/MC.1987.1663532
- Ford, N., Parsons, R., and Kua, P. Building Evolutionary Architectures: Support Constant Change. O'Reilly Media, 2017. Source of the fitness function pattern referenced above.
- GitHub. "Spec Kit: Toolkit to help you get started with Spec-Driven Development." Open-sourced September 2025. github.com/github/spec-kit
- AWS. "Kiro: The AI IDE for prototype to production." Spec mode, EARS notation, and the requirements-to-design-to-tasks flow. kiro.dev