SDD × TDD Começar ↓

Guia de engenharia · uPlexis · julho de 2026

Especificar o comportamento.
Provar com testes.
Só então implementar.

Spec-Driven Development (SDD) combinado com Test-Driven Development (TDD) é a forma mais confiável que conhecemos hoje de trabalhar com agentes de código como o Claude Code: a especificação registra a intenção, os testes tornam essa intenção executável, e o agente implementa dentro de limites verificáveis.

  • Exemplo completo: API de CNPJ
  • Prompts por etapa
  • Fontes citadas
  • Zero dependências externas
Ilustração do pipeline de desenvolvimento orientado a especificação: um documento de especificação à esquerda, uma etapa de testes falhando em vermelho, uma etapa de testes passando em verde e, à direita, o código implementado.
Da especificação ao código: a falha vem antes do verde, e o verde vem antes da implementação final.

01

A pergunta de partida

Agentes de código escrevem software rápido demais para os nossos processos antigos. A pergunta que este guia responde não é “a IA escreve código bom?”, e sim:

Como tornamos o desenvolvimento assistido por IA repetível, auditável e seguro — sem abrir mão de velocidade?

Repetível

Dois desenvolvedores diferentes, com o mesmo pedido, devem chegar a resultados equivalentes. Isso exige que a intenção viva em um artefato versionado — a especificação — e não na memória de quem escreveu o prompt.

Auditável

Cada mudança precisa responder: qual comportamento foi pedido, qual teste o prova e qual evidência mostra que passou? Sem essa trilha, revisar código gerado por agente vira leitura de fé.

Seguro

O agente executa; o humano decide. Portões explícitos (spec aprovada, teste falhando antes de implementar, CI independente) impedem que a velocidade do agente ultrapasse o julgamento do time.

02

O que é Spec-Driven Development

Especificação (spec), neste guia, é um documento curto e versionado que descreve o comportamento observável que se quer de uma mudança: cenários de entrada e saída, critérios de aceitação e — tão importante quanto — os não-objetivos, aquilo que a mudança deliberadamente não fará.

Spec-Driven Development é a prática de tratar essa especificação como a fonte compartilhada da verdade sobre a intenção: humanos a escrevem e aprovam, agentes a leem para planejar e implementar, revisores a usam como régua do que foi entregue. O código diz o que o sistema faz; a spec diz o que ele deveria fazer — e é contra ela que se discute.

O que a spec não é

03

Três níveis de maturidade

O modelo de três níveis abaixo vem da análise de Böckeler sobre as ferramentas de SDD existentes. Ele é útil porque separa práticas que costumam ser confundidas sob o mesmo nome.

Nível 1 Spec-first

Escreve-se uma spec antes de codar, mas ela é descartável: serve para alinhar a conversa com o agente naquela tarefa e depois envelhece sem manutenção. Melhor que prompt improvisado; frágil como memória do time.

Nível 2 Spec-anchored

A spec é versionada junto do código e atualizada quando o comportamento muda. Revisões comparam diff contra spec; testes referenciam cenários numerados. O código continua sendo o artefato executável — a spec é a âncora da intenção.

★ Recomendação deste guia como padrão prático

Nível 3 Spec-as-source

A spec é o artefato primário e o código é (re)gerado a partir dela, como um compilador de intenção. É a aposta de ferramentas como Tessl — promissora, mas ainda experimental para sistemas de produção.

04

O ciclo combinado SDD + TDD

Sete etapas, três portões humanos. As etapas 4–6 são o clássico RED–GREEN–REFACTOR de Kent Beck; as demais dão ao agente contexto, contrato e revisão. Nenhuma etapa é pulada — nem pelo agente, nem por pressa.

  1. 1

    Descobrir

    O agente lê o código, docs e convenções relevantes. Saída: resumo do contexto e lista de dúvidas. Nenhum código é escrito.

  2. 2

    Especificar

    Comportamento observável em cenários numerados + não-objetivos + critérios de aceitação. ⛔ Portão: humano aprova a spec.

  3. 3

    Planejar

    Arquitetura da mudança, riscos, decisões técnicas e plano de testes. ⛔ Portão: humano aprova o plano.

  4. 4

    RED

    Escrever um teste que expressa um cenário da spec e vê-lo falhar. A falha prova que o teste mede a lacuna, não a sorte.

  5. 5

    GREEN

    A menor implementação que faz o teste passar. Sem generalização especulativa, sem “aproveitar para arrumar”.

  6. 6

    REFACTOR

    Melhorar nomes, remover duplicação, simplificar — sem mudar comportamento. Testes verdes antes e depois.

  7. 7

    Revisar

    Diff comparado à spec, testes e evidências de execução. ⛔ Portão: humano dá o veredito final.

