sdd
Anatomia de uma spec: 12 critérios que separam código que funciona de código que fica
Os 12 critérios técnicos pra escrever spec que IA executa sem alucinar — comportamento observável, EARS, MoSCoW, glossário e exemplos concretos.
Spec ruim:
“Sistema deve gerenciar tarefas. Usuários podem criar, editar e completar. Deve ser rápido e seguro.”
Spec boa:
“US-001 — Criar tarefa: usuário autenticado em workspace W pode criar tarefa com título (2-500 chars), descrição markdown opcional (até 10000 chars), due date opcional (ISO 8601), 0+ assignees (members do workspace W), 0+ tags (do workspace W), prioridade (enum NONE/LOW/MEDIUM/HIGH/URGENT, default NONE). RNF: criação <300ms p95; real-time broadcast pra outros membros do workspace <200ms.”
A diferença entre as duas é o que separa 8-12 horas iterando vs 2-3 horas implementando uma vez. Esse artigo é a anatomia de uma spec que IA executa sem alucinar: os 12 critérios técnicos que separam o ruim do bom.
Tudo derivado do ebook Spec-Driven Development: O Guia Definitivo (cap. 3-4) — onde o método aparece aplicado no projeto canônico TaskFlow Pro.
Os 12 critérios
1. Comportamento observável, não implementação
❌ “Sistema usa bcrypt cost 12” ✅ “Senha armazenada hashed (bcrypt cost ≥12)”
A diferença: o primeiro amarra implementação. O segundo descreve o comportamento + restrição. Implementação é prerrogativa do design, não do requirement.
2. Linguagem de negócio (sem jargão técnico desnecessário)
❌ “Endpoint POST /tasks recebe payload validado com Zod” ✅ “Usuário cria tarefa em workspace ao qual pertence”
Endpoint, payload, Zod — tudo isso é design. Requirement fala em usuário + ação + objeto + escopo.
3. Critério de aceitação testável
Cada user story termina com lista de critérios em formato Dado/Quando/Então ou checklist verificável:
US-002 — Login com email/senha:
- [x] Dado credenciais válidas, retorna access token + refresh token
- [x] Dado email inexistente, retorna erro 401 com mensagem genérica ("credenciais inválidas")
- [x] Dado password errado, retorna erro 401 com mesma mensagem (não vaza qual campo falhou)
- [x] Após 5 tentativas falhas em 15 min, conta bloqueada por 15 min
- [x] Login com "lembrar-me" estende sessão pra 30 dias
Cada item vira teste automatizado.
4. Formato EARS quando dá
EARS (Easy Approach to Requirements Syntax) força clareza. 5 padrões:
- Ubiquitous (sempre): “Sistema DEVE validar permissões em todas as operações”
- Event-driven: “QUANDO tarefa for concluída, sistema DEVE registrar timestamp”
- Unwanted: “SE usuário tentar >50 subtasks, sistema DEVE exibir erro”
- State-driven: “ENQUANTO tarefa arquivada, sistema NÃO DEVE permitir edição”
- Optional: “ONDE notificações habilitadas, sistema DEVE notificar”
Cada keyword (QUANDO/ENQUANTO/SE/ONDE) mapeia 1:1 pra lógica condicional óbvia. Agente lê e implementa sem interpretar errado.
Aprofundamento EARS no ebook SDD (capítulo 3.4) (artigo dedicado em breve).
5. Prioridade MoSCoW explícita
Cada requisito etiquetado:
- M (Must) — sem isso, sistema não entrega valor primário. Quebra MVP.
- S (Should) — importante, mas sistema funciona sem
- C (Could) — desejável se sobrar tempo
- W (Won’t) — explicitamente fora do MVP
Sem MoSCoW, time/agente assume tudo é Must, supercarrega o sprint, descarta o que precisa.
6. Escopo NEGATIVO explícito
Seção dedicada do requirements.md:
## Fora do Escopo (MVP)
- Integração com Google Calendar (planejado v2)
- Tarefas recorrentes (v2)
- Kanban boards (v3)
- Time tracking (não no roadmap)
- API pública (v2)
Maior fonte de bug em SDD é feature que ninguém pediu mas o agente alucinou que “fazia sentido”. Listar o que NÃO faz elimina 50% das discussões de escopo.
7. Glossário de termos do domínio
Cada termo específico do produto/cliente tem definição inequívoca:
## Glossário
- **Workspace**: container lógico isolado. Dados de um workspace nunca aparecem em outro.
- **Member**: usuário que pertence a um workspace. Role: ADMIN ou MEMBER.
- **Task**: unidade de trabalho atribuível, com status (TODO/IN_PROGRESS/DONE/ARCHIVED).
- **Subtask**: task filha de uma task pai. Máximo 50 por pai.
- **Automation**: regra "QUANDO X ACONTECER, FAZER Y" disparada por evento.
Sem glossário, “task” pode significar 3 coisas diferentes pra 3 stakeholders. Com glossário, todos falam a mesma coisa.
8. Métricas numéricas (não adjetivos)
❌ “Sistema deve ser rápido e escalável” ✅ “Listar tarefas: p95 <500ms até 1000 tarefas/workspace. Criar tarefa: p95 <300ms. Real-time broadcast: <200ms. Suporta 10k workspaces simultâneos, cada um com 100 members ativos.”
Adjetivo é interpretação. Número é teste. Spec sem número é spec sem objetividade.
9. Exemplos concretos pra cada validação
Pra cada regra de validação, uma tabela input → output esperado:
Campo title | Resultado |
|---|---|
"" | erro “título obrigatório” |
"a" | erro “título: 2-500 chars” |
"a".repeat(501) | erro “título: 2-500 chars” |
"Implementar SDD" | ✓ válido |
"<script>alert()</script>" | ✓ válido (HTML sanitizado no render, não no input) |
Exemplo elimina ambiguidade que descrição textual nunca elimina.
10. FAQ inline antecipando perguntas óbvias
Toda spec real tem dúvidas óbvias que o agente vai assumir errado se não responder:
## FAQ — Autenticação
**Usuário pode ter 2 sessões em devices diferentes?**
Sim. Cada device tem refresh token próprio.
**O que acontece com refresh tokens existentes quando senha é alterada?**
Invalidados todos. Força logout em todos os devices.
**Email confirmado é obrigatório pra login?**
Sim. Bloqueia até confirmação.
**Login pode ser feito por username?**
Não. Email é único identificador no MVP.
5-10 FAQs poupam 50% das alucinações.
11. Rastreabilidade entre requirements → design → tasks → code
Cada artefato linka pro anterior:
## tasks.md
### Task 1.2.3 — Implementar bcrypt em UserService
**Implementa**: RF-001 (auth), US-001 critério 3
**Design ref**: design.md §3.2 "Security Primitives"
**Estimate**: 2h
**Output**: src/services/auth/UserService.ts + tests
Quando bug aparece em prod, você rastreia: code → task → design → requirement original. Saber se é bug de implementação ou de spec muda a correção inteira.
12. Spec versionada (git-friendly)
Spec é texto markdown em diretório .claude/specs/XXX-feature/ com:
.status(single line:requirements:approvedou similar)requirements.mddesign.mdtasks.md
Quando muda, comita. Cada PR de código também atualiza spec correspondente. Spec que dessincroniza do código vira ficção histórica — e ninguém confia em ficção histórica pra debugar.
A relação entre os 12 critérios
Os 12 não são checklist linear. São aspectos do mesmo princípio: spec é contrato humano↔agente, e contrato precisa ser:
Inequívoco (1, 2, 4, 7, 9) +
Verificável (3, 8) +
Priorizado (5, 6) +
Antecipativo (10) +
Rastreável (11, 12)
Falha em qualquer dimensão = retrabalho.
Spec ruim vs spec boa — comparação direta
Spec ruim (~80 palavras):
Sistema deve permitir usuários criarem tarefas em workspaces.
Tarefas têm título, descrição e status. Usuário pode atribuir
tarefa a outros membros. Notificar via email quando atribuído.
→ Agente assume 50 detalhes. Implementa 20 errado.
Spec boa (~500 palavras):
## US-001 — Criar tarefa em workspace
Usuário autenticado em workspace W pode criar tarefa.
### Campos:
- title: string, 2-500 chars, obrigatório
- description: string, markdown sanitizado, 0-10000 chars, opcional
- dueDate: ISO 8601, opcional
- assignees: array de userIds, devem ser members ativos do workspace W, 0-N
- tags: array de tag IDs do workspace W, 0-N
- priority: enum NONE|LOW|MEDIUM|HIGH|URGENT, default NONE
- parentId: ID de outra tarefa do mesmo workspace, opcional (vira subtask, max 50 subtasks/parent)
### Critérios de aceitação:
- [x] Tarefa criada aparece no listing em <300ms
- [x] Real-time broadcast pros outros members do workspace em <200ms
- [x] Validação server-side rejeita assignees fora do workspace W
- [x] Tags fora do workspace W ignoradas silenciosamente (não erro)
- [x] Criar como subtask além do limite 50 retorna erro 400 "subtasks máx atingido"
- [x] Notificação enviada a cada assignee (NotificationPreference respected)
### Eventos disparados:
- `task:created` no Socket.io room `workspace:${W}`
- `notification:new` no Socket.io room de cada assignee
- `automation:trigger` com event `task_created` (vê spec automations.md)
### RNF:
- p95 criação <300ms
- Real-time broadcast p95 <200ms
- Server-side validation: rate limit 60 tasks/minuto/usuário
### FAQ:
**Posso atribuir tarefa a alguém de outro workspace?** Não. Retorna 403.
**Tarefa criada sem dueDate aparece em "atrasadas"?** Não. "Atrasadas" só pra tasks com dueDate < now.
**Subtask herda assignees da parent?** Não. Cada uma independente.
→ Agente implementa em 1 iteração. Reviewer compara código vs spec. Test cases já praticamente prontos.
Próximos passos
Se você quer ver os 12 critérios aplicados num projeto inteiro (TaskFlow Pro: 5 features completas com requirements + design + tasks):
→ Ebook SDD — gratuito com email (215p)
Se quer praticar SDD num projeto real seu com revisão na mão:
→ Formação Consultor AI — Academy
Leitura relacionada:
- Spec-Driven Development: o método completo — cornerstone do pilar
- Workflow virou commodity — manifesto que ancora o porquê
FAQ
Esses 12 critérios valem pra startup pequena? Valem pra qualquer projeto que dure mais que 1 dia ou tenha mais de 1 feature. Script de 1h não precisa. Sistema com 3+ devs (ou 1 dev + 1 agente) precisa.
Quanto tempo demora pra escrever spec assim pra 1 feature? 30-60 min pra feature média. Comparado às 4-8h de retrabalho que evita, paga em 1 iteração só.
Posso usar IA pra escrever a spec?
Pode (eu uso). Comando /spec-requirements do .claude/ faz exatamente isso — agente pergunta, você responde curto, agente preenche EARS + MoSCoW + glossário. Você revisa. Aprova o gate.
Spec longa não vira “Waterfall mascarado”? Não, se a spec evolui com gates entre fases. Waterfall congela tudo upfront. SDD aprova fase por fase, ajusta entre cada. Você pode estar implementando feature A enquanto revisa requirements de B.
Quem não tem .claude/ precisa de tudo isso?
Sim, a estrutura é independente de ferramenta. Funciona em Cursor (.cursorrules), Copilot (.github/copilot-instructions.md), ou plano de Notion. O importante são os 12 critérios — não onde mora o arquivo.