Todo mundo que já escreveu software conhece a reclamação: spec antes de codificar é burocracia, plano é atraso, revisão antes de existir código é teatro. Um programador bom sabe o que fazer e faz. Para script de uso único, concordo sem ressalva. Uma exploração de dados que ninguém vai rodar de novo não merece dez seções de spec.

Para mudança em código de produção a conta vira. A sequência que uso (spec, plano, revisão, implementação, verificação, revisão de novo, documentação) não é a mesma checagem repetida sete vezes. Cada etapa existe para pegar uma classe de erro que as outras não pegam. Pular uma delas não produz um erro qualquer: produz exatamente o erro que aquela etapa existia para evitar.

Errar cedo, na etapa que dói agora, sai mais barato do que pular a etapa e reencontrar o mesmo erro com o código já rodando.

A pergunta útil, então, é o que cada etapa pega que as outras deixam passar.

O spec captura a decisão antes que ela vire código

Meu template de spec tem dez seções fixas: objetivo, requisitos de comportamento com caixa de seleção, detalhes de implementação, configuração, contratos de dados, dependências, casos de borda, restrições, Decision Log e Acceptance Criteria. As duas últimas são as que pagam o custo do resto. O Decision Log é datado e imutável: cada decisão de design entra com timestamp e nunca é reescrita por cima. Se a decisão muda, entra uma linha nova com a data nova, e a antiga fica lá contando por que um dia pareceu certa.

Dentro do Decision Log existe um aviso que eu chamo de alerta de conveniência. Se a justificativa de uma decisão apela para "mudança mínima de código", "ponto único de controle" ou "sem alterar X", quem escreve o spec é obrigado a defender por escrito que não está trocando correção por conveniência. Coloquei esse aviso no template depois de ver decisões desse tipo serem desfeitas mais tarde por outro agente, sem que ele soubesse que estava contrariando uma escolha deliberada. Sem o motivo registrado, a decisão parece arbitrária, e decisão arbitrária é a primeira coisa que alguém "simplifica".

Isso custa tempo real na frente. Escrever Decision Log e Acceptance Criteria antes de uma linha de código pode levar mais que a implementação, e para um script descartável esse tempo não volta. Por isso o processo inteiro é reservado para código de produção, não para todo código que sai da minha máquina.

A primeira revisão não lê código, porque ainda não existe código

Entre o plano e a implementação há uma revisão, e ela não olha para código nenhum. Não tem como: o código ainda não foi escrito. O que o revisor faz, como primeira tarefa, é um desafio de intenção. Para cada decisão no Decision Log, ele refaz o caminho da decisão até a intenção original e pergunta se o mecanismo escolhido atinge essa intenção em todos os estados de entrada ou só no caso comum.

Essa pergunta pega o que a revisão do código pronto não pega. Código revisado depois "funciona": o revisor roda o caso testado, vê o resultado esperado e aprova. A lacuna que só aparece com entrada incomum passa despercebida porque ninguém a exercitou. Na revisão de intenção o revisor não tem código para rodar, então sobra o mecanismo em abstrato, e é aí que o "e se a entrada for X" aparece antes de custar uma linha.

Paralelizar só depois que o plano separou o que é independente

Quando o plano mostra que quatro módulos não dependem uns dos outros, despacho quatro subagentes ao mesmo tempo. A diferença é de cerca de 5 minutos em paralelo contra cerca de 20 em série. É a etapa em que o processo devolve o tempo que cobrou antes.

Só que isso é seguro porque plano e revisão já separaram o que é de fato independente. Paralelizar sem essa separação prévia não economiza nada: espalha o mesmo erro de desenho em quatro lugares ao mesmo tempo, e depois alguém precisa consertar quatro vezes. A paralelização é uma consequência do plano, não um substituto dele.

LEIA TAMBÉM · OpiniãoParalelizar subagentes não economiza tempo, adia a conta da revisãoDá para pedir várias tarefas de uma vez a vários assistentes de IA, em vez de uma por vez. A execução termina mais rápido, mas alguém ainda precisa conferir cada resposta, e essa parte continua sendo uma de cada vez.

O verificador não pode ler a implementação

A etapa de verificação é onde a seção Acceptance Criteria paga o que custou escrever. Um subagente separado, o test-verifier, escreve os testes de aceite lendo só essa seção do spec. A linha que preserva essa independência é precisa: ele pode ler assinaturas públicas, stubs de tipo e definições de schema e configuração; nunca o corpo de uma função.

Quando o mesmo modelo escreve a funcionalidade e escreve o teste dela, o teste herda o mal-entendido de quem implementou. Se o modelo entendeu o requisito errado, o teste entende igual, e passa. O ciclo se quebra com um verificador cego ao código. Ele devolve um veredito por critério de aceite, não um "passou tudo" genérico, e uma falha aponta para um requisito específico.

Essa linha entre forma e comportamento não saiu de teoria. Saiu de um teste ao vivo contra o spec do dashboard do Solo Trader, quando ficou claro que sem a assinatura o verificador nem consegue chamar a função, e com o corpo ele deixa de ser independente.

LEIA TAMBÉM · OpiniãoQuem escreve a funcionalidade não pode escrever o teste que a aprovaSe a mesma IA escreve o programa e escreve a prova que confere o programa, ela pode errar nos dois do mesmo jeito e ninguém nota. Por isso quem confere não deveria ter visto o código por dentro.

Um bug em produção aponta a etapa que falhou

Se um bug chega em produção numa categoria que uma etapa dessa sequência existia para pegar, essa etapa falhou. Decisão revertida por conveniência? O Decision Log não estava sendo lido, ou o alerta não estava lá. Lacuna com entrada incomum? A revisão de intenção foi pulada ou feita por cima. Teste verde com requisito descumprido? O verificador viu o corpo da implementação. Nenhum desses casos é motivo para abandonar o processo. É motivo para revisar a etapa que deixou passar.

E se um dia o atalho deixar de produzir a classe de erro que a etapa pulada existia para evitar, essa tese cai. Até lá, cada bug que chega em produção me diz qual etapa foi pulada.