A premissa fundamental do SDD é que a especificação passa a ser a fonte da verdade do repositório. Em vez de enviar prompts diretos para o modelo criar funcionalidades, o desenvolvedor e o agente alinham o escopo, as regras de arquitetura e os critérios de aceite em arquivos de documentação versionados antes de gerar uma única linha de código.
O processo operacional do SDD divide-se em quatro etapas sequenciais, onde cada fase produz o artefato que serve de gabarito para a fase seguinte:
1. Specify (Especificação / PRD): Captura a intenção de negócio, o problema do usuário, o escopo principal, os requisitos funcionais e o que está explicitamente fora de escopo e coloca em um documento de produto ou especificação funcional (ex: spec.md ou PRD).
2. Design (Design Técnico e Arquitetura): Define a solução de engenharia para atender à especificação. Detalha modelos de dados, contratos de API, diagramas, padrões de arquitetura (DDD, Clean Architecture) e decisões técnicas (ADRs). Coloca em um documento de design técnico (ex: design.md ou technical_design.md).
3. Tasks (Plano de Ação e Tarefas Atômicas): Transforma o design e a especificação em um planejamento de tarefas acionáveis e otimizadas para o agente. Define a ordem de execução, quais tarefas dependem de outras e quais podem rodar em paralelo. Coloca em documento de lista sequencial de execução (ex: task.md)
4. Execute (Execução e Verificação): O agente lê os artefatos gerados e implementa o código estritamente dentro dos limites definidos, submetendo o resultado a testes e validações determinísticas.
Memória persistente
Modelos de linguagem são estatísticos e stateless (não mantêm memória de longo prazo por padrão).
Quando conversas longas acontecem em uma sessão, janelas de contexto estouram, o agente perde a memória da sessão e passa a degradar a qualidade do código gerado. Ao salvar a especificação em arquivos de texto dentro do repositório, o contexto é persistido.
Se a janela estourar ou se a sessão for reiniciada, basta recarregar os arquivos .md para que o agente recupere a intenção exata do projeto sem desperdiçar tokens em pesquisas redundantes.
No SDD, a especificação precisa ser verificável. O agente não deve ser o único juiz do próprio trabalho. A especificação define contratos explícitos e critérios de aceite que exigem validação por portões determinísticos (sensores externos), como a execução de suítes de testes unitários/integração, linteres e compilação de tipos.
À medida que os modelos de IA evoluíram, o SDD dividiu-se em duas abordagens de execução
-
Classic SDD: O trabalho é dividido em micro-tarefas extremas. Para cada pequena tarefa, o agente escreve um trecho de código e é obrigado a rodar um teste antes de passar para a próxima. Ideal para modelos menos robustos ou mais baratos que precisam de instruções passo a passo rígidas para não alucinar.
-
Lean / Plan-Based SDD: A especificação e o design são consolidados em um plano de ação unificado. Modelos mais avançados recebem esse plano com um checklist claro, implementam blocos maiores de código de forma autônoma e realizam a verificação rígida ao final. Maximiza a velocidade de entrega e economiza chamadas mantendo a consistência do contexto.
No SDD, a responsabilidade do engenheiro de software desloca-se da digitação manual de código sintático para o papel de especificador, orquestrador e validador.
O desenvolvedor aplica seu conhecimento de arquitetura e negócio para revisar a spec e o design propostos, garantindo que o agente execute a solução correta antes de consumir recursos computacionais de forma desordenada.
Benefícios do SDD
No desenvolvimento tradicional com LLMs, a janela de contexto tende a encher rapidamente conforme o desenvolvedor corrige erros em loop no chat.
O SDD gasta tokens na fase inicial de planejamento (pesquisa, especificações, arquitetura e tarefas).
Ao isolar a intenção em arquivos Markdown, a execução do código ocorre de forma direta, eliminando retrabalhos, buscas duplicadas do repositório e prompts longos de correção.
Os modelos de linguagem são stateless e degradam o raciocínio conforme o histórico da conversa se expande ou a janela estoura.
A especificação escrita em arquivos .md atua como a memória persistente da funcionalidade.
Se a sessão atingir o limite ou precisar ser reiniciada, qualquer agente pode carregar os artefatos (spec.md, design.md, tasks.md) e retomar o trabalho exatamente de onde parou sem perda de regras de domínio.
Sem amarras claras, agentes de IA tendem a assumir atalhos, gerar código solto ou declarar conclusão prematura sem validação real.
O SDD define o que deve ser feito e o que está fora de escopo, fechando o espaço para o agente criar abstrações indesejadas.
A especificação obriga a definição de critérios falsificáveis que devem passar por sensores determinísticos (testes unitários, linters e type checkers) para provar o funcionamento antes da aprovação.
Alterar comportamentos ou premissas técnicas em projetos grandes sem especificação exige refazer múltiplos prompts ou editar dezenas de arquivos manualmente.
Com o SDD, pequenas edições em poucas frases no arquivo de especificação orientam a IA a reescrever ou ajustar centenas de linhas de código mantendo a coerência arquitetural.
O SDD permite fatiar a demanda em tarefas atômicas e com dependências mapeadas (tasks.md).
Assim, é possível instanciar múltiplos subagentes simultâneos em janelas separadas para resolver diferentes partes do plano (ex: repositórios, APIs e telas) sem poluir o contexto principal do desenvolvedor.
Artefatos principais do SDD
Cada artefato representa o resultado de uma fase e serve de guia direto para a seguinte.
1. Documento de Requisitos do Produto (PRD ou spec.md)
Captura o problema sob a perspectiva de negócio e do usuário. O foco aqui é definir as intenções, os objetivos e o comportamento esperado da funcionalidade sem entrar no detalhe de implementação.
Conteém: objetivos do projeto, histórias de usuário (estruturadas em estilo Given/When/Then ou BDD), critérios de aceite e declaração explícita do que está fora do escopo.
2. Documento de Design Técnico (design.md ou TDD)
Traduz os requisitos de negócio do PRD em decisões técnicas e de arquitetura. Serve para o time alinhar a solução de engenharia e dar o mapa de navegação correto para o agente de IA.
Contém: modelo de dados (schemas e tabelas), contratos de API, diagramas de fluxo (como Mermaid), padrões de arquitetura a seguir (Clean Architecture, DDD), componentes afetados e decisões de arquitetura (ADRs).
3. Plano de Tarefas (tasks.md ou plan.md)
Converte a especificação e o design técnico em uma sequência ordenada de ações.
Contém: tarefas pequenas com ordem clara de execução. Ele indica quais tarefas dependem de outras, quais podem rodar em paralelo usando subagentes e qual o comando de verificação para validar a conclusão.
4. Contratos de Aceite e Progresso (contract.json ou progress.json)
Atuam como o rastreador determinístico do estado do projeto, permitindo que a IA sobreviva ao estouro da janela de contexto ou à troca de sessões sem perder a memória do que já foi feito.
Contém: indicadores do estado de cada funcionalidade (pendente, em progresso, concluída ou com falha), histórico do ciclo de tentativas e mapeamento direto entre os requisitos e os testes que precisam passar.
5. Registros de Decisão de Arquitetura (ADRs)
Arquivos pontuais de histórico que registram decisões importantes de engenharia tomadas ao longo do tempo.
Contém: o contexto de uma escolha técnica (como a mudança de um banco de dados ou adoção de uma biblioteca específica), os motivos da escolha e os impactos esperados. Permitem que agentes de IA compreendam decisões passadas e não proponham refatorações que violem a arquitetura combinada.
6. Guias de Arquitetura e Padrões (Architecture Guidelines)
Arquivos específicos mantidos na pasta de documentação do projeto (ex: docs/architecture.md ou docs/domain/). Detalha regras de Clean Architecture, Domain-Driven Design (DDD), padrões de rotas, contratos de API e modelos de dados.
Em vez de carregar todos esses guias na conversa inicial, o arquivo principal (AGENTS.md ou CLAUDE.md) orienta o agente a carregar esses guias sob demanda apenas quando for modificar a camada relevante (ex: ler o guia de banco de dados só quando for criar uma migration).
- Guias de Domínio e Glossário (Context Maps)
Mapeamento da linguagem ubíqua do projeto. Define os nomes exatos das entidades de negócio, termos do domínio e limites entre contextos do sistema (ex: diferenciar quando usar "Usuário" vs. "Cliente"). Dessa forma, evita que o agente crie variáveis, serviços ou classes com nomes genéricos ou conflitantes que divirjam das regras de negócio do time.
Nas versões mais recentes da metodologia de SDD, a separação rígida entre os arquivos spec.md e design.md costuma ser consolidada em um único arquivo de planejamento.
Essa simplificação reduz o consumo de tokens e atende melhor aos modelos de linguagem mais avançados, que conseguem ler uma especificação direta e partir para a execução sem a necessidade de microgerenciamento por tarefas.
Práticas Avançadas de SDD
LLM as Judge
A técnica de LLM as Judge usa um modelo separado do modelo executor para analisar a entrega contra a especificação e os critérios de aceite.
Em vez de depender de um julgamento determinístico simples, o modelo juiz recebe a spec, o design, o diff da alteração e os resultados dos testes. Ele avalia o código e entrega um veredito estruturado em JSON com a aprovação ou os pontos de falha.
Essa abordagem elimina a autoaprovação do agente executor. Para economizar recursos, o julgamento por LLM é posicionado como a última camada de verificação, sendo acionado apenas quando o diff supera filtros estatísticos de similaridade ou testes estáticos.
+------------------+ +-------------------+ +------------------+
| Agente Executor | --> | Estágio de Código | --> | Filtro Leve |
| (Gera a alteração| | (Git Diff/PR) | | (Estático/Vetor) |
+------------------+ +-------------------+ +------------------+
|
Passou pelo filtro?
|
v
+------------------+ +-------------------+ +------------------+
| Veredito Final | <-- | LLM as Judge | <-- | Validação |
| (Aprova / Ajusta| | (Modelo Separado) | | de Conformidade |
+------------------+ +-------------------+ +------------------+
Subagentes paralelos e isolamento por Git Worktrees
Rodar execuções longas em um único chat enche a janela de contexto e corrompe o raciocínio do modelo. A paralelização resolve isso dividindo a especificação em tarefas independentes.
+-------------------+
| Agente Principal |
| (Orquestrador) |
+---------+---------+
|
+-----------------------+-----------------------+
| |
v v
+------------------+ +------------------+
| Subagente A | | Subagente B |
| (Contexto ISO A) | | (Contexto ISO B) |
+--------+---------+ +--------+---------+
| |
v v
+------------------+ +------------------+
| Git Worktree A | | Git Worktree B |
| (Ramo Isolado) | | (Ramo Isolado) |
+--------+---------+ +--------+---------+
| |
+-----------------------+-----------------------+
|
v
+-------------------+
| Integrador de Git |
| (Resolução Merge) |
+-------------------+
O agente orquestrador dispara subagentes atribuindo a cada um apenas a especificação de sua tarefa. O trabalho de pesquisa ou escrita do subagente não polui a janela de contexto do agente principal.
Para impedir que subagentes sobrescrevam os mesmos arquivos localmente, o orquestrador isola a execução criando um Git Worktree (uma cópia leve do repositório) para cada tarefa. Ao final da execução, os ramos são integrados.
SDD em projetos Brownfield (Legado)
Diferente de projetos Greenfield, onde o SDD começa do zero, em bases de código legadas a especificação precisa considerar o comportamento já existente no repositório:
-
O agente faz uma leitura inicial da estrutura, extrai padrões arquiteturais existentes e consolida esse contexto em arquivos de orientação (como
agents.mdourules). -
Antes de alterar um fluxo, a IA analisa a funcionalidade legada para registrar o comportamento atual e os contratos implícitos em uma spec.
-
A spec de uma nova funcionalidade em código legado define com precisão os limites da alteração. O plano impede que o agente tente refatorar arquivos fora do escopo definido, reduzindo o risco de quebras em cascata.
Replanejamento contínuo entre features
O desenvolvimento com agentes não segue uma linha reta. À medida que o código é alterado e novas funcionalidades são entregues, as especificações de alto nível precisam ser ajustadas:
-
Finalizada a execução e validação de um bloco, o agente analisa os impactos da entrega no sistema.
-
Se uma decisão técnica tomada na implementação alterar contratos de API ou modelos de dados compartilhados, o agente atualiza o documento de design central, as ADRs ou a spec do projeto antes de iniciar o planejamento do próximo item do roadmap. Isso evita divergências entre o comportamento do repositório e a documentação que orienta os próximos passos da IA.
+-------------------+ +-------------------+ +-------------------+
| Planejamento de | --> | Execução da | --> | Verificação dos |
| Feature | | Feature | | Sensores |
+-------------------+ +-------------------+ +---------+---------+
^ |
| |
+---------------- Replanejamento -------------------+
(Atualização da
Constituição/Specs)
Limpeza sistemática de contexto
À medida que a conversa avança, tokens acumulados degradam o desempenho do modelo. É importante seguir boas práticas de gerencimento de contexto de forma sistemática:
-
Em vez de manter um chat aberto por horas, o ciclo de trabalho é quebrado. A pesquisa roda em uma janela, a criação do plano em outra e a implementação em uma nova sessão com o contexto zerado.
-
O progresso do agente não fica salvo na memória do chat. As decisões e o estado do sistema são gravados diretamente no repositório em arquivos
.mdou.json. -
Em uma nova sessão, o agente lê apenas os arquivos necessários para a tarefa atual (
spec.mdetasks.md), mantendo o consumo de tokens baixo (idealmente abaixo de 40% do limite da janela) e prevenindo alucinações.
BDD (Behavior-Driven Development) e Gherkin
Deixam de ser apenas ferramentas de testes para pessoas de QA e passam a atuar como contratos comportamentais de aceitação entre engenheiro e agente.
O formato de cenários em Gherkin com a estrutura: Given / When / Then (Dado / Quando / Então) serve como um padrão atômico e determinístico para definir a intenção do sistema antes de qualquer linha de código ser escrita.
Dentro do pipeline do SDD, os cenários Gherkin são produzidos na primeira etapa (Specify) para alimentar o design técnico e o plano de execução:
+-------------------+ +--------------------+ +--------------------+
| História / PRD | --> | Cenários Gherkin | --> | Design Técnico / |
| (Intenção de Ação)| | (Given/When/Then) | | Tasks Atômicas |
+-------------------+ +--------------------+ +---------+----------+
|
v
+-------------------+ +--------------------+ +--------------------+
| Validação Final | <-- | Autocorreção / IA | <-- | Execução do Código |
| (Suíte de Testes) | | (Feedback do CI) | | pelo Executor |
+-------------------+ +--------------------+ +--------------------+
-
A pessoa desenvolvedora passa o problema ou documento de produto (PRD) para o agente.
-
O agente especifica o comportamento em arquivos de funcionalidade (
.featureou em seções despec.md) detalhando os casos felizes e os cenários de borda no formato Gherkin. -
O modelo utiliza os cenários para construir o plano de tarefas e entender os critérios de parada.
-
A suíte de testes (seja unitária, de integração ou E2E) executa as validações mapeadas diretamente desses cenários.
O Gherkin expressa regras de negócio complexas usando poucas linhas. Ler um arquivo .feature custa muito menos contexto para a IA do que ler dezenas de arquivos de código fonte.
A própria natureza do Given/When/Then força o agente a dividir os comportamentos do sistema em cenários isolados, prevenindo que o modelo tente resolver a aplicação inteira de uma só vez (evitando a falha do One-Shot Hero).
Cada cláusula Then exige uma asserção clara (ex: Então a API responde 200 com um array vazio). Isso impede que a IA cometa "vitória prematura" ou se autoaprove sem demonstrar que o resultado funciona na prática.
Em um arquivo de especificação (spec.md), o BDD entra mapeando explicitamente o que precisa ser verificado:
Funcionalidade: Limite de requisições por usuário
Cenário: Usuário autenticado dentro do limite
Dado que o usuário "Alice" possui um token válido
E não excedeu a cota de 100 requisições por minuto
Quando ela envia uma requisição GET para "/api/v1/orders"
Então o sistema deve responder com status 200
E o cabeçalho "X-RateLimit-Remaining" deve indicar o saldo atual
Cenário: Usuário excede o limite permitido
Dado que o usuário "Bob" já realizou 100 requisições no último minuto
Quando ele envia uma nova requisição GET para "/api/v1/orders"
Então o sistema deve responder com status 429
E o corpo da resposta deve conter a mensagem "Rate limit exceeded"
No SDD, o cenário Gherkin é vinculado diretamente a sensores determinísticos do projeto (como testes automatizados com Playwright, Vitest ou Jest).
Quando o agente executor conclui o código, o harness aciona a suíte que roda esse cenário de teste. Se o teste falhar, o log de erro retorna para a janela do agente como feedback imediato para autocorreção, se passar, o comportamento está validado perante o contrato estabelecido.
Gestão de Agentes
Dentro do SSD a gestão de agentes envolve organizar como modelos de linguagem recebem, dividem, executam e validam o trabalho em um pipeline controlado, que impede que a IA estoure a janela de contexto ou se autoaprove sem testes reais.
Ferramentas de orquestração de tarefas
Gerenciam o backlog de execuções do agente dentro ou fora do repositório. Elas dividem a especificação em um grafo de dependências claro, definindo a ordem das demandas e quais itens estão bloqueados por outros. Força o modelo a focar em um passo por vez, registrando a evolução em um arquivo de progresso versionado (como progress.json).
┌─────────────────────────────────────────────────────────────┐
│ TaskMaster │
│ (Orquestrador do Backlog / Grafo de Dependências) │
└──────────────────────────────┬──────────────────────────────┘
│
v
┌─────────────────────────────────────────────────────────────┐
│ Tarefas Pai │
│ (Módulos Coesos / Delimitação de Arquitetura) │
└──────────────────────────────┬──────────────────────────────┘
│
v
┌─────────────────────────────────────────────────────────────┐
│ Subtarefas Granulares │
│ (Passos Atômicos com Gates de Validação) │
└─────────────────────────────────────────────────────────────┘
Subtarefas Granulares
Dividir o plano de ação em partes menores é necessário, mas a granularidade precisa ser ajustada com cuidado para não encarecer a operação:
A granularidade extrema exige que o agente crie um arquivo, pare, rode um teste e só então avance. Para cada micropasso, um novo contexto precisa ser carregado. O resultado é uma execução demorada, alto consumo de tokens e perda da visão global do código, o que reduz a qualidade da entrega.
O Agrupamento em fases com modelos mais capazes, o ponto ideal consiste em reunir de 4 a 6 tarefas atômicas em uma fase coesa (ex.: o schema do banco, o repositório e a rota da API). O agente executa essa fase em lote e o pipeline aplica as verificações ao final da entrega completa.
Orquestrador vs. Executor vs. Juiz
Nos fluxos agênticos avançados o trabalho divide-se entre diferentes papéis com processos isolados:
-
Orquestrador: Lê a especificação geral, monitora o progresso, cria os ramos de trabalho e atribui tarefas.
-
Executores (Workers): Recebem apenas o contexto estritamente necessário para sua tarefa. Eles escrevem e alteram o código.
-
Juiz (LLM-as-Judge ou Oracle): Um agente separado avalia o diff das alterações contra os critérios de aceite definidos no contrato. Como ele não participou da escrita do código, a avaliação não sofre com a tendência da IA de se autoaprovar.
No fluxo moderno de desenvolvimento de software, os agentes integram-se às ferramentas tradicionais da engenharia. Os quadros de tarefas (como Jira ou Linear) atuam como a fonte da verdade para o progresso do projeto, enquanto as regras técnicas e ADRs permanecem no repositório.
+------------------+ +------------------+ +-------------------+
| Board / Ticket | --> | Research & Plan | --> | Agente Executor |
| (Jira / Linear) | | (Gera a Spec) | | (Worker / Código) |
+------------------+ +------------------+ +---------+---------+
|
v
+------------------+ +-------------------+ +-------------------+
| Pull Request | <-- | LLM-as-Judge | <-- | Gates do CI |
| (Aprovação) | | (Revisão Técnica) | | (Tests / Linter) |
+------------------+ +-------------------+ +-------------------+
-
Triagem: Um ticket de problema ou funcionalidade entra na fila do board.
-
Planejamento: O agente orquestrador lê o ticket, faz a pesquisa inicial no código e gera o plano de ação (
spec.md). -
Execução: Um subagente implementa as tarefas isoladamente em um ambiente próprio (como um Git Worktree), impedindo conflitos no ramo principal.
-
Validadores (Sensors e Gates): O código passa por checagens estáticas (compilador e linters) e testes automatizados.
-
Revisão: O agente juiz valida o resultado contra a especificação e abre o Pull Request com um relatório detalhado. O engenheiro humano atua na revisão final da arquitetura e no aceite da entrega.
Loop Engineering
O objetivo do Loop Engineering é impedir que o agente rode de forma desgovernada — gerando código quebrado ou deletando arquivos em um impulso de "resolver a tarefa a qualquer custo" e garantir que ele convirja para uma solução correta através de verificações determinísticas.
Esse ecossistema no SDD funciona com base em quatro pilares principais:
- O agente de IA opera em um padrão contínuo de Observação -> Pensamento -> Ação.
O agente lê a especificação (spec.md) e o plano (plan.md), decide qual alteração precisa fazer e aplica a edição no repositório.
Em vez de assumir que a alteração funcionou, o loop força o agente a observar a resposta do sistema. Ele lê o retorno do compilador, os logs do console ou a saída da ferramenta.
- Para o loop funcionar sem intervenção humana constante, o harness é dividido em duas forças operacionais:
-
Feed-Forward (Guias/Direcionadores): É tudo o que é injetado antes de codificar para dar o rumo. No SDD, a especificação, as regras de arquitetura (
AGENTS.md) e os contratos de aceite atuam como o mapa que reduz a chance de o modelo alucinar. -
Feedback (Sensores Determinísticos): É o que avalia a entrega depois que o agente atua. A validação não depende da opinião do próprio agente; ela usa sensores externos como linters, checadores de tipo (TypeScript/mypy), suítes de teste e testes E2E (com Playwright ou Cypress).
+-------------------------------+
| Feed-Forward (Direcionadores)|
| - spec.md / design.md |
| - rules / AGENTS.md |
+---------------+---------------+
|
v
+------------------+ +------------------+ +-------------------+
| Agente Executor | --> | Alteração de | --> | Sensores |
| (Ação no Código) | | Código / Diff | | (Feedback) |
+------------------+ +------------------+ +---------+---------+
^ |
| Gatilho de Autocorreção |
+---------------- (Se reprovado) -----------------+
- Quando um sensor de feedback detecta uma falha (ex.: um teste quebrou ou o linter acusou erro de tipagem), o erro é injetado diretamente na janela de contexto do agente. Isso inicia a volta do loop: a IA lê a falha, ajusta a lógica e tenta novamente.
Para conter o risco de um infinite loop (onde a IA gasta milhares de tokens tentando corrigir o mesmo erro sem sucesso), a engenharia do loop aplica travas rígidas:
-
Bounded Retries: Limite máximo de ciclos para a mesma tarefa (ex.: 3 a 5 tentativas).
-
Stall Detection: Monitoramento para identificar quando a IA está em loops circulares, aplicando edições repetidas sem progresso real.
-
Fallback e transição: Se o agente executor estourar o limite de tentativas, a orquestração intervém. Ela pode subir o caso para um modelo de raciocínio mais avançado ou pausar a execução e chamar a revisão humana (Human-on-the-loop).
- No Loop Engineering do SDD, a etapa de validação final é isolada:
- O Executor altera os arquivos e roda a suíte de testes locais.
- O Juiz é disparado em um processo totalmente separado. Ele lê o diff da alteração, a
spec.mdoriginal e os relatórios dos sensores. - Se o Juiz identificar que a solução violou a arquitetura ou ignorou um critério de aceite, ele reprova a entrega e devolve um relatório exato dos pontos de falha para o orquestrador reiniciar o ciclo.