O ofício na era do código gerado
Este ano fazem a mesma pergunta a todos os estúdios: se um modelo escreve o código, o que é que estão a cobrar exatamente? A nossa resposta, na forma daquilo que a nossa própria build se recusa a aceitar.
Nesta página
Escrever código deixou de ser a parte cara. Ler código nunca ficou mais barato, e essa assimetria é toda a história do ano.
Um modelo produz quatrocentas linhas de TypeScript plausível no tempo em que acaba uma frase. A sua capacidade de segurar quatrocentas linhas na cabeça e perguntar o que teria de ser verdade para isto estar errado é exatamente a mesma que era em 2019. O estrangulamento mudou-se para a única parte do processo que não acelera. Todos os argumentos sobre engenharia assistida por AI que me interessam começam aí; os que me aborrecem são todos, no fundo, sobre se escrever à máquina alguma vez foi o essencial.
O código gerado também falha de uma maneira particular e desagradável: falha de forma plausível. Os erros escritos à mão costumam parecer erros — uma variável mal nomeada, um ramo que obviamente nunca corre, um comentário a discutir com a linha por baixo. Os erros de um modelo chegam bem vestidos. Os nomes são bons, a estrutura é convencional, os comentários concordam com o código, e a segunda resposta de DNS nunca é verificada.
Por isso deixámos de perguntar quem escreveu uma linha e passámos a perguntar o que é que, na build, protestaria se a linha estivesse errada.
Verificações que correm sem mim
O Orrery propaga órbitas de satélites no navegador a partir dos conjuntos de elementos publicados pelo CelesTrak. Em desenvolvimento, antes de um único píxel disso aparecer, corre uma autoverificação. Dê-lhe um conjunto de elementos do tipo ISS — movimento médio de 15.495 revoluções por dia — e tem de devolver um período orbital de 92.933 minutos e uma velocidade de 7.660 km/s. Dê-lhe um conjunto geostacionário e a longitude tem de derivar 0.010° em seis horas. Estes números não são nossos. Vêm da física, e eram verdade muito antes de o ficheiro existir.
O valor dessa verificação está inteiro naquilo que impede: um mapa de satélites que está errado em todo o lado e obviamente errado em lado nenhum. O erro orbital não se anuncia. Cada ponto continua a mover-se suavemente, o planeta continua a girar, e nada no ecrã lhe diz que o solucionador de Kepler perdeu uma iteração na arrumação de alguém. As asserções dizem.
O mesmo instinto, à escala do brincar. O Slipstream é um corredor de faixas cujas filas de obstáculos vêm de padrões gerados, e um padrão que não deixa nenhuma faixa alcançável à velocidade máxima não é um nível difícil — é um nível partido. Esse defeito sobrevive lindamente aos testes de jogo, porque quem morre assume que jogou mal. Por isso os padrões são validados quando o módulo carrega: propaga-se para a frente que faixas é que a nave consegue fisicamente alcançar no pior caso de velocidade, 32 unidades por segundo, e garante-se que cada fila mantém pelo menos uma delas sobrevivível. O comentário nesse ficheiro é a filosofia inteira em nove palavras — justo para o validador é justo para o jogador.
| O que corre | O que garante | Porque é que uma pessoa não o cobre |
|---|---|---|
| Autoverificação da propagação do Orrery | Órbita tipo ISS → período de 92.933 min, 7.660 km/s; deriva geostacionária de 0.010° em 6 h | O erro orbital é invisível de relance — o mapa parece certo enquanto está errado |
| Validador de padrões do Slipstream | Cada fila de obstáculos mantém uma faixa alcançável no pior caso de velocidade | Os testes de jogo podem não encontrar a fila injusta; não conseguem provar que não existe nenhuma |
| Esquema, limites e sanitizador do Blueprint | 3–14 nós, exatamente 3 fases, nenhuma ligação solta, nenhum id de opção desconhecido | O resultado do modelo lê-se com fluência mesmo quando é estruturalmente impossível |
Três verificações ligadas a caminhos de código que um programador já percorre. Nenhuma delas quer saber quem escreveu o código que está a verificar.
Essa última propriedade importa mais do que as próprias verificações. A verificação de que é preciso lembrar-se é verificação que mais tarde ou mais cedo vai saltar, normalmente no dia em que anda mais depressa — o que, hoje, é quase todos os dias.
O modelo propõe; o motor decide
O Blueprint é onde tivemos de responder a isto comercialmente e não filosoficamente. Um visitante descreve um produto, o Claude rascunha uma arquitetura, a página desenha-a e agarra-lhe um preço. A catástrofe óbvia é um modelo de linguagem inventar um número que um desconhecido depois trata, com toda a razão, como um orçamento nosso.
Por isso há uma regra nesse código, escrita como frase e não como flag de configuração: o LLM nunca orça nada — apenas propõe seleções, e mesmo essas são sanitizadas primeiro.
Na prática, o modelo escolhe de um catálogo fechado: plataformas, funcionalidades, capacidades de AI, um nível de design, um número de integrações. Os identificadores desconhecidos são descartados à chegada. Os campos obrigatórios de escolha única que voltaram vazios são preenchidos por omissão. Depois a aritmética acontece num sítio onde o modelo não chega — unidades de base somadas ao longo das seleções, multiplicadas pela complexidade do produto, pelo nível de QA e pelo âmbito de lançamento, convertidas por uma faixa de taxa unitária; o prazo com as plataformas a correr em paralelo, o resto a quinze unidades por semana, mais duas semanas de folga. É o mesmo motor determinístico por trás da nossa página de preços, a ler as mesmas regras. A lista de enums no esquema de saída, o catálogo de opções no prompt e a lista de permissões do sanitizador derivam todos desse mesmo objeto de regras, portanto não podem afastar-se em silêncio.
O modelo pode ser imaginativo quanto à arquitetura. Não pode é chegar perto de um número sobre o qual um cliente possa agir.
Duas decisões mais pequenas no mesmo espírito. A ideia do visitante é embrulhada em etiquetas e tratada como dados, não como instruções, porque uma caixa de texto numa página pública é entrada não fidedigna por mais conversacional que pareça. E quando um blueprint se torna um pedido de orçamento, a estimativa é recalculada no servidor a partir das seleções sanitizadas; os números que chegaram do navegador são ignorados por completo. O preço de um cliente nunca deve ser um valor que passou por um sítio onde um desconhecido pode escrever.
Saber contra o que não se defendeu
Um servidor que vai buscar URLs escritos por desconhecidos é uma arma carregada apontada à sua própria rede, e é exatamente isso que o Reliquary é: cola-se um link, o nosso servidor vai buscar a página, analisa-a e devolve uma peça. Os endereços que vale a pena atacar não estão na internet pública. 169.254.169.254 é onde os fornecedores de nuvem estacionam os metadados da instância; as gamas privadas são onde vive o resto da sua infraestrutura. Escrevemos sobre essa construção em junho; a proteção é a parte menos glamorosa dela e a primeira que eu defenderia.
Só http e https, só as portas 80 e 443, sem credenciais contrabandeadas no campo de userinfo. Uma lista de recusa que cobre as gamas privadas, reservadas, link-local e de NAT de operador. DNS resolvido com todos os endereços devolvidos e cada um obrigado a ser público, porque validar apenas a primeira resposta é o quase-acidente clássico. Cada salto de redireção reanalisado e revalidado de raiz — um URL público que redireciona para um endereço de loopback é o ataque inteiro. Prefixos IPv6 classificados antes da cauda em notação decimal, nessa ordem, já que o inverso deixaria passar um endereço mapeado com um quarteto de aspeto público.
E depois a parte de que tenho mais orgulho. Um comentário nesse ficheiro nomeia o ataque que não travámos: DNS rebinding. Entre o momento em que validamos um nome de anfitrião e o momento em que o socket liga, a resposta pode mudar para algo privado. Fechar isso como deve ser significa fixar a ligação ao endereço já validado, o que significa um dispatcher HTTP à medida e uma nova superfície de dependências, e julgámos que não compensava para uma funcionalidade que vai buscar anúncios de leilões. O julgamento pode estar errado. Está, pelo menos, escrito, para que a próxima pessoa a ler o ficheiro herde o raciocínio em vez da impressão de que está tudo tratado.
Esta é a parte que nenhum gerador faz por si. Um modelo escreve de bom grado um validador de URLs, e até pode escrever um bom. O que não consegue fazer é decidir que risco residual o seu negócio está disposto a carregar e depois dizê-lo em voz alta, num sítio onde se possa discutir com ele. Discernimento não é a capacidade de produzir a versão defendida. É conhecer a forma daquilo que fica por defender, escolhê-lo deliberadamente e pôr o seu nome na escolha.
Duas outras coisas continuam teimosamente humanas por aqui. Uma é a invariante — a frase que um sistema não tem licença para violar — porque as invariantes codificam aquilo que nos importa, e nada num corpus de treino sabe o que nos importa. A outra é decidir o que não construir. O Reliquary guarda cada peça no armazenamento local do seu navegador e absolutamente nada nos nossos servidores. Isso custou funcionalidades reais: sem partilha, sem sincronização entre portátil e telemóvel, um limite rígido de sessenta peças, e nenhuma ideia do que quem quer que seja faz com a coisa. Nenhum sistema treinado na última década de software teria proposto recusar os dados. Foi uma decisão de gosto, e o gosto é exatamente aquilo que o padrão de quem conjura foi escrito para proteger.
O que me traz à palavra que toda a gente usa este ano. Slop não é uma propriedade da AI; é uma propriedade da revisão. Código sobre o qual ninguém consegue dizer o que teria de ser verdade para isto estar errado é slop, tenha vindo de um modelo, de um subcontratado ou de mim à uma da manhã. A nossa indústria despachou oceanos disso muito antes de alguma coisa completar uma função automaticamente. Os modelos não inventaram essa falha. Baixaram o custo de a produzir, o que é um argumento para levar a revisão mais a sério, não menos.
A parte incómoda desta posição é que escala mal, e acho que quem vende o futuro sabe disso. Gerar é quase grátis e fica mais grátis a cada mês. Verificar é trabalho, é teimosamente linear, e é aquilo que estamos de facto a cobrar. Quando um cliente pergunta o que está a pagar a um engenheiro em 2026, a resposta honesta é: não é a escrita. São as recusas. O número que teve de vir da calculadora, a fila que teve de continuar sobrevivível, o risco que teve de ser nomeado num comentário onde alguém pudesse discordar dele.