Diagrama: as etapas RED, GREEN e REFACTOR formam um laço que se repete para cada cenário da especificação, e o resultado segue para revisão. Spec cenário Sn RED GREEN REFACTOR próximo cenário da spec cenários verdes → Revisão
O laço interno repete para cada cenário; a revisão humana só acontece quando os cenários estão verdes.

05

Quem decide, quem executa, quem confere

A divisão de responsabilidades é o coração da segurança do processo: o agente nunca é juiz do próprio trabalho, e o humano nunca gasta tempo no que a máquina faz melhor.

Responsabilidades de humanos, agente Claude Code e CI ou revisores em cada aspecto do processo
Humano decide Agente Claude Code executa CI / revisor confere
Define objetivos, restrições e critérios de aceitação Explora o código e resume contexto e riscos Roda a suíte de testes de forma independente do agente
Aprova (ou devolve) spec e plano nos portões Rascunha spec e plano a partir dos objetivos Bloqueia merge sem testes passando e sem spec referenciada
Decide riscos aceitáveis e exceções aos portões Escreve os testes (RED) e a implementação mínima (GREEN) Verifica que o teste novo falhava antes da implementação
Dá o julgamento final na revisão Executa comandos, refatora e reporta evidências (saídas reais, não resumos) Revisa o diff contra a spec, não contra a descrição do PR

Segundo a documentação da Anthropic, o Claude Code lê a base de código, edita arquivos, executa comandos e se integra ao fluxo de ferramentas do desenvolvedor — exatamente a coluna do meio. As boas práticas oficiais reforçam: dê ao agente uma forma de verificar o próprio trabalho (testes!) e corrija o rumo cedo.

06

Por que SDD não substitui TDD

A spec define o contrato; os testes tornam o contrato executável. Um sem o outro deixa uma lacuna que agentes de código exploram sem má-fé — e com consequências.

Comparação entre spec sem teste, teste sem spec e a combinação dos dois
Configuração O que acontece na prática Risco típico com agentes
Spec sem teste A intenção está escrita, mas nada a verifica. A conformidade depende de leitura humana do diff. O agente afirma “implementei conforme a spec” e ninguém tem como refutar barato. Deriva silenciosa entre texto e código.
Teste sem spec Há verificação, mas não há registro do porquê. O teste vira a única memória da intenção — e testes também têm bugs. O agente “conserta” um teste incômodo alterando a asserção, e ninguém percebe que o contrato mudou, porque o contrato nunca foi escrito.
Spec + teste (SDD + TDD) A spec diz o que deve valer; o teste prova que vale; a revisão compara os três: spec, teste e código. Para burlar, seria preciso corromper dois artefatos revisados de forma independente — o custo do desvio fica visível.

O TDD, na linhagem de Kent Beck (Test-Driven Development: By Example, 2002), acrescenta algo que a spec sozinha não dá: a prova da lacuna. Ver o teste falhar antes de implementar demonstra que o teste mede o comportamento novo — e não que passa por acidente. Com agentes, esse degrau vira o portão anti-alucinação mais barato do processo.

07

Exemplo completo: API de consulta de empresas por CNPJ

Um caso realista para produtos de dados corporativos: um endpoint de consulta cadastral por CNPJ, com limite de uso por chave de API e trilha de auditoria. Abaixo, os artefatos reais de um ciclo — spec, teste em RED, implementação mínima e checklist de evidências.

7.1 · A especificação specs/001-company-search/spec.md

spec.md — cenários, não-objetivos e aceitação
# Spec 001 — Consulta de empresa por CNPJ

## Objetivo
Expor `GET /v1/empresas/{cnpj}` para consulta pontual de dados
cadastrais, com limite de uso por chave de API e trilha de
auditoria completa por requisição.

