Nota: tudo aqui foi construído e validado com Claude Code, e os exemplos usam os primitivos dele, CLAUDE.md, hooks, skills, subagentes. O método não depende da ferramenta. Qualquer agente que ofereça instruções permanentes, gates determinísticos e contexto isolado para revisão suporta o mesmo desenho: mudam os nomes dos arquivos; as decisões seguem as mesmas.
A cena se repete em qualquer time que adotou coding agents: o modelo escreve em vinte minutos o que levaria uma tarde, o teste quebra, alguém copia a mensagem de erro, cola no chat, o modelo pede desculpa e tenta de novo. Até passar. No fim do dia, a pessoa mais cara da sala trabalhou de clipboard entre a máquina que gera e a máquina que valida. A geração de código ficou absurdamente barata, e a vazão do time continua a mesma, porque o gargalo nunca foi gerar. É verificar.
Venho construindo e refinando um guideline de desenvolvimento com IA há mais de um ano, num contexto onde errar custa caro: domínio regulado, regra com fonte normativa, dinheiro onde arredondamento errado vira passivo. Nesse período minerei dezenas de fontes, de artigos de engenharia da Anthropic a listicle que inventava comando inexistente, e cada ideia só entrou no sistema depois de verificada na fonte primária. Este artigo é a destilação: como fazer, por que fazer, e principalmente por que o desenho é esse e não outro. E o guideline completo, com as skills de implementação, o reviewer, os commands, os hooks e o template de spec prontos para instalar, está publicado num repositório aberto: este artigo explica o desenho, o repo entrega os artefatos.
A tese: o gargalo saiu da geração e mudou para a verificação
Desenvolver software nunca foi digitar código. É transformar intenção ambígua em mudança verificada, e a IA atacou de forma brutal só o miolo desse processo. Entender o que o negócio precisa continua caro. Garantir que a mudança faz o que deveria continua caro. Quando você acelera o meio sem escalar as pontas, o resultado é slop mais rápido: output que parece completo mas não reduz a bagunça. Compila, tem cara de pronto, e deixa o sistema mais difícil de mudar do que estava.
O Lucas F. Costa escreveu a frase que virou a lente permanente do meu sistema: qualquer fluxo que dependa de um humano para pegar os erros da máquina fica limitado pelo humano, não pela máquina. Se cada PR de agente precisa de um humano lendo linha por linha, sua capacidade de produção é a capacidade de leitura do seu time, e você pagou por um gerador que passa o dia esperando revisor. E o modo de falha é pior que a fila: quando o volume satura o revisor, o review vira skim, e slop passa. A resposta ele chama de backpressure, e eu adotei como princípio fundador: todo não que a máquina consegue produzir, um teste falhando, um type error, uma regra de lint, a objeção de um reviewer automatizado, tem que disparar antes de um humano olhar o trabalho. O sintoma de que falta backpressure é você se pegar copiando feedback da máquina de volta para o agente. Nesse momento está faltando um check, e a correção é construir o check em vez de aceitar o papel de clipboard.
A indústria automotiva resolveu esse problema há décadas e deu nome: jidoka. A linha da Toyota para sozinha quando detecta defeito, em vez de deixar a peça errada seguir até o inspetor no fim da esteira. O inspetor humano existe, mas olha exceção; a peça comum passa direto pela esteira. Com agentes é o mesmo desenho: o humano revisa o que sobreviveu a todos os gates, e quando algo escapa, a resposta é desenhar o gate que faltou.
A segunda metade da tese é sobre intenção. O Addy Osmani deu nome ao problema que specs e context files resolvem: intent debt, a dívida do porquê que nunca foi externalizado. Com times humanos, intenção implícita era um imposto pago no onboarding e em arqueologia de git blame. Com agentes, o custo mudou de escala: um porquê não escrito é pago de novo em toda sessão, multiplicado por cada agente que toca o código, porque o modelo não tem onde ler a intenção e re-deriva, ou inventa, a cada vez. Por isso o guideline insiste em intenção externalizada em artefatos versionados, cada um na altitude em que ela nasce: spec para regra de negócio, constitution para princípio inegociável, ADR para decisão arquitetural datada, o plano aprovado para o racional da implementação, lessons para o erro que não pode se repetir.
O terceiro pilar é a diferença entre instrução e enforcement. CLAUDE.md, AGENTS.md, regras em markdown: tudo isso é instrução, e instrução o modelo segue na maior parte do tempo. A própria Anthropic é explícita nisso: em sessão longa, sob ambiguidade ou pressão, uma regra de prompt pode ser ignorada, e guardrail de verdade precisa ser determinístico. Na minha experiência a adesão fica na casa dos 70%, um número que a comunidade repete de forma anedótica, sem medição rigorosa, mas que bate com o que vejo no dia a dia. Para convenção de nomenclatura, isso resolve. Para “nunca use float em valor monetário” num sistema fiscal, é um incidente agendado. A regra que precisa de 100% vira mecanismo: hook que bloqueia o commit, regra de linter, check de AST no CI. Instrução é esperança; hook é garantia. Boa parte das decisões de desenho que vêm a seguir deriva dessa distinção.
Os cinco princípios
Tudo no sistema deriva de cinco princípios. Quando uma situação nova aparece e nenhuma regra cobre, é para eles que eu volto.
- Menor mudança possível. Deletar linha vale mais que adicionar. Nada de refactor não pedido, helper especulativo, abstração para um futuro que talvez não venha. Agente tem tendência crônica de fazer mais do que foi pedido, e cada linha extra é superfície de review que alguém paga depois.
- Causa raiz, não band-aid. Bug apareceu, descobre por quê. Fix temporário que esconde sintoma vira permanente, e com agente gerando fix plausível em segundos a tentação de tratar sintoma só aumenta.
- Verificação é parte do trabalho, não opcional. Toda mudança nasce com sua forma de verificação: teste, output esperado, comportamento observável. Se não dá para verificar, não faz merge. Sem isso, “pronto” é opinião.
- Determinismo onde dá, agente onde precisa. Tarefa previsível, mover arquivo, indexar, manipular label de issue, append em log, vira script que o agente chama, e sai da lista de trabalho do agente. O agente é caro, não determinístico e queima contexto; script é barato, auditável e dá o mesmo resultado toda vez. Se você está pedindo ao modelo algo que um shell resolveria, mova para o shell.
- O primeiro não é da máquina. O backpressure da seção anterior, promovido a princípio de projeto: todo gate que a máquina consegue rodar dispara antes de pedir o olhar de um humano.
Os quatro primeiros parecem senso comum de engenharia, e são. A diferença é que com agente eles deixam de ser virtude pessoal e viram regra externalizada, porque quem precisa segui-los agora é um modelo que nasce sem memória a cada sessão.
Spec-anchored: a decisão de negócio vem antes do código e ancora tudo depois
O guideline tem nome, Spec-Anchored Agentic Development, e o nome diz o desenho: desenvolvimento organizado por capability, com uma spec por capability fazendo dois papéis. Capability é uma fatia coesa do que o sistema faz pelo negócio: pagamentos, pedidos, notificações, billing. Não é camada técnica (controller, repository), nem entidade (Product, Customer), nem mecanismo (cache, fila). É a unidade natural para escrever spec porque o negócio já desenhou a fronteira dela. Quem leu o que escrevi sobre DDD em serverless vai reconhecer o parentesco com bounded contexts, mas o vocabulário é opcional: você não precisa de DDD para saber que pagamentos não é pedidos.
Os dois papéis são as duas metades do nome. A spec vem antes: a decisão de negócio precede o código em vez de emergir dele, porque vibe coding não descobre arquitetura, descobre o caminho de menor resistência do modelo, que raramente coincide com a fronteira do seu domínio. E a spec ancora: dali em diante ela é o ponto fixo contra o qual tudo se verifica, os testes ancoram nos acceptance criteria dela, o reviewer compara o diff com ela, e divergência entre spec e código entra na fila como qualquer outro bug. Spec escrita e abandonada é papel morto; o valor mora na âncora que continua sendo cobrada depois do merge. Identificar as fronteiras, por sua vez, custa menos do que parece, porque na maioria dos projetos você já sabe onde elas estão. Quando não é óbvio, existem sinais, e o melhor deles é linguístico: se a mesma palavra mudou de significado, você cruzou uma fronteira. “Produto” no catálogo, nome, foto, descrição, não é “produto” no estoque, saldo, reserva, localização. Os outros sinais seguem a mesma lógica: o ator principal mudou, a cadência de mudança mudou (catálogo muda todo dia, regra de pagamento muda por trimestre), o que sempre muda junto se agrupa, o que precisa ser atômico fica junto. Em brownfield grande, onde a fronteira intencional e a real divergiram há muito tempo, minere evidência em vez de opinar: co-change no histórico do git, arquivos que sempre mudam juntos pertencem ao mesmo lugar, e clustering no grafo de dependências. Event Storming e cerimônias pesadas de modelagem entram como escalada, quando o caso é genuinamente difícil.
E o nome tem lastro fora daqui. Uma taxonomia está se consolidando na literatura, num paper de 2026 no arXiv ecoado pela série exploring-gen-ai do site do Martin Fowler, com três níveis de rigor dentro de spec-driven development. Spec-first: a spec precede o código, mas pode divergir ou ser descartada depois, e o código vira o artefato primário. Spec-anchored: a spec é permanente e o código responde a ela continuamente. Spec-as-source: o código é gerado ou derivado da spec. Kiro e Spec Kit, as ferramentas que você provavelmente conhece dessa conversa, são spec-first, specs por feature que guiam o trabalho e depois viram história; a observação de campo da série é que quase todo approach de SDD hoje para nesse nível. Este guideline é spec-anchored por construção, drift é bug e conformidade se verifica valor a valor. E para regra normativa ele caminha para as-source: os valores de referência da spec geram os golden tests que servem de oráculo.
Dois erros opostos matam projetos aqui. O primeiro é começar a codar sem identificar capabilities: na semana oito são 30 mil linhas, ninguém sabe onde nada mora e cada mudança quebra três coisas. O sintoma é você, ou o modelo, perguntando “onde isso vai?” e não existir resposta clara. O segundo é o inverso, tentar especificar toda regra e todo edge case no papel antes da primeira linha de código. Fronteira fica nítida durante a implementação, e spec tática completa escrita antes vira dívida antes do primeiro deploy; o sintoma é editar mais spec do que código nas primeiras semanas. O equilíbrio que funciona: fronteiras upfront e leves, detalhe tático evoluindo junto com a implementação. Estratégico antecipado, tático emergente.
A spec de capability captura a fonte da verdade de negócio: regras de domínio, edge cases com o tratamento esperado, non-goals (o que essa capability explicitamente não faz), contratos com as vizinhas. Regra que deriva de fonte externa cita a fonte, norma tal, versão tal, e isso em domínio regulado é obrigação auditável. O jeito mais eficiente que encontrei de escrever uma spec é inverter o fluxo: sessão em Plan Mode onde o modelo lê os contratos vizinhos e a constitution, e depois me entrevista, uma pergunta por vez, cada uma já com uma resposta recomendada que eu confirmo ou corrijo, sobre regras, edge cases e non-goals antes de escrever qualquer coisa; no repositório, esse fluxo é o command /shape. O modelo pergunta muito melhor do que preenche template, e as perguntas que ele faz expõem ambiguidade que eu nem sabia que estava carregando.
Uma decisão de desenho fecha essa parte: mudança de spec é mudança de regra de negócio, então qualquer PR que atualiza spec carrega um flag de requires_human_approval. O agente pode evoluir a spec durante a implementação, mas regra de negócio nunca passa sem olho humano.
E o ponto de entrada é menor do que todo esse aparato sugere: um arquivo. specs/pagamentos/pagamentos.md com regras, edge cases e non-goals em meia página já é spec-anchored. Você não precisa de constitution, reviewer nem trajetória de autonomia para começar; precisa da decisão de negócio escrita antes do código. Todo o resto deste artigo é como o sistema escala, e cada peça entra quando a dor correspondente aparece.
Contexto em três camadas
Context engineering aqui opera em três camadas, e misturá-las é a maior fonte de problema que vejo em setups de agente. A camada 1 é conhecimento permanente: convenções, regras de domínio, decisões arquiteturais, glossário. Vive em arquivos versionados e muda raramente; cada mudança é um commit consciente. A camada 2 é trabalho ativo: o plano da feature, notas de pesquisa, decisões locais. Muda o tempo todo durante a feature e é descartável depois dela. A camada 3 é intenção e priorização: o que fazer, em que ordem, por quê. Vive em GitHub Issues com labels. Se ajudar, pensa em memória de longo prazo, memória de trabalho e agenda. E a regra de fluxo entre camadas é o que mantém o sistema vivo: o que se aprendeu na camada 2 e merece sobreviver sobe para a camada 1; o que está obsoleto na camada 1 é atualizado ou morre.

