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

# Configuración

> Formato del archivo de configuración, sistema de tres ámbitos y reglas de fusión

failproofai usa archivos de configuración JSON para controlar qué políticas están activas, cómo se comportan y desde dónde se cargan las políticas personalizadas. La configuración está diseñada para compartirse fácilmente con tu equipo: confírmala en tu repositorio y cada desarrollador tendrá la misma red de seguridad para el agente.

***

## Ámbitos de configuración

Existen tres ámbitos de configuración, evaluados en orden de prioridad:

| Ámbito       | Ruta del archivo                          | Propósito                                                    |
| ------------ | ----------------------------------------- | ------------------------------------------------------------ |
| **proyecto** | `.failproofai/policies-config.json`       | Ajustes por repositorio, confirmados en control de versiones |
| **local**    | `.failproofai/policies-config.local.json` | Anulaciones personales por repositorio, ignoradas por git    |
| **global**   | `~/.failproofai/policies-config.json`     | Valores predeterminados del usuario en todos los proyectos   |

Cuando failproofai recibe un evento de hook, carga y fusiona los tres archivos que existen para el directorio de trabajo actual.

### Reglas de fusión

**`enabledPolicies`** — la unión de los tres ámbitos. Una política habilitada en cualquier nivel está activa.

```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ón deduplicada
```

**`policyParams`** — el primer ámbito que define los parámetros para una política dada gana por completo. No hay fusión profunda de valores dentro de los parámetros de una 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 gana, global ignorado
```

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

resolved: { allowPatterns: ["sudo systemctl status"] }  ← cae hasta global
```

**`customPoliciesPath`** — el primer ámbito que lo define gana.

**`llm`** — el primer ámbito que lo define gana.

***

## Formato del archivo de configuración

```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"
}
```

***

## Referencia de campos

### `enabledPolicies`

Tipo: `string[]`

Lista de nombres de políticas a habilitar. Los nombres deben coincidir exactamente con los identificadores de política que muestra `failproofai policies`. Consulta [Políticas integradas](/es/built-in-policies) para ver la lista completa.

Las políticas que no están en `enabledPolicies` están inactivas, incluso si tienen entradas en `policyParams`.

### `policyParams`

Tipo: `Record<string, Record<string, unknown>>`

Anulaciones de parámetros por política. La clave externa es el nombre de la política; las claves internas son específicas de cada política. Cada política documenta sus parámetros disponibles en [Políticas integradas](/es/built-in-policies).

Si una política tiene parámetros pero no los especificas, se usan los valores predeterminados integrados de la política. Los usuarios que no configuren `policyParams` en absoluto obtendrán un comportamiento idéntico al de versiones anteriores.

Las claves desconocidas dentro del bloque de parámetros de una política se ignoran silenciosamente cuando se dispara el hook, pero se marcan como advertencias cuando ejecutas `failproofai policies`.

#### `hint` (transversal)

Tipo: `string` (opcional)

Un mensaje que se agrega al motivo cuando una política devuelve `deny` o `instruct`. Úsalo para dar a Claude orientación accionable sin modificar la política en sí.

