> ## Documentation Index
> Fetch the complete documentation index at: https://exosphere-auto-translate-docs-20260626-1023.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Configuração

> Formato do arquivo de configuração, sistema de três escopos e regras de mesclagem

O failproofai utiliza arquivos de configuração JSON para controlar quais políticas estão ativas, como elas se comportam e de onde políticas personalizadas são carregadas. A configuração foi projetada para ser fácil de compartilhar com sua equipe — faça commit no repositório e todos os desenvolvedores terão a mesma rede de segurança para agentes.

***

## Escopos de configuração

Existem três escopos de configuração, avaliados em ordem de prioridade:

| Escopo      | Caminho do arquivo                        | Finalidade                                                       |
| ----------- | ----------------------------------------- | ---------------------------------------------------------------- |
| **project** | `.failproofai/policies-config.json`       | Configurações por repositório, versionadas no controle de versão |
| **local**   | `.failproofai/policies-config.local.json` | Substituições pessoais por repositório, ignoradas pelo git       |
| **global**  | `~/.failproofai/policies-config.json`     | Padrões do usuário aplicados a todos os projetos                 |

Quando o failproofai recebe um evento de hook, ele carrega e mescla os três arquivos existentes 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.

```text theme={null}
project:  ["block-sudo"]
local:    ["block-rm-rf"]
global:   ["block-sudo", "sanitize-api-keys"]

resolved: ["block-sudo", "block-rm-rf", "sanitize-api-keys"]  ← união sem duplicatas
```

**`policyParams`** — o primeiro escopo que define parâmetros para uma determinada política vence por completo. Não há mesclagem profunda de valores dentro dos parâmetros de uma política.

```text theme={null}
project:  block-sudo → { allowPatterns: ["sudo apt-get update"] }
global:   block-sudo → { allowPatterns: ["sudo systemctl status"] }

resolved: { allowPatterns: ["sudo apt-get update"] }   ← project vence, global é ignorado
```

```text theme={null}
project:  (sem entrada para block-sudo)
local:    (sem entrada para block-sudo)
global:   block-sudo → { allowPatterns: ["sudo systemctl status"] }

resolved: { allowPatterns: ["sudo systemctl status"] }  ← cai para o global
```

**`customPoliciesPath`** — o primeiro escopo que o define vence.

**`llm`** — o primeiro escopo que o define vence.

***

## Formato do arquivo de configuração

```json theme={null}
{
  "enabledPolicies": [
    "block-sudo",
    "block-rm-rf",
    "block-push-master",
    "sanitize-api-keys",
    "sanitize-jwt",
    "block-env-files",
    "block-read-outside-cwd"
  ],
  "policyParams": {
    "block-sudo": {
      "allowPatterns": ["sudo systemctl status", "sudo journalctl"]
    },
    "block-push-master": {
      "protectedBranches": ["main", "release", "prod"]
    },
    "block-rm-rf": {
      "allowPaths": ["/tmp"]
    },
    "block-read-outside-cwd": {
      "allowPaths": ["/shared/data", "/opt/company"]
    },
    "sanitize-api-keys": {
      "additionalPatterns": [
        { "regex": "myco_[A-Za-z0-9]{32}", "label": "MyCo API key" }
      ]
    },
    "warn-large-file-write": {
      "thresholdKb": 512
    }
  },
  "customPoliciesPath": "/home/alice/myproject/my-policies.js"
}
```

***

## 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 pelo `failproofai policies`. Consulte [Políticas Integradas](/pt-br/built-in-policies) para a lista completa.

Políticas que não estão 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](/pt-br/built-in-policies).

Se uma política possui parâmetros, mas você não os especifica, os padrões integrados da política são utilizados. Usuários que não configuram `policyParams` têm 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 do disparo do hook, mas sinalizadas como avisos quando você executa `failproofai policies`.

#### `hint` (transversal)

Tipo: `string` (opcional)

Uma mensagem anexada ao motivo quando uma política retorna `deny` ou `instruct`. Use para fornecer ao Claude orientações práticas sem modificar a própria política.

Funciona com qualquer tipo de política — integrada, personalizada (`custom/`), convenção de projeto (`.failproofai-project/`) ou convenção do usuário (`.failproofai-user/`).

```json theme={null}
{
  "policyParams": {
    "block-force-push": {
      "hint": "Try creating a fresh branch instead."
    },
    "block-sudo": {
      "allowPatterns": ["sudo apt-get"],
      "hint": "Use apt-get directly without sudo."
    },
    "custom/my-policy": {
      "hint": "Ask the user for approval first."
    }
  }
}
```

Quando 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. Este campo é definido automaticamente por `failproofai policies --install --custom <path>` (o caminho é resolvido para absoluto antes de ser armazenado).

O arquivo é carregado novamente a cada evento de hook — não há cache. Consulte [Políticas Personalizadas](/pt-br/custom-policies) para detalhes de criação.

### Políticas baseadas em convenção