## Comportamento observável
- S1. CNPJ válido e existente → 200 com `razaoSocial`, `cnpj`
  (normalizado, somente dígitos), `situacaoCadastral`, `atualizadoEm`.
- S2. CNPJ com formato ou dígito verificador inválido → 400 com
  corpo `{ "erro": "CNPJ_INVALIDO" }`. Nenhuma consulta à base ocorre.
- S3. CNPJ válido porém inexistente → 404 com `{ "erro": "NAO_ENCONTRADO" }`.
- S4. Chave de API acima de 60 req/min → 429 com cabeçalho
  `Retry-After` em segundos. A requisição excedente não consulta a base.
- S5. Toda requisição (atendida ou rejeitada) gera exatamente um
  registro de auditoria: `requestId`, hash da chave de API, CNPJ
  normalizado, decisão (`ATENDIDO` | `REJEITADO_VALIDACAO` |
  `NAO_ENCONTRADO` | `LIMITADO`) e timestamp UTC.

## Não-objetivos
- Busca por razão social ou nome fantasia.
- Consulta em lote.
- Garantia de frescor dos dados cadastrais (spec 002 tratará disso).

## Critérios de aceitação
- [ ] S1–S5 cobertos por testes que falharam antes da implementação.
- [ ] Validação de CNPJ usa o algoritmo oficial de módulo 11.
- [ ] A chave de API nunca aparece em claro na auditoria.
- [ ] `Retry-After` calculado a partir da janela real, não valor fixo.

Repare no que faz esta spec funcionar com agentes: cenários numerados (testes e commits citam “S2”), saídas observáveis (status, corpo, cabeçalho — nada de “deve ser robusto”), e não-objetivos que impedem o agente de “aproveitar” para implementar busca por nome.

7.2 · RED — o teste que prova a lacuna tests/consultar-empresa.test.ts

Vitest + TypeScript — cenário S2
import { describe, expect, it } from "vitest";
import { consultarEmpresa } from "../src/consultar-empresa";
import { contextoDeTeste } from "./apoio/contexto";

describe("S2 — CNPJ inválido", () => {
  it("responde 400, não consulta a base e audita a rejeição", async () => {
    const ctx = contextoDeTeste();

    const resposta = await consultarEmpresa("11.111.111/1111-11", ctx);

    expect(resposta.status).toBe(400);
    expect(resposta.corpo).toEqual({ erro: "CNPJ_INVALIDO" });
    expect(ctx.base.consultas).toHaveLength(0);
    expect(ctx.auditoria.registros).toHaveLength(1);
    expect(ctx.auditoria.registros[0]).toMatchObject({
      decisao: "REJEITADO_VALIDACAO",
      cnpj: "11111111111111",
    });
  });
});

Saída esperada nesta etapa (e ela deve falhar):

FAIL  tests/consultar-empresa.test.ts
  ✗ S2 — CNPJ inválido › responde 400, não consulta a base e audita a rejeição
    Error: Failed to resolve import "../src/consultar-empresa"

A falha é a informação: o módulo não existe, logo o teste mede exatamente a lacuna. Se ele passasse agora, o teste estaria quebrado — e implementá-lo em seguida esconderia isso para sempre.

7.3 · GREEN — a implementação mínima src/consultar-empresa.ts

Só o suficiente para o S2 passar
export interface RegistroAuditoria {
  cnpj: string;
  decisao: "ATENDIDO" | "REJEITADO_VALIDACAO" | "NAO_ENCONTRADO" | "LIMITADO";
}

export interface Contexto {
  auditoria: { registrar(evento: RegistroAuditoria): void };
}

const PESOS_DV1 = [5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2];
const PESOS_DV2 = [6, ...PESOS_DV1];

function digitoVerificador(digitos: number[], pesos: number[]): number {
  const soma = pesos.reduce((acc, peso, i) => acc + peso * digitos[i], 0);
  const resto = soma % 11;
  return resto < 2 ? 0 : 11 - resto;
}

export function cnpjEhValido(cnpj: string): boolean {
  const digitos = [...cnpj].map(Number);
  if (digitos.length !== 14 || new Set(digitos).size === 1) return false;
  return (
    digitos[12] === digitoVerificador(digitos.slice(0, 12), PESOS_DV1) &&
    digitos[13] === digitoVerificador(digitos.slice(0, 13), PESOS_DV2)
  );
}

