Todo mundo está pagando por modelo mais caro. Opus, GPT, Gemini, o que sair nesta semana. E o pull request continua voltando torto: botão no lugar errado, estado que some no refresh, um useEffect que o time já proibiu há um ano. Não é o modelo. É a especificação.
Em 2026, Claude Code, Codex, Cursor com agentes e o Gemini CLI — o Antigravity, pra quem já entrou nessa onda — escrevem a maior parte do código de frontend que eu reviso. O gargalo não é mais montar JSX. É dizer, sem folga, o que aquele componente faz quando o usuário erra o formulário, quando a API volta 429, quando o tema escuro encontra um modal legado. Código ficou barato. Clareza ficou cara.
No post anterior eu disse que o contexto é o novo código. Continuo achando isso. Só que a forma mais alta de contexto não é o AGENTS.md nem o grep bem feito. É a especificação. Prompt solto morre na sessão. Spec boa sobrevive ao chat, ao modelo e à pessoa que sai de férias. Vira o artefato mais importante do time.
O código já não é o que a gente escreve
Eu ainda abro o editor. Só que cada vez menos pra digitar a feature. Abro pra ler o diff que o agente gerou, pra recusar um padrão, pra apontar o token de cor que já existe no design system. Orquestro. Não sou o autor da linha. Sou o autor da intenção.
Isso muda o centro de gravidade do frontend. Componente, hook, teste — o agente faz. O que ele não inventa bem sozinho é o contrato: o que é sucesso, o que é erro, o que não pode acontecer. Se você não escreve isso, ele preenche o vazio. E o vazio no frontend vira loading infinito, toast genérico, formulário que aceita CEP inválido e um CSS que fura o grid do produto.

Spec-first de verdade não é waterfall
Quando eu falo spec-first, alguém ainda escuta documento de 40 páginas aprovado por comitê. Esquece. Waterfall é spec morta. Spec-first em 2026 é spec executável: curta, versionada, com critério de aceite que um agente consegue checar e um humano consegue recusar em dois minutos.
Não é planejar o produto inteiro antes. É recusar começar a gerar código com um “faz a tela de checkout”. É escrever o comportamento e só então soltar o Claude Code. Se o spec muda no review — e vai mudar — você atualiza o spec. O código acompanha. Não o contrário.
Pedido vago: “monta o formulário de endereço”. Pedido que funciona:
- Objetivo: capturar endereço de entrega no checkout, reusando o
AddressFielddo design system. - Entrada e saída: CEP com máscara entra; sai um objeto
{ cep, street, number, city, state }válido. - Sucesso: CEP com 8 dígitos dispara a busca; campos preenchidos ficam editáveis; número e complemento nunca vêm da API.
- Borda: CEP inexistente mostra erro no campo, não toast; timeout de 3s; botão Continuar desabilitado enquanto inválido.
- Limite: não criar cliente HTTP novo; usar o
useCepLookupque já existe. Sem página extra. Sem persistir nolocalStorage. - Aceite: teclado no mobile não cobre o botão; labels visíveis; erro anunciado pra leitor de tela.
Como escrever specs que o agente entende
Agente não lê sua mente. Lê estrutura. Eu uso sempre o mesmo esqueleto, no ticket ou num SPEC.md ao lado da pasta do componente:
- Objetivo em uma frase.
- Entrada e saída, com tipos.
- Caso feliz, passo a passo.
- Casos de borda — a parte que o agente mais inventa se você omitir.
- Limites: o que não fazer, o arquivo que não mexer, a lib que não adicionar.
- Critérios de aceite observáveis. Se não dá pra ver no browser ou no teste, não é aceite.
O item 5 é o que mais economiza retrabalho. “Não mexer em auth/.” “Não instalar lib de formulário.” “Seguir o padrão de erro do FormMessage.” Sem limite, o Cursor inventa um schema Zod paralelo, o Codex cria um context provider novo, o Claude Code “melhora” a paleta. Tudo com convicção. Tudo errado.

O ciclo curto: spec, agente, review, spec v2
O ciclo que pegou no meu dia a dia é curto de propósito. Escrevo o spec. Mando o agente. Reviso o diff como se fosse de um júnior muito rápido. O que estiver errado não vira só “ajusta isso” no chat. Vira emenda no spec. Aí roda de novo.
Esse loop cabe numa hora. Spec de checkout, Claude Code gera a tela, eu recuso o toast, atualizo o aceite pra “erro no campo”, segunda passagem já nasce certa. Quem tenta acertar o código no feeling, sem voltar pro spec, treina o agente a improvisar. Review sem atualizar o spec é retrabalho disfarçado: daqui a duas semanas outro modelo, mesma feature, e a regra do CEP inexistente some de novo.
Armadilhas que eu já pisei
- Spec vaga. “Deixa bonito e responsivo.” Bonito pra quem? Responsivo até qual breakpoint? O agente escolhe. Você herda. Sem copy do estado vazio, vai aparecer “No data” em inglês no meio do checkout em português.
- Spec gigante. Um arquivo que descreve o produto inteiro. O modelo dilui a atenção, começa bem e termina inventando tela que ninguém pediu. Uma fatia por vez. Checkout não é o mesmo spec do catálogo.
- Agente que inventa requisito. Ele “aproveita” e adiciona dark mode, skeleton, analytics. Se não estava no spec, é bug — mesmo que fique bonito. Recuso no review e registro o limite: sem feature extra.

O código é barato. A clareza é cara.
Senioridade em 2026 não é quem digita o hook mais rápido. É quem escreve o contrato que o hook precisa honrar. Agente escreve código. Humano escreve especificação. E se o contexto é o novo código, a spec é o contexto que o time inteiro — gente e modelo — consegue executar.
Paga pelo modelo que quiser. Sem spec clara, você só comprou um júnior confiante em escala. Com spec clara, você comprou um time. A diferença não está no token. Está na frase que você teve coragem de deixar inequívoca.