Fase Implement — execução disciplinada

TL;DR

Implement é onde o agente codifica — mas não em modo livre. Usa spec + plan + tasks como contexto persistente, trabalha uma task por vez, escreve teste antes ou junto, e marca a task como done só quando passa critério de aceitação. Se desviar do plan, pausa e atualiza o plan (não o oposto). É aqui que SDD se diferencia de “AI escrevendo código com mais documentação”: validação contínua contra spec, não só no final.

O que muda na forma de implementar

A fase Implement no SDD não é simplesmente “escrever código com contexto”. É uma mudança de postura do agente:

Modo vibe codingModo SDD Implement
Recebe prompt → gera código completoRecebe task → verifica spec → escreve teste → implementa
Faz a feature toda de uma vezUma task por vez, em ordem do DAG
Passa se “parece funcionar”Passa se o acceptance criteria binário é atendido
Ajusta spec/plan durante o códigoPausa e propõe mudança formal de spec/plan
Adiciona o que acha que faltaAdiciona apenas o que a task especifica
Sessão longa, contexto cresce sem controleSessão por task, contexto limpo

Essa mudança parece lenta no começo. Em prática, elimina a maior fonte de retrabalho: código que atende algo diferente do que o PM queria.

A regra de ouro

Trabalhe uma task de cada vez. Spec é referência, plan é roteiro, task é unidade de progresso.

graph LR
    A["📋 Pegar próxima\ntask do DAG"] --> B["📚 Carregar contexto:\nspec + plan + task"]
    B --> C["✍️ Escrever teste\ndo acceptance criteria"]
    C --> D["💻 Implementar\naté teste passar"]
    D --> E["🧪 Rodar suite\ncompleta"]
    E -->|✅ passa| F["☑️ Marcar task done\n+ commit referenciando spec/task"]
    E -->|❌ falha| G["🔍 Diagnosticar:\ncódigo, spec ou teste?"]
    G --> D
    F --> H{"Mais tasks?"}
    H -->|sim| A
    H -->|não| I["→ Validate phase"]

O ciclo parece familiar para devs com experiência em TDD — porque é TDD com um passo anterior: a spec define o que o teste deve testar.

Carregar o contexto certo antes de codificar

O “contexto persistente” do SDD é o que diferencia sessões de agente com SDD de sessões sem. A cada sessão (ou turno significativo), o agente carrega:

FontePor que incluiVolume típico
AGENTS.md / CLAUDE.mdConvenções do projeto, stack, padrões1-3K tokens
Spec da featureO que deve ser construído e por quê500-2K tokens
Plan da featureComo construir, ADRs, componentes1-2K tokens
Task atualO que fazer neste turno especificamente100-300 tokens
Código relevanteCódigo existente que a task modificaCarregado JIT

A combinação cabe confortavelmente em 8-10K tokens, deixando ampla janela para reasoning e geração de código. Sem esse contexto, o agente começa do zero e toma decisões que conflitam com o plan. Essa curadoria de “o que entra na janela a cada turno” é exatamente o problema que a trilha 05 - Camadas de contexto — persistente, temporal, transiente formaliza: spec e plan funcionam como contexto persistente (não muda a cada turno), enquanto a task atual é contexto transiente.

Context como pré-requisito

Implementar sem carregar spec + plan é equivalente a um dev júnior começar a codar sem ler os requisitos. A diferença é que o agente não tem como pedir esclarecimento implicitamente — ele vai inferir e a inferência vai ser plausível, não necessariamente correta.

Test-first dentro do SDD

O acceptance criteria (AC) de cada task vira teste antes de virar código. Essa sequência — teste → implementação — tem uma propriedade valiosa: o teste falha por razão certa quando o código não existe, garantindo que o teste está testando o que deve testar.

# tests/refunds/test_refund_service.py
# Escrito ANTES da implementação, baseado nos ACs da task T3
 