export async function consultarEmpresa(entrada: string, ctx: Contexto) {
  const cnpj = entrada.replace(/\D/g, "");
  if (!cnpjEhValido(cnpj)) {
    ctx.auditoria.registrar({ cnpj, decisao: "REJEITADO_VALIDACAO" });
    return { status: 400, corpo: { erro: "CNPJ_INVALIDO" } };
  }
  // S1, S3 e S4 pertencem aos próximos ciclos RED→GREEN.
  throw new Error("Cenário ainda não especificado neste ciclo (ver spec S1/S3/S4)");
}

“Mínima” não significa descuidada: o algoritmo de módulo 11 está correto e completo porque o cenário S2 o exige (critério de aceitação). Mas S1, S3 e S4 não foram implementados — cada um terá seu próprio RED primeiro. O throw explícito é honesto: o agente não finge um caminho feliz que nenhum teste pediu ainda.

7.4 · REFACTOR + evidências specs/001-company-search/evidence.md

Checklist de refatoração e evidência
# Evidência — Spec 001, ciclo S2

## Refatoração (comportamento inalterado)
- [ ] Testes verdes ANTES da refatoração (saída colada abaixo).
- [ ] Nomes revisados: domínio em português consistente com a spec.
- [ ] Duplicação extraída (pesos do DV declarados uma única vez).
- [ ] Testes verdes DEPOIS da refatoração (saída colada abaixo).

## Evidência de execução (colar saídas reais, nunca resumir)
- [ ] Saída do Vitest em RED (teste falhando, com a razão da falha).
- [ ] Saída do Vitest em GREEN (a suíte do ciclo passando).
- [ ] Prova de robustez: mutação manual (trocar um peso do DV)
      faz o teste falhar — o teste morde.
- [ ] Nenhuma asserção foi enfraquecida para “fazer passar”.

## Rastreabilidade
- [ ] Commits citam o cenário (ex.: "test: RED para S2 da spec 001").
- [ ] spec.md atualizada se a revisão mudou o comportamento acordado.

08

Workflow Claude Code: prompts por etapa

Nunca diga ao agente “construa a API inteira”. Um pedido vago produz um lote gigante de código sem trilha de verificação — o oposto do que este processo busca. Em vez disso, conduza o ciclo com um prompt por etapa, parando nos portões. Os prompts abaixo são copiáveis e usam o exemplo do CNPJ; adapte os nomes ao seu caso.

Etapa 1 Explore

prompt · exploração sem código
Leia CLAUDE.md e docs/architecture.md. Depois explore src/ e tests/
no que for relevante para consulta de empresas.

Não escreva nem altere código nesta etapa.

Devolva: (1) resumo dos pontos de entrada e convenções de teste,
(2) riscos e acoplamentos que você identificou,
(3) lista de dúvidas que eu preciso responder antes da spec.

Etapa 2 Spec portão humano em seguida

prompt · rascunho da especificação
Com base na exploração e nas minhas respostas, rascunhe
specs/001-company-search/spec.md com:
- objetivo em um parágrafo;
- cenários numerados (S1, S2, ...) com entrada e saída observáveis
  (status HTTP, corpo, cabeçalhos) — nada de adjetivos vagos;
- não-objetivos explícitos;
- critérios de aceitação verificáveis por teste automatizado;
- seção "Assunções e dúvidas" com tudo o que você assumiu.

Pare após escrever o arquivo. Eu vou revisar e aprovar a spec
antes de qualquer plano ou código.

Etapa 3 Plan portão humano em seguida

prompt · plano de arquitetura e risco
A spec specs/001-company-search/spec.md está aprovada.

Escreva specs/001-company-search/plan.md com:
- arquitetura da mudança (módulos novos/alterados e por quê);
- decisões técnicas com alternativas descartadas
  (ex.: algoritmo de rate limiting e onde vive o estado);
- riscos e como cada um será testado;
- ordem dos ciclos RED→GREEN (um cenário por ciclo);
- specs/001-company-search/tasks.md com tarefas pequenas e
  independentes.

Não implemente nada. Pare para minha revisão do plano.

Etapa 4 RED

prompt · teste que falha
Plano aprovado. Comece pelo cenário S2 da spec.

