There is a lot of enthusiasm around spec-driven development: write the specification in English, then use that specification to guide implementation, often with AI helping produce the code.
The appeal is obvious. English is accessible. Product people, engineers, domain experts, and executives can all participate. A written specification can create alignment before implementation begins.
But English is also part of the problem.
English has a rich vocabulary and many nuanced ways of expressing the same idea. That richness is useful in conversation, persuasion, and storytelling. It becomes more complicated when several people—or several AI agents—must interpret a requirement in the same way.
Nuance can clarify intent. It can also cloud it.
Programming languages have the opposite property. Their vocabulary and syntax are deliberately constrained. That limitation reduces expressiveness, but it also limits interpretation. A machine cannot decide that a statement probably meant something close to what was written. The code either satisfies the language’s rules or it does not.
That raises an uncomfortable question: does spec-driven development need a formal language?
Or perhaps a spec for the spec?
A constrained specification language sounds attractive. Define a limited vocabulary, prescribe a syntax, prohibit vague terms, and ambiguity should decline.
Behavior-driven development already moves in this direction:
Given a valid unused reset token
When the account owner submits a compliant password
Then the password is changed
And the token becomes unusable
That is more precise than saying, “Users should be able to reset their passwords securely.”
BDD gives us a constrained grammar, observable behavior, concrete examples, and a bridge between business language and executable validation.
But it also demonstrates the limits of formal structure.
Consider:
Given the user is logged in
When the user submits the form
Then the form is processed successfully
The syntax is valid. The meaning is not.
What does “logged in” permit the user to do? What does “processed” mean? What qualifies as “successfully”?
Formal syntax can expose ambiguity, but it cannot eliminate the need for judgment. Worse, it can create the appearance of rigor while leaving the important questions unresolved.
A limited vocabulary does not create clear intent. It makes ambiguity, omission, and contradiction easier to detect.
That is still valuable, but it is a different promise.
The answer may not be a single formal specification language. It may be a layered specification system that moves from broad intent toward progressively tighter definitions.
The first layer might express purpose in ordinary language: customers should be able to recover account access without contacting support.
The next layer would define important terms and invariants. An account owner might be defined as someone who has completed identity verification. The specification might state that a password reset must never change the account owner and that a reset token may be used only once.
A behavior layer could then describe what should happen when the owner uses a valid token and submits a compliant password. Another layer could define the security, reliability, delivery, rollback, and observability constraints around that behavior.
A final layer could make uncertainty explicit. Perhaps the team assumes that most users complete the reset process within fifteen minutes, but confidence is low and actual behavior should be measured before finalizing the token-expiration window.
This is not one language. It is a progression from intent to evidence.
SDD does not necessarily need to replace English with a formal language. It needs layers that progressively constrain English, expose uncertainty, connect intent to delivery, and direct unresolved decisions to the people who must make them.
There is a temptation to reserve structured specifications for large changes.
That is a mistake.
A one-line code change can alter authentication, billing, data retention, caching, deployment behavior, or rollback safety. “Small” often describes implementation effort, not consequence.
The answer is not to exempt small changes from definition. It is to preserve the same essential questions while allowing the answers to remain brief.
Every change should explain what is changing, why it is changing, what is in scope, and what is explicitly out of scope. It should identify what observable behavior will differ, what must remain unchanged, how the change will be verified, how it will be deployed, and how it will be recovered.
For a routine change, those answers may fit in ten lines.
That is still a specification.
Low ceremony does not mean low discipline.
A specification that describes only what the software should do is incomplete.
Software must be tested, built, deployed, observed, and sometimes reversed. Those delivery behaviors are part of the system’s behavior.
A change is not fully specified if nobody has decided which checks must pass, whether rollout should be gradual, what evidence will be collected after deployment, what condition should stop the rollout, or how the system will recover.
That does not mean every change should repeat the same delivery rules.
An organization can define standard profiles for routine classes of change. An individual specification can inherit those rules and record only the deviations.
That suggests an important principle:
Define everything, but do not restate everything.
Boilerplate can reduce repetition, but defaults must remain visible and reviewable. Otherwise, inherited rules become invisible assumptions.
This is where ITIL has something useful to contribute.
At its best, ITIL says something simple: have a change review process. Understand the change before making it. Apply more scrutiny where consequence is higher. Learn from the outcome. Improve the process itself.
That is reasonable.
Over time, organizations, consultants, auditors, certification programs, and tool vendors have often layered ceremony onto those principles.
“Review the change” becomes “complete a large ticket, populate mandatory fields, attend a CAB meeting, obtain several approvals, wait for a change window, and satisfy the tool.”
That is not the inevitable result of structured review. It is one implementation of it.
A useful change process may be no more than describe, challenge, decide, verify, learn.
The same warning applies to spec-driven development.
A valuable principle can become a framework. The framework can become a taxonomy. The taxonomy can become mandatory fields. The fields can become dashboards. The dashboards can become a platform.
Soon, the process consumes more attention than the changes it was supposed to improve.
Review should add judgment, not paperwork.
I first gave a talk called “ITIL in an Agile World” about ten years ago. Even then, my argument was that ITIL and Agile were not natural enemies. They often valued the same things, but described them differently and implemented them in very different ways.
Agile says, “Inspect and adapt.” ITIL says, “Continual improvement.”
Agile says to deliver in small increments and learn from feedback. ITIL says to assess change according to risk, observe the result, and improve the practice.
The conflict often comes from comparing the worst version of each approach.
Bad Agile becomes, “No planning. No documentation. Just ship.”
Bad ITIL becomes, “Tickets, gates, approvals, and meetings.”
Neither reflects the strongest version of the underlying idea.
A useful SDD practice should combine Agile feedback with disciplined change review. The specification should not be treated as a contract carved in stone. It should be the current shared model of intent, assumptions, constraints, and evidence.
When learning changes the understanding, the specification should change too.
AI can help with this process, but its first role should be review, not authority.
When introducing AI-assisted review, organizations may initially want humans and AI to examine the same changes in parallel.
The AI can look for missing scope, contradictory requirements, untested assumptions, unclear rollback, mismatches between claimed risk and actual system impact, and deviations from established policy.
The human can judge whether the intent is correct, whether the tradeoff is acceptable, whether the business consequence matters, and whether the organization is willing to accept the remaining risk.
The disagreement between human and AI is useful data. If an AI classifies a change as medium risk while a human classifies it as high risk, the difference may expose missing context, poor definitions, an unknown dependency, or a category the model has not learned to recognize.
Over time, review outcomes can help an organization discover what routine, low-risk, and exceptional changes actually look like in its own systems.
Those definitions should emerge from evidence, not solely from a taxonomy created in advance.
A one-line authorization change may be small in implementation and large in consequence. A migration involving thousands of lines may still be repeatable, bounded, and reversible.
Size can summarize the review demand. It should not substitute for understanding risk.
As patterns become better understood, AI may eventually be trusted to handle narrow, evidence-backed classes of change. That authority should be earned by domain, system, and change class—not granted globally.
Humans should remain responsible for intent, disputed tradeoffs, exceptions, irreversible decisions, and acceptance of consequential risk.
That is more precise than saying there is a “human in the loop.” A human may be present without contributing meaningful judgment. The process should make clear which decisions still require human responsibility.
Continual improvement must apply not only to the software, but also to the specification and review process.
Otherwise, every incident adds a field. Every audit adds an approval. Every exception adds a checklist. Nothing is ever removed.
That is how lightweight governance becomes process sediment.
A healthy process must be able to add a control when evidence shows a recurring gap, change it when it routes attention poorly, automate it when the decision is sufficiently understood, and remove it when it no longer improves outcomes.
Removal matters.
Most governance systems have a mechanism for adding controls. Few have a politically safe way to delete them.
A spec for the spec will eventually become another bureaucratic system unless it is designed to learn, inherit defaults, escalate exceptions, and remove controls.
The feedback loop also cannot stop when deployment succeeds.
Many damaging changes deploy cleanly. They pass CI. They do not trigger an incident.
They still increase cost, coupling, cognitive load, support burden, or the difficulty of future change.
A mature review process should ask more than whether the deployment worked.
Did reliability, latency, cost, or support load change? Did users experience the intended outcome? Did the change make the system harder to understand, operate, or modify?
Without those later signals, the process will optimize for deployability rather than survivability.
That is a dangerous form of local success.
The strongest role for AI in SDD may therefore not be generating increasingly polished documents.
It may be routing attention.
Instead of producing four pages of prose, the system might say:
This appears to be a standard API field addition, but the field contains personal data, the existing retention policy does not cover it, and downstream export behavior is unspecified. A human must decide the retention period, export eligibility, and whether existing customers must be notified.
That is useful.
It directs human judgment toward the places where judgment is still required.
A specification is not successful because it is complete, formal, or impressive. It is successful because it helps the organization make a better decision.
Spec-driven development should learn from BDD, ITIL, Agile, CI/CD, formal methods, and decades of failed attempts to turn engineering judgment into templates.
Every change needs defined intent and boundaries, but not every change needs the same amount of specification.
Use constrained language where it exposes ambiguity. Use examples where behavior matters. Use inherited profiles to avoid repetition. Use CI/CD evidence to connect intent to delivery. Use human review for judgment, tradeoffs, and risk acceptance. Use AI to challenge assumptions and route attention. Use observed outcomes to improve both the software and the process.
And remove controls when they no longer help.
Before adopting spec-driven development, do not ask only whether the specification is complete.
Ask whether it exposes the decisions still being made, the assumptions still untested, and the consequences that still require human judgment.

No responses yet