class TestRefundServiceRequest:
    """
    Task T3 — AC mapeados da spec specs/payments/refund/spec.md
    """
 
    def test_full_refund_within_7_days_creates_pending(self, refund_service, db):
        """AC1: Refund total ≤7 dias → status pending, sem aprovação."""
        payment = create_payment(age_days=3, amount=Decimal("100.00"))
 
        result = refund_service.request(
            payment_id=payment.id,
            amount=payment.amount,  # full
            reason="customer_request"
        )
 
        assert result.status == RefundStatus.PENDING
        assert result.refund_id is not None
        assert result.estimated_completion is not None
 
    def test_partial_refund_after_7_days_requires_approval(self, refund_service, db):
        """AC2: Refund parcial >7 dias → approval_required."""
        payment = create_payment(age_days=15, amount=Decimal("100.00"))
 
        result = refund_service.request(
            payment_id=payment.id,
            amount=Decimal("50.00"),  # partial
            reason="customer_request"
        )
 
        assert result.status == RefundStatus.APPROVAL_REQUIRED
        assert result.approval_request_id is not None
 
    def test_duplicate_request_returns_existing_refund(self, refund_service, db):
        """AC-idempotência: mesmo payment_id + client_reference_id → retorna existente."""
        payment = create_payment(age_days=3, amount=Decimal("100.00"))
 
        result1 = refund_service.request(
            payment_id=payment.id,
            amount=payment.amount,
            client_reference_id="unique-ref-123"
        )
        result2 = refund_service.request(
            payment_id=payment.id,
            amount=payment.amount,
            client_reference_id="unique-ref-123"
        )
 
        assert result1.refund_id == result2.refund_id
        assert result2.is_duplicate is True

A regra de ouro dos testes no SDD

A task não é done se o teste correspondente ao AC não está escrito e passando. Não há negociação sobre isso.

A unidade de progresso é a task

A disciplina de “uma task por vez” parece excessiva até o primeiro retrabalho causado por sua ausência. Quando o agente faz duas tasks juntas e a segunda introduz um bug na primeira, identificar o ponto exato da regressão é difícil. Tasks atômicas criam checkpoints rastreáveis.

Anti-patternO que acontecePadrão correto
”Implementar a feature toda na sessão”Contexto cresce, rastreabilidade cai”Implementar Task T3 neste turno"
"Vou refatorar enquanto implemento T3”Refactor não tinha AC; pode ter quebrado algo”T3 done. Refactor é T8 com seu próprio AC"
"O plan parece ruim, mudo no código”Plan e código divergem silenciosamente”Pauso, proponho update de plan, aguardo aprovação"
"Minha intuição diz Y, o plan diz X”Intuição pode estar certa, mas não está registrada”Sigo X. Se Y parece melhor, anoto em open questions”

Spec drift detection durante Implement

Situações não cobertas pela spec aparecem durante implementação — e a decisão de como tratá-las é o momento mais crítico do processo. A diferença entre SDD e vibe coding está exatamente aqui:

graph TB
    A["Agente encontra situação\nnão coberta pela spec"] --> B{"O que fazer?"}
    B -->|"ERRADO: decide sozinho\ne segue"| C["❌ Drift silencioso\nSpec e código divergem"]
    B -->|"CERTO: pausa"| D["✅ Registra na lista\nde open questions"]
    D --> E["Propõe spec change\nou interpretação"]
    E --> F["Aguarda decisão\nhumana"]
    F --> G["Spec atualizada\nno repositório"]
    G --> H["Continua implementação\ncom spec clara"]

Decisões silenciosas durante Implement são a fonte #1 de drift em projetos SDD. A postura correta é registrar e pausar, nunca decidir silenciosamente e seguir.

Exemplos de situações não cobertas que exigem pausa:

  • Comportamento com input fora do range especificado
  • Interação entre duas features que a spec não antecipou
  • Erro de dependência externa (o que fazer se o serviço de email está down?)
  • Performance pior que o esperado — NFR foi irrealista?

Hooks para disciplina automatizada

Ferramentas de 2026 (Kiro, Claude Code hooks, GitHub Actions) oferecem automação de disciplina que transforma “boa intenção” em “default do sistema”:

HookTriggerAção automatizada
pre-editAntes de modificar arquivoVerifica spec + plan estão no contexto da sessão
pre-commitAntes de commitRoda linter, type check, testes da task atual
post-testDepois que testes passamAtualiza status da task no tasks.md
pre-mergeAntes de merge do PRValida cobertura de todos os ACs da spec
spec-drift-checkEm CI, a cada PRDetecta endpoints/comportamentos no código sem AC correspondente na spec

Hooks transformam disciplina de responsabilidade individual para responsabilidade do sistema. Engenheiros cometem erros; sistemas de automação também, mas de formas previsíveis e detectáveis.

Commits rastreáveis: a trilha de auditoria