Funciona con cualquier tipo de política: integrada, personalizada (`custom/`), convención de proyecto (`.failproofai-project/`) o convención de usuario (`.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."
    }
  }
}
```

Cuando `block-force-push` deniega, Claude ve: *"Force-pushing is blocked. Try creating a fresh branch instead."*

Los valores que no sean cadenas de texto y las cadenas vacías se ignoran silenciosamente. Si `hint` no está definido, el comportamiento no cambia (compatible con versiones anteriores).

### `customPoliciesPath`

Tipo: `string` (ruta absoluta)

Ruta a un archivo JavaScript que contiene políticas de hook personalizadas. Se establece automáticamente mediante `failproofai policies --install --custom <path>` (la ruta se resuelve a absoluta antes de almacenarse).

El archivo se carga de nuevo en cada evento de hook; no hay caché. Consulta [Políticas personalizadas](/es/custom-policies) para detalles de creación.

### Políticas basadas en convenciones

Además del `customPoliciesPath` explícito, failproofai descubre y carga automáticamente archivos de políticas desde directorios `.failproofai/policies/`:

| Nivel    | Directorio                 | Ámbito                                                    |
| -------- | -------------------------- | --------------------------------------------------------- |
| Proyecto | `.failproofai/policies/`   | Compartido con el equipo a través de control de versiones |
| Usuario  | `~/.failproofai/policies/` | Personal, aplica a todos los proyectos                    |

**Coincidencia de archivos:** Solo se cargan los archivos que coincidan con `*policies.{js,mjs,ts}` (p. ej., `security-policies.mjs`, `workflow-policies.js`). Los demás archivos del directorio se ignoran.

**Sin configuración necesaria:** Las políticas de convención no requieren entradas en `policies-config.json`. Simplemente coloca los archivos en el directorio y se detectarán en el próximo evento de hook.

**Carga por unión:** Se analizan tanto el directorio de convenciones del proyecto como el del usuario. Todos los archivos coincidentes de ambos niveles se cargan (a diferencia de `customPoliciesPath`, que usa el primer ámbito que gana).

Consulta [Políticas personalizadas](/es/custom-policies) para más detalles y ejemplos.

### `llm`

Tipo: `object` (opcional)

Configuración del cliente LLM para políticas que realizan llamadas a IA. No es necesario en la mayoría de los casos.

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

***

## Gestión de la configuración desde la CLI

Los comandos `policies --install` y `policies --uninstall` escriben en el archivo de configuración de hooks de tu CLI de agente (los puntos de entrada del hook), mientras que `policies-config.json` es el archivo que gestionas directamente. Son dos cosas distintas:

* **Ajustes de la CLI del agente** — indica al agente que llame a `failproofai --hook <event>` en cada uso de herramienta:
  * **Claude Code**: `~/.claude/settings.json` (usuario), `<cwd>/.claude/settings.json` (proyecto), `<cwd>/.claude/settings.local.json` (local)
  * **OpenAI Codex**: `~/.codex/hooks.json` (usuario), `<cwd>/.codex/hooks.json` (proyecto) — Codex no tiene ámbito `local`
  * **GitHub Copilot CLI *(beta)***: `~/.copilot/hooks/failproofai.json` (usuario), `<cwd>/.github/hooks/failproofai.json` (proyecto) — Copilot no tiene ámbito `local`. Las entradas de hook usan los campos de comando `bash`/`powershell` con clave por SO de Copilot con `timeoutSec`; el archivo lleva un marcador de nivel superior `version: 1`. La compatibilidad con Copilot CLI está en **beta** mientras verificamos el esquema de registros `events.jsonl` (que la documentación pública no especifica) con más sesiones del mundo real.
  * **Cursor Agent *(beta)***: `~/.cursor/hooks.json` (usuario), `<cwd>/.cursor/hooks.json` (proyecto) — Cursor no tiene ámbito `local`. Las entradas de hook usan la forma `{type, command, timeout}` del estilo Claude (sin división `bash`/`powershell`), pero almacenadas bajo claves de evento en camelCase (`preToolUse`, `beforeSubmitPrompt`, …) en un array plano según el [esquema de hooks de Cursor](https://cursor.com/docs/hooks); el archivo lleva un marcador de nivel superior `version: 1`. El manejador canonicaliza camelCase → PascalCase mediante `CURSOR_EVENT_MAP` para que las políticas integradas existentes se activen sin cambios. La compatibilidad con Cursor Agent está en **beta** mientras verificamos el formato en disco de las transcripciones de Cursor (no especificado en la documentación pública) con más instalaciones del mundo real.
  * **OpenCode *(beta)***: `~/.config/opencode/opencode.json` + `~/.config/opencode/plugins/failproofai.mjs` (usuario), `<cwd>/.opencode/opencode.json` + `<cwd>/.opencode/plugins/failproofai.mjs` (proyecto) — OpenCode no tiene ámbito `local`. A diferencia de las otras seis CLIs, OpenCode **no tiene un sistema de hooks de comandos externos**: carga plugins JS/TS en proceso, registrados explícitamente mediante el array `plugin: []` en `opencode.json` (el autodescubrimiento desde `.opencode/plugins/` **no** es como se cargan los plugins en opencode v1.14.33). La instalación coloca un pequeño shim de plugin generado que llama como subproceso al binario de failproofai y traduce la respuesta JSON en forma Claude del binario a la semántica del plugin: `throw new Error()` para denegación de eventos de herramienta (cancela la llamada a la herramienta), `client.session.prompt(...)` para instruct Y para denegación de `Stop`/`SubagentStop` (envía el motivo de denegación como el siguiente mensaje de usuario — el único canal de reintento forzado, ya que `session.idle` es solo de notificación y lanzar desde él es un no-op), y no-op para allow. El shim canonicaliza tanto los nombres de herramientas (minúsculas → PascalCase mediante `OPENCODE_TOOL_MAP`) como las claves de argumentos de entrada de herramientas (camelCase → snake\_case mediante `OPENCODE_TOOL_INPUT_MAP` para `Read`/`Write`/`Edit`, p. ej. `filePath` → `file_path`, `oldString` → `old_string`) antes de reenviar al binario, de modo que las políticas integradas de verificación de rutas como `block-read-outside-cwd`, `block-env-files` y `block-secrets-write` se activan sin cambios en las llamadas de herramientas de OpenCode. Las sesiones viven en la base de datos SQLite de opencode en `~/.local/share/opencode/opencode.db`; el visor de sesiones del panel las lee mediante `opencode db --format json` y `opencode export <id>`. La compatibilidad con OpenCode está en **beta** mientras verificamos el comportamiento en distintas versiones y con más sesiones del mundo real. Consulta la [documentación de plugins de OpenCode](https://opencode.ai/docs/plugins/).
  * **Pi *(beta)***: `~/.pi/agent/settings.json` (usuario), `<cwd>/.pi/settings.json` (proyecto) — Pi no tiene ámbito `local`. Pi carga paquetes de extensión TypeScript al inicio; el archivo de ajustes es un array plano de cadenas `{"packages": ["./relative/path", …]}`. failproofai escribe una única entrada en el array de paquetes que apunta a su directorio `pi-extension/` incluido. La extensión se suscribe internamente a los eventos `tool_call`/`user_bash`/`input`/`session_start` de Pi y lanza `failproofai --hook <Event> --cli pi`; el manejador canonicaliza underscore\_lower\_snake\_case → PascalCase mediante `PI_EVENT_MAP` para que las políticas integradas existentes se activen sin cambios. Los argumentos de entrada de herramientas también se canonizan mediante `PI_TOOL_INPUT_MAP` (Read/Write/Edit de Pi entregan `path` en lugar de `file_path`; mapear la clave de nivel superior permite que `block-env-files` y `block-secrets-write` se activen — `block-read-outside-cwd` ya tenía una alternativa con `path`). La compatibilidad con Pi está en **beta** mientras la API de extensión de Pi y el diseño del registro de sesiones se estabilizan.
  * **Gemini CLI *(beta)***: `~/.gemini/settings.json` (usuario), `<cwd>/.gemini/settings.json` (proyecto) — Gemini no tiene ámbito `local` (documenta un ámbito `system` en `/etc/gemini-cli/settings.json` que failproofai no expone). Las entradas de hook usan la forma `{type, command, timeout}` de Claude envuelta en el esquema de matcher `{matcher, hooks: [...]}` de Gemini con `matcher: "*"` por defecto. Los eventos son PascalCase (`SessionStart`, `BeforeAgent`, `AfterAgent`, `BeforeModel`, `AfterModel`, `BeforeToolSelection`, `BeforeTool`, `AfterTool`, `PreCompress`, `Notification`, `SessionEnd`); el manejador mapea a nombres canónicos de Claude mediante `GEMINI_EVENT_MAP`. Los nombres de herramientas son snake\_case (`run_shell_command`, `read_file`, `write_file`, `replace`, …) — el manejador los canonicaliza mediante `GEMINI_TOOL_MAP` para que las políticas integradas existentes se activen sin cambios. El evaluador de políticas emite la forma plana `{decision: "deny", reason}` de Gemini (preferida según el contrato de salida-0 de la "Regla de Oro" de Gemini), `{hookSpecificOutput: {hookEventName, additionalContext}}` para inyección de contexto en BeforeAgent/AfterTool/SessionStart, y `{decision: "block", reason}` en AfterAgent para semántica de reintento forzado. La compatibilidad con Gemini CLI está en **beta** mientras ampliamos la cobertura del mundo real. Consulta la [documentación de hooks de Gemini CLI](https://geminicli.com/docs/hooks/).
* **`policies-config.json`** — indica a failproofai qué políticas evaluar y con qué parámetros (compartido entre todas las CLIs de agentes)

Pasa `--cli claude|codex|copilot|cursor|opencode|pi|gemini` para apuntar a un agente específico (separados por espacios o repetidos para cualquier 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
```

Cuando se omite `--cli`, `failproofai` detecta qué CLIs de agentes están instaladas (`which claude` / `which codex` / `which copilot` / `which cursor-agent` / `which opencode` / `which pi` / `which gemini`):

* **Una CLI detectada** — la selecciona automáticamente sin preguntar.
* **Múltiples CLIs detectadas** en una terminal interactiva — muestra un indicador de selección única con teclas de flecha agrupado en una sección `Detected (N)` (con una fila agregada `Install for all N detected` + cada CLI detectada individualmente) y una sección `Not installed (M) · install hooks ahead of time` que lista todas las CLIs compatibles no detectadas como opciones de instalación anticipada (↑↓ para moverse, Enter para seleccionar, ^C para salir). El flujo de desinstalación solo muestra la sección Detected.
* **Múltiples CLIs detectadas** en una ejecución no interactiva (CI, sin TTY) — instala para todas las CLIs detectadas sin preguntar.
* **Ninguna detectada** — recurre a `claude`, con una advertencia de que no se encontró ningún binario de agente en PATH; el comando de hook se escribe igualmente para que se active en cuanto instales uno.

Puedes editar `policies-config.json` directamente en cualquier momento; los cambios surten efecto de inmediato en el siguiente evento de hook sin necesidad de reiniciar.

***

## Ejemplo: configuración a nivel de proyecto con valores predeterminados del equipo

Confirma `.failproofai/policies-config.json` en tu repositorio:

```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 desarrollador puede luego crear `.failproofai/policies-config.local.json` (ignorado por git) para sus anulaciones personales sin afectar a sus compañeros de equipo.
