Amazon just launched Kiro, an agentic IDE built around a concept they’re calling spec-driven development. The premise is straightforward: instead of feeding an AI agent one prompt at a time and hoping it holds context, you write a specification — a version-controlled markdown document describing what the program should do — and let the agent build against that.
This isn’t a new idea. Amazon has been doing this internally for years with their “working backwards” methodology, press-release-first product development, and formal specifications using TLA+. What’s new is applying it to the AI coding workflow, where it solves a very specific problem: agents losing the plot.
The problem with prompt-by-prompt development
When you vibe code — prompt, review, prompt again — you’re holding the spec in your head. The agent only sees the current instruction. It doesn’t know that the button you asked for three prompts ago was supposed to solve the current game state, not start a new one. Each prompt is an isolated transaction.
This works for small tasks. It falls apart the moment you’re building anything with more than a few interconnected requirements. The agent starts making decisions that conflict with earlier ones, and you spend more time correcting course than making progress.
What a spec actually is
A spec is a markdown file that describes what your program should accomplish and what constraints it needs to respect. It can be as simple as a list of user stories or as detailed as a formal design document. The important properties:
- Version controlled. It lives in your repo, not in a chat history.
- Human readable. Stakeholders can review it without reading code.
- Persistent. The agent references it on every task, not just the first one.
In Kiro’s workflow, you start with a prompt, the agent generates user stories, you review and modify them, then the agent creates a design and implementation plan. The spec becomes a living document — when requirements change, you update the markdown, and the agent adjusts its implementation accordingly.
Best practices for spec-driven development
1. Start with outcomes, not implementation
Write what the program should do, not how it should do it. “Users can undo their last three moves” is a spec. “Add a stack data structure that stores move history and pop from it when the undo button is clicked” is an implementation detail masquerading as one.
The whole point is to let the agent figure out the how. Your job is to be precise about the what.
2. Keep specs atomic and testable
Each requirement should be independently verifiable. If you can’t look at the running program and confirm whether a requirement is met, it’s too vague. “The app should feel fast” isn’t testable. “Page transitions complete within 200ms” is.
Bad: The search feature should work well. Good: Search returns results within 500ms. Results are ranked by relevance. Queries with no matches display an empty state with suggested alternatives.
3. Update the spec, not the prompt
When something isn’t right, the instinct is to fire off another prompt: “Actually, make the button blue instead.” Resist that. Go back to the spec, update the requirement, and let the agent re-derive the change.
This matters because the next time the agent touches that component — for a different feature — it will still have the correct requirement. A prompt correction is ephemeral. A spec update is permanent.
4. Layer your specs
Not everything belongs in one file. A pattern that works well:
requirements.md— User-facing behavior. What the product does.design.md— Technical architecture. How systems interact.constraints.md— Non-functional requirements. Performance budgets, accessibility standards, security rules.
The agent can reference all three, and each serves a different audience. Product managers read requirements. Engineers read design. Everyone respects constraints.
5. Version your specs with your code
This sounds obvious, but it’s the thing that makes the whole approach work. When your spec is a markdown file committed alongside your source code, you get diffs, pull request reviews, blame history, and rollbacks — all the tools you already use for code, applied to intent.
A spec that lives in a Notion doc or a Slack thread is better than nothing. A spec that lives in the repo is an order of magnitude better.
6. Treat the spec as a conversation starter
The first draft will be wrong. That’s fine. The value isn’t in getting it perfect on the first pass — it’s in having a concrete artifact to react to. It’s much easier to look at a generated list of user stories and say “this one is wrong, that one is missing” than to enumerate every requirement from scratch.
Use the agent to generate the initial spec, then sharpen it with human judgment.
7. Use the spec to scope, not just to build
One of the less obvious benefits: a spec makes scope visible. When a stakeholder asks for a new feature, adding it to the spec forces you to articulate exactly what it entails. Three lines in requirements.md might translate to two weeks of work — but now everyone can see those three lines and have an informed conversation about priority.
The bigger picture
Programming languages have spent 60 years describing how to do things. SQL was the exception — you describe what you want, and the engine figures out the rest. Spec-driven development extends that idea to the entire development process.
We’re not there yet. Today’s specs are informal markdown, not formal proofs. Agents still make mistakes. But the direction is clear: the developers who get good at describing outcomes precisely will ship faster than the ones who get good at describing implementations precisely.
The spec is the product. The code is a side effect.