Cada commit da fase Implement deve referenciar o que foi implementado, de qual spec e task:

feat(refunds): T3 — implement RefundService.request

Implements AC1 (full refund ≤7 days → pending) and AC2
(partial refund >7 days → approval required) from
specs/payments/refund/spec.md.

Uses outbox pattern per plan decision D2 (idempotency).

Closes: plan/refunds/tasks.md#T3
Refs: specs/payments/refund/spec.md#acceptance-criteria

Por que isso importa: quando um bug é reportado em produção, o histórico de git com esse formato permite rastrear diretamente da spec que deveria ter prevenido o bug. A pergunta “o AC X foi implementado?” tem resposta nos commits, não em memória.

O loop diagnóstico quando o teste falha

Quando um teste falha, o primeiro instinto é “corrigir o código”. Em SDD, há uma etapa de diagnóstico antes:

graph TB
    A["Teste falhou"] --> B{"Qual a raiz?"}
    B -->|"Código errado"| C["✅ Corrigir código\nre-rodar"]
    B -->|"Spec era vaga/errada"| D["⏸ Pausa\nProponha spec change"]
    B -->|"Teste está errado"| E["⚠️ Revisar teste\ncom cautela — raro"]
    B -->|"NFR irrealista"| F["⏸ Pausa\nProponha update de NFR"]
    C --> G["Suite passa → done"]
    D --> H["Spec atualizada → re-teste"]
    E --> I["Só com revisão humana"]
    F --> J["NFR revisado → re-teste"]

O caso mais perigoso é “Teste está errado” — porque corrigir o teste para fazer o código passar destrói o sinal. Isso só é aceitável com revisão humana explícita e registro de por que o AC original estava errado.

Sessões por task: o tamanho certo

Uma prática convergente em 2026: cada sessão de agente cobre uma task completa — não mais, não menos. Isso tem duas consequências:

Sessão curta (< 30 min): provavelmente a task era pequena demais ou não tinha AC real. Tasks-fantasma que o agente completa em minutos geralmente não tinham critério de done real.

Sessão longa (> 90 min): provavelmente a task era grande demais, tinha ambiguidade escondida, ou o contexto cresceu tanto que qualidade caiu. Sinal para dividir a task ou para verificar se spec/plan estava completo.

A janela de 30-90 minutos por task é um proxy útil de granularidade correta.

Paralelização de tasks independentes

Tasks sem dependências no DAG podem ser executadas em paralelo — por diferentes desenvolvedores, por diferentes sessões, ou por diferentes agentes no modelo multi-agent:

T1 (schema) ──────────────────────────────────────────────→
                ↓
T2 (repository) ──────────────────────────────────────────→
                            ↓
T5 (notification — independente) ─────────────────────────→
                                          ↓
                            T3 (service, depende de T1+T2) →
                                                    ↓
                                        T4 (endpoint, depende de T3) →

T5 pode começar junto com T1 e T2, sem esperar. Em multi-agent SDD, um coordinator agent dispara subagentes para tasks independentes simultaneamente. Ver 09 - SDD com agentes — coordinator, implementor, validator.

Implement como diálogo com a spec

Uma forma de entender a fase Implement é como um diálogo entre o agente e a spec. O agente não “lê a spec uma vez e esquece” — ele retorna à spec como referência a cada decisão de implementação.

Perguntas que o agente deve fazer antes de cada decisão:

  • “A spec cobre esse caso?” → Se sim, implementar conforme spec. Se não, registrar e pausar.
  • “Esse código atende o AC X?” → Se não tem como verificar, há um AC faltando.
  • “Essa decisão de implementação conflita com a ADR D2?” → Consultar plan.
  • “Estou adicionando algo que a task não pede?” → Remover; scope creep silencioso é anti-pattern.

Esse diálogo contínuo é o que separa Implement em SDD de simplesmente “escrever código com um prompt longo”.

O papel do review de código no SDD Implement

Em SDD, o code review muda de foco. Sem SDD, o reviewer julga subjetivamente: “parece correto?”, “boas práticas?“. Com SDD:

Reviewer verifica:

  1. Cada AC da task tem um teste correspondente que passa?
  2. O código implementa o AC da spec ou algo diferente?
  3. Alguma decisão foi tomada silenciosamente sem registro?
  4. O código introduz comportamento não previsto na spec?
  5. O commit referencia a task e a spec?

