Todo mundo que me pergunta sobre o CaidoAIDriven quer saber a mesma coisa: "tá, mas na prática, como é usar isso?". Então em vez de explicar de novo em texto, resolvi mostrar uma sessão real — um teste rápido no OWASP Juice Shop que rodei pra validar um ajuste no fluxo. Do jeito que aconteceu, erro e correção inclusos.


O ponto de partida: o MCP conectado

Antes de qualquer coisa, o Claude Code precisa enxergar o Caido. Isso é o Caido MCP Server — a ponte que expõe 66 tools (mcp__caido__*) pra sessão principal do orquestrador. Sem isso conectado, não tem interceptação, não tem sitemap, não tem Replay Collection. É a espinha dorsal de tudo.

Caido MCP Server conectado com 66 tools disponíveis
Caido MCP Server conectado, expondo 66 tools para o orquestrador.

Rodo claude mcp list no início de toda sessão só pra confirmar isso antes de qualquer prompt. Um segundo perdido aqui evita meia hora de frustração depois.


Abrindo um engajamento de verdade

Todo teste no CaidoAIDriven vive dentro de um engajamento — nunca solto na conversa. Isso é findings.sh init, e a partir daí toda gravação de finding, todo tracker, todo state file de gate fica amarrado àquele nome:

export PENTEST_AI_ENGAGEMENT="lab-juice"
findings.sh init lab-juice --client "Teste Interno" --type web --scope "localhost:3000"
Terminal criando o engajamento lab-juice com findings.sh init
Terminal criando o engajamento lab-juice — cliente, tipo e escopo declarados de uma vez.

Isso é o que separa isso de "pedir pro Claude testar um site" — cada descoberta nasce já vinculada a um cliente, um escopo e um banco SQLite persistente entre sessões.


O orquestrador não assume nada — ele pergunta

Aqui é onde a arquitetura mostra a cara. Pedi pro Claude Code criar a estrutura de pastas e o tracker de cobertura pro engajamento. Ele criou — mas parou antes de marcar qualquer coisa como aplicável, porque eu ainda não tinha feito a Declaração de Tipo de Projeto (Fase 0).

Claude Code pausado aguardando declaração do tipo de projeto
O tracker criado com placeholders — nenhum backbone ativado sem declaração prévia do tipo de projeto.

Repara na frase: "Preciso que você declare isso antes de eu ativar o backbone certo no tracker." Isso não é o modelo sendo cauteloso por acaso — é a regra da seção 4.2 funcionando: se eu não declarar API, WEB ou MISTO, o orquestrador nunca assume WEB como default silencioso. Ele trava e escala.

Respondi: "Projeto é MISTO, WEB e API" — e só a partir daí o tracker foi liberado pra ativar os dois backbones (WSTG completo + API-SEC-NN) em paralelo.


Reconhecimento: sitemap primeiro, hipótese depois

Com o tipo declarado, o próximo passo é reconhecimento passivo — nunca ataque direto. Pedi pra mapear o Juice Shop via caido_get_sitemap e reportar tecnologia identificada, nada além disso.

Tracker atualizado com tipo MISTO e escopo declarado
Tracker atualizado após a declaração: backbones WSTG e API-SEC-NN ativados em paralelo.

O retorno trouxe a versão exata do Juice Shop (via header de resposta), stack de frontend (Angular), assinatura de backend (Express) e — detalhe que eu não esperava — um header X-Recruiting característico do próprio Juice Shop que serviu de fingerprint extra.

Sitemap completo mapeado com endpoints organizados por área
Sitemap completo: estáticos, REST, API sobre Sequelize, FTP exposto e WebSocket via Socket.IO — a base de hipóteses da Fase 1.

Note a tabela: estáticos, REST, API genérica sobre o banco (Sequelize), diretório de FTP exposto, WebSocket via Socket.IO. É esse mapa que vira a base de hipóteses da Fase 1 — nada de sair testando payload direto no primeiro endpoint que aparece.


O momento mais interessante: um gap encontrado e corrigido ao vivo

Essa é a parte que eu queria destacar de verdade. Durante os testes, percebi um problema de processo: eu estava criando a Replay Collection do Caido depois de já ter rodado send_request/edit_request — ou seja, a evidência ficava órfã por alguns segundos antes de ganhar um lar permanente.

Corrigi o processo ali mesmo, na conversa: a partir de agora, a collection nasce antes do primeiro request. E o que fiz em seguida foi pedir pro Claude Code salvar essa correção em memória, pra não precisar repetir a instrução em toda sessão futura.

Correção de processo sendo salva em memória pelo orquestrador
Correção salva em memória: no teste seguinte, a Replay Collection foi criada antes de qualquer chamada ao Caido — sem precisar repetir a instrução.

O resultado aparece na sequência imediata: no teste seguinte (WSTG-ATHZ-04, hipótese de directory traversal em /ftp/<file>), a primeira ação antes de qualquer chamada ao Caido foi criar a Replay Collection — exatamente como pedi. Teto declarado de 3 tool uses, critério de parada definido antes de começar (payload funcional ou negação), skill carregada (performing-directory-traversal-testing) e só então as chamadas ao Caido.


Por que isso importa mais que "a IA fez sozinha"

Se eu quisesse só velocidade, teria deixado o agente rodar solto desde o sitemap até o finding. Não é isso que o CaidoAIDriven propõe. O valor real está em:

  • Toda transição de fase é rastreável — do reconhecimento à hipótese, da hipótese à execução, da execução ao finding oficial;
  • Nenhuma decisão de escopo acontece sem eu declarar antes — o placeholder travado no tracker é prova disso;
  • Processo é corrigível em tempo real, e a correção persiste — não é um ajuste que se perde no fim da conversa.

Isso é o que separa uma ferramenta de bug bounty automatizado de um time virtual que eu realmente lidero. E é exatamente esse tipo de sessão — chata, com pausa, com pergunta de volta — que eu mostro quando alguém me pergunta "mas isso não é só um script rodando sozinho?"

Próximo post: como ficou o finding oficial gerado depois que o poc-validator confirmou o directory traversal — e o que aconteceu quando os gates de Portão 1/Portão 2 entraram em cena pela primeira vez num teste real.