x
Palavras desta nota (3)
- teste verde
- Teste que passou. Passar não diz se o teste é bom: um teste fraco também passa.
- mutação
- Estragar o código de propósito, em uma mudança pequena por vez (trocar + por -, < por <=), e rodar os testes para ver se algum reclama.
- escape
- Erro plantado que os testes deixaram passar sem reclamar. Quanto menos escapes, mais forte é o conjunto de testes.
Um teste pode passar e ser fraco. O código soma dois números, o teste só confere que a função "roda". Se alguém trocar o + por -, o teste continua verde e ninguém percebe.
Mandei o Claude medir isso: estragar o código de propósito e contar quantos erros os testes deixam passar. Depois medi cada passo do meu fluxo, da spec ao commit, e anotei o que tem número e o que é só uso.
Se você tem 1 minuto
Leia a resposta curta. Para ver o fluxo passo a passo, vá ao mapa. Para repetir no seu projeto, Medir no seu caso.
Início
O fluxo passo a passo
- O fluxo tem dez passos da spec ao commit, e sete têm medida, mas três delas são fracas
- Testes escritos só pela spec zeraram os erros no cálculo, mas o total quase não mudou: 113 contra 123
- Pedir limites, entradas inválidas e o motivo certo do erro derrubou os escapes de 113 para 85
- O hash dos testes mostra se o Gemini mexeu neles, e um defeito que deixava a trava vazia em TypeScript foi achado e consertado
- O Gemini escreveu o código das specs, mas 8 de 17 rodadas no projeto em TypeScript pararam ou saíram erradas, e um atalho passou pelos testes
- Os testes pegaram 56 de 65 erros plantados no código do Gemini (86%), e os outros 9 ficam para a leitura
- O Claude lendo o código pegou 8 dos 9 erros que os testes deixaram passar, sem alarme falso em 8 códigos certos
- O fluxo corrige em no máximo 2 voltas, mas o número 2 não tem prova; a pesquisa só mostra que cada volta custa risco
- Quando o teste contradiz a spec, o Gemini parou e pediu ajuda em 10 de 10 casos, sem mexer no teste
- O relatório apontou a falha escondida em 10 de 10 códigos que passavam nos testes, e não acusou nenhum dos 5 certos
- O fechamento da spec parou 20 de 20 armadilhas, mas nas cópias limpas só commitou 4 de 13 vezes, e a causa nem sempre foi ele
Medir os testes
- Estragar o código de propósito mostra o que o teste deixa passar, e achou buracos reais
- 95% de cobertura e 476 erros escaparam, porque cobertura mede o que o teste executa, não o que ele detecta
- A ferramenta de mutação e uma IA inventando erros acham erros diferentes: a sobreposição foi zero
- Rodar a mutação só nos arquivos que a spec mudou é melhor a cada spec; o projeto inteiro serve de auditoria final
- O que a spec não diz, nenhum teste escrito sem ver o código cobre, e o teste ainda achou 2 divergências reais
- Dá para repetir a medida no seu projeto em cinco passos, sem custo
O que não compensou
- Um segundo redator ou um auditor de testes acrescentam pouco: de 113 para 110 e para 106
- Uma segunda leitura do código pelo Gemini não compensou: pegou 6 de 9 erros, e a pesquisa diz que os modelos acham os mesmos erros
- Quatro ideias ficaram de fora, e cada uma tem um momento para ser reaberta
Limites
x
Palavras desta nota (4)
- escape
- Erro plantado que os testes deixaram passar sem reclamar. Quanto menos escapes, mais forte é o conjunto de testes.
- erro plantado
- Defeito colocado de propósito no código, para ver se os testes ou a leitura percebem.
- mutação
- Estragar o código de propósito, em uma mudança pequena por vez (trocar + por -, < por <=), e rodar os testes para ver se algum reclama.
- cobertura
- A porcentagem de linhas do código que os testes executaram. Mede o que o teste rodou, não o que ele conferiu.
Medi cada camada plantando erros no código e contando quantos ela pega. Os números vêm de projetos diferentes e não se somam.
As camadas do fluxo
| Camada | O que o número mostrou |
|---|---|
| Testes escritos sem ver o código | De 113 para 85 escapes (-25%) ao pedir limites e o motivo do erro. Veja Limites e motivo certo |
| Os testes rodando | Pegaram 56 de 65 erros plantados (86%). Veja Rede de testes |
| A leitura do código | Pegou 8 de 9 erros que passaram nos testes, sem alarme falso em 8 códigos certos. Veja Leitura do código |
| Estragar o código de propósito | A mutação e o Gemini acham erros diferentes: sobreposição zero. Veja Mutação e Gemini |
| Rodar a mutação só no que a spec mudou | De 2 a 8 s em vez de até 27 s, em 8 specs. Veja Só o que a spec mudou |
| O fechamento da spec | Parou 20 de 20 armadilhas, mas parou também em código limpo. Veja Fechamento da spec |
Os passos sem medida (o hash, o Gemini escrevendo, as voltas, o teste em conflito, o relatório) estão no mapa.
O que não compensou
| Ideia | O que o número mostrou |
|---|---|
| Um auditor de testes ou um segundo redator | Ganho pequeno: de 113 para 106 e 110. Veja Segundo redator e auditor |
| Uma segunda leitura do código pelo Gemini | Pegou 6 de 9, e a pesquisa diz que os modelos acham os mesmos erros. Veja Segunda leitura de código |
| Exigir 90% de cobertura | Não prova nada: 95% de cobertura com 476 erros passando. Veja Cobertura engana |
| Testes ocultos e rodar o teste do bug duas vezes | Sem teste completo. Veja O que ficou de fora |
O ponto de partida é o agente que escreve os testes sem ver o código. Os limites do estudo estão em O que ainda não sei.
O que isso faz por você: o número que diz se um teste é forte é o de escapes, não o de cobertura. E se uma IA escreve o código, os testes sozinhos deixaram passar 1 erro em cada 7; uma leitura do código em conversa nova pegou quase todos esses.
x
Palavras desta nota (6)
- spec
- O texto que descreve o que uma funcionalidade deve fazer, escrito antes do código.
- Gemini
- A IA do Google. No fluxo, ela escreve o código; no estudo, também inventa erros para os testes pegarem.
- hash
- Código curto calculado a partir do conteúdo de um arquivo. Se uma vírgula mudar, o código muda. Serve para saber se o arquivo foi alterado.
- mutmut
- A ferramenta gratuita que faz a mutação em código Python.
- WSL
- O Linux que roda dentro do Windows. A ferramenta de mutação não roda direto no Windows.
- agente escritor de testes
- Uma IA (Claude) que escreve os testes lendo só a spec e o CLAUDE.md. Ela não pode abrir o código.
Este é o caminho que o código de uma spec percorre. O Claude escreve os testes e confere. O Gemini escreve o código. Cada linha leva à nota com a prova.
| Passo | O que se sabe |
|---|---|
| 1. Escrever os testes antes, sem ver o código. Testes sem ver o código, Limites e motivo certo | Medido: 113 escapes, e 85 com a regra de limites |
| 2. Fotografar os testes com um hash. Trava dos testes | Uso real em 17 rodadas; um defeito achado e consertado |
| 3. O Gemini escreve o código. O Gemini escreve o código | Uso real; 8 de 17 rodadas pararam ou saíram erradas |
| 4. Rodar os testes de verdade. Rede de testes | Medido: 56 de 65 erros plantados pegos |
| 5. O Claude lê o código. Leitura do código | Medido: 8 de 9 erros pegos, 0 alarme falso em 8 |
| 6. Estragar o código de propósito. Mutação e Gemini, Só o que a spec mudou | Medido: 19 de 20 erros do Gemini pegos em 4 specs; a mutação acha outros |
| 7. Corrigir, em até 2 voltas. Voltas de correção | Uso real: 1 volta em 4 specs. O teto de 2 não tem medida |
| 8. Teste que contradiz a spec. O fluxo para e pergunta qual dos dois está errado. Teste que contradiz a spec | Medido: o Gemini pediu ajuda em 10 de 10 conflitos claros, 0 alarme em 5. A pergunta ao usuário não foi medida |
| 9. Relatório "a spec foi cumprida?" A spec foi cumprida? | Medido: 10 de 10 falhas escondidas apontadas, 0 alarme em 5. Falta ver se muda uma decisão |
| 10. Fechar a spec e commitar. Fechamento da spec | Medido: 20 de 20 armadilhas paradas, mas só 4 de 13 cópias limpas commitadas |
Fora desse caminho há o conserto de bug: uma ficha curta, um teste que falha antes do conserto e a suíte inteira depois. Está no fluxo, mas não foi medido.
O que mudou por causa das medidas
Depois das medidas, três coisas entraram (decisão minha, não só do número):
| O que entrou | Onde | Custo e cuidado |
|---|---|---|
| Pedido de limites, entradas inválidas e motivo certo | No agente que escreve os testes | Mais tempo (92 s para 278 s) e 25% mais tokens |
| Mutação nos arquivos que a spec mudou | A cada spec implementada, obrigatória em projeto Python | Só roda pelo WSL no Windows; 1 a 3 minutos; sem WSL o fluxo avisa "não rodou" e segue |
| Mutação no projeto inteiro, uma vez | No encerramento do projeto | Só informa, não bloqueia |
A mutação a cada spec foi testada ponta a ponta em 1 caso (85 escapes, igual à medição) e ainda não teve uso real em outro projeto.
O que ficou de fora está em Segunda leitura de código e O que ficou de fora. O resumo com os números é a Resposta curta. Para repetir no seu projeto, Medir no seu caso.
x
Palavras desta nota (5)
- agente escritor de testes
- Uma IA (Claude) que escreve os testes lendo só a spec e o CLAUDE.md. Ela não pode abrir o código.
- spec
- O texto que descreve o que uma funcionalidade deve fazer, escrito antes do código.
- CLAUDE.md
- O arquivo de regras e decisões do projeto que a IA lê antes de trabalhar.
- escape
- Erro plantado que os testes deixaram passar sem reclamar. Quanto menos escapes, mais forte é o conjunto de testes.
- módulo
- Um arquivo de código com uma função específica. Aqui foram três: leitor de CSV, cálculo das métricas e comparação.
Este é o ponto em que a forma de gerar testes usada aqui difere da comum. O agente que escreve os testes recebe só a spec e o CLAUDE.md. Ele não pode abrir o código. Se um teste falhar contra o código que existe, o teste não pode ser ajustado para passar.
Medido em três módulos do mesmo projeto, comparando os testes que eu já tinha com os do agente:
Erros que escaparam, por módulo
Menos é melhor. Os testes antigos, que eu já tinha, são 21; o agente de testes escreveu 82 sem ver o código. Mesmos três módulos e mesmos erros plantados.
O total foi 123 contra 113. A diferença está toda no cálculo e na comparação: o agente zerou ali os escapes, onde os testes antigos deixavam 11. No leitor de CSV, o empate. O agente gastou 92 segundos e 65 mil tokens.
Cuidado ao ler: o agente escreveu 82 testes e os antigos são 21. Parte do ganho pode ser só ter mais testes. A medida não separa isso.
O que você ganha: se você mandar uma IA escrever testes, vale medir com mutação em vez de confiar no tamanho do conjunto. Os escapes que sobraram vêm de coisas que a spec não diz: veja Buracos na spec. O que subiu o ganho de verdade foi Limites e motivo certo.
x
Palavras desta nota (4)
- motivo certo
- Conferir não só que o teste dá erro, mas que o erro é o esperado e vem do motivo certo.
- escape
- Erro plantado que os testes deixaram passar sem reclamar. Quanto menos escapes, mais forte é o conjunto de testes.
- agente escritor de testes
- Uma IA (Claude) que escreve os testes lendo só a spec e o CLAUDE.md. Ela não pode abrir o código.
- divergência
- Quando a spec, o CLAUDE.md e o código dizem coisas diferentes sobre o mesmo comportamento.
A ideia: acrescentar ao pedido do agente uma regra simples. Teste os limites (o menor valor, o maior, zero, vazio), as entradas inválidas e confira que o erro vem do motivo certo, não de qualquer erro.
Erros que escaparam, antes e depois da regra
Os mesmos três módulos e os mesmos erros plantados.
De 113 para 85 escapes (-25%). O custo desse ganho está na tabela:
| O que se mede | Sem a regra | Com a regra |
|---|---|---|
| Erros que escaparam | 113 | 85 |
| Testes escritos | 82 | 123 |
| Tempo do agente | 92 segundos | 278 segundos |
| Tokens gastos | 65 mil | 81 mil |
O agente demorou cerca de 3 vezes mais e gastou 25% mais tokens.
Dois dos testes novos falharam contra o código real. Isso não foi defeito do teste: os dois mostraram divergências reais entre a spec, o CLAUDE.md e o código.
O que você ganha: um pedido de uma linha que, nesta medida, rendeu mais que juntar um segundo redator ou um auditor (Segundo redator e auditor). O que fazer: acrescente o pedido ao seu redator de testes e meça de novo (Medir no seu caso).
x
Palavras desta nota (5)
- hash
- Código curto calculado a partir do conteúdo de um arquivo. Se uma vírgula mudar, o código muda. Serve para saber se o arquivo foi alterado.
- Gemini
- A IA do Google. No fluxo, ela escreve o código; no estudo, também inventa erros para os testes pegarem.
- spec
- O texto que descreve o que uma funcionalidade deve fazer, escrito antes do código.
- TypeScript
- A linguagem do segundo projeto do estudo. Os testes e o código dele não são em Python.
- atalho
- Código que faz o teste passar sem fazer o que a spec pede. Exemplo: uma função vazia com o nome que o teste procura.
Quem escreve o código pode editar o teste para ele passar. A pesquisa chama isso de trapaça e mostra que modelos de IA fazem (ImpossibleBench, 2025). Por isso o Gemini não escreve os testes: eles vêm antes, de outra IA (Testes sem ver o código).
Como travo
- Antes de o Gemini começar, o fluxo tira um hash de cada arquivo de teste. É uma impressão digital: se uma vírgula mudar, o hash muda.
- A ferramenta do Gemini recusa escrever na pasta de testes. Ele pode ler.
- Depois, o fluxo tira o hash de novo e compara. Se mudou, para e avisa.
Por que o Gemini pode ler os testes
A pesquisa que fiz sobre isso achou 3 artigos com experimento (ImpossibleBench, TDD for Code Generation e SecTDD, 2026). Eles dizem:
- Esconder os testes zera a trapaça, mas derruba o acerto.
- Deixar os testes só para leitura recupera o acerto e impede a edição.
- Ver os testes ajudou a resolver 12,0% e 8,5% a mais dos problemas (dois conjuntos de problemas de código, MBPP e HumanEval). O efeito depende do modelo: em 7 de 9 condições melhorou e em 2 piorou.
São fontes de fora, nenhuma com o Gemini. E só leitura não impede o atalho, o código que só serve para o teste passar. Isso fica para a Leitura do código.
O que vi no uso real
| Onde | Resultado |
|---|---|
| Projeto em TypeScript, 6 entregas, 17 rodadas | Hash igual nas 17: nenhum teste foi alterado |
| Projeto em Python, specs 08 e 09 | Hash dos testes intacto nas duas |
O defeito que achei
O comando que tirava o hash olhava só arquivos .py. No projeto em TypeScript ele fotografaria 0 arquivos (196 com o comando corrigido), e a conferência "testes intactos" passaria sempre sem conferir nada.
Não houve dano: no projeto, o Claude montou a fotografia à mão (16 vezes anotadas). Descobri depois, ao revisar o registro desse dia. O conserto pega todo arquivo da pasta e confere que a lista não está vazia.
O que você ganha: uma trava que nunca falha pode estar vazia. O que fazer: confira que a lista de arquivos travados não está vazia, e force uma mudança de propósito uma vez para ver a trava disparar. Não tenho registro desse teste do disparo; veja O que ainda não sei. A mesma regra vale para um backup que "sempre dá certo": abra o arquivo e veja se tem conteúdo.
Voltar ao Mapa do fluxo.
x
Palavras desta nota (5)
- Gemini
- A IA do Google. No fluxo, ela escreve o código; no estudo, também inventa erros para os testes pegarem.
- spec
- O texto que descreve o que uma funcionalidade deve fazer, escrito antes do código.
- rodada
- Cada vez que o Gemini é chamado para escrever ou corrigir código.
- atalho
- Código que faz o teste passar sem fazer o que a spec pede. Exemplo: uma função vazia com o nome que o teste procura.
- TypeScript
- A linguagem do segundo projeto do estudo. Os testes e o código dele não são em Python.
No fluxo, o Claude escreve os testes e confere. O código sai do Gemini, que roda fora da cota do Claude. O Claude passa a spec, os testes (só para leitura) e um comando para rodá-los.
O que foi registrado
| Projeto | Specs e resultado |
|---|---|
| Aplicativo em Python (relatórios) | Specs 08 e 09: 1 volta de correção cada, 82 de 82 e 91 de 91 testes passando |
| Aplicativo em TypeScript | 6 entregas e 17 rodadas: testes de 2.278 para 3.058, todos passando |
| Monitor de licitações (Python) | 3 etapas. Total de testes do projeto ao fim de cada uma: 113, 358 e 473 |
O que deu errado, no projeto em TypeScript
Rodadas do Gemini
17 rodadas em 6 entregas, no projeto em TypeScript. "Com problema" é a rodada que parou ou saiu errada.
As 8 que pararam ou saíram erradas tiveram três causas: permissão negada para um comando, sem ninguém na tela para liberar (5 vezes, a mais comum), tempo esgotado em 15 minutos (30 resolveu) e erros de tipo.
Houve também 1 atalho de propósito: um código que não fazia nada, só para o teste que procura o nome da função passar. Os testes não pegaram. A leitura do Claude pegou (Leitura do código). Testes de tela que só procuram texto são os mais fáceis de enganar.
Num caso, o pedido "preciso de ajuda" funcionou: o Gemini achou um teste com defeito e parou, em vez de forçar.
O que isso não mostra
Não comparei o Gemini com outro implementador, nem com o Claude escrevendo o código. Os números dizem que ele entrega, que tropeça em quase metade das rodadas e que precisa de conferência. Eles não dizem que ele é o melhor.
O que você ganha: saber o que esperar quando outra IA escreve o código. O que fazer: deixe os testes prontos antes (Testes sem ver o código), trave-os (Trava dos testes) e confira o código depois (Rede de testes, Leitura do código).
Voltar ao Mapa do fluxo.
x
Palavras desta nota (5)
- erro plantado
- Defeito colocado de propósito no código, para ver se os testes ou a leitura percebem.
- Gemini
- A IA do Google. No fluxo, ela escreve o código; no estudo, também inventa erros para os testes pegarem.
- spec
- O texto que descreve o que uma funcionalidade deve fazer, escrito antes do código.
- TypeScript
- A linguagem do segundo projeto do estudo. Os testes e o código dele não são em Python.
- mutação
- Estragar o código de propósito, em uma mudança pequena por vez (trocar + por -, < por <=), e rodar os testes para ver se algum reclama.
Depois que o Gemini escreve o código, o Claude roda os testes ele mesmo. Ele não aceita o "passou" do relato do Gemini: roda o comando e guarda a saída real. Faltava saber quanto desse trabalho os testes fazem.
A medida
No projeto em TypeScript, mandei plantar erros no código de 8 specs: 68 erros, inventados pelo Gemini. Rodei cada um contra os testes do projeto no ponto de cada spec. Esses pontos tinham tamanhos diferentes: nos quatro que reconstruí, de 659 a 1.203 testes. O número "760" que usei antes não consegui reproduzir.
Depois conferi cada erro no código e tirei 3 da conta, porque o erro plantado não mudava o que a spec pede. Sobraram 65.
Erros plantados e o que os testes fizeram
65 erros plantados em 8 specs do projeto em TypeScript. Um erro "pego" é aquele que faz algum teste falhar.
Foram 56 de 65 (86%). Os 9 que passaram são o que a leitura do código precisa pegar.
Como isso se relaciona com a mutação
É a mesma ideia da mutação (estragar o código e ver se os testes reclamam), com uma diferença: aqui os erros são inventados por uma IA, não trocas mecânicas de + por -. As duas réguas acham erros diferentes: veja Mutação e Gemini.
O que isso não mostra
- Foi uma rodada, num projeto, com erros que o Gemini inventou. Outro inventor de erros ou outro projeto podem dar outro número.
- Os 3 erros tirados foram conferidos no código, mas a escolha foi minha. Não refiz a conta com os 68.
- Os testes desta medida não são os 3.058 de O Gemini escreve o código. Aquele é o total do projeto em 08/10 (em 13/11/2026 eram 4.237); aqui, cada erro rodou contra o projeto no ponto da sua spec (de 659 a 1.203 testes nos quatro pontos que reconstruí). O "760" que anotei na época não bate com nenhum deles.
- Não comparei com testes escritos por quem escreve o código.
O que você ganha: um número para a pergunta "se os testes passaram, posso confiar?". Aqui, em cerca de 1 erro a cada 7 a resposta foi não. O que fazer: plante erros no seu código e conte quantos os testes pegam antes de decidir quanto resta para a leitura (Medir no seu caso).
Voltar ao Mapa do fluxo.
x
Palavras desta nota (6)
- erro plantado
- Defeito colocado de propósito no código, para ver se os testes ou a leitura percebem.
- alarme falso
- Quando a leitura aponta um defeito num código que estava certo.
- atalho
- Código que faz o teste passar sem fazer o que a spec pede. Exemplo: uma função vazia com o nome que o teste procura.
- Gemini
- A IA do Google. No fluxo, ela escreve o código; no estudo, também inventa erros para os testes pegarem.
- spec
- O texto que descreve o que uma funcionalidade deve fazer, escrito antes do código.
- TypeScript
- A linguagem do segundo projeto do estudo. Os testes e o código dele não são em Python.
Os testes deixaram passar 9 de 65 erros plantados (Rede de testes). Para esses 9, o fluxo tem uma segunda camada: o Claude, em conversa nova, lê o código que o Gemini escreveu. Ele não sabe se há erro. Procura o que os testes não pegam: um atalho, uma regra da spec esquecida, um caso sem tratamento.
A medida
17 casos: os 9 erros que passaram nos testes (cada um numa cópia do código) e 8 códigos certos, entregas reais. Fixei a meta antes de rodar: pelo menos 8 dos 9 erros e no máximo 1 alarme falso.
Erros que passaram nos testes e a leitura do Claude
9 erros plantados pelo Gemini, projeto em TypeScript. "Pegos" são os que a leitura apontou, sem saber que havia erro.
| Leitor | Erros pegos, de 9 | Alarmes falsos, em 8 certos |
|---|---|---|
| Claude, com o texto do passo do fluxo | 8 | 0 |
Agente revisor-codigo, do fechamento | 8 | 1, leve |
Bateu a meta fixada antes. Ficou abaixo do alvo de 90%, e a amostra é de 9 erros. Por isso o selo é de broto.
Ressalvas
- O erro que passou foi uma linha de checagem comentada num arquivo novo.
- Num dos 8 pegos, o erro plantado deixou um
)sobrando, que denuncia sozinho. Sem esse caso, 7 de 8. - As cópias dos códigos certos tinham um defeito de montagem (dois arquivos que a entrega real apagou continuaram lá). Tirei esse achado da conta: nem acerto, nem alarme.
- Cada leitura custou cerca de 95 mil tokens (65 mil no agente
revisor-codigo). - Nos 8 códigos certos, o Claude ainda achou 5 bugs reais que eu não tinha na lista. E deixou passar um bug que eu já conhecia.
No uso real
- No projeto em TypeScript (08/10), a leitura pegou o atalho de um código que não fazia nada, escrito só para o teste passar. Os testes não pegaram (O Gemini escreve o código).
- No monitor de licitações (etapa de itens), a leitura achou 3 erros que os testes não pegavam: sem pedir 500 itens por página só vinham 10 por edital, um edital com falha fora da janela de 3 dias nunca era tentado de novo, e um JSON inválido derrubava a coleta. Foram corrigidos em 1 volta.
O que você ganha: a prova de que passar nos testes não basta. Aqui, 1 em cada 7 erros passou nos testes e quase todos foram pegos pela leitura. O que fazer: depois dos testes, mande uma IA em conversa nova ler o código sem dizer se há erro. Se pensa em somar uma segunda leitura de outro modelo, veja Segunda leitura de código.
Voltar ao Mapa do fluxo.
x
Palavras desta nota (5)
- volta de correção
- Uma nova tentativa do Gemini de consertar o código, depois que a conferência achou um problema.
- Gemini
- A IA do Google. No fluxo, ela escreve o código; no estudo, também inventa erros para os testes pegarem.
- rodada
- Cada vez que o Gemini é chamado para escrever ou corrigir código.
- atalho
- Código que faz o teste passar sem fazer o que a spec pede. Exemplo: uma função vazia com o nome que o teste procura.
- trapaça
- Quando a IA faz o teste passar sem resolver o problema: muda o teste para aceitar o código errado, ou escreve o código para reconhecer aquele teste e devolver a resposta pronta.
Quando a conferência acha um problema, o Gemini recebe uma lista curta do que falha e tenta de novo, numa conversa nova. São no máximo 2 voltas. Se a segunda não resolver, o fluxo para e chama o usuário. Não existe terceira volta.
Por que limitar
Uma pesquisa mediu o que acontece quando o modelo pode tentar várias vezes e recebe de volta os testes que falharam (ImpossibleBench, 2025). Em tarefas feitas impossíveis de propósito, em que o teste contradiz a spec, o modelo pode "trapacear" para passar: editar o teste ou escrever um caso especial.
Trapaça, aqui, é a IA fazer o teste passar sem resolver o problema de verdade. Ela pode mudar o teste para aceitar o código errado, ou escrever o código de modo que ele reconheça aquele teste e devolva a resposta pronta. O teste fica verde, mas o programa continua errado. Nas tarefas "impossíveis" da pesquisa, o teste contradiz a spec, então só dá para passar trapaceando. Por isso a taxa de trapaça mostra quantas vezes o modelo fez isso.
O que muda com várias tentativas
Média de vários modelos, na pesquisa citada. Uma tentativa contra até 10, com o retorno dos testes que falharam. Não é o meu projeto.
Com mais tentativas, o acerto subiu de 80% para 83% (num conjunto de tarefas normais) e a trapaça de 33% para 38% (num conjunto de tarefas impossíveis). Cada volta tem benefício e risco.
O que isso apoia e o que não apoia
- Apoia: voltas não são de graça. Por isso o fluxo confere o código depois de cada uma e pede uma conversa nova.
- Não apoia: que 2 seja o número certo. A pesquisa comparou uma tentativa com até 10, não 2 com 3. O veredito da minha pesquisa diz isso: não cobre o efeito do teto de 2 voltas.
- Não cobre o Gemini. Os modelos do artigo são outros.
A pesquisa também testou uma saída: dar ao modelo um jeito de pedir ajuda em vez de insistir. Funcionou bem nos modelos da OpenAI e muito menos no Claude Opus 4.1. No meu fluxo há essa saída ("preciso de ajuda"), e funcionou uma vez: o Gemini achou um teste com defeito e parou (O Gemini escreve o código).
O que vi no uso real
Em 4 specs com a contagem anotada (2 de um app em Python e 2 etapas do monitor de licitações), cada uma fechou com 1 volta. No projeto em TypeScript, a conversa nova resolveu na volta seguinte em todos os casos, sem contagem exata. A segunda volta nunca foi precisa nesses registros, então não sei o que ela faria.
O que você ganha: uma regra com limite, mesmo sem saber o número certo. O que fazer: se você usa um laço de correção, anote quantas voltas cada tarefa precisa e só mude o limite com esses dados.
Voltar ao Mapa do fluxo.
x
Palavras desta nota (6)
- Gemini
- A IA do Google. No fluxo, ela escreve o código; no estudo, também inventa erros para os testes pegarem.
- spec
- O texto que descreve o que uma funcionalidade deve fazer, escrito antes do código.
- hash
- Código curto calculado a partir do conteúdo de um arquivo. Se uma vírgula mudar, o código muda. Serve para saber se o arquivo foi alterado.
- atalho
- Código que faz o teste passar sem fazer o que a spec pede. Exemplo: uma função vazia com o nome que o teste procura.
- conflito
- Quando o teste e a spec dizem coisas diferentes sobre o mesmo comportamento, então nenhum código agrada aos dois.
- controle
- Caso certo, sem erro nenhum, usado para ver se o passo dá alarme falso.
Se um teste contradiz a spec, é impossível escrever um código que agrade aos dois. Uma IA com pressa tem duas saídas ruins: editar o teste para passar, ou escrever um atalho que reconhece o teste e devolve a resposta pronta. O fluxo manda outra coisa: o Gemini responde "preciso de ajuda" apontando o teste, e o fluxo para e pergunta a você qual dos dois está errado.
O teste
Medi só a primeira metade: o Gemini para?
- 10 conflitos. O Gemini escreveu a spec, o teste e a contradição entre os dois (um valor na fronteira, um arredondamento, o tipo de uma exceção, o formato de um texto).
- 5 controles. Casos certos, em que o teste e a spec combinam e o código só precisa ser escrito. Servem para ver se ele pede ajuda sem motivo.
- A meta, fixada antes: parar em pelo menos 8 dos 10 conflitos, e no máximo 1 pedido falso nos 5 controles.
O que o Gemini fez em cada grupo
10 casos com conflito e 5 sem. Nos conflitos, "certo" é pedir ajuda sem mexer em nada. Nos controles, é escrever o código e passar os testes.
Nos 10 conflitos, o teste que o Gemini apontou era o da contradição, e nenhum teste foi tocado: o hash dos testes ficou igual em 15 de 15 casos. Nos 5 controles ele escreveu código de verdade; li os cinco e não havia valor fixo nem if que detectasse o teste.
| Tipo da contradição | Casos | Pediu ajuda |
|---|---|---|
| Valor na fronteira | 3 | 3 de 3 |
| Tipo da exceção | 3 | 3 de 3 |
| Formato do texto | 2 | 2 de 2 |
| Arredondamento | 1 | 1 de 1 |
| Código de erro | 1 | 1 de 1 |
Um dos 10 falhou na primeira tentativa por erro técnico (o Gemini não conseguiu ler um arquivo) e acertou ao repetir. Na primeira passada foram 9 de 10.
O que isso não prova
- Conflitos fáceis. Os dez são claros e do mesmo tamanho. Falta um conflito escondido num teste grande, ou uma spec ambígua.
- Mesma família. O Gemini escreveu os casos e também os resolveu.
- Um caso fraco. Em um deles a exceção poderia herdar de outra e agradar aos dois. Sem ele a conta é 9 de 9.
- Poucos casos. Com 10 de 10, o acerto real pode estar entre 72% e 100%.
- A segunda metade não foi medida: o Claude mostrar o conflito e perguntar qual dos dois está errado.
O que você ganha: um sinal de que o "preciso de ajuda" funciona em conflitos claros. O que fazer: se você deixa uma IA escrever código contra testes prontos, dê a ela uma saída para pedir ajuda e meça com testes que você contradisse de propósito.
Voltar ao Mapa do fluxo. O teto de tentativas está em Voltas de correção.
x
Palavras desta nota (5)
- spec
- O texto que descreve o que uma funcionalidade deve fazer, escrito antes do código.
- Gemini
- A IA do Google. No fluxo, ela escreve o código; no estudo, também inventa erros para os testes pegarem.
- alarme falso
- Quando a leitura aponta um defeito num código que estava certo.
- escape
- Erro plantado que os testes deixaram passar sem reclamar. Quanto menos escapes, mais forte é o conjunto de testes.
- controle
- Caso certo, sem erro nenhum, usado para ver se o passo dá alarme falso.
Depois que o código passa nos testes, o fluxo gera um relatório com uma pergunta: a spec foi cumprida? Ele lê cada critério da spec, confere se tem teste para ele e lê o código dos que não têm. O risco que ele cobre é o de um código que passa em tudo e mesmo assim descumpre um critério da spec que nenhum teste olha.
O teste
- 10 códigos com falha escondida. O Gemini escreveu cada um para passar em todos os testes e descumprir um critério da spec que nenhum teste cobre.
- 5 controles. Códigos que cumprem tudo.
- Conferi rodando o pytest: os 15 passam nos testes. Um teste oculto, que só eu rodei, falha nos 10 com falha e passa nos 5 controles. Nenhum caso foi tirado da conta.
- Quem escreveu o relatório foi um Claude em sessão separada, sem saber qual era qual, com o texto do passo e nada mais.
- A meta, fixada antes: "não cumpre" no critério certo em pelo menos 8 dos 10, e no máximo 1 "não cumpre" falso nos 5 controles.
O que o relatório disse em cada grupo
10 códigos com falha escondida e 5 certos. "Certo" é dizer "não cumpre" no critério da falha, ou não acusar nada nos certos.
| Falha escondida (exemplos) | O relatório disse |
|---|---|
| A senha pede 1 dígito e a spec pede 2 | Não cumpre |
| O desempate sai do mais novo e a spec pede o mais antigo | Não cumpre |
| O cupom vale com subtotal igual a 100 e a spec pede maior que 100 | Não cumpre |
| Os juros também incidem sobre a entrada | Não cumpre |
| Telefone vazio levanta erro em vez de devolver vazio | Não cumpre |
Nos 5 códigos certos o relatório disse "cumpre com ressalva": marcou o critério sem teste, mas leu o código e concluiu que estava certo. É o que o manual manda.
O que isso não prova
- Casos fáceis. Código curto, uma falha só, e todas no formato "critério sem teste", que é exatamente o que o manual manda procurar. O teste mede se o relatório segue o manual, não se ele acharia uma falha qualquer.
- Leitura e relatório juntos. Não separa o quanto do acerto vem de ler o código e o quanto vem do relatório.
- Não mede se muda uma decisão minha. Só o uso real diz se, com o relatório na mão, eu deixo de aprovar.
- Poucos controles. Com 0 alarmes em 5, o alarme falso real ainda poderia chegar a 43%.
- Mesma família. O Gemini escreveu as falhas; um projeto real pode errar de outro jeito.
O que você ganha: um sinal de que um relatório em formato fixo ajuda a achar o que os testes deixam passar. O que fazer: se você confere código gerado por IA, plante falhas que nenhum teste cobre e veja se a sua conferência as acha.
Voltar ao Mapa do fluxo. A leitura do código em si está em Leitura do código.
x
Palavras desta nota (5)
- spec
- O texto que descreve o que uma funcionalidade deve fazer, escrito antes do código.
- commit
- O registro de uma versão do código no Git.
- escape
- Erro plantado que os testes deixaram passar sem reclamar. Quanto menos escapes, mais forte é o conjunto de testes.
- alarme falso
- Quando a leitura aponta um defeito num código que estava certo.
- controle
- Caso certo, sem erro nenhum, usado para ver se o passo dá alarme falso.
É o último passo de cada spec. Antes de gravar o commit, o fechamento:
- roda todos os testes;
- confere o relatório "a spec foi cumprida?" e se o veredito é "não cumpre";
- confere se algum arquivo marcado "não mexer" na spec foi alterado;
- marca a spec como concluída, atualiza o histórico de mudanças e só então commita.
Se algo não bate, para e pergunta. Não commita sozinho.
Os testes
Cada cópia de um projeto pequeno era fechada por uma IA que só tinha o texto do passo e não sabia se havia armadilha. "Certo" é parar sem commitar numa armadilha, e commitar numa cópia limpa. Rodei três vezes, e fixei a meta antes de cada uma.
| Teste | Armadilhas paradas | Cópias limpas commitadas |
|---|---|---|
| 1. Um projeto, 3 testes, armadilhas escritas pelo Claude | 5 de 5 | 1 de 1 |
| 2. Três projetos, armadilhas escritas pelo Gemini | 15 de 15 | 2 de 6 |
| 3. Só as limpas de novo, com o código conferido antes | sem armadilhas | 1 de 6 |
Cópias limpas que o fechamento commitou
Em cada teste, o certo era commitar. Os números são cópias limpas commitadas sobre cópias limpas testadas.
As armadilhas foram de cinco tipos: um teste falhando, um relatório com veredito "não cumpre", um total de testes diferente do relatório, um arquivo de "não mexer" alterado e arquivos soltos que não deviam entrar (uma credencial, um banco de dados). No teste 2, o Gemini escolheu o disfarce de cada uma. Em todas as 20, a IA parou e citou o problema plantado.
Por que as limpas falharam
- Teste 2: as 4 paradas vieram do revisor de código achando algo real no código que o Gemini escreveu: uma linha com 99 caracteres, num projeto cujo limite é 88, e um frete que devolvia 0,0 para um número inválido. Conferi os dois. Ou seja, as minhas cópias "limpas" não eram limpas, e o passo fez o que deve.
- Teste 3: corrigi essas duas falhas e conferi cada projeto com lint, tipos, testes e o revisor, que não achou nada. Mesmo assim 5 das 6 pararam. Em nenhuma o motivo era o conteúdo: testes, totais, veredito, "não mexer" e revisor passaram em todas. O ambiente sem janela, onde rodei, bloqueou a edição de um arquivo de spec e o commit, e não havia ninguém para aprovar. O bloqueio foi intermitente: numa das cópias a mesma edição passou. Esse 1 de 6 mede o fechamento mais a permissão do ambiente.
Por que continua sem prova
- A meta tinha duas partes. A das armadilhas bateu (15 de 15, meta 14). A das cópias limpas não bateu em nenhum dos dois testes.
- Para separar o fechamento do ambiente, seria preciso rodar com a permissão liberada numa cópia descartável, ou com alguém aprovando cada pedido. Não fiz nenhum dos dois.
- Os cinco tipos de armadilha são os que o passo diz conferir; só o disfarce é do Gemini. Um teste desligado com
skipou umassert Truenão foi testado. - Projetos minúsculos, uma rodada por armadilha e duas por cópia limpa.
O que você ganha: um portão que para quando há motivo. Com 20 de 20, ele para mais do que deixa passar. O que fazer: se você monta um passo assim, teste também com código limpo, porque o custo de um portão que para demais é a sua atenção.
Voltar ao Mapa do fluxo. O relatório que ele confere está em A spec foi cumprida?.
x
Palavras desta nota (3)
- mutação
- Estragar o código de propósito, em uma mudança pequena por vez (trocar + por -, < por <=), e rodar os testes para ver se algum reclama.
- mutmut
- A ferramenta gratuita que faz a mutação em código Python.
- escape
- Erro plantado que os testes deixaram passar sem reclamar. Quanto menos escapes, mais forte é o conjunto de testes.
A técnica se chama mutação. Uma ferramenta (o mutmut, grátis) muda o código em um ponto pequeno por vez: troca + por -, < por <=, apaga um valor. Depois roda os testes. Se algum teste falha, o erro foi pego. Se todos passam, o erro escapou.
No projeto inteiro, em 24 segundos, a ferramenta plantou 1.178 erros. Os testes pegaram 647 e deixaram escapar 476. Outros 54 estavam em código que nenhum teste executa.
O que aconteceu com os erros plantados
A ferramenta plantou 1.178 erros no projeto inteiro. As três barras somam 1.177; 1 erro não aparece na contagem que anotei.
Quatro buracos reais que apareceram:
- Na soma do engajamento de cada post, trocar
+por-não quebrava nenhum teste. Esse valor decide qual é o melhor e o pior post. - Os totais da semana (alcance, engajamento, taxa e número de posts) podiam virar "nada" sem teste reclamar.
- No
retry, mudar<para<=e o número de tentativas não era pego. - Em
buscar_ultimos_resumos, mudarquantidade < 1para<= 1também passava: limite sem teste.
Nem todo escape é erro real. Dos 23 que olhei um a um, uns 17 eram falhas reais e 6 eram ruído (texto de log, caminho padrão).
O que você ganha: uma lista concreta de onde os testes são fracos. O que fazer: rode no seu projeto, olhe os primeiros escapes e leia Medir no seu caso.
Por que não usar só cobertura: Cobertura engana.
x
Palavras desta nota (2)
- cobertura
- A porcentagem de linhas do código que os testes executaram. Mede o que o teste rodou, não o que ele conferiu.
- escape
- Erro plantado que os testes deixaram passar sem reclamar. Quanto menos escapes, mais forte é o conjunto de testes.
A cobertura marca quais linhas o teste executou. Um teste pode chamar a função sem conferir o resultado e dar 100% de cobertura sem pegar erro nenhum.
No projeto medido: 95% de cobertura no total, 19 de 21 arquivos em 100%. Mesmo assim, 476 erros plantados escaparam (Estragar o código).
Uma regra como "90% de cobertura nas linhas alteradas" passaria direto e esconderia o problema. Ela só serve como alarme barato (cobertura baixa avisa que falta teste), nunca como prova de que o teste é forte.
O que você ganha: não gastar esforço perseguindo a porcentagem. O que fazer: use a cobertura para achar código sem teste e a contagem de escapes (Medir no seu caso) para saber se os testes que existem conferem alguma coisa.
x
Palavras desta nota (4)
- mutmut
- A ferramenta gratuita que faz a mutação em código Python.
- mutação
- Estragar o código de propósito, em uma mudança pequena por vez (trocar + por -, < por <=), e rodar os testes para ver se algum reclama.
- Gemini
- A IA do Google. No fluxo, ela escreve o código; no estudo, também inventa erros para os testes pegarem.
- escape
- Erro plantado que os testes deixaram passar sem reclamar. Quanto menos escapes, mais forte é o conjunto de testes.
O fluxo já tinha um passo em que o Gemini propõe 5 erros pequenos e realistas nos módulos. Perguntei se a ferramenta de mutação repete esse passo, é nula ou acrescenta algo.
Rodei o passo do Gemini de verdade, 3 vezes (ele muda a cada vez): 15 erros. Apliquei cada um contra três versões de testes.
| Testes | Erros que escapam da mutação | Dos 15 erros do Gemini, escaparam |
|---|---|---|
| Testes antigos | 123 | 2 |
| Agente sem a regra | 113 | 1 |
| Agente com a regra de limites | 85 | 0 |
Duas coisas aparecem:
- As duas réguas concordam na ordem. Pior, meio, melhor, nas duas. Isso reforça o ganho de Limites e motivo certo.
- Não se repetem. Os 2 buracos que o Gemini achou não estão na lista da mutação. A ferramenta só troca operadores e valores (
+por-,<por<=). Ela não troca uma coluna por outra nem reescreve uma condição. Exemplo do Gemini: trocarif faltantes:porif len(faltantes) > 1:, o que deixaria passar um CSV com uma coluna faltando.
Em volume, a mutação achou 123 escapes contra 2 do Gemini. O Gemini foca em erros de lógica; a mutação, nos mecânicos.
No uso real do passo do Gemini
Registrei o passo (5 erros por spec, cada um aplicado e desfeito) em 4 specs de dois projetos Python:
| Spec | Erros do Gemini pegos pelos testes |
|---|---|
| Relatórios, spec 09 | 5 de 5 |
| Monitor, filtro por texto | 4 de 5 |
| Monitor, filtro por itens | 5 de 5 |
| Monitor, filtro por distância | 5 de 5 |
Foram 19 de 20. O único que sobreviveu foi trocar continue por break quando o objeto do edital vem vazio: o laço parava no primeiro vazio e ignorava os editais seguintes. O passo não trava nada, só avisa. Esse sobrevivente é um teste que faltava, achado num caso real.
O que você ganha: saber que as duas se completam, nenhuma é nula. O que fazer: se o seu fluxo já pede erros a uma IA, acrescente a mutação por cima (Medir no seu caso). Sobre o que rodar a cada spec: Só o que a spec mudou.
x
Palavras desta nota (3)
- mutação
- Estragar o código de propósito, em uma mudança pequena por vez (trocar + por -, < por <=), e rodar os testes para ver se algum reclama.
- spec
- O texto que descreve o que uma funcionalidade deve fazer, escrito antes do código.
- escape
- Erro plantado que os testes deixaram passar sem reclamar. Quanto menos escapes, mais forte é o conjunto de testes.
Voltei o projeto ao commit de cada uma de 8 specs e rodei a mutação de duas formas: no projeto inteiro e só nos arquivos que aquela spec mudou. Comparei o que cada forma mostra.
Erros que escaparam em cada forma, por spec
Quatro das 8 specs; a tabela abaixo traz todas. A coluna da esquerda é o projeto inteiro; a da direita, só os arquivos que a spec mudou.
| Spec | Projeto inteiro | Só a spec |
|---|---|---|
| 01 persistência | 2 | 2 |
| 03 ingestão e métricas | 128 | 126 |
| 04 IA | 187 | 59 |
| 05 PDF | 250 | 65 |
| 06 e-mail | 295 | 48 |
| 07 watcher | 464 | 162 |
| 08 tendência | 488 | 3 |
| 09 desempenho por tipo | 476 | 9 |
Três leituras:
- O projeto inteiro vira ruído. Na spec 09, de 476 escapes só 9 são dela. Os outros 467 são de arquivos antigos e continuam na lista a cada rodada, porque ninguém os consertou. Quem lê o relatório a cada spec veria sempre a mesma lista enorme.
- O tempo do projeto inteiro sobe com o projeto (de 2 para 27 segundos). Só nos arquivos da spec ficou entre 2 e 8 segundos, com uma exceção: na spec 07 levou 27 s, porque o
watcher.pyé grande. - O projeto inteiro mostra a dívida acumulada (476 no total) e a forma menor mostra o que cada spec deixou. Para a pergunta "esta spec deixou buraco?", a forma menor responde sozinha.
Resposta: a cada spec, rode só nos arquivos que ela mudou. Uma vez por projeto, no fim, rode no projeto inteiro como auditoria.
O que você ganha: um relatório curto e um tempo menor a cada spec. O que fazer: use o roteiro de Medir no seu caso só sobre os arquivos mudados. Se a mutação ainda levar minutos no seu projeto, essa escolha pesa mais. Voltar à Mutação e Gemini.
x
Palavras desta nota (4)
- spec
- O texto que descreve o que uma funcionalidade deve fazer, escrito antes do código.
- divergência
- Quando a spec, o CLAUDE.md e o código dizem coisas diferentes sobre o mesmo comportamento.
- CLAUDE.md
- O arquivo de regras e decisões do projeto que a IA lê antes de trabalhar.
- escape
- Erro plantado que os testes deixaram passar sem reclamar. Quanto menos escapes, mais forte é o conjunto de testes.
Os escapes que sobram estão quase todos no leitor de CSV, e boa parte deles é de coisas que a spec não diz: o texto das mensagens de erro, a codificação ao abrir o arquivo, campos que a spec não menciona (post_text, plays, watch_time, retention) e a leitura de número decimal opcional. Quem escreve testes sem ver o código não tem como testar o que a spec não diz.
Os dois testes que falharam contra o código real, escritos só a partir da spec, acharam duas divergências:
ler_csvnão aceita o caminho como texto (str), só comoPath. A spec diz apenasler_csv(caminho).- O CLAUDE.md do projeto diz que campo vazio conta como 0 no engajamento, mas o leitor rejeita o campo de compartilhamentos vazio com um erro. Spec e código discordam.
Nenhuma das duas está consertada: o teste só as achou.
O que você ganha: um alarme barato. Teste escrito só pela spec denuncia onde a spec, as regras do projeto e o código dizem coisas diferentes. O que fazer: depois de rodar a mutação (Estragar o código), separe os escapes entre "falta teste" e "falta dizer na spec", e complete a spec.
De onde vieram os testes: Limites e motivo certo.
x
Palavras desta nota (4)
- mutmut
- A ferramenta gratuita que faz a mutação em código Python.
- WSL
- O Linux que roda dentro do Windows. A ferramenta de mutação não roda direto no Windows.
- escape
- Erro plantado que os testes deixaram passar sem reclamar. Quanto menos escapes, mais forte é o conjunto de testes.
- módulo
- Um arquivo de código com uma função específica. Aqui foram três: leitor de CSV, cálculo das métricas e comparação.
- Escolha de 2 a 3 módulos pequenos com lógica de verdade (cálculo, leitura de arquivo, comparação). Evite arquivos só de configuração.
- Rode o mutmut sobre esses módulos com os testes que você já tem. No Windows, rode pelo WSL. O mutmut recusa um pacote chamado
src: na cópia de teste, renomeie a pasta (aqui virouapp). - Anote o número de escapes por módulo e leia os primeiros um a um. Separe o que é falha real do que é ruído (texto de mensagem, caminho padrão).
- Mude uma coisa só (por exemplo, acrescente ao pedido do redator de testes: "teste limites, entradas inválidas e confira o motivo do erro") e meça de novo.
- Compare o número de escapes, o tempo e o custo. Se o número não caiu, a mudança não vale.
Cuidados que valem em qualquer projeto:
- Meça uma variante por vez, no mesmo código e nos mesmos módulos.
- Uma rodada só pode ser ruído. Aqui, dois redatores com o mesmo pedido deram o mesmo número (113 e 113), mas isso é um sinal, não uma prova.
- Escapes não são todos erros reais.
Para medir as outras camadas
O princípio é o mesmo: plante erros e conte quantos a camada pega, sem avisar quem confere.
- Peça a uma IA para inventar erros pequenos no seu código, um por cópia.
- Rode os seus testes em cada cópia e conte quantos erros eles pegam (Rede de testes).
- Com os erros que passaram, mande outra IA, em conversa nova, ler o código sem dizer se há erro. Misture alguns códigos certos para contar os alarmes falsos (Leitura do código).
- Confira o código de cada erro antes de contar. Se o erro plantado não muda o que a spec pede, tire da conta e diga quantos tirou.
Se quiser o fluxo pronto
O fluxo que usei nestas medidas está no meu repositório, o claude-dev-flow: as skills de cada etapa, os agentes (como o escritor-testes, que escreve os testes sem ver o código) e o arquivo docs/provas.md, com o que cada passo provou e o que ainda não provou. Copie as peças que servirem e meça no seu projeto com os cinco passos acima.
Volte à Resposta curta para ver o que cada ideia rendeu.
x
Palavras desta nota (2)
- escape
- Erro plantado que os testes deixaram passar sem reclamar. Quanto menos escapes, mais forte é o conjunto de testes.
- agente escritor de testes
- Uma IA (Claude) que escreve os testes lendo só a spec e o CLAUDE.md. Ela não pode abrir o código.
Testei duas formas de juntar mais uma IA ao agente de testes sem regra extra, que deixava 113 escapes.
Erros que escaparam, por combinação
Menos é melhor. Os mesmos três módulos. As barras são o agente sem regra extra, ele com um segundo redator, ele com um auditor e ele com a regra de limites.
- Segundo redator independente: sozinho deu o mesmo número do primeiro (113). Os dois juntos, 163 testes, deixaram 110 escapes (-3%).
- Auditor de testes antes do código: listou 12 fraquezas e escreveu 31 testes novos. Resultado: 106 escapes (-6%). Várias das "fraquezas" já estavam cobertas: no cálculo e na comparação, o agente sem regra extra já deixava 0 escapes. O auditor também marcou o que era palpite dele, comportamento que a spec não diz.
Nesta medida, nenhum dos dois compensou o tempo extra. O resumo de todas as ideias está em Resposta curta.
O que você ganha: poupar uma IA a mais no seu fluxo. O que fazer: antes de acrescentar mais um revisor, meça se ele reduz os escapes (Medir no seu caso). A regra de Limites e motivo certo tirou 28 escapes; o segundo redator tirou 3 e o auditor, 7.
x
Palavras desta nota (4)
- erro plantado
- Defeito colocado de propósito no código, para ver se os testes ou a leitura percebem.
- alarme falso
- Quando a leitura aponta um defeito num código que estava certo.
- Gemini
- A IA do Google. No fluxo, ela escreve o código; no estudo, também inventa erros para os testes pegarem.
- TypeScript
- A linguagem do segundo projeto do estudo. Os testes e o código dele não são em Python.
A ideia: depois da leitura do Claude, o Gemini lê o código também. Dois leitores, de modelos diferentes, deveriam achar mais.
O que medi
Nos mesmos 9 erros que passaram nos testes e nos 8 códigos certos (10/10, leitura sem saber qual era qual):
| Leitor | Erros pegos, de 9 | Alarmes falsos, em 8 certos |
|---|---|---|
| Gemini | 6 | 1 |
| Claude (rodada de 21/10) | 8 | 0 |
Os dois erram casos diferentes. Numa rodada anterior, em que o Claude leu só 6 dos casos, os dois juntos pegaram 5 de 6, contra 4 de 6 do Claude sozinho. Era um caso a mais em 6, pago com um alarme falso a cada 8 códigos certos.
O que a pesquisa diz
- Um artigo (arXiv 2606.15689) testou juntar os achados de dois modelos para achar defeitos em código. A união não subiu o recall e piorou o F1. Os modelos "detectam em grande parte os mesmos erros".
- Um segundo trabalho (Kohli, 2026) mostrou que 9 modelos juízes valem cerca de 2 votos independentes. Mas o teste dele é de linguagem, não de código.
Nenhuma das fontes que achei mostrou ganho em somar leitores.
A decisão
Fora do fluxo. Só entra o que a medida ou a pesquisa sustentam, e aqui nenhuma sustentou. Também medi o agente revisor-codigo contra a leitura do Claude: pegou os mesmos 8 de 9 e deixou passar o mesmo caso, ou seja, ganho zero (Leitura do código). Duas leituras do mesmo modelo erram juntas.
O que você ganha: poupar uma leitura a mais, que custa tokens e traz alarme falso. O que fazer: antes de somar um segundo revisor de IA, meça se ele acha algo que o primeiro não achou (Medir no seu caso).
Voltar ao Mapa do fluxo.
x
Palavras desta nota (3)
- cobertura
- A porcentagem de linhas do código que os testes executaram. Mede o que o teste rodou, não o que ele conferiu.
- spec
- O texto que descreve o que uma funcionalidade deve fazer, escrito antes do código.
- escape
- Erro plantado que os testes deixaram passar sem reclamar. Quanto menos escapes, mais forte é o conjunto de testes.
| Ideia | O que aconteceu | Quando reabrir |
|---|---|---|
| Auditor de testes antes do código | Ganho pequeno: 113 para 106 escapes. Veja Segundo redator e auditor | Se o agente de testes voltar a deixar escapes no cálculo |
| Testes ocultos para quem escreve o código | Só a metade barata foi medida: 113 para 110. A parte principal, ver se quem implementa ajusta o código só para passar, não foi testada | Se aparecer quem implementa ajustando código só para passar |
| Cobertura de 90% nas linhas alteradas | Ganho pequeno: 95% de cobertura com 476 escapes. Veja Cobertura engana | Só como alarme barato, nunca como prova |
| Rodar o teste do bug 2 vezes antes e 2 depois | Fora por decisão minha, em 06/11. Não foi testada. O passo de consertar bug já exige que o teste falhe antes e passe depois | Não há motivo para reabrir |
A segunda leitura do código pelo Gemini também ficou de fora, mas foi medida: está em Segunda leitura de código.
O que você ganha: saber o que já foi pensado e deixado de lado, para não repetir. O que fazer: se o seu caso for diferente (por exemplo, o código sendo ajustado só para passar nos testes), meça pelo roteiro de Medir no seu caso. Voltar ao Mapa do fluxo.
x
Palavras desta nota (4)
- escape
- Erro plantado que os testes deixaram passar sem reclamar. Quanto menos escapes, mais forte é o conjunto de testes.
- spec
- O texto que descreve o que uma funcionalidade deve fazer, escrito antes do código.
- erro plantado
- Defeito colocado de propósito no código, para ver se os testes ou a leitura percebem.
- hash
- Código curto calculado a partir do conteúdo de um arquivo. Se uma vírgula mudar, o código muda. Serve para saber se o arquivo foi alterado.
Sobre a mutação e os testes
- Uma rodada por variante. Um projeto Python, uma spec (a 03), um modelo. Dois redatores com o mesmo pedido deram o mesmo número (113), o que sugere pouco ruído, mas não prova.
- Escapes não são todos erros reais. Dos 23 olhados um a um, uns 17 eram falhas reais e 6 eram ruído. Os outros escapes não foram classificados.
- Mais testes de um lado. Na comparação com os testes antigos, o agente escreveu 82 testes contra 21; o ganho no cálculo pode ser em parte só quantidade.
- Comparação com o Gemini feita com o modelo
flashe só 15 erros, porque o modelo normal estava sem cota. O "buraco real" que o Gemini achou foi lido por mim, sem outra conferência. - Rodar só no que mudou foi medido em 8 specs de um projeto pequeno, e o arquivo inteiro conta, não só as linhas alteradas. Não testei o caso em que uma spec nova enfraquece um teste antigo de verdade; não apareceu nos dados.
- A variação da ferramenta entre rodadas ficou sem explicação.
Sobre os outros passos do fluxo
- Os erros plantados vêm do Gemini. A rede de testes (56 de 65) e a leitura do código (8 de 9) foram medidas com erros que ele inventou, num projeto em TypeScript. Outro inventor de erros pode dar outro número.
- A leitura do código foi testada em 9 erros: um caso a mais ou a menos muda a porcentagem. Ficou abaixo do alvo de 90%.
- O número de testes da rede de testes. Cada erro rodou contra o projeto no ponto da sua spec (de 659 a 1.203 testes nos quatro pontos que reconstruí), e o "760" que anotei na época não bate com nenhum deles. Os 3.058 são outro momento do projeto.
- A trava dos testes nunca disparou de verdade, porque o Gemini nunca mexeu nos testes. Não tenho registro de um teste do disparo.
- O Gemini escrevendo o código não foi comparado com outro implementador.
- As voltas de correção: o teto de 2 não tem medida. A segunda volta nunca foi precisa nos registros.
- O fechamento da spec foi testado em projetos minúsculos, e nas cópias limpas ele parou demais; não separei o quanto disso é o passo e o quanto é a permissão do ambiente.
- O conserto de bug não tem medida. O teste em conflito e o relatório "a spec foi cumprida?" foram medidos só em casos fáceis, escritos pelo Gemini, com 10 falhas cada.
- As pesquisas de fora não usam o Gemini nem o meu fluxo; apoiam a direção, não o número.
Sobre as decisões
- As metas foram propostas pelo Claude: a da mutação antes de medir, as outras depois. A decisão de adotar foi minha.
Volte à Resposta curta.