As três camadas de contexto: conhecimento permanente versionado, trabalho ativo descartável, backlog de intenção. A regra de fluxo entre elas é o que impede o sistema de apodrecer: o que merece sobreviver sobe, o que ficou obsoleto morre.
Na prática, a camada permanente tem uma topologia:
projeto/
├── CLAUDE.md ← entrada, ~60 linhas (nunca 100)
├── architecture/
│ ├── constitution.md ← princípios inegociáveis
│ ├── pipeline.md ← contratos entre capabilities
│ └── decisions/ ← ADRs
├── .claude/
│ ├── rules/ ← regras invariantes, auto-carregadas
│ ├── commands/ ← /implement, /review, /shape, /spec-to-tickets
│ ├── agents/reviewer.md ← o reviewer independente
│ └── skills/ ← implement-feature, implement-backlog
│ e os critérios de review
├── docs/ ← glossário, normas, walkthroughs
├── specs/ ← fonte da verdade, espelha src/
│ └── pagamentos/
│ ├── pagamentos.md
│ └── contracts/
└── src/
└── pagamentos/
├── CLAUDE.md ← ponteiro para a spec, 20-40 linhas
└── ...
Duas decisões nessa estrutura carregam o peso. specs/ e docs/ são centralizados, fonte da verdade num lugar só, espelhando os nomes de src/. E cada capability tem um CLAUDE.md próprio (ou AGENTS.md, o padrão aberto que Codex, Cursor e os outros leem; mesma mecânica), ao lado do código, porque esses arquivos carregam por proximidade: o agente carrega o mais próximo do arquivo que está editando. Context file longe do código que descreve simplesmente não é lido na hora certa. E uma convenção que vale adotar desde o início: tudo que o agente lê, context files, specs, rules, skills, é escrito em inglês, mesmo num time que fala português, porque os modelos são treinados majoritariamente em inglês e contexto em inglês reduz drift de terminologia.
Mais importante que a estrutura é a disciplina do que escrever nela, e são três regras de ouro.
Documente só o que o agente não consegue inferir. Não descreva estrutura de pastas; deixe o layout falar. Referência estrutural desatualizada engana ativamente, enquanto a ausente não custa nada. O corolário é que isso só funciona se o layout de fato revela o domínio, e é por isso que package-by-feature é pré-condição: pagamentos/, pedidos/, notificacoes/, cada pasta uma fatia vertical completa da capability, nunca controllers/, services/, repositories/ espalhando cada capability por três lugares. É a Screaming Architecture do Robert Martin com uma justificativa nova: estrutura que grita o domínio é estrutura que dispensa documentação para o agente. E cuidado com o package-by-entity disfarçado, pasta com substantivo de dado (produto/, cliente/) que parece feature folder mas reproduz fatiamento anêmico. O teste é triplo: o nome é verbo ou resultado de negócio, a pasta é fatia vertical, e os imports apontam para dentro dela.
Ponteiro, não cópia. O CLAUDE.md da capability tem 20 a 40 linhas: escopo em três frases, as três a cinco regras mais importantes resumidas, onde as coisas moram, e um ponteiro para a spec completa com a instrução de lê-la antes de mexer em regra de domínio. Ele não importa a spec inteira, porque isso carregaria a spec em toda edição trivial, queimando contexto à toa. Edição trivial se resolve com o resumo; mudança de regra dispara a leitura da spec. O root fica em torno de 60 linhas e nunca passa de 100: comandos de build e teste, mapa da estrutura, ponteiros para os documentos de referência. Todo token desses arquivos é carregado a cada turno, então enxuto ganha de completo.
Trate drift como bug. Spec e context file divergem do código com o tempo, e não existe detector automático de staleness. A defesa é tratar esses arquivos como código: versionados, revisados no diff, atualizados no mesmo PR que muda o comportamento. Spec falsa engana mais que spec ausente.
Fecham a camada permanente a constitution e as rules. A constitution é o inegociável do sistema em 15 a 30 linhas; no meu caso: valor sensível usa tipo decimal, nunca float; toda decisão crítica é rastreável à regra aplicada, ao input e à versão do código; regra codificada de fonte externa cita a fonte; e regra de período passado não muda retroativamente. As rules em .claude/rules/ são regras curtas auto-carregadas, cada arquivo com menos de 30 linhas e, quando só valem numa região do código, com paths: no frontmatter para carregar apenas quando o agente toca aquele glob. E aqui volta a distinção instrução versus enforcement: rule é instrução, com os tais ~70% de adesão. O subconjunto crítico é promovido a hook. Decimal handling foi o primeiro candidato no meu domínio; no seu, é a regra cuja violação custa mais caro.
O fluxo de implementação e o reviewer que não escreve
Com o contexto no lugar, o trabalho roda num fluxo de sete fases: entender, resolver ambiguidades, planejar, implementar, testar, revisar, fechar o loop. No modo local, quem confirma as três primeiras é você. São gates humanos posicionados onde ficam as decisões load-bearing, as que determinam se a abordagem funciona e qual arquitetura está sendo comprometida, e o plano pina essas agora; o resto é detalhe deferível, reversível, que a implementação decide na hora. Esse é o teste decisivo de um plano bom, e é onde a atenção humana rende: no que é caro de reverter.
A fase de ambiguidade existe porque ambiguidade não tem gradiente. Modelo diante de instrução ambígua não para, escolhe uma interpretação e segue com confiança total. O fluxo obriga o contrário: as ambiguidades sobem estruturadas, com interpretações propostas, e nada prossegue sem resposta. Te garanto que essa fase sozinha paga o guideline, porque o desperdício mais caro do desenvolvimento com agentes é o PR perfeito construído sobre a interpretação errada.
Na implementação, dois hábitos que vêm direto do backpressure. Lint, type check e os testes do trecho tocado rodam a cada chunk, nunca acumulados no fim, e vermelho não avança: agente empilhando quarenta minutos de trabalho sobre um teste quebrado multiplica o custo do conserto. E os testes ancoram nos acceptance criteria da spec. Teste que espelha a implementação só codifica o comportamento atual, bugs inclusos, e a partir daí passa a defender o erro contra o conserto.
Depois do verde vem o review, e aqui mora a decisão de desenho mais importante do fluxo: quem revisa não é quem escreveu. O reviewer é um agente separado, rodando em contexto isolado, que recebe o diff e o plano sem o histórico de quem produziu o trabalho, e que nunca escreve, read-only por configuração de ferramenta em vez de instrução no prompt. O motivo é o viés de autoavaliação, que a própria Anthropic documentou em primeira mão no artigo de harness engineering deles: agente elogia com confiança o próprio trabalho medíocre, e calibrar um avaliador independente para ser cético é tratável de um jeito que fazer o gerador criticar a si mesmo não é. É o mesmo ponto cego que faz você não enxergar o bug no código que acabou de escrever.
E o reviewer é um router: o que ele carrega é a decisão de quais critérios se aplicam ao que recebeu. Os critérios em si vivem em skills modulares: plan-review julga abordagem antes de qualquer código; general-code-review cobre o genérico que vale em qualquer projeto, correção, simplicidade, qualidade de teste, desenho de tipos; constitution-compliance-review entra quando o diff toca regra de domínio, cálculo, valor sensível ou trilha de auditoria, e checa contra a constitution; conformance-review entra quando o diff implementa uma spec ou um plano aprovado, e checa as duas conformidades, o código faz o que a spec exige, valor a valor, e faz o que o plano prometeu, intenção versus implementação. Adicionar uma dimensão nova, segurança, por exemplo, é um SKILL.md novo e uma linha de routing. Nada mais muda.
Essa separação entre critério genérico e contextual também define o lugar do reviewer externo, os SaaS de code review com LLM: ele complementa o genérico com um modelo de arquitetura diferente, que pega um conjunto de bugs razoavelmente disjunto do que o seu reviewer pega, mas entra como advisory, nunca como gate. Precisão mediana num gate autônomo significa loop abortado por falso positivo. O que bloqueia é determinístico, teste, lint, type check, mais o reviewer contextual que conhece a sua constitution; o resto comenta para o humano que decide o merge.