O review no SDD é mais rápido porque tem critério objetivo, e mais efetivo porque detecta divergência spec/código enquanto está quente — não em produção.

graph LR
    PR["PR aberto"] --> ReviewSpec["Revisar spec"]
    ReviewSpec --> ReviewAC["Verificar AC cobertos\ncom testes"]
    ReviewAC --> ReviewCode["Verificar código\natende spec (não mais, não menos)"]
    ReviewCode --> ReviewDrift["Verificar drift:\ndecisões silenciosas?"]
    ReviewDrift -->|"Tudo ok"| Approve["✅ Aprova"]
    ReviewDrift -->|"Drift detectado"| RequestChange["🔄 Request Changes\n+ nota de onde diverge"]

O estado dos arquivos durante Implement

Durante a fase Implement, os arquivos têm papéis claros e não se misturam:

projeto/
├── specs/payments/refund/
│   └── spec.md          ← IMUTÁVEL durante Implement (lei)
│                          Só muda via PR de spec
├── plan/payments/refund/
│   ├── plan.md          ← Quase imutável (exceção: discovery crítico)
│   └── tasks.md         ← MUDA: [x] conforme tasks completam
└── src/payments/refund/
    ├── models/          ← Criado em T1
    ├── repositories/    ← Criado em T2
    ├── services/        ← Criado em T3
    └── api/             ← Criado em T4

spec.md é lei durante Implement. Se a spec precisar mudar, há um PR de spec com revisão antes de qualquer mudança de código que reflita a mudança.

tasks.md é o estado vivo do progresso — o único arquivo que muda naturalmente conforme Implement avança.

Quando o Agente é humano (ou quando não é)

As regras da fase Implement se aplicam igualmente quando o “agente” é:

  • Um agente autônomo (Claude, GPT, Gemini) executando tasks
  • Um desenvolvedor humano usando AI como copilot
  • Um desenvolvedor humano sem AI

A diferença é a velocidade e a tendência a errar. Agentes autônomos são mais rápidos e erram de formas menos previsíveis. Desenvolvedores humanos são mais lentos e erram de formas mais conhecidas. Em ambos os casos, a disciplina de “uma task, um AC, um teste” é igualmente valiosa.

Em 2026, o padrão emergente são loops humano-no-meio: agente executa uma task, humano revisa o resultado antes de autorizar a próxima. Isso captura a velocidade do agente com o julgamento humano no momento certo.

Quando o Agente não sabe o que fazer

SDD tem protocolo explícito para incerteza do agente:

  1. Pesquisar na codebase — existe código similar que resolve o padrão?
  2. Consultar a spec — a resposta está nos ACs ou NFRs?
  3. Consultar o plan — existe uma ADR que cobre essa decisão?
  4. Registrar a dúvida — adicionar em “open questions” do plan/spec
  5. Pausar e perguntar — o humano toma a decisão

O que nunca deve acontecer: inferir e seguir adiante sem registro. Inferência silenciosa é a semente do drift.

Anti-patterns da fase Implement

Pular tasks — fazer várias juntas

Perde rastreabilidade; regressões difíceis de localizar.

Não escrever teste antes de implementar

Code review descobre tarde; “done” vira subjetivo.

Mudar plan no commit message em vez de PR no plan

Drift silencioso; próxima sessão lê plan desatualizado.

Marcar task done com teste falhando

Destrói o sinal de qualidade; build fica vermelho “aceitável”.

Adicionar funcionalidade fora da spec

Viola o contrato; scope creep silencioso.

Sessões longas sem checkpoint de task

Perda em caso de erro; contexto polui próxima task.

Patchear teste para fazê-lo passar

O teste estava testando algo errado — corrija o teste com razão, não esconda o problema.

Decidir silenciosamente casos não cobertos pela spec

Spec e código divergem; bug aguarda em produção.

Implement em sistemas brownfield

Sistemas existentes com tech debt apresentam o desafio de “não há spec para o código atual”. A abordagem para introduzir SDD em brownfield:

Estratégia 1 — Spec-as-found: antes de modificar qualquer área, escrever uma spec descrevendo o comportamento atual (como ele é, não como deveria ser). Depois modificar o comportamento e atualizar a spec. Gradualmente, o sistema vem coberto.

Estratégia 2 — Spec-for-new: todo código novo segue SDD, mesmo que o código circundante não. Cria uma linha de demarcação clara: código antes de X → sem spec; código depois de X → spec-anchored.

