A IA já roubou o trabalho do dev
Palavras difíceis de engolir: a IA não vai roubar o trabalho do dev. Ela já roubou.
Toda semana aparece um artigo novo perguntando se a IA vai substituir os programadores. A premissa está errada. Não é “quando vai”: ela já substituiu.
O trabalho que existia em 2022 não existe mais. O que sobrou tem outro nome, outra natureza e outro conjunto de habilidades. Adianto o nome: engenharia de harness.
Quem ainda está discutindo se deve ou não “adotar IA” está basicamente discutindo se embarca num trem que já partiu.
Isso é a minha opinião, formada por operar esse fluxo todos os dias, e não uma previsão confortável sobre um futuro distante.
Contexto: como eu trabalho hoje
Sou engenheiro de backend e infraestrutura. Sou o único dono da infra AWS da empresa onde trabalho e carrego o on-call de produção sozinho.
Quando algo quebra às três da manhã, o telefone que toca é o meu. Não estou teorizando de fora, tenho vivência diária com isso.
Meu workflow hoje é o seguinte: eu praticamente não escrevo código. Tomo as decisões estratégicas e arquiteturais de alto nível, descrevo em linguagem natural, e agentes de IA implementam.
Quase nunca leio diffs. Valido por funcionalidade, com testes unitários e E2E que também são conduzidos por IA.
Sei o que você está pensando: “esse cara não sabe mais programar”. Errado. O que aconteceu é que revisar código deixou de ser a alocação mais eficiente da minha atenção.
A IA revisa o mecânico melhor e mais rápido do que eu. Programação virou commodity. Na verdade sempre foi, só que agora o preço apareceu na etiqueta.
Ainda existe revisão humana, mas ela foi para o lugar caro: mudanças irreversíveis, arquitetura, modelo de ameaça, IAM, custo e definição do que um teste realmente prova.
Mas se eu não escrevo o sistema, o que eu construo? Essa é a pergunta certa, e a resposta reorganiza a profissão inteira: eu construo o harness.
Construir-consertar ficou barato demais
Antes de definir harness, o porquê dele. A tese central é simples: o custo de construir e consertar software despencou.
Quando o custo de regenerar algo cai perto de zero, revisar cada linha desse algo vira micro-otimização de um recurso que não é mais escasso.
Existe uma analogia útil com o compilador, mas não uma equivalência. Ninguém audita a saída do GCC linha por linha porque compiladores têm semântica estável, testes, benchmarks e décadas de maturidade.
Agentes são probabilísticos. A lição que importa não é tratá-los como compiladores. É mover a verificação para onde ela escala: contratos de comportamento, testes, métricas, gates e rollback.
“Ah, mas e os bugs? E vazamento de dados, corrupção de estado, custo de cloud explodindo?” Esses problemas sempre existiram, antes de qualquer LLM.
O erro é inevitável em qualquer regime. A pergunta certa nunca foi “como evitar todo erro”, e sim “quão rápido eu detecto, limito e conserto?”.
E responder isso de forma automática, contínua e barata é exatamente o trabalho que sobrou para o humano.
Harness é o novo código
Se o código é descartável, sua confiança inteira precisa morar em outro lugar. Esse lugar é o harness.
O nome vem de test harness: o ambiente, as dependências e os controles usados para exercitar um componente em teste. Na era dos agentes, o conceito expandiu.
Harness é todo o aparato ao redor do código gerado que responde, automaticamente e o tempo todo, a uma única pergunta: isso funciona dentro dos limites que eu aceito?
Um agente sozinho perde coerência quando a tarefa cresce. O contexto enche, o escopo escapa e ele marca como pronta a feature que só parece pronta.
A divisão em planner, generator e evaluator, com contratos, artefatos de estado e loop de feedback fecha esse buraco.
Separar quem gera de quem julga é parte central desse loop. Um agente revisando o próprio trabalho tende a se aprovar. Um avaliador cético, com critérios e acesso ao sistema rodando, encontra a feature de mentira que o gerador chama de pronta.
O loop que interessa
a spec] --> B[Planner quebra a spec
em tarefas e contratos] B --> C[Generator implementa
com testes] C --> D[Evaluator exercita
o artefato e critérios] D --> E[Gate executa testes,
métricas e políticas] E --> F{Contrato e gates
passaram?} F -->|não| C F -->|sim| G[Entrega no alvo real] G --> H[Eu valido
a experiência]
No meu harness, eu aprovo a especificação executável e valido a experiência entregue. Entre esses dois pontos, o agente trabalha contra uma escada de testes e um gate que bloqueia regressão.
O meu harness inclui:
- Uma spec Gherkin que aprovo antes da implementação, com cenários e decisões registradas
- Step definitions falhando antes da implementação e testes de aceitação rodando no comando normal de testes
- Domínio testável sem UI, rede, relógio ou filesystem reais, com seams injetáveis e fakes de primeira classe
- Testes de interação que atravessam o pipeline real de eventos em modo headless, em vez de chamar handler direto
- Um script de gate único para agente, hook, CI e humano, com níveis fast, push e full
- Format, lint em deny, testes, limites de tamanho, direção de dependências, auditoria de dependências e ratchet de cobertura
- Mutation testing no diff, teto de complexidade, CRAP score e orçamento de performance como métricas de qualidade
- Specs, contexto de trabalho, definição de pronto e ratchets versionados para o próximo agente retomar o estado real
É a execução prática da regra do Uncle Bob: gerenciar código de agentes por cobertura, estrutura de dependências, complexidade, tamanho de módulo e mutação, em vez de revisar cada linha.
Parêntese técnico: CC e CRAP
Complexidade ciclomática, ou CC, conta os caminhos independentes que uma função abre. Ela não mede linhas. Cada decisão acrescenta uma rota que o teste precisa conhecer.
e-mail verificado?} D -->|sim| Y D -->|não| X
Esse fluxo tem três decisões. A CC é 4: o caminho-base mais uma unidade por decisão. Não diz que a função está errada. Diz que ela tem quatro caminhos independentes para justificar com teste.
Uma função com CC 1 é linear. Com CC 10, já é preciso explicar por que dez caminhos independentes vivem no mesmo lugar. No meu harness, o lint tem teto para essa dívida não crescer no escuro.
CRAP transforma isso em risco: função complicada e sem teste custa caro para
mudar. A fórmula usada pelo harness é CRAP = CC² × (1 - cobertura)³ + CC.
| Função | Cobertura | CRAP | Leitura |
|---|---|---|---|
| CC 4 | 100% | 4 | cobertura reduz o score ao valor da CC |
| CC 4 | 50% | 6 | a falta de cobertura já aumenta o risco |
| CC 4 | 0% | 20 | quatro decisões sem teste viram dívida |
| CC 10 | 0% | 110 | a combinação escala rápido demais para ignorar |
Métrica mede a qualidade do artefato. Ela não sabe se o artefato é o que o produto pediu. A spec Gherkin descreve cenários Given, When e Then; os testes de aceitação executam esses cenários pelo caminho do usuário.
Cobertura só mostra que o código rodou. Mutation testing muda o código de forma controlada e verifica se a suíte mata a mudança. Mutante sobrevivente é teste que passou sem restringir o comportamento que importa.
O harness é o que separa vibe coding de produção de slop. O dev deixou de desenvolver sistemas para desenvolver o harness que permite que sistemas sejam gerados.
O código virou output. O harness virou o produto. Isso é AI harness engineering, e é o fundamento da profissão daqui para frente.
O dev que não aprende isso fica com duas opções, ambas ruins: ler cada diff, mais lento que a máquina, ou confiar às cegas, mais irresponsável que a máquina.
O operador com harness não escolhe entre velocidade e confiança. Ele constrói a confiança uma vez, em infraestrutura, e a máquina a executa em toda mudança.
O failure ledger é a memória que falta
O pulo do gato é fazer o harness se alimentar sozinho. Cada falha relevante em produção precisa virar um artefato que muda o comportamento da próxima rodada.
Eu chamo isso de failure ledger: um livro-razão de tudo que já quebrou e do que foi feito para impedir ou detectar a repetição.
Cada entrada é dado operacional: incidente, hipótese, sinal, causa, correção, teste, alerta, versão e dono.
RAG guarda fatos sobre o mundo. O ledger guarda o que o agente e o sistema fizeram no mundo, o contexto daquela decisão e a consequência observada.
Parêntese: RAG não substitui ledger
RAG combina o que o modelo aprendeu com trechos recuperados de uma base externa. O retriever busca contexto relevante e o modelo usa esse contexto para responder ou tomar a próxima decisão.
Isso resolve acesso à informação. Se o runbook de uma API está indexado, o agente pode recuperá-lo antes de chamar a ferramenta. RAG não registra que a chamada foi feita, com quais argumentos, qual efeito externo aconteceu e se o resultado foi bom ou ruim.
No ledger, decisão, ação, resultado e causa são o centro. Sem essa cadeia, você dá contexto ao próximo agente, mas não prova o que o anterior fez.
Agente sem memória de resultado é estagiário com amnésia: executa, quebra, começa de novo e repete.
Um outcome ledger guarda decisões, consequências e a cadeia causal do que deu errado. Sem histórico causal, o incidente seguinte vira inferência, não evidência.
Uma entrada útil do meu ledger teria, no mínimo, incident_id, commit e imagem do deploy, versão do prompt e do modelo, tool calls, inputs sanitizados, assertions quebradas, trace, métrica, blast radius e a contramedida criada.
A contramedida não é só “corrigi o bug”. Pode ser um teste de regressão, uma invariante no banco, uma política IAM, um alarme de custo, um canário ou uma aprovação antes de alterar estado irreversível.
O estado do ledger deve ser append-only. Correção é evento novo, não edição da história. Sem isso você não responde o que o agente decidiu, por que decidiu e qual dado anterior contaminou a decisão.
Meu objetivo é simples: a mesma falha não deveria nos ensinar a mesma lição duas vezes. Não é magia. Dependências e requisitos mudam, e um teste pode continuar incompleto. Mas esquecer o que quebrou é escolha, não destino.
O ledger aprende com uma falha real. Ainda falta testar o que não falhou, mas vai falhar. Esperar o incidente para descobrir se o sistema se recupera é uma forma cara de testar recuperação.
É por isso que a Netflix entra aqui. O Chaos Engineering da Netflix usa o Chaos Monkey para injetar falhas controladas e comprovar a recuperação automática. Não é uma história sobre servidores aleatórios caindo. É um método para trocar suposição por evidência antes que a produção faça o experimento por você.
O paralelo com agentes é direto. O ledger transforma a falha que já aconteceu em contramedida. O teste de caos força falhas plausíveis para verificar se as contramedidas, os limites e a recuperação realmente funcionam.
Para agentes, isso significa testar timeout de ferramenta, resposta 429, schema desatualizado, fila fora de ordem, permissão IAM negada, migração parcial, cache mentiroso e prompt injection vindo da saída de uma ferramenta.
Não basta ver se o agente concluiu a happy path. Ele precisa sobreviver a dados ruins, dependência lenta, autorização revogada e efeito externo que diz sucesso sem ter acontecido.
Uma ressalva honesta: o ledger aprende com falha que aconteceu e foi detectada. Ele é cego para corrupção silenciosa, permissão larga que ninguém explorou e custo vazando devagar.
Para essas classes de problema, a resposta é mais harness: detector de anomalia de billing, reconciliação de dados, drift de schema, varredura de segredo, auditoria periódica de permissões e limites de blast radius.
Terceirize o sensível, vibecode o resto
“Mas e as partes críticas? Auth, pagamento, identidade?” Resposta: você não deveria estar escrevendo isso na unha em 2026, com ou sem IA.
Stripe, Okta, Clerk. Empresas com times inteiros dedicados só a isso fazem melhor do que você jamais fará. Terceirizar o sensível é boa engenharia, ponto.
O que sobra como responsabilidade sua depois de terceirizar? Integração, configuração e os seus dados de domínio, aqueles que nenhum SaaS resolve por você.
A maioria dos vazamentos que vejo não é código ruim. É bucket S3 público, política IAM permissiva, webhook sem validação de assinatura e cola mal feita entre componentes.
A superfície de erro migrou do código para a cola. Ou seja: migrou para exatamente o território do harness.
O modelo completo fecha assim:
- Compre o sensível: auth, pagamento e identidade.
- Vibecode o descartável: praticamente todo o resto.
- Concentre o cérebro humano no harness: testes, observabilidade, configuração e decisão de risco.
Isso não é preguiça. É alocação racional do recurso mais caro do sistema, que é a sua atenção.
O dev de CRUD já era
Alocação racional tem um lado B: ela expõe quem estava alocado no lugar errado.
Pensa no dev das antigas: recebia ticket, escrevia endpoint, montava CRUD em cima do ORM, mapeava request para query para response e ia levando de sprint em sprint.
Backend de sistema interno, formulário para o banco, relatório para a tela. Vida estável.
Esse trabalho foi o primeiro a virar commodity, e não por acaso. É o código mais previsível, repetitivo e bem representado nos dados de treino que existe.
Ambiguidade quase zero. Um agente entrega em minutos, por centavos, e ainda entrega com teste junto. Não existe cenário em que digitar isso à mão seja uma alocação defensável de um salário de engenheiro.
A parte desconfortável: esse dev não “vai ser” substituído. Já foi. O crachá ainda existe; a função, não.
A vaga sobrevive por inércia organizacional, e inércia é um prazo, não uma proteção. Quando uma empresa descobre que um operador com agentes entrega o backlog de N devs de CRUD, a matemática do headcount se resolve sozinha.
É extinção com delay, e o delay está encurtando.
Os anos de experiência desse dev não convertem automaticamente para o trabalho novo. Saber escrever um CRUD não é saber o que medir, quando desconfiar, nem como desenhar um teste que prova alguma coisa.
São músculos diferentes. A rota de fuga existe, mas não se chama “aprender a fazer prompt”. Prompt é trivial. Se chama aprender a construir harness.
Quem fizer essa migração vira operador. Quem não fizer vai competir em preço com uma API que cobra centavos por milhão de tokens.
O dev virou operador
Junta tudo isso e o quadro fica claro: o “dev” que usa IA hoje não é mais dev no sentido de 2022. É um operador.
Quem não entende de system design, produto, segurança e harness já ficou para trás, mesmo que ainda não tenha percebido.
Digitar código virou o cartão perfurado da nossa era. O que não virou legado foi fundamento: saber o que construir, como estruturar, o que medir e quando desconfiar.
A camada de valor subiu, e quem ficou agarrado na camada de baixo está competindo com uma API.
Tem um efeito colateral que pouca gente discute: a pirâmide achatou. O júnior que só escrevia código perdeu a função, mas o caminho para virar quem toma decisão de arquitetura passava justamente por anos escrevendo código.
A indústria ainda não resolveu de onde vão sair os próximos operadores. Isso sugere que quem já cruzou a ponte fica mais escasso com o tempo, não menos.
A defasagem que ninguém te conta
Agora a parte incômoda. O trabalho já mudou, mas o mercado ainda não.
A maioria das empresas contrata, entrevista e paga pelo modelo antigo. LeetCode, diff review ao vivo, system design sem IA. Existe uma defasagem brutal entre o que o trabalho virou e o que o funil de contratação mede.
Isso gera uma situação esquisita: o operador é mais valioso na prática e, ao mesmo tempo, mal medido pelo processo seletivo.
A consequência prática é que você precisa dos dois modos. Opera do jeito novo no dia a dia e mantém o modo entrevista aquecido em paralelo.
É irritante? É. Mas é o pedágio de estar na frente da curva enquanto o resto do mercado alcança.
Concluindo
A discussão “IA vai substituir devs?” já morreu, só não avisaram todo mundo. A substituição aconteceu na natureza do trabalho, não nas vagas.
O que era escrever código virou orquestrar agentes com julgamento. O que era code review virou engenharia de harness. O que era “conhecer o codebase” virou “conhecer o sistema pelos seus sinais”.
A aposta não é defender a habilidade antiga. É ser excelente no que sobrou de humano no loop: decisão, arquitetura, harness e a responsabilidade final por aquilo que roda.
Construir-consertar ficou barato. Julgamento continua caro. Cobre por ele.