Além do `customPoliciesPath` explícito, o failproofai descobre e carrega automaticamente arquivos de política dos diretórios `.failproofai/policies/`:

| Nível   | Diretório                  | Escopo                                            |
| ------- | -------------------------- | ------------------------------------------------- |
| Projeto | `.failproofai/policies/`   | Compartilhado com a equipe via controle de versão |
| Usuário | `~/.failproofai/policies/` | Pessoal, aplica-se a todos os projetos            |

**Correspondência de arquivos:** Apenas arquivos que correspondem 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 por convenção não requerem 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:** Ambos os diretórios de convenção — de projeto e de usuário — são verificados. Todos os arquivos correspondentes de ambos os níveis são carregados (diferente do `customPoliciesPath`, que usa o primeiro escopo encontrado).

Consulte [Políticas Personalizadas](/pt-br/custom-policies) 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 dos cenários.

```json theme={null}
{
  "llm": {
    "model": "claude-sonnet-4-6",
    "apiKey": "sk-ant-..."
  }
}
```

***

## Gerenciando a configuração pela CLI

Os comandos `policies --install` e `policies --uninstall` escrevem no arquivo de configurações de hooks da CLI do agente (os pontos de entrada dos hooks), enquanto o `policies-config.json` é o arquivo que você gerencia diretamente. Os dois são separados:

