Documentação que mente: como construímos um guarda que verifica tudo no pre-commit
TL;DR: Toda base de código acumula dívida de documentação em silêncio. Construímos um sistema que trata cada afirmação numérica como um contrato verificável — se a evidência não existir, o commit não passa. Resultado: de 33 claims sem prova para 0 drift detectado em 9 domínios do kernel.
O número que me incomodou #
First dry-run: 33 unbacked claims in CAPABILITY_REGISTRY.mdEssa foi a saída do primeiro run do Evidence Gate em 2026-04-09. Não erros. Não bugs. Trinta e três afirmações — "24 agents", "16 padrões de PII", "6 domínios cobertos" — sem nenhuma prova automatizada de que ainda eram verdade.
Não eram mentiras intencionais. Eram precisas quando foram escritas. O problema é que o código continuou evoluindo e a documentação ficou para trás. Em cinco semanas de desenvolvimento intenso, 33 claims tinham divergido sem que eu percebesse.
O que me preocupou não foi os 33. Foi perceber quantos outros projetos — incluindo os meus — provavelmente têm o dobro disso e nunca mediram.
Por que isso acontece #
Documentação tem o mesmo problema que testes manuais: funciona até a primeira mudança que ninguém rastreou.
Quando você escreve "o sistema tem 24 agentes", está fazendo uma afirmação. Sem um mecanismo que verifique essa afirmação contra o código real, ela vai divergir. Não é questão de disciplina — é inevitável em qualquer velocidade não-trivial.
O padrão usual de como isso fica invisível:
| Passo | O que acontece | Resultado |
|---|---|---|
| 1 | Dev escreve feature + atualiza doc no mesmo PR | Correto |
| 2 | Segundo dev adiciona feature menor, só muda o código | Doc desatualizado +1 |
| 3 | Terceiro dev remove feature deprecated, só muda o código | Doc desatualizado +1 |
| 4 | README ainda diz o número original. Ninguém olhou. | Drift invisível |
Em projetos solo como o EGOS, o problema é pior: a mesma pessoa que escreveu o doc assume que lembra do que mudou. Não lembra. Karpathy tem um princípio direto sobre isso: atividade não é progresso. Escrever "24 agentes" no README quando existem 31 é atividade de documentação que produz desorientação, não clareza.
O que construímos: Doc-Drift Shield em três camadas #
Camada 1: .egos-manifest.yaml — o contrato
Cada afirmação numérica no código ou nos docs precisa de uma entrada no manifest com o comando que a prova:
claims:
- id: total_agents
description: "Agents registered in agents.json"
command: "python3 -c 'import json; data=json.load(open(\"agents/registry/agents.json\")); print(len(data.get(\"agents\", [])))'"
tolerance: "min:18"
last_value: "24"O campo command é a prova. Um comando shell que, executado agora, retorna o valor real. Se o número divergiu além da tolerance, é drift. O manifest vive no raiz do repo e é lido por dois consumidores: o pre-commit hook e o cron diário.
Camada 2: scripts/evidence-gate.ts — o verificador
Roda em dois contextos:
- No pre-commit hook, modo
--staged-only: verifica apenas os arquivos sendo commitados - Cron diário (00h17 BRT): verifica o repo inteiro e grava
docs/jobs/YYYY-MM-DD-doc-drift-verifier.json
bun scripts/evidence-gate.ts
# Resultado atual (2026-04-16):
{
"total_claims": 15,
"passed": 15,
"drifted": 0,
"domains_ok": 9
}Camada 3: ativação progressiva #
Semana 1 (warning): mostra violações, deixa o commit passar. Você aprende o que está quebrando sem travar o trabalho.
Semana 2+ (blocking): commit não passa se houver drift em docs do kernel. Override disponível via DOC-DRIFT-ACCEPTED: motivo no corpo do commit — mas precisa ser justificado.
Casos reais encontrados no primeiro run #
| Claim encontrada | Valor no doc | Valor real | Ação |
|---|---|---|---|
| Guard Brasil endpoint | /v1/check | /v1/inspect | Doc corrigido |
| Agents registrados | 24 | 31 | Manifest atualizado |
| Caminho do repo | /home/enio/br-acc | /home/enio/intelink | Propagado em 4 docs |
| Packages no kernel | 8 | 19 | Claim reescrita |
Todos os 4 casos eram invisíveis antes do Evidence Gate. Nenhum causou bug em produção — mas dois deles teriam confundido qualquer pessoa tentando usar os docs para integrar o sistema. O endpoint errado do Guard Brasil especialmente: quem tentasse /v1/check receberia 404 sem nenhuma pista do que aconteceu.
O que o manifest cobre hoje #
| Claim | Tolerância | Último valor |
|---|---|---|
| Total de agents | min:18 | 24 |
| Capabilities declaradas | ±10 | 27 |
| Arquivos de governança | ±5 | 59 |
| Packages no kernel | ±2 | 19 |
| Commits últimos 30d (todos os repos) | min:50 | 1213 |
O que não funcionou #
- Comandos frágeis: verificações que dependem de ambiente local falham silenciosamente em CI. Solução em aberto: containerizar o verificador.
- Pre-commit hooks têm bypass:
--no-verifyainda existe. O cron diário é o backstop real — sem ele, o sistema é facilmente contornado. - Overhead em projetos menores: faz sentido para 15+ claims. Para um README com 3 afirmações, é overkill.
- Os comandos precisam de prova própria: se o comando de verificação está errado, o manifest passa com drift real. O meta-problema não tem solução elegante ainda.
Próximas perguntas #
- Como conectar o manifest ao CI/CD sem depender de ambiente local?
- É possível gerar entradas do manifest automaticamente a partir de afirmações no markdown?
- Como tratar claims qualitativos ("o sistema é rápido") que não têm número direto?
- O Evidence Gate deve bloquear PRs no GitHub, não só commits locais?
Recursos citados neste artigo #
- .egos-manifest.yaml — contrato de claims verificáveis do kernel EGOS
- scripts/evidence-gate.ts — verificador que roda no pre-commit e no cron diário
- docs/CAPABILITY_REGISTRY.md — registro canônico de capabilities (entrada principal do drift)
- .guarani/RULES_INDEX.md — regras de governança do kernel, também monitoradas
No EGOS, isso também se conecta com #
- Altitude Errada — como construir no nível certo de abstração para não criar débito invisível desde o início
- Guard Brasil: 16 padrões de PII em 4ms — o sistema cujo endpoint o manifest agora monitora
Código aberto. Tudo que você viu aqui está disponível em github.com/enioxt/egos. Se você está construindo algo parecido ou quer aplicar no seu contexto, fala comigo no X: @eniorocha_. Construindo em público.