📐 Adopt the spec-driven workflow
Spec-Driven Development means the specification comes before the code—and remains the source of truth throughout execution. A specification isn’t generic text: it exists to reduce ambiguity and turn intent into verifiable criteria.
How to read: look at both ends. The specification (left, highlighted) and the verification (right, in cyan) cover the same thing—the second exists only to check the first. If you didn't write the spec, there's nothing for the verification to compare against, and "done" becomes a matter of opinion.
🆕 New here?
Specification (spec) is a short document that says what needs to exist and how to tell when it’s done — it’s not architecture documentation or a Jira ticket. Acceptance criteria is a sentence that can be answered yes or no by looking at the system (“the response stays identical for the same parameters”). If the sentence depends on taste (“make it more organized”), it isn’t a criterion yet.
Before the code
Spec precedes the plan
Ambiguity
Someone always decides
Verifiable
Yes/no, not “better”
Source of truth
Matters more than the chat
🧱 Assemble the Elements of a Good Specification
This is the skeleton. Every missing field becomes a decision the agent makes on its own—usually the most generic one possible. Use this as a checklist: if a field is empty, ask yourself who will decide that, and when.
Problem
What problem needs to be solved? (not the solution)
Objective
What result should be achieved?
Scope · Out of scope
What’s part of the task—and what no must be changed.
Inputs · Outputs
Which data or events go in; which results the system produces.
Contracts
Interfaces, formats, and behaviors that must be preserved.
Error conditions
What should happen when something fails.
Constraints
Technologies, standards, limits, and rules to follow.
Acceptance criteria · Tests
How to verify completion; which tests to create or run.
Definition of done
Which conditions end the work—with no renegotiation afterward.
💡 Practical tip
Start by saving this outline as specs/_template.md in the repository. A spec that lives alongside the code gets read; a spec that lives in an external wiki goes stale in two weeks.
Empty field
= delegated decision
Out of scope
Refactoring brake
Contract
Protects consumers
Ready
Ends the discussion
🎯 Define scope and acceptance criteria
Everyone writes the positive scope. What saves the review is the negative scope: the list of what must not be touched. Without it, a capable agent "takes the opportunity" and returns a diff of forty files that nobody reviews properly.
✓ Verifiable criteria
- ✓"The response remains identical for the same parameters."
- ✓"A duplicate request with the same idempotency key does not create a second charge."
- ✓"No files outside src/pagamentos/ is changed."
- ✓"The suite runs in under 90 seconds."
✗ Criteria that don’t decide anything
- ✗"Make the code cleaner."
- ✗"Improve performance."
- ✗"Follow best practices."
- ✗"Maintain compatibility" (without saying with what).
Negative scope test
Before assigning the task, answer each in one line:
Which files/folders must it NOT touch?
Which dependencies must it NOT add?
Which existing behavior must NOT change?
Which refactoring can wait until later?
Yes/no
Criteria are binary
Negative scope
Matters as much as the positive
Small diff
It’s truly reviewable
No “best”
Vague comparisons don't help
🔌 Describe contracts, inputs, outputs, and errors
Almost every serious regression starts with an implicit contract: someone knew that field could never be null, but that wasn’t written anywhere. The agent can’t guess what the whole team forgot to document.
🔒 What a contract defines
- •Form: field names, types, required fields, date format, monetary value unit.
- •Behavior: sorting, pagination, idempotency, side effects.
- •Failure: which error code, what response body, whether it retries, and how long to wait.
- •Compatibility: who uses it today and what must not break for that person.
🧭 Error conditions that are almost always missing
Implicit breaks
Write the obvious
Error is a requirement
Sad path has a spec
Consumer
List before changing
Contract test
Turns agreement into a gate
🆚 Compare a bad spec with a complete spec
The canonical workshop pair. Read both and count how many decisions were hidden in the short sentence.
✗ Poor specification
Crie um sistema de pagamentos.
Payment methods, duplicate handling, states, webhooks, sensitive data, tests, rollback—all of this will be decided by whoever implements it, however seems reasonable at the time.
✓ More complete specification
Criar um serviço de pagamentos que: - aceite PIX e cartão; - impeça duplicidade por chave de idempotência; - registre todos os estados da transação; - processe webhooks; - realize retentativas; - gere logs estruturados; - preserve compatibilidade com a API atual; - não armazene dados sensíveis de cartão; - inclua testes unitários e de integração; - tenha rollback para migrações; - bloqueie o merge se os testes falharem.
Each line closes off a decision. The better the specification, the lower the chance that the agent will make decisions that conflict with the system.
🧪 Copyable exercise — have the agent generate the spec
Objective: move beyond the short sentence without writing everything from scratch. Paste it into your agent, inside the real repository.
Você vai escrever uma ESPECIFICAÇÃO, não código. Não altere nenhum arquivo. Tarefa que eu quero fazer: <descreva em uma frase> Repositório: leia <caminhos relevantes> antes de responder. Produza um documento com estas seções, e nada além delas: problema · objetivo · escopo · fora do escopo · entradas · saídas · contratos · condições de erro · restrições · critérios de aceitação · testes · definição de pronto Regras: - cada critério de aceitação deve ser verificável com sim ou não; - liste explicitamente o que NÃO deve ser alterado; - no final, liste em "PERGUNTAS" tudo que você teve que supor. - não invente regras de negócio: se não achou no código, vai para PERGUNTAS.
How to verify: the “QUESTIONS” section is the gold in this exercise — it lists exactly the decisions the agent would have made on its own if you’d sent the short prompt. Answer them, update the spec, and only then authorize implementation.
One line
Hides ten decisions
Idempotency
Requirement, not a detail
QUESTIONS
Assumptions in plain sight
Versioned spec
Lives in the repository
🔗 Turn Every Criterion into a Test
Here, the spec stops being a document and becomes a mechanism. A rule written in text is useful; the same rule turned into an automated test is much more reliable — and that’s what lets you delegate execution to the agent without losing control.
Read the criterion aloud
"A duplicate request with the same key does not generate a second charge."
Write the test that fails today
Sends the same request twice and claims there is exactly one charge. It needs to fail before implementation—otherwise it isn't testing anything.
Give the test to the agent as the definition of done
The task stops being “implement idempotency” and becomes “make this test pass without changing the test itself.” It’s an objective stopping condition—the subject of track 2.
⚠️ Attention
If the agent can freely edit tests, it has permission to redefine what “done” means. Treat test files as protected: changing a test is a spec change and requires explicit human approval.
Executable spec
A test is the living rule
Failure first
Otherwise, it proves nothing
Protected test
Changing the test = changing the spec
Autonomy
Comes from the verifier
📌 Module Summary
Next track:
Track 2 - Harness Engineering: the system around the model (tools, context, permissions, limits).