quarta-feira, 4 de novembro de 2026

SDD - Spec Driven Development

spec.md IA ✔ testes passando Spec-Driven Development primeiro a intenção, depois o código

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.

Em uma frase: no SDD você revisa intenção antes de revisar código. Aprovar uma spec de duas páginas é muito mais barato do que desfazer um diff de quarenta arquivos.

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:

O ciclo do SDD 1 · Especificar spec · regras · fluxos 2 · Tarefas tasks.md por camada 3 · Implementar código + testes 4 · Revisar conformidade c/ spec 5 · Segurança 0 Crítico/Alto aberto ✔ Pronto commit limpo mudou? spec primeiro 0 · Base do projeto (lida em todos os passos) CLAUDE.md · ai/conventions.md · ai/module_map.md

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-1 caminho feliz, F-2 falha…), 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:

R-1 rules.md AC-1 spec.md T2 tasks.md teste cita R-1 review ✔ confere o fio regra sem teste ou teste sem regra = achado na revisão

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.startPasso 1: gera spec.md, flows.md e rules.md
/app.tasksPasso 2: tasks.md por app, módulo e camada, com contrato entre apps
/app.codePasso 3: implementa com testes e lint limpo, delegando aos agentes especialistas
/app.reviewPasso 4: conformidade com a spec, arquitetura, clean code e testes
/app.securityPasso 5: checklist AppSec mapeado no OWASP, com gate de severidade
/app.goOs cinco passos com check-point de aprovação após cada um
/app.expressVia rápida para features simples (pula a revisão, nunca a segurança)
/app.fixAjuste pequeno em feature já especificada
/app.reverseEscreve a spec a partir de código existente (traz o legado para o SDD)
/app.askConsultor técnico e de arquitetura; não escreve código
/app.commitVarre o diff atrás de segredos e dados reais, depois faz um commit limpo
/app.updateAtualiza 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! ⭐

Referências