As três práticas que nunca esperam gatilho
A confiança na IA não começa no modelo, começa no processo.
É a quarta parte de uma série sobre a metodologia que uso para continuar sendo, de fato, o responsável pelo que um agente de IA produz. Aqui, aprofundo as três práticas citadas na abertura da série, e entrego o guardrail que resolve o problema descrito no artigo anterior.
Quantas vezes você já concordou, em teoria, que “deveria haver mais disciplina” num projeto, e, na prática, isso nunca virou nada além de uma boa intenção que ninguém cobrava de ninguém, nem de si mesmo?
Disclaimer: este texto reflete minha visão prática sobre o tema, construída em projetos pessoais e profissionais. Não representa, necessariamente, a posição oficial de nenhuma organização à qual eu esteja afiliado.
No artigo de abertura desta série, nomeei três práticas baratas o suficiente para nunca precisarem de um evento de risco como justificativa e no artigo anterior, mostrei o que se acumula quando uma delas (a mais específica das três) ainda não tem forma concreta: código duplicado, silenciosamente, apesar de tudo o mais já estar rodando. Chegou a hora de dar forma às três, uma de cada vez.
Guardrails fixos: parar de precisar lembrar de pedir cuidado
Quantas vezes você já pediu, numa conversa com um agente de IA, para ele “ser mais cuidadoso” com alguma coisa, e, três conversas depois, teve que pedir de novo, porque o cuidado nunca tinha virado hábito, só uma exceção daquele dia específico?
Foi essa repetição cansativa que me fez perceber a diferença entre duas formas de trabalhar com um agente: instruções pontuais, que preciso lembrar de repetir a cada nova conversa, e guardrails permanentes, princípios que valem por padrão, entre projetos, até eu dizer explicitamente o contrário.
A diferença entre “pedir cuidado” e “ter cuidado embutido no processo” é a diferença entre boa intenção e metodologia.
Quatro princípios, especificamente, mudaram mais o resultado prático do que qualquer prompt pontual:
Pensar antes de codificar. O agente declara suposições antes de implementar, e apresenta alternativas quando existe mais de uma leitura razoável do pedido, em vez de escolher uma sozinho e seguir em frente. Um pedido ambíguo, interpretado silenciosamente da forma mais conveniente para quem está implementando, gera trabalho que precisa ser refeito porque a interpretação estava errada. Um guardrail que obriga essa declaração explícita transforma um mal-entendido silencioso numa pergunta visível, respondida antes de qualquer código ser escrito.
Simplicidade em primeiro lugar. Nada de abstração para código de uso único, nada de configurabilidade que ninguém pediu. A pergunta de controle que uso: “um engenheiro sênior chamaria isso de complicado demais?” Um agente de IA, sem esse guardrail, tende para o lado oposto: soluções mais genéricas, mais “robustas”, porque essas palavras soam bem, mesmo quando ninguém pediu essa flexibilidade e ninguém vai usá-la.
Mudanças cirúrgicas. Toda linha alterada precisa remontar diretamente ao pedido que a motivou. Um diff que só contém o que foi pedido é um diff que dá para revisar de verdade, e revisar de verdade, não por cima, é a única forma de manter a responsabilidade quando o volume de código produzido cresce rápido. Sem esse guardrail, cada tarefa pequena corre o risco de virar uma oportunidade de “já que estou aqui, vou melhorar isso também”: bem-intencionado, e ainda assim um jeito garantido de tornar cada revisão mais difícil do que precisava ser.
Avaliar um padrão antes de adotá-lo, mesmo quando eu peço por nome. Se peço um padrão específico, a instrução é checar o que o próprio projeto já faz para problemas parecidos antes de aplicá-lo, e me dizer o custo real daquele padrão naquele código.
Recebi de volta, mais de uma vez, um “isso que você pediu custa isso aqui, quer mesmo assim?”: exatamente o atrito produtivo que eu queria, e que raramente recebo de um time humano com pressa de entregar. É este o guardrail que resolve, quando aplicado com intenção, o problema descrito no artigo anterior: antes de escrever uma implementação nova, a pergunta padrão passa a ser se algo parecido já existe no projeto, transformando duplicação de acidente silencioso em decisão explícita.
Nenhum dos quatro depende de eu lembrar de pedir. Todos são o padrão, e é isso que os torna guardrails, e não apenas boas práticas que eu conheço mas às vezes esqueço de aplicar.
Vale nomear os dois jeitos mais comuns de um guardrail não funcionar: o guardrail vago demais para ser aplicável (“seja cuidadoso”, “priorize qualidade”, frases que soam bem mas não dão nenhuma instrução acionável), e o guardrail rígido demais, aplicado sem julgamento em situações que ele nunca foi desenhado para cobrir.
Um guardrail útil precisa ser específico o suficiente para mudar um comportamento observável, e ainda ter espaço para exceção deliberada e documentada, sem virar burocracia que ninguém questiona porque “é a regra”.
Prova, não crença: transformar “acho que corrigi” em prova reproduzível
Código que compila não é código que funciona. Código que “parece” corrigir um bug não é código que corrige um bug, até existir um teste que falhava pelo motivo certo antes da correção, e passa a passar depois. Essa distinção, sozinha, é o que separa quem apenas acredita que corrigiu algo de quem tem uma prova de que corrigiu.
Essa disciplina tem nome: test-driven development, formalizada por Kent Beck em torno de um ciclo simples (vermelho, verde, refatorar). Aqui, virou protocolo obrigatório para todo bug fix, sem exceção: antes de tocar no código de produção, escreve-se um teste que reproduz o problema, roda-se esse teste, e confirma-se que ele falha pela razão certa, não por um erro de digitação, não por uma dependência quebrada. Só então a correção é implementada. O mesmo teste roda de novo para confirmar que passa. A suíte inteira roda para garantir que nada que funcionava antes quebrou no processo.
O passo mais fácil de pular, e o mais importante de não pular, é o “pela razão certa”. Um teste que falha por acidente, e não pelo motivo do bug que você está tentando provar, não prova nada quando volta a passar. Ele só confirma que você mexeu em alguma coisa, não que mexeu na coisa certa.
Num dos oito projetos, um alerta de “métrica abaixo do limite mínimo configurado” disparava sem parar, a cada ciclo de correção automática, em vez de reportar uma vez e esperar um intervalo razoável antes de repetir. A primeira tentativa de testar a correção usou um teste de integração baseado em tempo real, e não provou nada. O próprio mecanismo de retry do sistema, por coincidência, já limitava a frequência das tentativas a algo parecido com o intervalo esperado, mascarando exatamente a diferença que o teste precisava mostrar entre o comportamento antigo e o novo.
O teste passava. A correção parecia funcionar. E, ainda assim, não havia prova nenhuma de que o comportamento certo estava acontecendo pela razão certa: só uma coincidência de timing que por acaso produzia o resultado esperado. A solução foi extrair a lógica de decisão para uma função pura, testável sem depender de tempo real. Só aí o comportamento antigo e o novo ficaram genuinamente distinguíveis.
Um agente de IA pode gerar um relatório de correção articulado, coerente, convincente, e ainda assim estar descrevendo um cenário que não corresponde exatamente ao que o commit real faz. Não é má-fé: é o mesmo overclaiming que descrevi em Disciplina em rajada: por que o rigor não nasce junto com o código.
Um teste que falha pela razão certa antes da correção, e passa a passar depois, é o único antídoto que não depende de detectar esse overclaiming pela leitura atenta de um relatório. Depende de uma prova que existe independentemente de quem, ou o que, escreveu a explicação.
Vale registrar que TDD como religião universal tem seus críticos sérios, não só entusiastas. David Heinemeier Hansson chamou o fundamentalismo do “teste primeiro” de campanha moralista pouco realista, argumentando que testar tudo antes de escrever qualquer linha de código pode empurrar o design para indireções e mocks excessivos, artificiais. Eu não discordo do risco.
A diferença é onde apliquei a régua. Não é “todo código nasce de um teste antes de existir”: é, especificamente, “toda correção de um bug de comportamento precisa provar, com um teste que falhava pela razão certa, que o bug era real e que a correção o fechou”. É uma régua bem mais estreita que a bandeira universal de Beck, e por isso mais fácil de manter íntegra ao longo do tempo, sem virar dogma nem munição para a crítica de DHH.
Isso também bate com a pesquisa: uma meta-análise de Rafique e Mišić mostra efeito real, mas modesto, de TDD sobre qualidade externa em geral. O ganho que vejo na prática não vem de TDD universal. Vem especificamente dessa régua estreita aplicada a correção de bug.
Registrar decisão com prazo curto: nem em tempo real, nem indefinidamente
A terceira prática sempre-ativa é a mais fácil de subestimar, porque parece, à primeira vista, uma versão mais frouxa da disciplina de registro em lote que descrevo no artigo (mais para frente) ADRs em lote, e a regra da visibilidade. Não é. É uma prática diferente, com uma régua própria.
Em Disciplina em rajada: por que o rigor não nasce junto com o código, expliquei, usando Nonaka e Takeuchi, por que a documentação de uma decisão sempre chega um pouco depois da decisão em si. O “por quê” vive na cabeça de quem decidiu, e só vira texto legível quando alguém é forçado a explicar. Isso é inevitável. O que não é inevitável é o tamanho desse atraso.
Nenhum dos oito projetos registrou uma decisão relevante no exato momento em que foi tomada. Isso simplesmente não acontece na prática, e insistir nisso como meta seria ignorar como conhecimento tácito realmente se converte em conhecimento explícito. Mas também não faz sentido deixar o atraso indefinido, porque uma decisão não registrada é, para um agente sem memória de sessões anteriores, uma decisão que nunca existiu. Ele vai propor exatamente a mesma coisa que já foi decidida e rejeitada, sem saber que essa conversa já aconteceu.
O que venho usando é um teto: se uma decisão relevante ainda não foi escrita em alguns dias, isso já é atraso, não só falta de tempo. O número muda com o risco do projeto (trato disso com mais detalhe no artigo Calibrando a intensidade ao risco real), mas o princípio é o mesmo em qualquer risco: um prazo curto e explícito, não tempo real e não indefinido, é o único jeito de dar espaço para o atraso natural que Nonaka e Takeuchi descrevem, sem deixar esse espaço virar desculpa permanente para nunca escrever nada.
O que essas três práticas têm em comum
Nenhuma das três depende de um evento de risco para justificar seu custo. Guardrails fixos custam a atenção de escrevê-los uma vez, não a cada conversa. Um teste que prova uma correção de bug custa menos tempo do que descobrir, mais tarde, que a correção não funcionava.
Um prazo de uma semana para registrar uma decisão custa uma interrupção pequena, não uma reconstrução arqueológica de por que algo foi feito assim, meses depois. É exatamente por serem baratas que essas três práticas não deveriam esperar nenhum gatilho. O resto da disciplina, mais cara, é isso que os eventos de risco existem para justificar.
Conclusão
Guardrails fixos, prova em vez de crença, e um prazo curto para registrar decisão: as três coisas que valem sempre, porque custam pouco o suficiente para nunca precisarem de uma desculpa. Tudo o que é mais caro do que isso (auditoria com várias frentes, consolidação retroativa de registros de arquitetura, revisão de documentação como caça a bugs) precisa de um evento de risco real para justificar o investimento.
O próximo artigo desta série é outro caso aplicado: uma decisão que a maioria dos times nem percebe como decisão (atualizar uma dependência), e como o mesmo guardrail de avaliar um padrão antes de adotar se aplica, sem alteração conceitual nenhuma, ao lugar onde ninguém pensava em procurá-lo.
Tenham um excelente dia!
Eu sou Fernando Cerqueira e entrego estratégias digitais para os desafios do presente, com propostas de inovação para um futuro sustentável. Como arquiteto sênior, aproveito meus mais de 30 anos de experiência em arquitetura e desenvolvimento de software para projetar e implementar soluções baseadas em nuvem que ajudam os clientes a transformar seus negócios com tecnologia.
Este texto foi escrito com apoio do Claude Code, a partir da minha experiência, minhas decisões e revisão: o próprio processo que a série descreve.
Nesta série
- Metodologia de Desenvolvimento Assistido por IA Centrada na Decisão Humana
- Disciplina em rajada: por que o rigor não nasce junto com o código
- O código duplicado que a IA cria enquanto parece produtiva
- As três práticas que nunca esperam gatilho (este artigo)
- Quem autorizou essa atualização de dependência? Pode ter sido sua IA
- Os quatro eventos de risco e a auditoria multi-frente
- Seu agente de IA resolve a issue de verdade, ou só parece resolver?
- ADRs em lote, e a regra da visibilidade
- IA no time não reduz o bus factor do seu projeto — pode aumentar
- Calibrando a intensidade ao risco real
- O alinhamento entre produto e engenharia começa onde a decisão fica registrada
- Segurança psicológica também vale para o time formado por você e sua IA
- Releitura: o papel do humano, os sinais que funcionam, e onde a metodologia ainda é fraca
Referências citadas
- Kent Beck, Test-Driven Development: By Example (Addison-Wesley, 2002): ISBN 978-0321146533
- Yahya Rafique & Vojislav Mišić, “The Effects of Test-Driven Development on External Quality and Productivity: A Meta-Analysis”, IEEE Transactions on Software Engineering, vol. 39, n. 6 (2013)
- David Heinemeier Hansson, “TDD is dead. Long live testing.” (2014): https://dhh.dk/2014/tdd-is-dead-long-live-testing.html
- Nonaka & Takeuchi, sobre a conversão de conhecimento tácito em conhecimento explícito: citado com mais profundidade em Disciplina em rajada: por que o rigor não nasce junto com o código.






