
Scaneia diffs de código com contexto para construir um grafo de impacto e usa LLMs para encontrar vulnerabilidades, suportando varreduras multi-repositório e gating de CI com saída SARIF.
Os scanners de diff de segurança ignoram os efeitos das alterações; o Zairo encontra esses efeitos e procura vulnerabilidades. O Zairo analisa o que mudou no seu código com contexto, cria um subgrafo para você examinar e encontra vulnerabilidades usando LLMs de sua escolha.

pipx install zairo
# Analise tudo o que você ainda não commitou
zairo .
# Analise um diff de PR/branch
zairo . --base main --target HEAD
# Faça o build falhar se algo de alta gravidade aparecer
zairo . --base main --target HEAD --fail-on high
Dê a ele mais de um repositório, como argumentos extras ou um por linha em um --repos-file (ou ambos, mesclados em uma única lista), e ele muda sozinho para o modo multi-repositório: cada repositório recebe seu próprio relatório, além de um resumo combinado.
zairo backend frontend infra --base main --fail-on high -o zairo_multi_out
--base/--target (e todas as outras opções) se aplicam da mesma forma a cada repositório da lista, então o modo multi-repositório se encaixa melhor quando todos fazem diff contra a mesma referência (por exemplo, o main de todos). Repositórios com convenções diferentes precisam de execuções separadas.
O que analisar
--base, -b (nenhum): ref para fazer diff a partir, ex.: main ou HEAD~3. Se omitido, o zairo analisa alterações não commitadas.--target, -t (nenhum): ref para fazer diff até. Requer --base; se omitido (com --base definido), ele faz diff contra sua árvore de trabalho.--depth, -d (1): quantos saltos de chamadores/callees puxar para o grafo de impacto ao redor de cada alteração.--language, -l (auto): força um idioma em vez de deixar o Trailmark detectá-lo automaticamente.Análise com LLM
--graph-only (desativado): pula a análise de vulnerabilidades e apenas constrói o grafo de impacto — sem descobertas, sem report.sarif.--model (gemini/gemini-2.5-pro): qualquer string de modelo LiteLLM.--concurrency, -c (5): requisições LLM paralelas, dentro da análise de um único repositório.--batch-size (1): agrupa esse número de nós em uma única requisição LLM em vez de uma chamada por nó — menos requisições (ajuda com limites de taxa do provedor), ao custo de isolamento de falhas compartilhado: uma resposta ruim/malformada faz todos os nós daquele lote falharem, não apenas um. O cache permanece por nó de qualquer forma.--max-tokens (4096): orçamento de saída por requisição. Modelos de raciocínio gastam isso também em pensamento interno, então aumente se você vir respostas vazias.--cache / --no-cache (cache ativado): pula a reanálise de código inalterado desde a última execução (armazenado em cache por hash de conteúdo em <output>/.llm_cache.json).--tokens (desativado): imprime quantos tokens a análise realmente usou (acertos de cache não contam, pois não fizeram nenhuma chamada).Saída e controle
--output, -o (zairo_out): onde os relatórios vão. Modo multi-repositório: cada repositório recebe seu próprio <output>/<repo-slug>/, além de um rollup.* combinado aqui também.--fail-on (nenhum): sai com código não zero se uma descoberta em ou acima desta gravidade aparecer (low/medium/high/critical). Gera erro se combinado com --graph-only (não há nada para controlar). Modo multi-repositório: verificado em todos os repositórios combinados. Veja Controle de CI / PR.--verbose, -v (desativado): imprime o que está acontecendo passo a passo (comandos git, configuração da worktree, progresso da análise por nó).--debug, -vv (desativado): tudo o que --verbose imprime, além do prompt exato enviado ao LLM e sua resposta bruta para cada nó — gravado em <output>/debug.log (por repositório no modo multi-repositório), pois é demais para imprimir no console.Somente modo multi-repositório
--repos-file (nenhum): um caminho de repositório por linha (comentários # permitidos), mesclado com quaisquer repositórios fornecidos diretamente.--repo-concurrency (1): quantos repositórios analisar de uma vez. O total de requisições LLM em andamento pode chegar a --concurrency × --repo-concurrency, então fique atento aos limites de taxa do seu provedor. Acima de 1, o progresso imprime uma linha de resumo por repositório ao concluir, em vez de detalhes passo a passo ao vivo.--continue-on-error / --stop-on-error (continuar): continue analisando o restante da lista, ou pare, quando um repositório falhar. De qualquer forma, qualquer repositório que falhar ainda faz o código de saída geral falhar.Execute zairo --help a qualquer momento para ver esta mesma lista pela CLI.
report.json (sempre): o grafo de impacto bruto (nós, arestas e quaisquer descobertas anexadas), como dados.report.html (sempre): um visualizador de grafo de dependências interativo e autocontido (Cytoscape.js). Clique em um nó para ver suas descobertas.report.sarif (a menos que --graph-only seja usado): descobertas em SARIF 2.1.0, para code scanning do GitHub ou qualquer outro consumidor de SARIF. Sempre gravado, mesmo para uma análise limpa (um log vazio, mas válido), para que uma interface de análise possa marcar alertas relatados anteriormente como resolvidos. As descobertas são agrupadas em regras por CWE quando o modelo marcou uma, então problemas recorrentes do mesmo tipo se agrupam em uma única regra em vez de uma nova por variação de redação.O modo multi-repositório produz os mesmos três arquivos por repositório, além de rollup.json / rollup.html / rollup.sarif: status por repositório e contagens de gravidade, uma tabela de painel vinculando aos relatórios de cada repositório, e os resultados SARIF de todos os repositórios mesclados em um único log de múltiplas execuções.
Uma função/classe/módulo removido inteiramente (não apenas editado) ainda aparece em report.html, com status deleted: um nó tracejado e esmaecido marcando onde costumava existir. O grafo do Trailmark não consegue representar isso sozinho (ele só reflete a árvore como está agora), então o zairo detecta exclusões separadamente: ele também analisa os arquivos alterados como existiam em --base (ou HEAD, se --base não foi fornecido) e faz diff dos dois conjuntos de símbolos. Uma função excluída nunca é enviada ao scanner LLM (não há código vivo restante para analisar), então ela carrega apenas seu nome, tipo e localização anterior, nunca descobertas.
--fail-on <low|medium|high|critical> sai com código não zero se qualquer descoberta em ou
acima dessa gravidade for encontrada (em todos os repositórios combinados, no modo
multi-repositório), para que uma etapa de CI possa bloquear um merge com base nisso. Algumas coisas
que vale a pena saber:
--graph-only (não haveria nada para controlar).zairo . --base "$BASE_REF" --target HEAD --fail-on high -o zairo_out
Veja examples/github-actions/zairo-pr-scan.yml
para um fluxo de trabalho completo de análise de PR: ele executa o zairo no diff do PR, envia
report.sarif para o code scanning do GitHub e faz o job falhar se o controle
falhar.