O fluxo de implementação: gates humanos nas decisões load-bearing, verificação determinística a cada chunk, e um reviewer independente que roteia critérios modulares e nunca escreve.
A última fase fecha o loop, e é a mais negligenciada: a lição aprendida vira linha em lessons ou regra versionada, a spec atualiza se regra mudou, com o flag de aprovação humana, e tudo no mesmo PR. Atualizar contexto “depois” é não atualizar nunca.
Autonomia é um gradiente, não um switch
A pergunta que mais recebo sobre esse sistema é quando deixar o agente rodar sozinho. A resposta tem três partes: uma divisão de trabalho, um começo estreito e uma regra para alargar.
A divisão: trabalho de arquitetura nunca entra na esteira autônoma. Capability nova, sub-área nova, reorganização de contratos, tudo isso é decisão de negócio com forma de código, e permanece human-led: você cria a spec, dirige a implementação pelo fluxo da seção anterior, revisa o PR. Não existe milestone em que isso muda. O que entra na esteira é incremento: bugfix, tech-debt, feature dentro de capability existente, ajuste isolado com fonte citada. Incremento entra pelo backlog, GitHub Issues com labels de capability, tipo e prioridade, uma triagem semanal de meia hora e um limite duro de três issues em priority:now. Cadência mínima, mas inegociável: quando a triagem morre, o resto vira teatro.
O começo é deliberadamente estreito, porque autonomia é gradiente. O narrow start liga cedo: a rotina só pega issues de uma allowlist hard-coded de classes triviais, bugfix bem especificado, tech-debt pequeno, ajuste com fonte já citada, com caminhos permitidos enforçados no harness, coisa que prompt não garante; CI verde é obrigatório antes de qualquer review; e um humano aprova todo PR. O humano aqui é a última linha de defesa; antes dele, a suite acumulada de todas as features anteriores, cada teste ancorado nos acceptance criteria da sua spec, é a rede mecânica que pega regressão fora do diff, exatamente o que um humano olhando o diff não enxerga. E esse começo não exige suite formal de evals: allowlist mais humano em todo PR mantém o risco proporcional à proteção.
O motor da esteira é o /goal nativo do Claude Code, e usar o mecanismo nativo em vez de empacotar um loop numa skill é escolha deliberada. /goal é um Stop hook de sessão: ao fim de cada turno, um modelo fresco, que não fez o trabalho, re-checa a condição de done e força mais um turno se ela não vale. Isso é enforcement. Skill é instrução, e instrução o agente pode ignorar justamente no turno em que mais importa. É o princípio do reviewer aparecendo de novo, quem declara pronto nunca é quem fez o trabalho, e vale tanto que, mesmo no modo local, com os gates humanos intactos, a invocação que uso é a skill embrulhada num /goal supervisionado: a pergunta continua pausando o turno para eu responder, mas o worker perde o poder de se autodeclarar concluído. Só o incremento pequeno dispensa o loop, quando o overhead supera o que ele protege.
No headless, uma propriedade governa o desenho inteiro: pergunta ao usuário não segura um run sem usuário, porque não existe quem responda e o evaluator só lê o transcript; um gate interativo seria atropelado em silêncio em vez de bloquear. Por isso a skill autônoma nunca pergunta: toda pergunta que existiria vira abort com blocker nomeado, e o julgamento humano se move para as pontas, os acceptance criteria da issue antes do run, o review do PR depois. E a condição é tudo, porque o evaluator decide só com o que está visível na conversa, então ela exige evidência concreta:
/goal Implemente a issue #142 seguindo a skill implement-backlog de ponta a ponta.
DONE apenas quando, tudo visível na conversa: cada acceptance criterion verificado
por teste passando, com o output real do runner na conversa, não por alegação;
suite completa verde, com testes ancorados nos criteria da spec; lint e coverage
no threshold; o reviewer rodou no diff final sem [BLOCKER]; PR aberto com CI
verde até o fim.
OU DONE COM BLOCKER NOMEADO quando a skill abortar, comentar na issue e aplicar o
label: ambiguidade → needs-refinement; expansão de escopo → scope-expansion-needed;
mesma falha 3+ vezes → qa-blocked.
Restrições: não expandir escopo silenciosamente; spec atualizada marca o PR como
requires_human_approval; nunca declarar done com check vermelho. Máximo 40 turnos.
Repara em dois detalhes, porque neles mora a filosofia. Primeiro, abort é estado final legítimo da condição: sem a cláusula de blocker nomeado, o evaluator forçaria turno atrás de turno diante de uma issue ambígua. Ambiguidade comenta na issue com as interpretações possíveis e sai com label; escopo que cresceu, comenta e sai; a mesma falha três vezes, sai. Abortar cedo é mais barato que um PR inteiro construído sobre a interpretação errada. Segundo, abrir PR não é done. O agente monitora até o PR estar merged limpo: CI até o fim, comentário tardio de review, conflito de merge.
Alargar é outra história. Mais classes, mais volume, qualquer passo em direção a auto-merge: isso sim exige uma trajetória de quatro milestones com critério de saída explícito, que mantenho num playbook separado do guideline, para ler na hora de alargar e não antes. O milestone 1 constrói a rede de medição: suite de regressão a partir de issues reais já fechadas, e vinte tasks valem mais que zero esperando a suite perfeita, medida com a métrica certa, que é pass^k, não pass@k. pass@k mede se o agente acerta em pelo menos uma de k tentativas; pass^k mede se acerta as k. Para demo, a primeira serve; para agente que abre PR sem supervisão, consistência importa mais que capacidade. E a medição tem dois eixos, o output final e a trajetória do run: um output fluente que pulou seus passos de verificação é falha mais perigosa que um com erro visível. O milestone 2 põe o Tier 1 no CI, coverage por capability, complexidade ciclomática, mutation testing, mais os checks de domínio, e só então as classes da allowlist alargam. O milestone 3 adiciona validação dinâmica pós-deploy em ambiente de integração: agentes de QA, E2E e contrato exercitando a aplicação de verdade, além do diff. E o milestone 4 é auto-merge condicional por classe, com track record: a classe “ajuste de parâmetro com fonte normativa citada” acumulou trinta PRs autônomos consecutivos sem rejeição humana, com tudo verde? Qualifica para auto-merge. Mudança em cálculo crítico ou trilha de auditoria? Humana para sempre. O agente até consegue; o custo do erro é que não justifica a delegação. Alargar sem essa escada é fé, e fé não é critério de engenharia.
E uma fronteira é permanente além da arquitetura: cálculo normativo. Mudança que toca cálculo com fonte normativa só entra na esteira, em qualquer largura de autonomia, com verificação golden na frente, dataset de referência com input e output esperado, porque revisor humano de PR não recalcula valor contra a norma. Sem o golden, ninguém está verificando de verdade, e aprovação vira liturgia.
A aviação trata habilitação exatamente assim: piloto não é liberado “para voar”, é habilitado por tipo de aeronave, com histórico auditado e revalidação periódica. Autonomia de agente com o mesmo desenho: por classe de mudança, com track record verificável, revisada trimestralmente. O que vejo o mercado fazer, ligar o modo autônomo global no dia um porque a demo foi boa, é dar type rating de A350 para quem taxiou um Cessna.