Escreva SOMENTE o teste (Vitest/TypeScript) que expressa o S2,
seguindo as convenções de tests/. Não crie a implementação.

Rode a suíte e cole a saída completa mostrando o teste falhando.
Se o teste passar sem implementação, pare e me avise: ou o teste
está errado, ou o comportamento já existe.

Etapa 5 GREEN

prompt · implementação mínima
O teste do S2 está em RED (saída registrada).

Implemente o MÍNIMO necessário para esse teste passar, sem
antecipar os cenários S1, S3 e S4 e sem tocar em outros arquivos
além do necessário.

Rode a suíte inteira e cole a saída completa. Se algum teste
antigo quebrar, pare e reporte antes de tentar consertar.

Etapa 6 REFACTOR

prompt · melhorar sem mudar comportamento
Com a suíte verde, refatore o que este ciclo tocou:
nomes, duplicação e estrutura — sem mudar comportamento
observável e sem alterar nenhuma asserção de teste.

Rode a suíte antes e depois; cole as duas saídas.
Liste cada refatoração feita e por quê, em uma linha cada.

Etapa 7 Review

prompt · revisão contra a spec
Compare o diff completo deste ciclo com a spec
specs/001-company-search/spec.md:

- Cada mudança rastreia para qual cenário?
- Algum comportamento implementado que a spec não pede?
- Algum critério de aceitação sem teste correspondente?

Atualize specs/001-company-search/evidence.md com as saídas de
teste em RED e em GREEN e o checklist preenchido. Aponte
desvios encontrados em vez de corrigi-los por conta própria —
a decisão de corrigir é minha.

09

Estrutura de repositório recomendada

A estrutura abaixo mantém specs versionadas ao lado do código (spec-anchored) e dá ao agente pontos de leitura previsíveis.

árvore do repositório
.
├── CLAUDE.md                     # contexto permanente para o agente:
│                                 # comandos, convenções, o que nunca fazer
├── docs/
│   └── architecture.md           # visão de arquitetura estável
├── specs/
│   └── 001-company-search/
│       ├── spec.md               # comportamento, não-objetivos, aceitação
│       ├── plan.md               # arquitetura da mudança e riscos
│       ├── tasks.md              # tarefas pequenas, uma por ciclo
│       └── evidence.md           # saídas de teste RED/GREEN, checklist
├── src/                          # implementação
└── tests/                        # a spec executável

10

Anti-padrões — e o portão que bloqueia cada um

Cada processo falha do jeito que seus incentivos permitem. Estes são os sete modos de falha que mais vemos em adoções de SDD com agentes, cada um pareado com um portão barato de implantar.

Spec vaga

“Melhore a validação de CNPJ” não é especificação — é desejo. O agente preenche as lacunas com suposições plausíveis e erradas.

Portão: cenários numerados com entrada e saída observáveis; spec sem cenário testável não passa da revisão.

Implementar antes do teste falhar

Sem o RED, ninguém sabe se o teste mede algo. Testes escritos depois tendem a fotografar a implementação, não o contrato.

Portão: o PR mostra a saída do teste falhando antes da implementação (commit ou evidence.md).

Autocertificação do agente

“Rodei tudo e passou” é narrativa, não evidência. Agentes erram com confiança — e resumos escondem o erro.

Portão: CI roda os mesmos testes de forma independente; evidências são saídas coladas, nunca parafraseadas.

Mudança gigante

Um diff de 3.000 linhas gerado em uma tarde é irrevissável na prática — a revisão vira teatro.

Portão: tasks.md fatia o trabalho; um cenário por ciclo, um ciclo por PR quando possível.

Spec desatualizada

Se o comportamento muda e a spec não, a “fonte da verdade” vira fonte de confusão — pior que não ter spec.

Portão: PR que altera comportamento observável precisa tocar a spec correspondente; deriva de spec é métrica acompanhada.

Suposições ocultas

O agente decide sozinho que “rate limit por IP serve” e a decisão só aparece em produção.

Portão: seção obrigatória “Assunções e dúvidas” na spec; o agente é instruído a parar e perguntar, não a presumir.

Teste frágil superajustado

Testes que fotografam detalhes internos (ordem de chamadas, mensagens exatas de log) quebram a cada refatoração e ensinam o time a ignorá-los.

