A próxima dívida técnica será escrita por IA
TL;DR
- A próxima onda de dívida técnica não vai parecer dívida. Vai parecer código limpo, testado, lint-clean — porque vai ser tudo isso. O erro é arquitetural e sistêmico, não sintático. Dívida técnica bonita é a categoria mais difícil de detectar — e a mais cara de desfazer depois.
- Quatro padrões recorrentes de dívida técnica que IA escreve em escala sem detecção: abstrações plausíveis, duplicação semântica, inconsistência arquitetural, dependências desnecessárias.
- Dívida técnica hoje escapa do code review. A revisão humana mira no alvo errado. O custo está na soma de centenas de PRs coerentes isoladamente que viram sistema incoerente.
- Times ruins não produzem código pior com IA — produzem dívida técnica mais rápido e mais convincente. Capacidade de revisão arquitetural não cresce na mesma proporção que a produção.
- A governança da dívida técnica importa mais que a da IA em si — é “qual categoria de erro IA está autorizado a cometer”. Esse é o filtro que separa times que escalam dos que só aceleram.
~ 9 min de leitura · 1557 palavras
A dívida técnica clássica tinha cara de código ruim
A dívida técnica clássica tinha assinatura visual. Métodos com 300 linhas. Classes que misturavam persistência, regra de negócio e UI em um único arquivo. `if` aninhados em seis níveis. Ausência de testes. Nomes genéricos (`Manager`, `Helper`, `Utils`). A revisão identificava sem esforço: bastava ler.
Esse tipo de dívida técnica continua existindo. Não é o que está crescendo. O que está crescendo é uma classe diferente — dívida técnica que passa na revisão tradicional porque está sintaticamente correta, semanticamente plausível, e arquiteturalmente problemática.
A diferença entre as duas categorias importa porque a solução é diferente. A primeira se resolve com code review disciplinado, refactoring local, e teste de regressão. A segunda exige governança sistêmica que o code review não captura.
A nova dívida técnica tem cara de código bom
A IA generativa aplicada a código produz, com alta consistência, código que cumpre todos os checks superficiais que um time típico usa para garantir qualidade:
- Lint passa (eslint, ruff, clippy, conforme a stack).
- Testes existem e cobrem os caminhos óbvios.
- Type check passa (TypeScript strict mode, mypy strict, Rust borrow checker).
- Code style segue a configuração do projeto.
- O PR é pequeno e coerente.
O senior que revisa aprova sem hesitar. O CI passa em verde. O código vai para produção. O bug não existe. O problema também não — mas só até o sistema acumular dezenas, depois centenas, desses PRs.
O sintoma aparece em horizonte mais longo: “o sistema está difícil de mexer, ninguém sabe onde mexer, cada feature nova demora mais que a anterior, e nenhum teste falha”. Métricas tradicionais de qualidade continuam verdes. A dor é arquitetural e está abaixo da superfície que os números medem.
Esse é o cerne da dívida técnica sintaticamente bonita: a evidência de que existe só aparece quando o custo de desfazer já é maior que o custo de conviver.
Quatro padrões que IA escreve sem pestanejar
Abstrações plausíveis
O prompt pede “crie um sistema flexível para gerenciar usuários”. A resposta entrega `UserFactoryBuilderProvider` com três níveis de indireção, configurável via injeção de dependência, com interface `IUserCreationStrategy`. Cada peça resolve um problema real e está isoladamente correta.
O erro: a abstração não existe no domínio. Nenhum stakeholder pediu `UserCreationStrategy`. Nenhum caso de uso real muda a estratégia. O código está preparado para variação que nunca vai acontecer — e o custo de manter a indireção é pago agora, em legibilidade, em onboarding, em cognitive load para quem vai ler.
IA não distingue “abstração que resolve problema real” de “abstração que parece resolver problema genérico”. Para o modelo, ambas são igualmente válidas em superfície. Para o time, uma é investimento, outra é imposto.
Duplicação semântica
Dois PRs, dois prompts quase idênticos, dois engenheiros (ou o mesmo engenheiro em dias diferentes) recebem da IA funções que fazem a mesma coisa em forma diferente. `formatCurrency` em `utils/format.ts` e `formatMoney` em `helpers/money.ts`, com implementação 95% idêntica mas tokens diferentes. Nenhum `grep` simples pega. Nenhum linter pega. Nenhum teste pega.
O problema escala geometricamente. Em 50 PRs assistidos por IA, há uma probabilidade alta de que existam 5-10 duplicações semânticas que serão descobertas só quando alguém precisar mudar o comportamento em todas elas — e descobrir que cada uma tem um edge case sutil diferente.
Inconsistência arquitetural
Três pastas vizinhas resolvem a mesma classe de problema com três padrões diferentes: `/users` usa repository pattern, `/orders` usa active record direto no ORM, `/payments` usa query objects custom. Cada PR está coerente isoladamente. O sistema é incoerente.
A inconsistência não aparece em revisão porque cada arquivo está bem escrito. Aparece quando o time tenta introduzir uma mudança transversal (auditoria, multi-tenancy, rate limiting) e descobre que tem que reimplementar a regra três vezes em três padrões. Dívida técnica que se acumula silenciosamente entre PRs.
IA escolhe o padrão com base em exemplos próximos do que está gerando naquele momento. Se o contexto da janela é pequeno, padrões divergem entre arquivos que deveriam ser consistentes.
Dependências desnecessárias
O prompt não diz “use `datetime.fromisoformat`”. A IA adiciona `moment.js`, `date-fns`, ou `dayjs` — uma biblioteca inteira para resolver parsing de data. Funciona. Tem testes. Tem type definitions. Vai para produção.
A auditoria trimestral de bundle size detecta. Mas auditoria trimestral é retrospectiva. O custo já foi pago em tempo de bundle, em superfície de supply chain attack, em mais um `package.json` que o time tem que manter atualizado.
O padrão se repete com `lodash` quando bastam três funções nativas, com `axios` quando `fetch` resolve, com `uuid` quando `crypto.randomUUID()` já existe no runtime. Cada adição é razoável isoladamente. O conjunto é um imposto permanente.
Por que revisão humana não detecta mais
Code review tradicional — a humana, linha-a-linha, com contexto carregado e atenção focada — foi desenhada para detectar a dívida técnica clássica. Métodos longos, complexidade ciclomática alta, padrões violados, bugs sutis.
Esses problemas são locais: estão em um arquivo, são visíveis ao ler. Code review pega.
Os quatro padrões acima são sistêmicos: nenhum deles aparece em um único arquivo. Abstrações plausíveis parecem boas no arquivo onde estão. Duplicação semântica aparece em dois arquivos distantes que revisão humana raramente cruza no mesmo olhar. Inconsistência arquitetural é visível apenas comparando três ou mais arquivos em paralelo. Dependências desnecessárias parecem razoáveis até alguém olhar o `package.json` acumulado.
A revisão humana, com sua capacidade de foco em uma mudança de cada vez, é estruturalmente incapaz de detectar esse tipo de problema. Não é falha dos revisores — é incompatibilidade entre a ferramenta e o tipo de defeito.
A solução não é “revisar mais” ou “revisar com mais atenção”. A solução é mudar o que está sendo revisado: revisar o sistema, não o arquivo. Diff acumulado por sprint. Padrões arquiteturais comparados entre arquivos. Bundle size por trimestre. Coerência de padrões por bounded context.
Esse tipo de revisão tem que ser parcialmente automatizado. Ferramentas como ArchUnit (Java), dependency-cruiser (JS/TS), import-linter (Python), ou testes de mutação arquitetural conseguem detectar boa parte das inconsistências. Mas nenhuma ferramenta cobre tudo. O senior que revisa vira designer desses guardrails — exatamente o papel descrito no post sobre gargalo e multiplicador.
O que fazer antes que a próxima geração de código IA vire legado
Três movimentos práticos separam times que escalam com IA de times que só aceleram com IA.
Primeiro: definir quais categorias de erro IA está autorizada a cometer. Política explícita: “IA pode gerar testes, mas testes de integração são revisão humana”. “IA pode adicionar dependência de runtime, mas mudanças em `package.json` requerem justificativa arquitetural”. “IA pode propor abstração, mas só depois do humano validar que o problema a ser abstraído existe no domínio”. Esse filtro transforma o “usar IA” em “usar IA dentro de limites explícitos” — e transforma dívida técnica invisível em categoria de erro auditável.
Segundo: investir em guardrails automatizados para os quatro padrões. Lint arquitetural (dependency-cruiser, ArchUnit) que detecta ciclos e dependências desnecessárias. Detector de duplicação semântica (jscpd, copy-paste-detector semântico) configurado com threshold agressivo. Análise estática de padrões por bounded context. Code review focado em diff acumulado por sprint, não em PR individual. Cada guardrail tem custo de implementação — mas o custo de não ter é o que se paga depois.
Terceiro: medir coerência arquitetural como KPI técnico. Não basta medir LOC, cobertura de testes, ou lead time. Esses números vão subir com IA sem que o sistema fique melhor. Métricas como “número de padrões arquiteturais distintos em uso por bounded context”, “duplicação semântica detectada por linha de código”, e “dependências adicionadas por trimestre justificadas arquiteturalmente” expõem o que LOC esconde.
Nenhum desses movimentos substitui o senior que revisa — mas transforma o senior de gargalo linha-a-linha em arquiteto de sistemas de verificação. Multiplicador, não gargalo.
Conclusão: governança da dívida técnica de IA
A pergunta “usamos IA no time?” tem resposta binária e irrelevant. A pergunta relevante é “qual categoria de erro o time está disposto a pagar com IA?”. Cada equipe responde implicitamente através dos prompts que aceita, dos PRs que aprova, e das dependências que deixa entrar. A diferença entre times que escalam e times que só aceleram está em tornar essa resposta explícita.
A próxima onda de dívida técnica não vai ser combatida com mais revisão linha-a-linha, code style guides mais detalhados, ou coverage targets mais agressivos. Esses são os guardrails da era anterior. A governança da próxima década é arquitetural, automatizada nos pontos onde dá para ser, e humana nos pontos onde a decisão é genuinamente trade-off.
Código IA que parece bom é a categoria de problema mais difícil de detectar. Mas é exatamente por isso que é a categoria que mais vai custar — e que mais separa times que escalam de times que apenas aceleram em direção ao próximo legado. Dívida técnica invisível ao CI é a categoria que mais cresce com IA — e a mais cara de desfazer depois.
Leitura relacionada
- A IA está produzindo código mais rápido do que seu time consegue revisar — a fila de PR é o sintoma operacional; este post mostra a categoria de erro que cresce embaixo dela.
- Senior revisor: gargalo ou multiplicador de confiança no time — quem paga a conta quando a revisão tradicional não detecta o tipo certo de coisa.
- O microsserviço que nunca deveria ter existido — exemplo concreto de decisão arquitetural que parecia boa no momento e custou caro depois.

1 Comentário