Autonomia como gradiente: o narrow start liga cedo, com allowlist estreita, CI verde obrigatório e humano em todo PR; alargar exige a suite de regressão e os quatro milestones. Arquitetura nunca entra, e cálculo normativo espera a rede de golden tests.
Por que foi desenhado assim: o método atrás do guideline
Além do que o sistema é, importa como ele chegou aqui, porque o método é replicável mesmo que o seu guideline final seja outro.
Minerar ideias, não adotar pacotes. A arquitetura de reviewer com critérios modulares veio do repositório do Lucas Costa; os critérios em si eu reescrevi por inteiro para o meu domínio, porque os dele não sabem o que é uma fonte normativa. Da metodologia AI-DLC da AWS levei o esqueleto, planejar, clarificar, humano valida, implementa, que é a sequência das minhas fases, e descartei a cerimônia, porque lá todo não é um humano em mob síncrono, o anti-padrão do humano-limite institucionalizado. Cerimônia sem mecanismo. A diferença entre instalar uma solução e entender por que ela funciona é a diferença entre dependência e design, o mesmo argumento de primeiros princípios que já defendi aqui: quem copia padrão sem entender o problema que ele resolve carrega o custo sem garantia do benefício.
Verificar na fonte primária. Um artigo popular de “padrões de Claude Code” inventou dois comandos que não existem em lugar nenhum. Outro apresentou truque de prompt da comunidade como se fosse sintaxe suportada da ferramenta. Um terceiro citou ganhos de produtividade impossíveis de rastrear. Listicle é lead: a referência é o doc, o repo, o blog primário que ele aponta. Metade do que circula sobre ferramenta de IA não sobrevive a cinco minutos de verificação, e a metade que sobrevive costuma chegar com os números inflados.
Convergência é o sinal. Um engenheiro escrevendo sobre backpressure, a AWS formalizando um lifecycle para clientes enterprise, o Addy Osmani nomeando intent debt, a Anthropic publicando a própria arquitetura de harness, e o Google, num whitepaper de 50 páginas assinado entre outros pelo mesmo Osmani, traçando o espectro que vai de vibe coding a agentic engineering, onde o que separa os dois extremos é exatamente como o output é verificado. Fontes independentes, sem se citarem, chegando na mesma forma: intenção externalizada em artefatos versionados, gates de máquina antes de review humano, humano nas decisões load-bearing. Convergência independente no desenho que você construiu é a evidência mais forte disponível antes de rodar em produção. Não é prova; é o melhor sinal que existe.
Determinismo primeiro é o que aparece em quem opera em escala. A Stripe publicou o caso dos minions, os coding agents internos deles: mais de 1.300 PRs mergeados por semana sem uma linha escrita por humano. Revisados por humanos, isso sim, e essa é a divisão desta tese em escala: a geração saiu das mãos humanas, a decisão de merge continua nelas. A parte que interessa é onde mora a confiabilidade: antes de o agente acordar, o pipeline roda ferramenta determinística para montar o contexto, puxa o ticket, a documentação interna, o status de build, localiza o código relevante via Sourcegraph, e o próprio loop intercala passos determinísticos para git, linter e teste. Nada que lógica determinística resolve chega ao modelo, e onde você traça essa linha é o que decide se o loop é confiável. No meu domínio a linha é ainda mais nítida: qual norma se aplica, qual contrato vale, qual fatia da spec importa são regras, então são injetadas deterministicamente em vez de deixar o modelo procurar e citar a norma errada com confiança. Na mesma direção, o port do runtime Bun de Zig para Rust com agentes, 750 mil linhas com 99,8% da suite passando em 11 dias, e ainda assim fora de produção, prova o princípio geral: ferramenta de escala amplifica exatamente o que o harness de verificação permite. A suite do Bun era a spec executável; sem ela, as mesmas 750 mil linhas seriam slop em volume industrial. E 0,2% de erro ali são 1.500 linhas erradas, aceitável para preview de runtime, inaceitável para cálculo com consequência jurídica. A régua de aceitação é do domínio, nunca da ferramenta.
E devo a honestidade sobre a fraqueza atual: a razão entre processo escrito e processo executado ainda está alta demais no meu sistema. A próxima lição não vai vir de mais um artigo minerado, vai vir de issue real atravessando a esteira. Escrevo isso como lembrete para mim e aviso para você: guideline se valida rodando.
O custo honesto e quando não usar
Harness custa caro, e fingir que não custa é desonestidade intelectual. Os números que a Anthropic publicou do experimento deles: a tarefa que o modelo resolve sozinho por cerca de 9 dólares em 20 minutos saiu por cerca de 200 dólares em 6 horas com o harness completo, e a segunda versão baixou para uns 124 dólares em 4 horas. Uma ordem de grandeza a mais, em dinheiro e em tempo. O harness paga quando a tarefa excede o que o modelo entrega sozinho com confiabilidade, e só nesse caso. Para tarefa pequena e bem delimitada, Claude Code vanilla ganha de workflow elaborado em quase todos os cenários. Antes de perguntar se o processo está completo, pergunta se o custo do erro desta tarefa justifica o overhead deste gate.
Segundo custo: harness apodrece. Cada componente, cada gate, cada regra codifica uma suposição sobre o que o modelo não consegue fazer sozinho, e essas suposições vencem a cada release de modelo. A própria Anthropic descreve ter derrubado peças do harness deles conforme os modelos melhoraram: os resets de contexto que o Sonnet 4.5 exigia, o Opus 4.5 dispensou; a decomposição do trabalho em sprints caiu na geração seguinte. O que era load-bearing virou peso morto sem avisar. A prática que adotei: a cada modelo novo, re-auditar o harness por ablação, desligando um componente de cada vez, e cortar o que deixou de ser necessário. O harness de hoje é o overhead de amanhã, e harness que só cresce vira burocracia com sintaxe de YAML.
E o modo de falha final não é técnico: é o sistema virar museu. Se a triagem semanal morre, se as specs param de refletir o código, se a suite de regressão não roda, o guideline vira um documento bonito descrevendo um processo que não existe. Contra isso, checks trimestrais de sim ou não: sigo fazendo triagem? Os context files continuam pequenos e atuais? As specs refletem o código? A suite roda? Um não é bug, e se trata como bug. E se em seis meses o sistema virou museu de boas intenções, queima e recomeça com um terço do conteúdo. O guideline existe para te servir, e mudar a regra abertamente é parte do jogo; o que mata é a erosão silenciosa dela.
Por fim, quando não usar: protótipo de fim de semana, projeto descartável, exploração onde o custo do erro é zero. Ali, vibe coding é honesto e eficiente, e montar constitution para isso é cerimônia sem propósito. Este sistema é para software que vai viver, receber manutenção e custar caro quando errar. A régua, de novo, é custo do erro vezes frequência de mudança, e ela decide inclusive quanto do sistema vale adotar.
Fechando
O guideline cabe em quatro movimentos. A decisão de negócio vem antes do código, escrita como spec por capability que segue ancorando testes, review e conformidade dali em diante, com fronteiras leves e detalhe tático emergindo com a implementação. O contexto vive em três camadas, com a intenção externalizada onde o agente lê e disciplina para não apodrecer. A máquina dá o primeiro não: verificação determinística a cada chunk, reviewer independente que nunca escreve, hook onde instrução não basta. E autonomia é gradiente: começa estreita, com humano em todo PR, e alarga por classe de mudança com evals e track record, sem nunca encostar num switch global. Evidência antes de “pronto”, em todos os níveis.
O próximo passo concreto, e recomendo muito que seja esta semana: escolhe a capability que você vai mexer na próxima sprint e escreve a spec dela, meia página com regras, edge cases e non-goals. Pega a correção que você mais repete para o seu agente e transforma em regra versionada; se a violação dela custa caro, promove a hook. E roda uma issue real pelo fluxo completo, plano com gate, implementação com teste a cada chunk, review independente, antes de adicionar qualquer peça a mais. O sistema inteiro nasceu assim, uma peça por vez, cada uma quando a dor justificou. E quando o próximo artigo te apresentar uma prática ou ferramenta, este incluído, verifica na fonte primária antes de adotar. Se você levar uma única coisa daqui, que seja essa. As fontes estão logo abaixo.
Referências
- Raphael Moura — spec-anchored-agentic-development, o guideline completo deste artigo e o bundle instalável (skills, reviewer, commands, hooks, template de spec)
- Lucas F. Costa — Backpressure is All You Need e o repositório backpressured
- Addy Osmani — The Intent Debt
- Anthropic Engineering — Harness design for long-running application development
- Anthropic Engineering — Demystifying evals for AI agents
- Anthropic — Steering Claude Code: skills, hooks, rules, subagents, and more
- Anthropic — Introducing dynamic workflows in Claude Code (o caso do port do Bun)
- Claude Code Docs — /goal
- Stripe Engineering — Minions: Stripe’s one-shot, end-to-end coding agents
- AWS DevOps Blog — AI-Driven Development Life Cycle
- Robert C. Martin — Screaming Architecture
- arXiv — Spec-Driven Development: From Code to Contract in the Age of AI Coding Assistants
- Birgitta Böckeler (martinfowler.com) — Understanding Spec-Driven Development: Kiro, spec-kit, and Tessl
- Google — The New SDLC With Vibe Coding
Changelog
- 2026-07-08 — O repositório evoluiu e o artigo acompanhou. A entrevista de spec virou o
/shape, cinco modos numa máquina só (ideia, transcript, brownfield, refino de spec, afiar task), sempre uma pergunta por vez com resposta recomendada; e ganhou o irmão/spec-to-tickets, que quebra a spec em tickets verticais ancorados nos acceptance criteria numerados, com dependências explícitas entre eles. Type check entrou no loop de chunk ao lado de lint e testes. E finding de review agora fecha com teste de regressão que falhava antes do fix e passa depois, sempre que o finding tem forma de teste. - 2026-07-02 — Publicação.