Estratégia 3 — Spec-por-área-crítica: identificar as áreas de maior risco (auth, pagamentos, dados sensíveis) e aplicar SDD Implement apenas nelas primeiro. ROI maior, custo menor.

A maioria dos projetos reais começa com a estratégia 2 ou 3, não com uma reescrita completa com spec.

Métricas da fase Implement

MétricaAlvoPor que importa
% tasks completadas em primeira tentativa (sem rework)> 70%Tasks bem definidas = execução limpa
% ACs com teste correspondente100%Sem teste = sem done real
Tempo médio por task vs estimativa≤ 120%Tasks subestimadas revelam ambiguidade
Mudanças de plan durante Implement< 2/featurePlan incompleto = rework
Tasks com decisão silenciosa (sem registro)ZeroToda decisão fora de spec deve ser registrada

O que vem a seguir

Implement produz código que passa nos testes que o próprio time escreveu — mas isso não garante que a spec, como um todo, continua sendo um contrato válido. A próxima fase, 07 - Fase Validate — spec como contrato executável, fecha esse ciclo: valida a feature completa contra a spec (não task por task) e decide se ela está pronta para produção.

Veja também

Referências

  • AnthropicBest Practices for Claude Code: Implementation (2026). Diretrizes de implementação com agentes.
  • KiroHooks and Subagents documentation (2026). Automação de hooks para disciplina de implement.
  • GitHub Spec KitImplement phase docs (2026). Tasks e commits rastreáveis.
  • OpenSpecApply phase state machine (2026). Ciclo de implement no modelo OpenSpec.
  • Beck, K.Test-Driven Development: By Example (2002). TDD como base do test-first no SDD.
  • Freeman, S.; Pryce, N.Growing Object-Oriented Software, Guided by Tests (2009). Integração de TDD com design de sistema — antecedente direto do SDD Implement.
  • Martin, R.C.Clean Code (2008). Princípios de código que SDD preserva ao limitar escopo por task.
  • Humble, J.; Farley, D.Continuous Delivery (2010). Commits pequenos e rastreáveis como base do pipeline que SDD implementa.
  • AmazonKiro Hooks: automating spec compliance in agent coding (2026). Como hooks enforçam disciplina de implement automaticamente.
  • Meszaros, G.xUnit Test Patterns (2007). Padrões de organização de testes que estruturam os testes de AC no SDD.
  • Fowler, M.Refactoring: Improving the Design of Existing Code (2018). Refactoring separado de feature — princípio de tarefa atômica que SDD formaliza.
  • Forsgren, N.; Humble, J.; Kim, G.Accelerate: The Science of DevOps (2018). Métricas DORA que SDD otimiza: lead time, deployment frequency, failure rate, recovery time. itrevolution.com/product/accelerate
  • DORAState of AI-Assisted Software Development 2025 — evidências de que disciplina de commit pequeno e teste contínuo correlacionam com performance de elite. dora.dev/dora-report-2025

Como explicar em inglês

Em entrevistas e PRs em inglês, a fase Implement do SDD tem vocabulário próprio que não é intuitivo para quem só conhece “AI coding” genérico. A ideia central para comunicar: “I don’t let the agent freewheel — it works off a spec and a plan, one task at a time, test-first, and pauses instead of guessing when the spec doesn’t cover a case.”

PT-BRENNota de uso
specspec / specificationDocumento imutável durante Implement; “the spec is the source of truth”
planplanRoteiro técnico (ADRs, componentes); “quase imutável”, exceção só com discovery crítico
tasktaskUnidade atômica de progresso; “one task per session”
critério de aceitaçãoacceptance criteria (AC)Binário — passa ou não passa; “the AC is the definition of done”
test-firsttest-firstTeste escrito a partir do AC antes do código; não confundir com TDD puro (aqui o teste vem da spec, não da intuição do dev)
spec driftspec driftDivergência silenciosa entre spec e código; “silent drift is the #1 failure mode”
task atômicaatomic taskTask pequena o bastante para não misturar duas mudanças; unidade de rastreabilidade
scope creepscope creepAdicionar algo que a task não pede; “silent scope creep”
rastreabilidade de commitcommit traceabilityCommit referencia task + spec; “traceable from bug report back to the spec that should’ve prevented it”
spec-anchoredspec-anchoredCódigo cuja origem e comportamento remetem a uma spec versionada, não a memória do time