Se você já usa IA para programar, provavelmente já viveu esta cena: você descreve uma funcionalidade em duas linhas, o assistente gera quarenta arquivos, e no meio do diff você descobre que ele inventou uma regra de negócio, ignorou um caso de borda e criou uma tabela que você não pediu. O código até compila, mas não é o que você queria.
O problema quase nunca é a IA "ser burra". O problema é que a intenção nunca foi escrita. É exatamente isso que o Spec-Driven Development (SDD) resolve. Neste post eu explico o que é SDD, como funciona cada passo, como organizar as pastas e, no final, apresento um template open source que eu criei para aplicar SDD no Claude Code.
O que é Spec-Driven Development?
SDD é uma forma de trabalhar em que a especificação, e não o código, é a fonte da verdade. Antes de qualquer linha de código existe uma spec curta, versionada no repositório, que diz:
- o quê deve acontecer (objetivo e comportamento observável);
- por quê (contexto, quem depende disso);
- quais regras valem (regras de negócio numeradas);
- como saber se está pronto (critérios de aceite verificáveis).
O código é derivado dessa spec por uma cadeia explícita: spec → tarefas → código → revisão → segurança. Os testes citam as regras que cobrem e a revisão confere se cada regra tem o seu teste. Quando a realidade muda, a spec muda primeiro, e só depois o código.
Por que o SDD ganhou força com a IA
A ideia de especificar antes de codar não é nova (TDD e BDD já caminhavam nessa direção). O que mudou é que agora quem escreve boa parte do código é um agente que não pode adivinhar requisitos e esquece tudo quando a sessão termina.
O chamado vibe coding (ir conversando com a IA até "parecer bom") funciona muito bem para protótipos. Mas em um sistema que você vai manter, as decisões tomadas no chat se perdem, cada sessão nova recomeça do zero e ninguém consegue revisar de verdade o que foi combinado.
| Vibe coding | SDD | |
|---|---|---|
| Fonte da verdade | O histórico do chat | Arquivos de spec no repositório |
| Ambiguidade | Descoberta no diff | Resolvida antes do código |
| Revisão | Um "parece bom" no final | Um check-point por etapa |
| Testes | Se sobrar tempo | Um teste por regra de negócio |
| Sessão nova | Recomeça do zero | Lê as mesmas specs e convenções |
| Melhor para | Protótipos e scripts descartáveis | Qualquer coisa que você vai manter |
O ciclo do SDD, passo a passo
Existem várias variações do fluxo (o GitHub Spec Kit, por exemplo, separa um "plano técnico" da spec). A versão que eu uso tem uma base fixa e cinco passos, cada um com um check-point de aprovação:
Passo 0 — A base do projeto
Antes da primeira feature, o projeto precisa de um conjunto de princípios permanentes que toda spec herda. Algumas ferramentas chamam isso de "constituição". Aqui entram a arquitetura (quais apps existem, onde cada tipo de código mora), as convenções (comandos de teste e lint, nomenclatura, banco, variáveis de ambiente, commits) e as regras inegociáveis (por exemplo: "toda regra de negócio tem teste" ou "nenhum segredo no código").
Essa base fica em arquivos enxutos, porque o assistente os lê em toda sessão. O detalhe fica em documentos carregados só quando necessário.
Passo 1 — Especificar
Você descreve a funcionalidade e a IA faz perguntas até eliminar as ambiguidades. O resultado são três arquivos curtos em /specs/<feature>/:
spec.md: objetivo, contexto, requisitos funcionais e não funcionais, critérios de aceite numerados (AC-1,AC-2…), casos de borda e o que está fora de escopo;rules.md: as regras de negócio, cada uma numerada (R-1,R-2…), dizendo a quem se aplica, quando e o que acontece se for violada;flows.md: os fluxos de ponta a ponta (F-1caminho feliz,F-2falha…), com passos numerados que citam as regras.
Repare que a spec fala de comportamento, não de tecnologia. "O cupom expirado é rejeitado com a mensagem X" é spec. "Criar um índice na coluna expires_at" é detalhe de implementação.
Check-point: você lê e aprova a spec antes de seguir.
Passo 2 — Tarefas
A spec aprovada vira um tasks.md: uma lista de tarefas pequenas, ordenadas e verificáveis, cada uma apontando para o app, o módulo e a camada onde vai morar e para as regras e critérios que implementa. Quando mais de um app é afetado (por exemplo, back-end e front-end), o arquivo começa com o contrato entre eles (endpoint, request, response, erros), para que cada lado implemente a mesma coisa.
Check-point: você confere se a divisão faz sentido e se nada ficou de fora.
Passo 3 — Implementar
Agora sim o código. O agente segue o tasks.md tarefa por tarefa, escreve os testes junto, respeita as convenções da base e deixa o lint limpo. Se encontrar algo que a spec não responde, ele para e pergunta em vez de inventar. Esse é o ponto principal do SDD.
Check-point: testes verdes e você dá uma olhada no diff.
Passo 4 — Revisar
Uma revisão de conformidade, não de gosto pessoal: cada regra e cada critério de aceite foi implementado? Cada regra tem um teste que a cita? O código está na camada certa, sem lógica de negócio vazando para controller ou tela? Os achados vêm classificados por severidade.
Passo 5 — Segurança
Um checklist de AppSec sobre o que mudou: controle de acesso, injeção, segredos, exposição de dados, dependências. Os achados são mapeados no OWASP e existe um gate: nada está pronto com um achado Crítico ou Alto em aberto. Segurança vira etapa obrigatória, não um lembrete para depois.
Só então vem o commit, de preferência com uma varredura final no diff para garantir que nenhum segredo, arquivo de credencial ou dado real está indo junto.
Rastreabilidade: o fio que liga tudo
A numeração (R-n, AC-n, T-n) parece burocracia, mas é ela que torna a revisão objetiva. Cada peça cita a anterior, então dá para seguir o fio da regra até o teste:
Exemplo: uma spec de verdade (resumida)
Imagine a feature "aplicar cupom de desconto no carrinho". Uma versão enxuta ficaria assim:
# specs/cupom-desconto/rules.md
## R-1 — Cupom expirado
Cupom com data de validade vencida é rejeitado com
"Cupom expirado". O carrinho não muda.
## R-2 — Um cupom por pedido
Aplicar um segundo cupom substitui o primeiro.
## R-3 — Valor mínimo
Desconto nunca deixa o total abaixo de R$ 0,00.
# specs/cupom-desconto/spec.md (trecho)
## Acceptance Criteria
- AC-1: cupom válido reduz o total e aparece no resumo do pedido.
- AC-2: cupom expirado mostra "Cupom expirado" e mantém o total (R-1).
- AC-3: cupom de R$ 50 num carrinho de R$ 30 resulta em total R$ 0,00 (R-3).
## Out of Scope
- Cupons cumulativos.
- Cupom aplicado no checkout de assinatura.
Com isso em mãos, qualquer pessoa (ou qualquer modelo) sabe exatamente o que construir, o que testar e o que não construir.
Estrutura de pastas
Tudo vive no próprio repositório, junto do código, e passa pelo mesmo code review. Uma organização que funciona bem:
meu-projeto/
├── CLAUDE.md # base enxuta, lida em toda sessão
├── ai/
│ ├── module_map.md # onde cada tipo de código mora
│ ├── conventions.md # comandos, testes, nomes, banco, env, commits
│ └── docs-authoring-rules.md
├── docs/
│ └── Product.md # visão do produto
├── specs/
│ ├── _template/ # modelos: spec, rules, flows, tasks
│ ├── cupom-desconto/
│ │ ├── spec.md # objetivo, requisitos, AC-n, fora de escopo
│ │ ├── rules.md # R-1, R-2, ...
│ │ ├── flows.md # F-1 (feliz), F-2 (falha), ...
│ │ └── tasks.md # T1, T2, ... por app/módulo/camada
│ └── checkout/
│ └── ...
├── .claude/
│ ├── skills/ # os comandos do fluxo (start, tasks, code...)
│ └── agents/ # tech lead + especialistas por app
└── src/ ... # o código de sempre
A regra de ouro é um fato, um lugar: a regra de negócio mora no rules.md e o resto aponta para ela com um link, em vez de copiar o texto. Isso evita specs contraditórias e economiza tokens.
Quanto de SDD adotar?
Na prática existem três níveis de rigor:
- Spec first: a spec guia a primeira implementação e depois é esquecida. Já ajuda, mas apodrece rápido.
- Spec anchored: a spec evolui junto com o código; toda mudança de comportamento passa por ela. É o ponto ideal para a maioria dos times e o que eu recomendo.
- Spec as source: só a spec é editada e o código é regerado a partir dela. Interessante, mas ainda experimental.
Quando usar (e quando é burocracia)
Vale a pena em qualquer sistema que você vai manter: produtos, APIs, regras de negócio com dinheiro ou permissões envolvidas, times com mais de uma pessoa e projetos em que várias sessões de IA vão trabalhar ao longo do tempo. Funciona até em código legado: dá para escrever a spec do que o código já faz hoje (engenharia reversa) e trazer a feature antiga para o fluxo.
Pule em protótipos descartáveis, provas de conceito e scripts de uma vez só. Para mudanças pequenas em features já especificadas, use uma via curta (ajuste a spec, implemente, rode a segurança) em vez do ciclo completo.
Erros comuns
- Spec gigante: se ninguém lê, ninguém revisa. Duas páginas costumam bastar.
- Spec que decide tecnologia: a spec diz o quê; o como fica nas tarefas e nas convenções.
- Critérios vagos: "deve ser rápido" não é verificável; "responde em menos de 300 ms no p95" é.
- Esquecer o "fora de escopo": é o que impede a IA de construir coisas que ninguém pediu.
- Corrigir o código e não a spec: na próxima sessão a IA vai "consertar" de volta. A spec muda primeiro.
- Pular a revisão e a segurança "só desta vez": é exatamente quando o problema passa.
Ferramentas
Dá para fazer SDD só com arquivos markdown e qualquer assistente, mas algumas ferramentas empacotam o fluxo: o GitHub Spec Kit, o Kiro (AWS) e o OpenSpec, entre outras. E também o projeto que eu criei para o meu dia a dia, apresentado a seguir.
Meu template: SDD para Claude Code
🚀 github.com/emersonmendes/sdd
Um template open source (MIT) de skills, agentes e documentos de projeto para o Claude Code que coloca qualquer projeto, novo ou existente, no fluxo descrito neste post. Acesse o repositório →
Em vez de copiar comandos genéricos, o template é renderizado para o seu projeto: um setup guiado entrevista você (idioma, nome, arquitetura, tecnologias, comandos de teste e lint, regras inegociáveis), faz engenharia reversa do código se o projeto já existir e gera as skills com o prefixo do seu projeto e os documentos já preenchidos.
Os comandos (troque app pelo prefixo que você escolher):
| Comando | O que faz |
|---|---|
/app.start | Passo 1: gera spec.md, flows.md e rules.md |
/app.tasks | Passo 2: tasks.md por app, módulo e camada, com contrato entre apps |
/app.code | Passo 3: implementa com testes e lint limpo, delegando aos agentes especialistas |
/app.review | Passo 4: conformidade com a spec, arquitetura, clean code e testes |
/app.security | Passo 5: checklist AppSec mapeado no OWASP, com gate de severidade |
/app.go | Os cinco passos com check-point de aprovação após cada um |
/app.express | Via rápida para features simples (pula a revisão, nunca a segurança) |
/app.fix | Ajuste pequeno em feature já especificada |
/app.reverse | Escreve a spec a partir de código existente (traz o legado para o SDD) |
/app.ask | Consultor técnico e de arquitetura; não escreve código |
/app.commit | Varre o diff atrás de segredos e dados reais, depois faz um commit limpo |
/app.update | Atualiza o projeto com a versão nova do template |
Além das skills, vêm um agente tech lead, que conduz o fluxo e delega, e um agente especialista por app, que implementa a sua parte e responde BLOCKED: em vez de adivinhar quando falta informação.
Como usar: abra o Claude Code na pasta do seu projeto e cole o prompt abaixo. Ele está em inglês porque o protocolo de setup é em inglês, mas a primeira pergunta é o idioma, e daí em diante tudo segue em português.
Set up Spec-Driven Development in this project from the template at
https://github.com/emersonmendes/sdd. Clone it into a temporary folder, read its
setup/SETUP.md and follow it step by step: interview me first (start by asking which
language I want to use), reverse-engineer the codebase if this is an existing project,
then render and adapt the skills, agents and project docs. Do not commit anything.
Depois do setup, o dia a dia fica assim:
/app.go aplicar cupom de desconto no carrinho # fluxo completo
/app.express exportar pedidos em CSV # feature simples
/app.fix mensagem de cupom expirado # ajuste pequeno
/app.commit # commit limpo
E quando o template evoluir, o seu projeto recebe as melhorias com bash .sdd/sdd update (ou /app.update). O script faz um merge de 3 vias que preserva as personalizações que você fez nas skills, e os documentos do projeto nunca são sobrescritos.
Conclusão
SDD não é sobre escrever mais documentação. É sobre escrever a intenção uma vez, no lugar certo, para que humanos e IA trabalhem a partir da mesma fonte. Você troca alguns minutos de especificação por menos retrabalho, revisões objetivas, testes que significam algo e um projeto que qualquer sessão nova entende.
Se quiser experimentar, comece pequeno: escolha a próxima feature, escreva as regras numeradas e os critérios de aceite antes de pedir código e veja a diferença. E se quiser o fluxo pronto no Claude Code, o template está no GitHub. Issues, sugestões e estrelas são muito bem-vindas! ⭐