Portão: testar o comportamento observável da spec, não a implementação; mutação (manual ou ferramenta) como prova de que o teste morde.

11

Roadmap de adoção

Não adote por decreto. A sequência abaixo constrói prova antes de construir obrigação — cada fase só começa quando a anterior mostrou números.

  1. Fase 1 Piloto

    Um time voluntário, um serviço de risco moderado, 4–6 semanas. Specs completas + ciclo RED–GREEN–REFACTOR em todas as mudanças. Coleta de linha de base das métricas antes de começar.

  2. Fase 2 Padronizar templates

    O que o piloto validou vira template: spec.md, plan.md, evidence.md e CLAUDE.md padrão. Prompts por etapa entram no repositório para qualquer pessoa reutilizar. Nada de processo em wiki morta — os templates vivem junto do código.

  3. Fase 3 Portões no CI

    Os portões manuais viram verificações automáticas: PR sem spec referenciada não passa; suíte roda em ambiente independente do agente; mudança de comportamento sem mudança de spec é sinalizada para revisão humana.

  4. Fase 4 Medir e ajustar

    Com o processo rodando, as métricas dizem onde apertar e onde afrouxar. Portão que nunca barra nada é atrito; portão que barra tudo é gargalo. Ambos merecem revisão.

As cinco métricas que importam

Defeitos escapados

Bugs encontrados após o merge, por mudança. A métrica-fim: o processo existe para derrubá-la.

Lead time

Da spec aprovada ao merge. Vigia o custo do processo — se subir sem defeitos caírem, há portão de mais.

Qualidade de teste (mutação)

Percentual de mutações do código que os testes matam. Proxy de que a suíte morde, não só cobre.

Deriva de spec

Mudanças de comportamento mergeadas sem atualização da spec correspondente. Meta: zero.

Retrabalho de revisão

Rodadas de revisão por PR. Specs boas derrubam esse número; specs vagas o inflam.

12

Perguntas frequentes

SDD substitui o TDD?

Não — e essa é a tese central deste guia. A spec define o contrato em linguagem humana; o teste torna o contrato executável e verificável a cada commit. Remover o TDD devolve o processo à leitura de fé sobre código gerado por agente. Veja a comparação detalhada.

Preciso do GitHub Spec Kit para praticar SDD?

Não. O Spec Kit é uma implementação open source do fluxo (constitution → specify → plan → tasks) e vale estudar — mas a prática exige apenas arquivos Markdown versionados, disciplina de portões e uma suíte de testes. Comece simples; adote ferramenta quando o processo pedir.

Quanto detalhe uma spec deve ter?

O suficiente para que cada cenário vire um teste sem conversa adicional — e nada além. Se um cenário não é observável (status, corpo, efeito registrado), ele ainda não está especificado. Se a spec descreve estrutura interna do código, ela detalhou demais e vai atrapalhar a refatoração.

Quem escreve a spec: o humano ou o agente?

O agente pode (e deve) rascunhar — ele explora o código mais rápido. Mas a aprovação é humana e intransferível: aprovar a spec é decidir o que o sistema fará. É exatamente o portão que separa “assistido por IA” de “decidido pela IA”.

Isso funciona em código legado sem testes?

Sim, com uma adaptação: antes do primeiro ciclo, escreva testes de caracterização que fotografam o comportamento atual da área que será tocada. Eles viram a rede de proteção para o agente refatorar; as specs novas passam a valer para o comportamento novo.

O processo não deixa tudo mais lento?

Ele desloca o tempo: mais minutos antes de codar, menos horas em retrabalho de revisão e caça a regressões. É uma afirmação testável — e o roadmap existe para testá-la no seu contexto: meça lead time e defeitos escapados no piloto antes de padronizar.

E quando o agente discorda da spec?

Ótimo sinal — é o processo funcionando. O agente deve registrar a objeção (na seção de dúvidas ou na revisão) e parar. Se ele estiver certo, a spec muda por decisão humana e fica registrado o porquê. O que ele não pode é implementar a própria opinião em silêncio.

13

Fontes e leituras

Fontes consultadas em 17 de julho de 2026. As posições recomendadas neste guia (por exemplo, spec-anchored como padrão) são nossas; o que cada fonte afirma está resumido abaixo, junto ao link.