{"id":1131,"date":"2026-08-24T04:02:41","date_gmt":"2026-08-24T07:02:41","guid":{"rendered":"https:\/\/adrianosantostreina.com.br\/blog\/protocolo-validacao-codigo-gerado-por-ia\/"},"modified":"2026-08-24T04:02:48","modified_gmt":"2026-08-24T07:02:48","slug":"protocolo-validacao-codigo-gerado-por-ia","status":"publish","type":"post","link":"https:\/\/adrianosantostreina.com.br\/blog\/protocolo-validacao-codigo-gerado-por-ia\/","title":{"rendered":"A Falsa Sensa\u00e7\u00e3o de Seguran\u00e7a: Um Protocolo de Valida\u00e7\u00e3o para C\u00f3digo que Voc\u00ea N\u00e3o Escreveu"},"content":{"rendered":"<p>Voc\u00ea revisou o pull request. O c\u00f3digo compilou de primeira, os testes unit\u00e1rios passaram em verde, a cobertura subiu dois pontos percentuais e a fun\u00e7\u00e3o resolve exatamente o que o ticket pedia. Voc\u00ea aprova, faz o merge, segue para a pr\u00f3xima tarefa. Tr\u00eas semanas depois, em produ\u00e7\u00e3o, um cliente relata que valores de desconto acumulado est\u00e3o sendo calculados errado em pedidos com mais de um cupom aplicado \u2014 um caso de borda que ningu\u00e9m testou porque ningu\u00e9m pensou nele, nem voc\u00ea, nem a IA que escreveu a fun\u00e7\u00e3o.<\/p>\n<p>O problema n\u00e3o \u00e9 que a IA errou. O problema \u00e9 que o seu processo de valida\u00e7\u00e3o foi desenhado para pegar os erros que um humano cansado comete \u2014 esquecer um ponto e v\u00edrgula, inverter uma condi\u00e7\u00e3o, ignorar um null \u2014 e n\u00e3o os erros que uma IA comete: c\u00f3digo sintaticamente impec\u00e1vel, estilisticamente consistente, que resolve o caso feliz com perfei\u00e7\u00e3o e ignora silenciosamente os casos que n\u00e3o foram explicitados no prompt.<\/p>\n<p>Este artigo n\u00e3o \u00e9 sobre como usar IA para escrever c\u00f3digo. \u00c9 sobre o que muda no seu processo de <strong>garantia de qualidade<\/strong> quando uma fra\u00e7\u00e3o relevante do c\u00f3digo que passa pelo seu review n\u00e3o foi pensada por um humano linha a linha. A resposta n\u00e3o \u00e9 &#8220;revisar com mais aten\u00e7\u00e3o&#8221; \u2014 isso n\u00e3o escala e n\u00e3o \u00e9 onde o risco realmente mora. A resposta \u00e9 um protocolo de valida\u00e7\u00e3o estruturado, com camadas espec\u00edficas para os tipos de falha que modelos de linguagem produzem com mais frequ\u00eancia.<\/p>\n<h2>Por que o code review tradicional falha com c\u00f3digo gerado por IA<\/h2>\n<p>Code review humano foi otimizado, ao longo de d\u00e9cadas, para detectar um padr\u00e3o espec\u00edfico de erro: o erro de <em>distra\u00e7\u00e3o<\/em> ou de <em>desconhecimento parcial<\/em>. Um desenvolvedor j\u00fanior esquece de tratar exce\u00e7\u00e3o, um s\u00eanior apressado copia um trecho de outro lugar sem adaptar o contexto, algu\u00e9m n\u00e3o sabia que aquela API tinha um efeito colateral documentado. Revisores humanos s\u00e3o bons em pegar isso porque reconhecem os &#8220;cheiros&#8221; de quem estava com pressa ou com informa\u00e7\u00e3o incompleta.<\/p>\n<p>C\u00f3digo gerado por IA tem uma assinatura de erro completamente diferente. O modelo n\u00e3o est\u00e1 com pressa, n\u00e3o est\u00e1 cansado, n\u00e3o esqueceu nada \u2014 ele simplesmente n\u00e3o sabe o que voc\u00ea n\u00e3o perguntou. Ele produz a solu\u00e7\u00e3o estatisticamente mais prov\u00e1vel para o prompt dado, e essa solu\u00e7\u00e3o costuma ser gen\u00e9rica, plaus\u00edvel e sintaticamente perfeita, mas frequentemente m\u00edope em rela\u00e7\u00e3o a:<\/p>\n<ul>\n<li><strong>Invariantes de dom\u00ednio n\u00e3o explicitadas<\/strong> \u2014 regras de neg\u00f3cio que existem na cabe\u00e7a do time, mas n\u00e3o no prompt nem no c\u00f3digo-fonte que a IA teve como contexto.<\/li>\n<li><strong>Casos de borda estatisticamente raros<\/strong> \u2014 o modelo otimiza para o caso comum porque \u00e9 o que domina os dados de treinamento e o que aparece com mais frequ\u00eancia em exemplos an\u00e1logos.<\/li>\n<li><strong>Efeitos colaterais concorrentes<\/strong> \u2014 race conditions, ordem de inicializa\u00e7\u00e3o, estado compartilhado \u2014 que exigem racioc\u00ednio sobre execu\u00e7\u00e3o real, n\u00e3o sobre padr\u00f5es de texto.<\/li>\n<li><strong>Seguran\u00e7a contextual<\/strong> \u2014 a IA sabe escrever uma query parametrizada quando pedida, mas n\u00e3o sabe que aquele endpoint espec\u00edfico do seu sistema precisa de uma checagem de autoriza\u00e7\u00e3o adicional que existe em tr\u00eas outros lugares do c\u00f3digo, n\u00e3o documentada.<\/li>\n<\/ul>\n<p>Esse ponto aparece com for\u00e7a em uma publica\u00e7\u00e3o do desenvolvedor Guilherme Lima no LinkedIn, que resume bem o risco: a quest\u00e3o n\u00e3o \u00e9 se a IA escreveu c\u00f3digo seguro, \u00e9 medir o que o desenvolvedor deixa de verificar quando a IA est\u00e1 no loop. Governan\u00e7a, no caso, n\u00e3o significa bloquear o uso da ferramenta \u2014 significa desenhar checkpoints que compensem exatamente esse ponto cego.<\/p>\n<blockquote><p><strong>\ud83d\udca1 Dica do Mestre:<\/strong> vale a leitura completa da publica\u00e7\u00e3o de Guilherme Lima sobre o tema, dispon\u00edvel em <a href=\"https:\/\/pt.linkedin.com\/posts\/guilherme-lima-developer_o-c%C3%B3digo-foi-feito-por-ia-ou-n%C3%A3o-para-saber-activity-7446910838277484544-4s2R\" target=\"_blank\" rel=\"noopener\">seu perfil no LinkedIn<\/a>. O argumento central \u2014 que governan\u00e7a de IA no desenvolvimento \u00e9 sobre medir lacunas de verifica\u00e7\u00e3o, n\u00e3o sobre proibir a ferramenta \u2014 deveria estar na abertura de qualquer pol\u00edtica interna de uso de IA para c\u00f3digo.<\/p><\/blockquote>\n<h2>O protocolo: quatro camadas de valida\u00e7\u00e3o<\/h2>\n<p>O que proponho aqui n\u00e3o substitui seus testes unit\u00e1rios nem seu pipeline de CI\/CD existente. \u00c9 uma camada adicional, espec\u00edfica para c\u00f3digo de origem IA, que ataca os quatro pontos cegos descritos acima. Trate isso como um checklist de PR, n\u00e3o como burocracia extra \u2014 cada camada tem um objetivo claro e um custo de execu\u00e7\u00e3o baixo quando automatizada.<\/p>\n<h3>Camada 1 \u2014 Verifica\u00e7\u00e3o de invariantes expl\u00edcitas<\/h3>\n<p>Antes de qualquer teste, escreva (ou pe\u00e7a \u00e0 pr\u00f3pria IA que escreva, sob sua supervis\u00e3o) as invariantes de dom\u00ednio como asser\u00e7\u00f5es execut\u00e1veis, n\u00e3o como coment\u00e1rios. Se a regra \u00e9 &#8220;o desconto total nunca pode exceder 100% do valor do pedido, mesmo com m\u00faltiplos cupons empilhados&#8221;, essa regra precisa existir como um teste que falha explicitamente se violada \u2014 e voc\u00ea precisa confirmar que ela nunca foi mencionada no prompt original.<\/p>\n<pre><code class=\"language-python\">import pytest\nfrom decimal import Decimal\nfrom pricing import apply_coupons\n\ndef test_desconto_total_nunca_excede_valor_do_pedido():\n    \"\"\"\n    Invariante de neg\u00f3cio que N\u00c3O estava no prompt original.\n    A IA implementou apply_coupons() pensando em um \u00fanico cupom;\n    este teste for\u00e7a o comportamento correto com m\u00faltiplos.\n    \"\"\"\n    valor_pedido = Decimal(\"100.00\")\n    cupons = [\n        {\"tipo\": \"percentual\", \"valor\": 60},\n        {\"tipo\": \"percentual\", \"valor\": 50},\n    ]\n    resultado = apply_coupons(valor_pedido, cupons)\n    assert resultado.total_desconto = Decimal(\"0.00\")\n<\/code><\/pre>\n<p>Esse teste n\u00e3o veio &#8220;de gra\u00e7a&#8221; da IA porque ela nunca soube que essa invariante existia. \u00c9 trabalho humano, insubstitu\u00edvel, e \u00e9 exatamente aqui que a experi\u00eancia s\u00eanior do revisor vale mais do que qualquer prompt mais elaborado.<\/p>\n<h3>Camada 2 \u2014 Testes baseados em propriedades (property-based testing)<\/h3>\n<p>Testes unit\u00e1rios tradicionais verificam exemplos espec\u00edficos. C\u00f3digo gerado por IA tende a passar em todos os exemplos que voc\u00ea pensou em escrever \u2014 porque, no fundo, tanto voc\u00ea quanto a IA est\u00e3o ancorados nos mesmos casos &#8220;\u00f3bvios&#8221;. Property-based testing inverte a l\u00f3gica: voc\u00ea declara propriedades que devem valer para <em>qualquer<\/em> entrada v\u00e1lida, e a ferramenta gera centenas de casos aleat\u00f3rios tentando quebrar essa propriedade.<\/p>\n<pre><code class=\"language-python\">from hypothesis import given, strategies as st\nfrom pricing import apply_coupons\nfrom decimal import Decimal\n\n@given(\n    valor=st.decimals(min_value=\"0.01\", max_value=\"1000000\", places=2),\n    percentuais=st.lists(st.integers(min_value=1, max_value=100), min_size=1, max_size=10)\n)\ndef test_propriedade_desconto_nunca_negativo(valor, percentuais):\n    cupons = [{\"tipo\": \"percentual\", \"valor\": p} for p in percentuais]\n    resultado = apply_coupons(valor, cupons)\n    assert resultado.valor_final &gt;= Decimal(\"0.00\")\n    assert resultado.valor_final &lt;= valor\n<\/code><\/pre>\n<p>Em Python, a biblioteca de refer\u00eancia \u00e9 o <a href=\"https:\/\/hypothesis.readthedocs.io\/\" target=\"_blank\" rel=\"noopener\">Hypothesis<\/a>. Em outras linguagens voc\u00ea tem equivalentes maduros: <a href=\"https:\/\/fscheck.github.io\/FsCheck\/\" target=\"_blank\" rel=\"noopener\">FsCheck<\/a> para .NET, <a href=\"https:\/\/github.com\/jlink\/jqwik\" target=\"_blank\" rel=\"noopener\">jqwik<\/a> para a JVM, e o cl\u00e1ssico <a href=\"https:\/\/hackage.haskell.org\/package\/QuickCheck\" target=\"_blank\" rel=\"noopener\">QuickCheck<\/a> que originou a t\u00e9cnica. O ganho real aqui \u00e9 que esses geradores encontram exatamente os casos de borda que tanto voc\u00ea quanto a IA teriam ignorado por estarem ancorados no mesmo espa\u00e7o de exemplos mentais.<\/p>\n<h3>Camada 3 \u2014 Mutation testing para validar a qualidade da su\u00edte, n\u00e3o s\u00f3 do c\u00f3digo<\/h3>\n<p>Um risco espec\u00edfico do fluxo com IA \u00e9 gerar testes e implementa\u00e7\u00e3o no mesmo prompt, ou em prompts sequenciais do mesmo contexto. Isso cria um vi\u00e9s perigoso: os testes tendem a validar exatamente o comportamento que a implementa\u00e7\u00e3o tem, n\u00e3o o comportamento que deveria ter. Cobertura de linha sobe, mas a su\u00edte n\u00e3o pega regress\u00f5es reais.<\/p>\n<p>Mutation testing resolve isso introduzindo pequenas altera\u00e7\u00f5es (muta\u00e7\u00f5es) no c\u00f3digo de produ\u00e7\u00e3o \u2014 trocar um <code>&lt;<\/code> por <code>&lt;=<\/code>, inverter um booleano, remover uma chamada \u2014 e verificando se ao menos um teste falha para cada muta\u00e7\u00e3o. Se uma muta\u00e7\u00e3o sobrevive sem quebrar nenhum teste, isso significa que sua su\u00edte tem um buraco.<\/p>\n<pre><code class=\"language-bash\"># Exemplo com mutmut, para Python\npip install mutmut\nmutmut run --paths-to-mutate=pricing.py\nmutmut results\n<\/code><\/pre>\n<p>Ferramentas de refer\u00eancia por ecossistema: <a href=\"https:\/\/mutmut.readthedocs.io\/\" target=\"_blank\" rel=\"noopener\">mutmut<\/a> e <a href=\"https:\/\/cosmic-ray.readthedocs.io\/\" target=\"_blank\" rel=\"noopener\">Cosmic Ray<\/a> em Python, <a href=\"https:\/\/pitest.org\/\" target=\"_blank\" rel=\"noopener\">PIT (Pitest)<\/a> na JVM, <a href=\"https:\/\/stryker-mutator.io\/\" target=\"_blank\" rel=\"noopener\">Stryker<\/a> para JavaScript\/TypeScript e .NET. Rodar mutation testing em todo o codebase \u00e9 caro computacionalmente \u2014 a recomenda\u00e7\u00e3o pr\u00e1tica \u00e9 aplic\u00e1-lo de forma seletiva, nos m\u00f3dulos cr\u00edticos que passaram por gera\u00e7\u00e3o assistida de IA, n\u00e3o no reposit\u00f3rio inteiro a cada commit.<\/p>\n<blockquote><p><strong>\ud83d\udca1 Dica do Mestre:<\/strong> um bom indicador de maturidade de su\u00edte de testes n\u00e3o \u00e9 a cobertura de linha, \u00e9 o <em>mutation score<\/em> \u2014 a porcentagem de muta\u00e7\u00f5es que sua su\u00edte efetivamente detecta. Cobertura de 100% com mutation score baixo \u00e9 o retrato exato de &#8220;testes que s\u00f3 confirmam o que o c\u00f3digo j\u00e1 faz&#8221;, o padr\u00e3o mais comum em c\u00f3digo gerado e testado pela mesma IA no mesmo contexto.<\/p><\/blockquote>\n<h3>Camada 4 \u2014 An\u00e1lise est\u00e1tica e SAST focada no que a IA costuma errar<\/h3>\n<p>Ferramentas de an\u00e1lise est\u00e1tica (linters, type checkers, SAST) sempre fizeram parte de pipelines maduros, mas ganham peso adicional aqui porque capturam categorias de erro que revis\u00e3o manual apressada deixa passar: inje\u00e7\u00e3o de SQL sutil, uso incorreto de criptografia, exposi\u00e7\u00e3o de segredos, depend\u00eancias vulner\u00e1veis introduzidas por sugest\u00e3o do pr\u00f3prio assistente.<\/p>\n<p>Ferramentas como <a href=\"https:\/\/semgrep.dev\/\" target=\"_blank\" rel=\"noopener\">Semgrep<\/a>, <a href=\"https:\/\/codeql.github.com\/\" target=\"_blank\" rel=\"noopener\">CodeQL<\/a> e <a href=\"https:\/\/bandit.readthedocs.io\/\" target=\"_blank\" rel=\"noopener\">Bandit<\/a> (para Python) devem rodar automaticamente em todo PR, com regras espec\u00edficas para os padr\u00f5es que assistentes de c\u00f3digo costumam reproduzir de forma insegura \u2014 por exemplo, concatena\u00e7\u00e3o de strings em queries quando o contexto do prompt n\u00e3o deixou expl\u00edcito que aquela vari\u00e1vel vem de entrada do usu\u00e1rio.<\/p>\n<pre><code class=\"language-yaml\"># .github\/workflows\/sast.yml\nname: SAST\non: [pull_request]\njobs:\n  semgrep:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions\/checkout@v4\n      - uses: semgrep\/semgrep-action@v1\n        with:\n          config: &gt;-\n            p\/security-audit\n            p\/owasp-top-ten\n<\/code><\/pre>\n<h2>Detectar se o c\u00f3digo &#8220;\u00e9 de IA&#8221; \u00e9 a pergunta errada<\/h2>\n<p>Existe uma tenta\u00e7\u00e3o \u2014 vis\u00edvel em discuss\u00f5es acad\u00eamicas e corporativas \u2014 de tentar identificar se um trecho de c\u00f3digo foi gerado por IA, como se isso por si s\u00f3 fosse um sinal de risco. A <a href=\"https:\/\/www.pangram.com\/pt\/blog\/ai-code-detector\" target=\"_blank\" rel=\"noopener\">Pangram publicou uma an\u00e1lise t\u00e9cnica<\/a> sobre os limites desses detectores de c\u00f3digo de IA, mostrando o que eles conseguem identificar e onde falham. Vale a leitura, mas o ponto pr\u00e1tico para o seu time \u00e9 outro: mesmo que a detec\u00e7\u00e3o fosse perfeita, ela n\u00e3o te diria nada sobre a <em>corretude<\/em> do c\u00f3digo.<\/p>\n<p>Um trecho escrito por IA e validado pelas quatro camadas acima \u00e9 mais confi\u00e1vel do que um trecho escrito por um humano s\u00eanior sem nenhum teste de propriedade ou mutation testing. A origem do c\u00f3digo \u00e9 irrelevante para a decis\u00e3o de merge; o que importa \u00e9 o rigor da valida\u00e7\u00e3o aplicada. Esse debate aparece de forma recorrente em threads como a do <a href=\"https:\/\/www.reddit.com\/r\/learnpython\/comments\/10o413v\/is_it_possible_to_detect_if_a_code_is_written_by\/?tl=pt-br\" target=\"_blank\" rel=\"noopener\">r\/learnpython sobre detec\u00e7\u00e3o de c\u00f3digo gerado por IA<\/a>, geralmente motivado por contextos de integridade acad\u00eamica \u2014 um problema real, mas categoricamente diferente do problema de engenharia que voc\u00ea resolve em produ\u00e7\u00e3o.<\/p>\n<h2>O risco arquitetural que os testes unit\u00e1rios n\u00e3o pegam<\/h2>\n<p>H\u00e1 uma categoria de problema que nenhuma das quatro camadas acima resolve sozinha: deriva arquitetural. Um agente de IA, ao resolver uma tarefa isolada, otimiza para aquela tarefa \u2014 n\u00e3o para a coer\u00eancia do sistema como um todo. Ele pode introduzir uma nova forma de acessar o banco de dados que ignora a camada de reposit\u00f3rio j\u00e1 estabelecida, ou duplicar uma regra de valida\u00e7\u00e3o que j\u00e1 existe em outro m\u00f3dulo, porque simplesmente n\u00e3o tinha esse contexto no momento da gera\u00e7\u00e3o.<\/p>\n<p>Rodrigo de Toledo levanta exatamente esse ponto em uma publica\u00e7\u00e3o sobre como lidar com gera\u00e7\u00e3o de c\u00f3digo por IA em escala: a necessidade de os times conseguirem visualizar a evolu\u00e7\u00e3o da arquitetura do sistema mesmo quando a velocidade de gera\u00e7\u00e3o de c\u00f3digo aumenta \u2014 porque revis\u00e3o linha a linha n\u00e3o escala para detectar esse tipo de eros\u00e3o estrutural.<\/p>\n<blockquote><p><strong>\ud83d\udca1 Dica do Mestre:<\/strong> leia a publica\u00e7\u00e3o completa de Rodrigo de Toledo em <a href=\"https:\/\/pt.linkedin.com\/posts\/rodrigodetoledo_como-estamos-lidando-com-gera%C3%A7%C3%A3o-de-c%C3%B3digo-activity-7441820182576050177-1TZQ\" target=\"_blank\" rel=\"noopener\">seu perfil no LinkedIn<\/a>. O ponto central \u00e9 que ferramentas de visualiza\u00e7\u00e3o e mapeamento de arquitetura (dependency graphs, fitness functions arquiteturais) deixam de ser &#8220;nice to have&#8221; e passam a ser mecanismo de defesa ativo quando o volume de c\u00f3digo gerado cresce r\u00e1pido.<\/p><\/blockquote>\n<p>Na pr\u00e1tica, isso significa complementar seu protocolo de valida\u00e7\u00e3o com <strong>testes de arquitetura<\/strong> \u2014 regras automatizadas que verificam se as depend\u00eancias entre m\u00f3dulos respeitam as camadas definidas. Em Java, ferramentas como <a href=\"https:\/\/www.archunit.org\/\" target=\"_blank\" rel=\"noopener\">ArchUnit<\/a> permitem escrever isso como c\u00f3digo:<\/p>\n<pre><code class=\"language-java\">@ArchTest\nstatic final ArchRule camada_de_dominio_nao_depende_de_infraestrutura =\n    noClasses().that().resideInAPackage(\"..domain..\")\n        .should().dependOnClassesThat().resideInAPackage(\"..infrastructure..\");\n<\/code><\/pre>\n<p>Esse tipo de regra pega, de forma autom\u00e1tica e em todo PR, exatamente o erro que um agente de IA comete quando resolve um problema local sem visibilidade da arquitetura global: acesso direto ao banco a partir de uma classe de dom\u00ednio, importa\u00e7\u00e3o cruzada entre m\u00f3dulos que deveriam ser independentes, viola\u00e7\u00e3o de fronteiras de bounded context.<\/p>\n<h2>Montando o pipeline completo<\/h2>\n<p>Juntando as quatro camadas mais a checagem arquitetural, um pipeline de CI para c\u00f3digo com origem mista (humano + IA) fica assim, em ordem de execu\u00e7\u00e3o recomendada \u2014 do mais r\u00e1pido\/barato para o mais lento\/caro:<\/p>\n<ol>\n<li><strong>Lint e type checking<\/strong> \u2014 feedback em segundos, pega erros triviais antes de gastar tempo de CI.<\/li>\n<li><strong>Testes unit\u00e1rios e de invariantes expl\u00edcitas<\/strong> \u2014 a camada que exige mais trabalho humano de verdade, porque codifica conhecimento de dom\u00ednio que a IA n\u00e3o tem.<\/li>\n<li><strong>SAST (Semgrep\/CodeQL\/Bandit)<\/strong> \u2014 roda em paralelo aos testes, foco em seguran\u00e7a.<\/li>\n<li><strong>Testes de arquitetura (ArchUnit ou equivalente)<\/strong> \u2014 barato de rodar, pega deriva estrutural cedo.<\/li>\n<li><strong>Property-based testing<\/strong> \u2014 mais lento, pode rodar apenas em m\u00f3dulos alterados no PR.<\/li>\n<li><strong>Mutation testing<\/strong> \u2014 o mais caro; reservado para m\u00f3dulos cr\u00edticos ou execu\u00e7\u00e3o noturna\/semanal, n\u00e3o em todo PR.<\/li>\n<\/ol>\n<p>Esse ordenamento importa: se voc\u00ea rodar mutation testing antes do lint, est\u00e1 desperdi\u00e7ando minutos de CI em c\u00f3digo que sequer compila corretamente. O princ\u00edpio geral \u2014 <em>fail fast, fail barato<\/em> \u2014 se aplica com ainda mais for\u00e7a quando o volume de PRs aumenta por causa da produtividade que a pr\u00f3pria IA proporciona.<\/p>\n<h2>Um caso pr\u00e1tico: revis\u00e3o de PR gerado por agente aut\u00f4nomo<\/h2>\n<p>Considere um cen\u00e1rio concreto: voc\u00ea delega a um agente (via Claude Code, Cursor Agent Mode ou similar) a tarefa de &#8220;adicionar suporte a pagina\u00e7\u00e3o por cursor no endpoint de listagem de pedidos&#8221;. O agente entrega um PR funcional, com testes que passam. Aplicando o protocolo:<\/p>\n<ul>\n<li><strong>Invariantes expl\u00edcitas:<\/strong> voc\u00ea percebe que o agente n\u00e3o tratou o caso de o cursor apontar para um registro que foi deletado entre duas requisi\u00e7\u00f5es \u2014 escreve o teste manualmente, porque \u00e9 conhecimento de neg\u00f3cio, n\u00e3o de sintaxe.<\/li>\n<li><strong>Property-based:<\/strong> gera cursores aleat\u00f3rios, incluindo strings malformadas e valores fora do intervalo esperado, e descobre que o parser de cursor lan\u00e7a exce\u00e7\u00e3o n\u00e3o tratada para entrada inv\u00e1lida \u2014 algo que os exemplos manuais do agente nunca cobriram.<\/li>\n<li><strong>Mutation testing:<\/strong> revela que a condi\u00e7\u00e3o de &#8220;h\u00e1 pr\u00f3xima p\u00e1gina&#8221; pode ser invertida sem que nenhum teste falhe \u2014 sinal de que a su\u00edte gerada testou apenas o caminho feliz.<\/li>\n<li><strong>Arquitetura:<\/strong> o teste de depend\u00eancias acusa que o agente importou o modelo de banco diretamente no controller, pulando a camada de servi\u00e7o que todo o resto do sistema respeita.<\/li>\n<\/ul>\n<p>Nenhum desses quatro problemas apareceria em um code review de &#8220;leitura do diff em cinco minutos&#8221;. Todos apareceram porque o protocolo foi desenhado especificamente para os pontos cegos de gera\u00e7\u00e3o automatizada de c\u00f3digo.<\/p>\n<h2>Onde este protocolo tem limites<\/h2>\n<p>Vale ser honesto sobre o custo: as quatro camadas juntas representam investimento real de tempo de engenharia, principalmente na escrita de invariantes expl\u00edcitas \u2014 que n\u00e3o pode ser automatizada, porque exige conhecimento de neg\u00f3cio que s\u00f3 existe na cabe\u00e7a do time. N\u00e3o adote as quatro camadas com o mesmo rigor em todo o codebase; reserve o protocolo completo para m\u00f3dulos com regras de neg\u00f3cio complexas, fluxo financeiro, autentica\u00e7\u00e3o e autoriza\u00e7\u00e3o, e qualquer c\u00f3digo que toque dados sens\u00edveis. Para CRUDs simples e c\u00f3digo de baixo risco, testes unit\u00e1rios tradicionais mais lint continuam sendo proporcionais ao risco.<\/p>\n<p>O v\u00eddeo <a href=\"https:\/\/www.youtube.com\/watch?v=6Wn3Nequ72I\" target=\"_blank\" rel=\"noopener\">&#8220;O mundo da IA em 2026 com Vibe Coding&#8221;<\/a> discute justamente essa tens\u00e3o entre velocidade de gera\u00e7\u00e3o e disciplina de valida\u00e7\u00e3o \u2014 o ponto relevante para times s\u00eaniores n\u00e3o \u00e9 &#8220;vibe coding \u00e9 ruim&#8221;, \u00e9 que a velocidade ganha na gera\u00e7\u00e3o precisa ser reinvestida, ao menos parcialmente, em valida\u00e7\u00e3o estrutural, sob risco de a d\u00edvida t\u00e9cnica crescer mais r\u00e1pido do que a capacidade de perceb\u00ea-la.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Voc\u00ea revisou o pull request. O c\u00f3digo compilou de primeira, os testes unit\u00e1rios passaram em verde, a cobertura subiu dois pontos percentuais e a fun\u00e7\u00e3o resolve exatamente o que o ticket pedia. Voc\u00ea aprova, faz o merge, segue para a pr\u00f3xima tarefa. Tr\u00eas semanas depois, em produ\u00e7\u00e3o, um cliente relata que valores de desconto acumulado [&hellip;]<\/p>\n","protected":false},"author":127,"featured_media":1132,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-1131","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-blog"],"_links":{"self":[{"href":"https:\/\/adrianosantostreina.com.br\/blog\/wp-json\/wp\/v2\/posts\/1131","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/adrianosantostreina.com.br\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/adrianosantostreina.com.br\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/adrianosantostreina.com.br\/blog\/wp-json\/wp\/v2\/users\/127"}],"replies":[{"embeddable":true,"href":"https:\/\/adrianosantostreina.com.br\/blog\/wp-json\/wp\/v2\/comments?post=1131"}],"version-history":[{"count":1,"href":"https:\/\/adrianosantostreina.com.br\/blog\/wp-json\/wp\/v2\/posts\/1131\/revisions"}],"predecessor-version":[{"id":1133,"href":"https:\/\/adrianosantostreina.com.br\/blog\/wp-json\/wp\/v2\/posts\/1131\/revisions\/1133"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/adrianosantostreina.com.br\/blog\/wp-json\/wp\/v2\/media\/1132"}],"wp:attachment":[{"href":"https:\/\/adrianosantostreina.com.br\/blog\/wp-json\/wp\/v2\/media?parent=1131"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/adrianosantostreina.com.br\/blog\/wp-json\/wp\/v2\/categories?post=1131"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/adrianosantostreina.com.br\/blog\/wp-json\/wp\/v2\/tags?post=1131"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}