* **Configurações da CLI do agente** — 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 escopo `local`
  * **GitHub Copilot CLI *(beta)***: `~/.copilot/hooks/failproofai.json` (usuário), `<cwd>/.github/hooks/failproofai.json` (projeto) — o Copilot não tem escopo `local`. As entradas de hook usam os campos de comando `bash`/`powershell` com chave de SO do Copilot com `timeoutSec`; o arquivo contém um marcador `version: 1` no nível superior. O suporte ao Copilot CLI está em **beta** enquanto verificamos o esquema de registro `events.jsonl` (não especificado na documentação pública) contra mais sessões do mundo real.
  * **Cursor Agent *(beta)***: `~/.cursor/hooks.json` (usuário), `<cwd>/.cursor/hooks.json` (projeto) — o Cursor não tem escopo `local`. As entradas de hook usam o formato no estilo Claude `{type, command, timeout}` (sem separação `bash`/`powershell`), mas armazenadas sob chaves de evento em camelCase (`preToolUse`, `beforeSubmitPrompt`, …) em um array plano seguindo o [esquema de hooks](https://cursor.com/docs/hooks) do Cursor; o arquivo contém um marcador `version: 1` no nível superior. O handler canonicaliza camelCase → PascalCase via `CURSOR_EVENT_MAP`, então as políticas integradas existentes disparam sem alterações. O suporte ao Cursor Agent está em **beta** enquanto verificamos o formato de transcrição em disco do Cursor (não especificado na documentação pública) contra mais instalações do mundo real.
  * **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 tem escopo `local`. Diferente dos outros seis CLIs, o OpenCode **não possui sistema de hook por comando externo**: ele carrega plugins JS/TS em processo, explicitamente registrados via o array `plugin: []` em `opencode.json` (a descoberta automática de `.opencode/plugins/` **não** é como os plugins carregam no opencode v1.14.33). A instalação cria um pequeno shim de plugin gerado que chama o binário failproofai como subprocesso e traduz a resposta JSON no formato Claude de volta para semântica de plugin: `throw new Error()` para deny em eventos de ferramenta (cancela a chamada da ferramenta), `client.session.prompt(...)` para instruct E para deny de `Stop` / `SubagentStop` (envia o motivo da negação como próxima mensagem do usuário — o único canal de força de reenvio, já que `session.idle` é apenas notificação e lançar exceção a partir dele não tem efeito), e no-op para allow. O shim canonicaliza tanto os nomes das ferramentas (lowercase → PascalCase via `OPENCODE_TOOL_MAP`) quanto as chaves dos argumentos de entrada de ferramentas (camelCase → snake\_case via `OPENCODE_TOOL_INPUT_MAP` para `Read` / `Write` / `Edit`, por exemplo `filePath` → `file_path`, `oldString` → `old_string`) antes de repassar ao binário, de modo que as políticas integradas de verificação de caminho como `block-read-outside-cwd`, `block-env-files` e `block-secrets-write` disparam normalmente em chamadas de ferramenta do OpenCode. As sessões ficam no banco SQLite do opencode em `~/.local/share/opencode/opencode.db`; o visualizador de sessões do dashboard as lê via `opencode db --format json` e `opencode export <id>`. O suporte ao OpenCode está em **beta** enquanto verificamos o comportamento em diferentes versões e contra mais sessões do mundo real. Consulte a [documentação de plugins do OpenCode](https://opencode.ai/docs/plugins/).
  * **Pi *(beta)***: `~/.pi/agent/settings.json` (usuário), `<cwd>/.pi/settings.json` (projeto) — o Pi não tem escopo `local`. O Pi carrega pacotes de extensão TypeScript na inicialização; o arquivo de configurações é um array simples de strings `{"packages": ["./relative/path", …]}`. O failproofai escreve uma única entrada no array de pacotes apontando para seu diretório `pi-extension/` empacotado. A extensão internamente assina os eventos `tool_call` / `user_bash` / `input` / `session_start` do Pi e executa `failproofai --hook <Event> --cli pi`; o handler canonicaliza underscore\_lower\_snake\_case → PascalCase via `PI_EVENT_MAP`, então as políticas integradas existentes disparam sem alterações. Os argumentos de entrada das ferramentas também são canonicalizados via `PI_TOOL_INPUT_MAP` (Read / Write / Edit do Pi entregam `path` em vez de `file_path`; mapear a chave de nível superior permite que `block-env-files` e `block-secrets-write` disparem — `block-read-outside-cwd` já possuía um fallback para `path`). O suporte ao Pi está em **beta** enquanto a API de extensão e o layout do log de sessão do Pi se estabilizam.
  * **Gemini CLI *(beta)***: `~/.gemini/settings.json` (usuário), `<cwd>/.gemini/settings.json` (projeto) — o Gemini não tem escopo `local` (documenta um escopo `system` em `/etc/gemini-cli/settings.json`, que o failproofai não expõe). As entradas de hook usam o formato Claude `{type, command, timeout}` encapsulado no esquema de matcher do Gemini `{matcher, hooks: [...]}` com `matcher: "*"` por padrão. Os eventos são PascalCase (`SessionStart`, `BeforeAgent`, `AfterAgent`, `BeforeModel`, `AfterModel`, `BeforeToolSelection`, `BeforeTool`, `AfterTool`, `PreCompress`, `Notification`, `SessionEnd`); o handler mapeia para nomes canônicos Claude via `GEMINI_EVENT_MAP`. Os nomes das ferramentas são snake\_case (`run_shell_command`, `read_file`, `write_file`, `replace`, …) — o handler canonicaliza via `GEMINI_TOOL_MAP`, então as políticas integradas existentes disparam sem alterações. O avaliador de políticas emite o formato plano `{decision: "deny", reason}` do Gemini (preferido pela "Regra de Ouro" do exit-0 do Gemini), `{hookSpecificOutput: {hookEventName, additionalContext}}` para injeção de contexto em BeforeAgent / AfterTool / SessionStart, e `{decision: "block", reason}` no AfterAgent para semântica de força de reenvio. O suporte ao Gemini CLI está em **beta** enquanto ampliamos a cobertura do mundo real. Consulte a [documentação de hooks do Gemini CLI](https://geminicli.com/docs/hooks/).
* **`policies-config.json`** — instrui o failproofai sobre quais políticas avaliar e com quais parâmetros (compartilhado entre todos os CLIs de agentes)

Passe `--cli claude|codex|copilot|cursor|opencode|pi|gemini` para direcionar um agente específico (separado por espaço ou repetido para qualquer subconjunto):

```bash theme={null}
failproofai policies --install --cli codex --scope project
failproofai policies --install --cli copilot --scope project
failproofai policies --install --cli cursor --scope project
failproofai policies --install --cli opencode --scope project
failproofai policies --install --cli pi --scope project
failproofai policies --install --cli gemini --scope project
failproofai policies --install --cli claude codex copilot cursor opencode pi gemini
```

Quando `--cli` é omitido, o `failproofai` detecta quais CLIs de agentes estão instalados (`which claude` / `which codex` / `which copilot` / `which cursor-agent` / `which opencode` / `which pi` / `which gemini`):

* **Um CLI detectado** — seleciona automaticamente esse CLI sem solicitar confirmação.
* **Múltiplos 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 agregada `Install for all N detected` + cada CLI detectado individualmente) e uma seção `Not installed (M) · install hooks ahead of time` listando todos os CLIs suportados não detectados como opção de instalação antecipada (↑↓ para mover, Enter para selecionar, ^C para sair). O fluxo de desinstalação exibe apenas a seção Detected.
* **Múltiplos CLIs detectados** em uma execução não interativa (CI, sem TTY) — instala para todos os CLIs detectados sem solicitar confirmação.
* **Nenhum detectado** — volta 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.

Você pode editar o `policies-config.json` diretamente a qualquer momento; as alterações têm efeito imediato no próximo evento de hook, sem necessidade de reinicialização.

***

## Exemplo: configuração no nível do projeto com padrões da equipe

Faça commit de `.failproofai/policies-config.json` no seu repositório:

```json theme={null}
{
  "enabledPolicies": [
    "block-sudo",
    "block-rm-rf",
    "block-push-master",
    "sanitize-api-keys",
    "block-env-files"
  ],
  "policyParams": {
    "block-push-master": {
      "protectedBranches": ["main", "release", "hotfix"]
    }
  }
}
```

Cada desenvolvedor pode então criar `.failproofai/policies-config.local.json` (ignorado pelo git) para substituições pessoais sem afetar os colegas de equipe.
