Um dos autores do Manifesto Ágil, Kent Beck publicou recentemente uma reflexão sobre um problema que está se tornando cada vez mais evidente na engenharia de software: estamos acumulando código mais rapidamente do que conseguimos acumular confiança nele.
Com agentes de IA, uma mudança que anteriormente exigia dias pode ser implementada em poucas horas, acompanhada de testes, documentação e um pull request pronto para revisão. Entretanto, a capacidade humana de compreender essas alterações, avaliar suas consequências e garantir que estão corretas não aumentou na mesma proporção.
Beck apresenta três caminhos possíveis: aprender a conviver com software no qual não conseguimos confiar plenamente, reduzir a velocidade de produção para acompanhar nossa capacidade de validação ou aprender a produzir confiança mais rapidamente. A terceira alternativa me parece a mais promissora, inclusive porque nos ajuda a lidar com parte da primeira sem transformar a segunda em uma restrição permanente.
Para isso, precisamos mudar a maneira como construímos confiança no processo de desenvolvimento. Em vez de depender principalmente de alguém compreender cada linha de código produzida, precisamos fortalecer as evidências de que uma mudança faz o que deveria fazer, respeita as restrições do sistema e pode ser entregue com segurança.
O problema é que nossas pipelines ainda estão longe de fornecer esse nível de confiança.
Um PR verde não significa que a implementação está correta
Hoje, um pull request costuma ser considerado pronto quando compila, passa nos testes automatizados, não apresenta problemas conhecidos na análise estática e recebe a aprovação de um revisor. Esses mecanismos são importantes, mas verificam apenas aquilo que fomos capazes de definir antecipadamente.
Imagine que um agente receba a tarefa de implementar frete grátis para clientes de fidelidade em compras acima de R$ 200. Ele escreve a regra, cria testes unitários e abre um PR com todos os checks verdes.
O que acontece se o valor mínimo deveria considerar descontos? E se vale-presentes não deveriam contar para atingir o limite? O que fazer quando um pedido possui múltiplas entregas?
O agente pode ter implementado corretamente uma interpretação incompleta da regra. Pior: os testes gerados pelo próprio agente podem confirmar exatamente essa interpretação, sem identificar o erro.
A pipeline está verde, mas a implementação continua incorreta.
Esse problema não nasceu com a IA. Entretanto, quando a produção de código acelera, as limitações dos nossos mecanismos de verificação ficam mais evidentes. Escalar a confiança significa aumentar a capacidade de detectar implementações incorretas sem depender de um crescimento proporcional no esforço de revisão humana.
Como começar a produzir confiança mais rapidamente
A solução não está em adicionar indiscriminadamente ferramentas ou etapas de aprovação. Precisamos melhorar a qualidade das verificações que já fazem parte do desenvolvimento e incorporar novos mecanismos onde existem riscos relevantes.
1. Defina o comportamento antes de gerar a implementação
A primeira mudança é separar a especificação do comportamento da produção do código.
Para uma feature, a equipe deveria conseguir explicitar os principais critérios de aceite, cenários de erro e invariantes antes de solicitar sua implementação ao agente. Esses critérios precisam representar decisões de negócio, e não apenas uma descrição técnica da solução desejada.
No exemplo do frete grátis, poderíamos estabelecer:
Regra: frete grátis para clientes de fidelidade
com valor elegível a partir de R$ 200.
Cenário 1:
R$ 200 em produtos elegíveis
Resultado: frete grátis
Cenário 2:
R$ 220 em produtos com R$ 30 de desconto
Resultado: frete normal
Cenário 3:
R$ 180 em produtos e R$ 30 em vale-presente
Resultado: frete normal
Invariante:
Clientes fora do programa nunca recebem
esse benefício.
O agente continua livre para escolher como implementar a solução, mas sua implementação pode ser confrontada com critérios estabelecidos independentemente dela.
Não precisamos necessariamente transformar toda demanda em uma especificação extensa. O importante é preservar as decisões que determinam o que significa estar correto.
2. Faça os testes verificarem o negócio, não apenas o código
Uma suíte grande não é necessariamente uma suíte confiável. Testes que reproduzem os detalhes da implementação podem continuar passando mesmo quando existem erros importantes de comportamento.
Para melhorar isso, equipes podem incorporar práticas conhecidas, mas nem sempre utilizadas de maneira consistente.
Testes baseados em propriedades ajudam a verificar invariantes para diferentes combinações de entrada. Já os testes de contrato protegem expectativas entre serviços. E os testes de mutação avaliam se a suíte realmente detecta alterações incorretas no comportamento.
Outra prática importante é evitar que a única fonte de verdade dos testes seja a implementação que acabou de ser produzida. Os critérios de negócio e contratos existentes precisam orientar a validação, inclusive quando os próprios testes forem gerados por agentes.
O objetivo não é aumentar indiscriminadamente a quantidade de testes. É melhorar sua capacidade de identificar problemas reais.
3. Transforme decisões arquiteturais em guardrails verificáveis
Boa parte das decisões que aparecem durante code reviews é recorrente. Uma equipe não deveria precisar discutir repetidamente se determinado módulo pode acessar diretamente o banco de outro domínio, se uma dependência é permitida ou se uma API pode expor informações sensíveis.
Sempre que possível, essas decisões deveriam ser transformadas em verificações automatizadas.
Testes de arquitetura podem validar dependências entre módulos. Análises estáticas podem identificar padrões inseguros. Testes de contrato podem detectar incompatibilidades entre consumidores e provedores. Políticas de CI podem impedir que mudanças avancem sem as verificações exigidas.
Isso não elimina o julgamento arquitetural. Uma implementação ainda pode respeitar todas as regras e introduzir uma abstração inadequada. Entretanto, a automação reduz o tempo gasto na fiscalização de decisões conhecidas e permite que os revisores se concentrem em questões mais relevantes.
O ganho é especialmente importante quando a quantidade de código produzido aumenta. Não precisamos revisar manualmente aquilo que conseguimos verificar de maneira objetiva e confiável.
4. Ajuste as verificações ao risco de cada mudança
Aplicar exatamente o mesmo processo a todos os pull requests não é necessariamente uma boa estratégia.
Uma correção de texto e uma alteração no cálculo de pagamentos possuem riscos diferentes. O nível de evidência exigido para aprová-las também deveria ser diferente.
Uma política simples para equipes pode começar assim:
| Tipo de mudança | Verificações prioritárias |
|---|---|
| Alteração localizada e reversível | Testes direcionados e análise estática |
| Regra de negócio | Critérios de aceite independentes e testes de comportamento |
| API ou integração | Testes de contrato e compatibilidade |
| Dados financeiros ou persistência | Invariantes, reconciliação e estratégia de recuperação |
| Mudança de alto impacto | Testes de integração, observabilidade e liberação progressiva |
Essa classificação não precisa ser totalmente automatizada desde o início. A equipe pode começar estabelecendo critérios objetivos no template do PR e, gradualmente, incorporar políticas à pipeline.
O resultado esperado é reduzir o esforço em mudanças simples e ampliar a profundidade das verificações quando o risco justifica.
5. Continue produzindo evidências depois do merge
Mesmo uma boa suíte de testes não reproduz integralmente o ambiente de produção.
Por isso, mecanismos como feature flags, canary releases, métricas de negócio e rollback continuam fundamentais. Eles permitem observar o comportamento real de uma alteração e limitar seu impacto caso algo inesperado aconteça.
No exemplo do frete grátis, não bastaria acompanhar erros HTTP ou latência. Também seria importante observar a proporção de pedidos recebendo o benefício, o valor total concedido e possíveis divergências no cálculo.
Essa etapa fecha uma lacuna importante: uma implementação pode estar tecnicamente saudável e produzir um resultado de negócio incorreto.
Ao combinar verificações antes do merge com observação e mecanismos de contenção depois dele, a equipe consegue construir confiança progressivamente, sem depender de uma única aprovação como garantia de qualidade.
O que uma equipe pode mudar já na próxima sprint
Não é necessário redesenhar todo o processo de engenharia para começar.
Eu iniciaria com três mudanças simples.
Primeiro, escolheria uma feature de negócio e definiria seus critérios de comportamento antes da implementação, garantindo que os testes de aceite sejam derivados desses critérios, não apenas do código gerado.
Depois, analisaria os últimos pull requests que apresentaram problemas em produção ou receberam muitas correções durante a revisão. A pergunta seria quais desses problemas poderiam ter sido detectados automaticamente. A resposta ajuda a priorizar novos testes, contratos e guardrails com base em falhas reais, em vez de adotar ferramentas sem um problema definido.
Por fim, estabeleceria uma política mínima de risco para os PRs. Alterações pequenas e reversíveis seguiriam um fluxo mais simples, enquanto mudanças críticas exigiriam evidências adicionais e, quando necessário, liberação progressiva.
O resultado pode ser acompanhado por indicadores que a equipe já conhece: defeitos identificados depois do merge, retrabalho, tempo de revisão, falhas em produção e duração do ciclo de entrega. O objetivo não é maximizar a quantidade de checks, mas verificar se estamos aumentando a capacidade de entregar mudanças confiáveis sem tornar o processo progressivamente mais lento.
Escalar confiança é o próximo investimento em produtividade
Durante anos, a engenharia de software investiu em reduzir o tempo necessário para escrever, compilar, testar e colocar código em produção. Integração contínua, automação de testes e entrega contínua aumentaram nossa capacidade de produzir mudanças com segurança.
A IA está criando uma nova pressão sobre esse equilíbrio. Quando um agente consegue produzir em minutos algo que uma pessoa levaria horas para implementar, o custo relativo de revisar e validar aquela mudança aumenta.
Podemos responder a isso exigindo mais revisões humanas e limitando a velocidade de produção. Em determinados casos, essa será a decisão correta, principalmente quando ainda não possuímos evidências suficientes para avançar com segurança.
Mas não deveria ser nossa única resposta.
Precisamos investir em especificações melhores, testes independentes, verificações arquiteturais, pipelines orientadas ao risco e mecanismos que validem o comportamento em produção. Essas capacidades devem fazer parte da plataforma de engenharia e ser reutilizadas por diferentes equipes, em vez de depender de esforços individuais a cada mudança.
Não conseguiremos provar automaticamente que qualquer software está correto. A confiança sempre envolverá algum nível de incerteza, e decisões importantes continuarão exigindo julgamento humano.
Entretanto, podemos reduzir significativamente a quantidade de incertezas que precisam ser resolvidas manualmente.
É nesse ponto que as alternativas apresentadas por Kent Beck se conectam. Quanto mais evoluímos nossa capacidade de produzir evidências confiáveis, menos dependemos de conhecer detalhadamente cada linha de código gerada e menor se torna a necessidade de limitar artificialmente a velocidade de implementação.
O próximo grande avanço da engenharia de software não será produzir ainda mais código. Será conseguir confiar, de maneira fundamentada, no código que já somos capazes de produzir.
