Codebase do Claude Code vazou. O que eu fiz com isso.
TL;DR: A versão 2.1.88 do pacote @anthropic-ai/claude-code vazou acidentalmente 512 mil linhas de TypeScript. Em vez de ficar no drama, usei o próprio Claude Code para ler a codebase dele e gerar um guia com 8 princípios de arquitetura interna, o agent-optimization.md. Depois usei esse guia para auditar o meu próprio sistema de agentes. Este post explica os 8 princípios e o que a auditoria encontrou.
Quando a codebase do Claude Code apareceu no GitHub, a maioria das discussões ficou no aspecto do vazamento em si. O que me interessava era outra coisa: o que o código revela sobre como o sistema funciona internamente.
Usei o próprio Claude Code para fazer leitura estática dos 1.900 arquivos e extrair os princípios de arquitetura que não estão documentados em nenhum lugar. Depois apliquei esses princípios para auditar o meu próprio sistema de agentes.
Este post documenta os dois resultados.
O que aconteceu com o vazamento?
A versão 2.1.88 do pacote @anthropic-ai/claude-code incluiu acidentalmente um source map de 59.8MB no npm, expondo 512 mil linhas de TypeScript em 1.900 arquivos. Erro humano no empacotamento, possivelmente ligado a um bug no Bun. A Anthropic confirmou e removeu a versão, mas o código já tinha sido espelhado no GitHub.
O pacote afetado é o @anthropic-ai/claude-code no npm. O post do AkitaOnRails cobre o aspecto técnico, incluindo o bug no Bun que tornou o acidente possível. Não vou repetir isso aqui. O que me interessa é o que dá pra usar do código.
Quais são os 8 princípios que o código revelou?
O código expôs 8 princípios concretos de arquitetura interna: fork cost proporcional ao contexto, risco de autocompact recursivo sem querySource, cycle counter desconectado do budget real, custo invisível do git status por turno, custo do CLAUDE.md por request, ferramentas unsafe quebrando paralelismo, cache invalidado por conteúdo dinâmico antes do boundary, e system prompt congelado no fork do subagent.
Não li 512 mil linhas manualmente. Apontei o Claude Code para a codebase dele mesmo, com uma instrução simples: leitura estática apenas, sem modificar nada, e gera um documento com os princípios concretos de arquitetura interna. O resultado foi o agent-optimization.md. Saíram 8 princípios.
Princípio 1: fork cost de subagent é proporcional ao contexto no momento do fork.
AgentTool clona o histórico completo do agente pai quando cria um subagent. O custo não é fixo. Disparar um subagent com 5 mensagens no contexto é muito mais barato do que disparar com 80.
Princípio 2: subagent sem querySource pode acionar autocompact dentro de autocompact.
shouldAutoCompact() guarda apenas três tipos de mensagem: session_memory, compact e marble_origami. Se o subagent não recebe um querySource no dispatch, ele pode acionar um ciclo de compactação autônomo enquanto o pai já está compactando. O resultado é imprevisível.
Princípio 3: cycle counter arbitrário é inferior à função real.
A função real é finalContextTokensFromLastResponse(). O buffer real do sistema é contextWindow - 13000 - min(maxOutputTokens, 20000). Um counter de N ciclos não reflete isso. Às vezes para cedo, às vezes passa do limite.
Princípio 4: git status consome tokens em todo turno.
getSystemContext() injeta o git status a cada request. É memoized por turno, não por sessão. Em repos com muitos arquivos modificados, o custo por request é significativo e invisível.
Princípio 5: CLAUDE.md é injetado a cada turno via getUserContext().
Um arquivo de 10k tokens custa 10k tokens por request ao longo de toda a sessão, não uma vez. Isso muda bastante o cálculo de quanto custa manter instruções longas no CLAUDE.md.
Princípio 6: ferramenta unsafe no meio de uma sequência força round-trips extras.
Ferramentas com isConcurrencySafe=true rodam em paralelo. Uma ferramenta unsafe no meio da sequência quebra o lote e força um round-trip adicional para continuar. A ordem das ferramentas importa.
Princípio 7: conteúdo antes de SYSTEM_PROMPT_DYNAMIC_BOUNDARY é cacheado.
Conteúdo dinâmico (git status, data atual) entra depois desse marcador. Qualquer mudança no estado do repo invalida o cache do sistema inteiro. CLAUDE.md deve ficar antes do marcador para ser cacheado.
Princípio 8: renderedSystemPrompt é congelado no fork.
Para compartilhar cache com o agente pai, o subagent precisa herdar o mesmo renderedSystemPrompt. Se o sistema prompt do subagent for diferente, mesmo que levemente, o cache não é compartilhado e o custo de context window dobra.
Como usar os princípios para auditar um sistema de agentes?
Cada princípio funciona como uma pergunta aplicada ao sistema. Você abre cada agente, persona ou instrução e pergunta: o fork está sendo disparado com contexto pesado? Existe querySource no dispatch? O CLAUDE.md é maior do que precisa ser? Onde tem ferramenta unsafe quebrando o lote? As respostas indicam exatamente onde otimizar.
Com os 8 princípios em mãos, abri cada persona e skill do meu framework e apliquei o guia como régua. O resultado foi o agent-review.md: uma auditoria de cada componente com o princípio específico que revelou o problema.
O sistema que rodei essa auditoria é o mesmo que entregou o ticket LOT-98 enquanto eu dormia: um conjunto de personas especializadas (maestro, architect, coder, reviewer, tester) coordenadas pelo Claude Code.
O que a auditoria encontrou de errado?
Quatro problemas principais: querySource ausente em todos os dispatches (risco de autocompact recursivo), cycle counter de 7 ciclos desconectado do budget real, Reviewer sendo disparado em 100% das tarefas independente de complexidade, e CoT obrigatório de 70 linhas no Coder para qualquer tipo de tarefa incluindo correção de typo.
querySource ausente em todos os subagents despachados.
Anti-pattern direto do princípio 2. Qualquer subagent no meu sistema podia acionar autocompact recursivo sem nenhuma proteção. O fix é uma linha no template de dispatch. Não tinha feito porque não sabia que o campo existia. Agora sei.
Cycle counter de 7 ciclos no Maestro desconectado do orçamento real.
O Maestro tinha um hard stop em 7 ciclos. O princípio 3 expôs que esse número não tem relação com o budget real de contexto. A fórmula é contextWindow - 13000 - min(maxOutputTokens, 20000). O counter de 7 cria falsos positivos (para quando ainda tem budget) e falsos negativos (deixa passar quando o contexto já está pesado).
Reviewer disparado em 100% das tarefas.
Anti-pattern do princípio 1. O Reviewer tem 337 linhas de persona e é criado após Architect e Coder, quando o contexto já está carregado. Para tarefas com LOC menor que 50 e task_type trivial (bugfix simples, config, docs), o fork do Reviewer é custo puro. Um gate de skip corta entre 40 e 60% do custo nesses ciclos sem impactar qualidade nas tarefas complexas.
CoT obrigatório de 70 linhas no Coder para qualquer tarefa.
O bloco [CRAFTSMAN THINKING] era marcado como "MANDATORY, never skip". O modelo produzia o bloco completo para correção de typo. Pior: a CoT misturava pitfalls de frontend e backend. Para uma tarefa de backend em NestJS, o modelo processava e produzia output sobre Cypress intercepts e React Query. Output desnecessário que vai para o contexto do turno seguinte, conforme o princípio 3.
O que já estava certo
Não era só problema. Algumas decisões de design passaram pela régua dos 8 princípios sem ajuste:
- A estrutura geral do Maestro com CoT de 5 etapas está alinhada com como o sistema processa sequências de raciocínio.
- O filtro de noise do Reviewer antes de analisar (gerados, lock files, vendor) está correto: evita que o Reviewer gaste contexto em arquivos que nunca precisam de revisão.
- O human approval gate no plan-from-jira é o lugar certo para esse gate.
- A separação de tiers de memória (long-term vs session) com size discipline está alinhada com os princípios de cache do sistema.
O agent-optimization.md está disponível
O agent-review.md é específico do meu sistema. Não faz sentido compartilhar.
O agent-optimization.md é diferente. É um guia da arquitetura interna do Claude Code baseado no código real: como o fork funciona, como o cache é invalidado, como o autocompact decide quando agir, quais são os thresholds reais. Qualquer pessoa que usa ou constrói sistemas de agentes pode usar como referência.
Está disponível para download aqui: agent-optimization.md. Se quiser discutir os princípios ou como aplicar no seu sistema, o melhor lugar é a comunidade.
Perguntas Frequentes
O que foi o vazamento tecnicamente?
A versão 2.1.88 do pacote @anthropic-ai/claude-code no npm incluiu acidentalmente um source map não minificado de 59.8MB. Esse arquivo continha o TypeScript original, não compilado, de toda a codebase: 512 mil linhas em 1.900 arquivos. O erro foi no processo de empacotamento, possivelmente relacionado a um bug no Bun. A Anthropic removeu a versão do registry e confirmou o incidente. O código já tinha sido espelhado no GitHub antes disso.
O que é o agent-optimization.md e como ele foi criado?
É um documento gerado pelo próprio Claude Code a partir de leitura estática da codebase vazada. O prompt foi direto: analise os arquivos sem modificar nada e extraia princípios concretos do funcionamento interno. O objetivo foi documentar como o fork de subagents funciona, como o cache é gerenciado, como o autocompact decide quando agir, quais são os thresholds e fórmulas reais. Saíram 8 princípios, cada um referenciando a função ou estrutura de dados específica no código que o originou. Não é análise do vazamento como evento. É um guia de arquitetura gerado a partir do código real, pelo próprio sistema que estava sendo analisado.
Como usar os princípios no próprio sistema de agentes?
A forma mais direta é pegar cada princípio como uma pergunta e aplicar ao seu sistema. O princípio 1 pergunta: você está disparando subagents com contexto pesado? O princípio 2 pergunta: seus dispatches incluem querySource? O princípio 5 pergunta: quanto do seu CLAUDE.md é conteúdo estático que poderia ser cacheado? Cada resposta aponta um lugar específico para otimizar. O agent-optimization.md disponível na comunidade inclui as perguntas e os critérios para cada princípio.
Por que o agent-review.md não é público?
Porque ele documenta os internos do meu sistema específico: paths de arquivo, nomes de personas, estrutura de memória, lógica de dispatch do Maestro. Compartilhar seria expor arquitetura de produto sem nenhum benefício para quem lê, já que o contexto necessário para entender não existe fora do meu projeto. O que tem valor universal são os princípios que revelaram os problemas, não o inventário dos problemas em si.
O que muda na prática para quem constrói agentes?
Dois comportamentos mudam imediatamente com esses princípios. Primeiro: você para de usar cycle counters arbitrários como proxy de orçamento de contexto e começa a calcular com a fórmula real. Segundo: você inclui querySource em todo dispatch de subagent. Os outros princípios são otimizações progressivas: revisar o tamanho do CLAUDE.md, auditar a ordem das ferramentas, pensar em quando faz sentido criar um gate de skip para agentes pesados. Nenhuma dessas mudanças exige refatoração grande. A maioria é configuração ou uma linha de código.