Escopos de configuração
Existem três escopos de configuração, avaliados em ordem de prioridade:
Quando failproofai recebe um evento de hook, ele carrega e mescla os três arquivos que existirem para o diretório de trabalho atual.
Regras de mesclagem
enabledPolicies — a união dos três escopos. Uma política habilitada em qualquer nível fica ativa.
policyParams — o primeiro escopo que define os parâmetros para uma política específica vence por completo. Não há mesclagem profunda de valores dentro dos parâmetros de uma política.
customPoliciesPath — o primeiro escopo que o define vence.
llm — o primeiro escopo que o define vence.
Formato do arquivo de configuração
Referência de campos
enabledPolicies
Tipo: string[]
Lista de nomes de políticas a serem habilitadas. Os nomes devem corresponder exatamente aos identificadores de política exibidos por failproofai policies. Consulte Políticas Integradas para ver a lista completa.
Políticas que não estejam em enabledPolicies ficam inativas, mesmo que tenham entradas em policyParams.
policyParams
Tipo: Record<string, Record<string, unknown>>
Substituições de parâmetros por política. A chave externa é o nome da política; as chaves internas são específicas de cada política. Cada política documenta seus parâmetros disponíveis em Políticas Integradas.
Se uma política tiver parâmetros mas você não os especificar, os padrões internos da política serão usados. Usuários que não configurarem policyParams terão comportamento idêntico ao das versões anteriores.
Chaves desconhecidas dentro do bloco de parâmetros de uma política são silenciosamente ignoradas no momento em que o hook é disparado, mas sinalizadas como avisos ao executar failproofai policies.
hint (transversal)
Tipo: string (opcional)
Uma mensagem anexada ao motivo quando uma política retorna deny ou instruct. Use para fornecer orientações práticas a Claude sem modificar a própria política.
Funciona com qualquer tipo de política — integradas, personalizadas (custom/), convenções de projeto (.failproofai-project/) ou convenções de usuário (.failproofai-user/).
block-force-push nega, Claude vê: “Force-pushing is blocked. Try creating a fresh branch instead.”
Valores não-string e strings vazias são silenciosamente ignorados. Se hint não estiver definido, o comportamento permanece inalterado (compatível com versões anteriores).
customPoliciesPath
Tipo: string (caminho absoluto)
Caminho para um arquivo JavaScript contendo políticas de hook personalizadas. Esse campo é configurado automaticamente por failproofai policies --install --custom <path> (o caminho é resolvido para absoluto antes de ser armazenado).
O arquivo é carregado do zero a cada evento de hook — não há cache. Consulte Políticas Personalizadas para detalhes de autoria.
Políticas baseadas em convenção
Além docustomPoliciesPath explícito, failproofai descobre e carrega automaticamente arquivos de política dos diretórios .failproofai/policies/:
Correspondência de arquivos: Apenas arquivos que correspondam a
*policies.{js,mjs,ts} são carregados (por exemplo, security-policies.mjs, workflow-policies.js). Outros arquivos no diretório são ignorados.
Sem configuração necessária: Políticas de convenção não precisam de entradas em policies-config.json. Basta colocar os arquivos no diretório e eles serão detectados no próximo evento de hook.
Carregamento por união: Os diretórios de convenção do projeto e do usuário são verificados. Todos os arquivos correspondentes de ambos os níveis são carregados (ao contrário de customPoliciesPath, que utiliza o primeiro escopo que vencer).
Consulte Políticas Personalizadas para mais detalhes e exemplos.
llm
Tipo: object (opcional)
Configuração do cliente LLM para políticas que fazem chamadas de IA. Não é necessário para a maioria das configurações.
Gerenciando a configuração pela CLI
Os comandospolicies --install e policies --uninstall escrevem no arquivo de configurações de hook do seu agente CLI (os pontos de entrada dos hooks), enquanto policies-config.json é o arquivo que você gerencia diretamente. Os dois são independentes:
- Configurações do agente CLI — instrui o agente a chamar
failproofai --hook <event>a cada uso de ferramenta:- Claude Code:
~/.claude/settings.json(usuário),<cwd>/.claude/settings.json(projeto),<cwd>/.claude/settings.local.json(local) - OpenAI Codex:
~/.codex/hooks.json(usuário),<cwd>/.codex/hooks.json(projeto) — o Codex não possui escopolocal - GitHub Copilot CLI (beta):
~/.copilot/hooks/failproofai.json(usuário),<cwd>/.github/hooks/failproofai.json(projeto) — o Copilot não possui escopolocal. As entradas de hook usam os campos de comandobash/powershellcom chave por SO do Copilot comtimeoutSec; o arquivo carrega um marcadorversion: 1no nível superior. O suporte ao Copilot CLI está em beta enquanto verificamos o esquema de registrosevents.jsonl(não especificado na documentação pública) em mais sessões reais. - Cursor Agent (beta):
~/.cursor/hooks.json(usuário),<cwd>/.cursor/hooks.json(projeto) — o Cursor não possui escopolocal. As entradas de hook usam o formato Claude{type, command, timeout}(sem divisãobash/powershell), mas armazenadas sob chaves de evento em camelCase (preToolUse,beforeSubmitPrompt, …) em um array plano, conforme o esquema de hooks do Cursor; o arquivo carrega um marcadorversion: 1no nível superior. O handler canonicaliza camelCase → PascalCase viaCURSOR_EVENT_MAP, de modo que as políticas integradas existentes disparam sem alteração. O suporte ao Cursor Agent está em beta enquanto verificamos o formato em disco da transcrição do Cursor (não especificado na documentação pública) em mais instalações reais. - OpenCode (beta):
~/.config/opencode/opencode.json+~/.config/opencode/plugins/failproofai.mjs(usuário),<cwd>/.opencode/opencode.json+<cwd>/.opencode/plugins/failproofai.mjs(projeto) — o OpenCode não possui escopolocal. Diferentemente dos outros cinco CLIs, o OpenCode não possui sistema de hooks para comandos externos: ele carrega plugins JS/TS em processo, explicitamente registrados pelo arrayplugin: []noopencode.json(a autodescoberta a partir de.opencode/plugins/não é como os plugins são carregados no opencode v1.14.33). A instalação deposita um pequeno shim de plugin gerado que chama o binário failproofai em subprocesso e traduz a resposta JSON no formato Claude do binário para a semântica do plugin:throw new Error()para negação em eventos de ferramenta (cancela a chamada da ferramenta),client.session.prompt(...)para instruct E para negação deStop/SubagentStop(envia o motivo da negação como a próxima mensagem do usuário — o único canal de força de nova tentativa, já quesession.idleé apenas de notificação e lançar exceção a partir dele é um no-op), e no-op para allow. O shim canonicaliza nomes de ferramentas (minúsculas → PascalCase viaOPENCODE_TOOL_MAP) e chaves de argumentos de entrada de ferramentas (camelCase → snake_case viaOPENCODE_TOOL_INPUT_MAPparaRead/Write/Edit, por exemplofilePath→file_path,oldString→old_string) antes de encaminhar ao binário, de modo que políticas integradas de verificação de caminho comoblock-read-outside-cwd,block-env-fileseblock-secrets-writedisparam sem alteração em chamadas de ferramentas do OpenCode. As sessões ficam no banco de dados SQLite do opencode em~/.local/share/opencode/opencode.db; o visualizador de sessões do dashboard as lê viaopencode db --format jsoneopencode export <id>. O suporte ao OpenCode está em beta enquanto verificamos o comportamento entre versões e em mais sessões reais. Consulte a documentação de plugins do OpenCode. - Pi (beta):
~/.pi/agent/settings.json(usuário),<cwd>/.pi/settings.json(projeto) — o Pi não possui escopolocal. O Pi carrega pacotes de extensão TypeScript na inicialização; o arquivo de configurações é um array de strings plano{"packages": ["./relative/path", …]}. failproofai escreve uma única entrada no array de pacotes apontando para seu diretóriopi-extension/empacotado. A extensão subscreve internamente aos eventostool_call/user_bash/input/session_startdo Pi e executafailproofai --hook <Event> --cli piem shell; o handler canonicaliza eventos viaPI_EVENT_MAP(underscore_lower_snake_case → PascalCase) para que as políticas integradas existentes disparem sem alteração. Os argumentos de entrada de ferramentas também são canonicalizados viaPI_TOOL_INPUT_MAP(o Read / Write / Edit do Pi entregampathem vez defile_path; mapear a chave de nível superior permite queblock-env-fileseblock-secrets-writedisparem —block-read-outside-cwdjá tinha um fallback parapath). O suporte ao Pi está em beta enquanto a API de extensão do Pi e o layout do log de sessão se estabilizam. - Hermes (hermes-agent):
~/.hermes/config.yaml(somente escopo de usuário — o Hermes não possui configuração de projeto/local). O Hermes é um gateway para Slack/Telegram, portanto uma única instalação intercepta chamadas de ferramentas de todas as plataformas (Slack/Telegram/cli/cron) e de subagentes internos. As entradas de hook são um par{command, timeout}(timeout em segundos) sob um mapahooks:com chave pelos eventos snake_case do Hermes (pre_tool_call/post_tool_call/on_session_start/on_session_end/subagent_stop); o handler canonicaliza eventos viaHERMES_EVENT_MAPe nomes de ferramentas viaHERMES_TOOL_MAPpara que as políticas integradas disparem sem alteração. A configuração é editada por meio de uma edição de ida e volta deDocumentYAML que preserva comentários, para que as outras configurações do operador sobrevivam, e a instalação definehooks_auto_accept: truepara que o gateway headless (sem TTY) execute os hooks sem uma solicitação de consentimento. O avaliador emite o contrato stdout{"decision":"block","reason"}do Hermes (o Hermes ignora códigos de saída). Limitações: O Hermes não possui eventoStopde fim de turno, portanto as políticas integradasrequire-*-before-stopnunca disparam para ele (inaplicável, não quebrado);instructé rebaixado para allow com nota registrada (sem canal de contexto adicional); e a redação de segredos na saída (sanitize-*) não pode reescrever a saída das ferramentas pelo contrato de hook de shell. O Hermes é também uma fonte de auditoria offline — o dashboard lê suas sessões de gateway diretamente de~/.hermes/state.db.
- Claude Code:
policies-config.json— informa ao failproofai quais políticas avaliar e com quais parâmetros (compartilhado entre todos os agentes CLI)
--cli claude|codex|copilot|cursor|opencode|pi|hermes para direcionar um agente específico (separado por espaço ou repetido para qualquer subconjunto):
--cli é omitido, failproofai detecta quais agentes CLI estão instalados (which claude / which codex / which copilot / which cursor-agent / which opencode / which pi / which hermes):
- Um CLI detectado — seleciona automaticamente esse CLI sem solicitar confirmação.
- Vários CLIs detectados em um terminal interativo — exibe um prompt de seleção única com teclas de seta, agrupado em uma seção
Detected (N)(com uma linha agregadaInstall for all N detected+ cada CLI detectado individualmente) e uma seçãoNot installed (M) · install hooks ahead of timelistando todos os CLIs suportados não detectados como opções de instalação antecipada (↑↓ para mover, Enter para selecionar, ^C para sair). O fluxo de desinstalação exibe apenas a seção Detected. - Vários CLIs detectados em uma execução não interativa (CI, sem TTY) — instala para todos os CLIs detectados sem solicitar confirmação.
- Nenhum detectado — retorna para
claude, com um aviso de que nenhum binário de agente foi encontrado no PATH; o comando de hook ainda é escrito para que seja ativado assim que você instalar um.
policies-config.json diretamente a qualquer momento; as alterações entram em vigor imediatamente no próximo evento de hook, sem necessidade de reinicialização.
Exemplo: configuração no nível de projeto com padrões da equipe
Faça o commit de.failproofai/policies-config.json no seu repositório:
.failproofai/policies-config.local.json (incluído no gitignore) para substituições pessoais sem afetar os colegas de equipe.
