Á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 |
Reglas de fusión
enabledPolicies — la unión de los tres ámbitos. Una política habilitada en cualquier nivel está activa.
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.
customPoliciesPath — el primer ámbito que lo define gana.
llm — el primer ámbito que lo define gana.
Formato del archivo de configuración
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 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.
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/).
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 para detalles de creación.
Políticas basadas en convenciones
Además delcustomPoliciesPath 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 |
*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 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.
Gestión de la configuración desde la CLI
Los comandospolicies --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 ámbitolocal - GitHub Copilot CLI (beta):
~/.copilot/hooks/failproofai.json(usuario),<cwd>/.github/hooks/failproofai.json(proyecto) — Copilot no tiene ámbitolocal. Las entradas de hook usan los campos de comandobash/powershellcon clave por SO de Copilot contimeoutSec; el archivo lleva un marcador de nivel superiorversion: 1. La compatibilidad con Copilot CLI está en beta mientras verificamos el esquema de registrosevents.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 ámbitolocal. Las entradas de hook usan la forma{type, command, timeout}del estilo Claude (sin divisiónbash/powershell), pero almacenadas bajo claves de evento en camelCase (preToolUse,beforeSubmitPrompt, …) en un array plano según el esquema de hooks de Cursor; el archivo lleva un marcador de nivel superiorversion: 1. El manejador canonicaliza camelCase → PascalCase medianteCURSOR_EVENT_MAPpara 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 ámbitolocal. 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 arrayplugin: []enopencode.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 deStop/SubagentStop(envía el motivo de denegación como el siguiente mensaje de usuario — el único canal de reintento forzado, ya quesession.idlees 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 medianteOPENCODE_TOOL_MAP) como las claves de argumentos de entrada de herramientas (camelCase → snake_case medianteOPENCODE_TOOL_INPUT_MAPparaRead/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 comoblock-read-outside-cwd,block-env-filesyblock-secrets-writese 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 medianteopencode db --format jsonyopencode 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. - Pi (beta):
~/.pi/agent/settings.json(usuario),<cwd>/.pi/settings.json(proyecto) — Pi no tiene ámbitolocal. 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 directoriopi-extension/incluido. La extensión se suscribe internamente a los eventostool_call/user_bash/input/session_startde Pi y lanzafailproofai --hook <Event> --cli pi; el manejador canonicaliza underscore_lower_snake_case → PascalCase mediantePI_EVENT_MAPpara que las políticas integradas existentes se activen sin cambios. Los argumentos de entrada de herramientas también se canonizan mediantePI_TOOL_INPUT_MAP(Read/Write/Edit de Pi entreganpathen lugar defile_path; mapear la clave de nivel superior permite queblock-env-filesyblock-secrets-writese activen —block-read-outside-cwdya tenía una alternativa conpath). 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 ámbitolocal(documenta un ámbitosystemen/etc/gemini-cli/settings.jsonque 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 conmatcher: "*"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 medianteGEMINI_EVENT_MAP. Los nombres de herramientas son snake_case (run_shell_command,read_file,write_file,replace, …) — el manejador los canonicaliza medianteGEMINI_TOOL_MAPpara 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.
- Claude Code:
policies-config.json— indica a failproofai qué políticas evaluar y con qué parámetros (compartido entre todas las CLIs de agentes)
--cli claude|codex|copilot|cursor|opencode|pi|gemini para apuntar a un agente específico (separados por espacios o repetidos para cualquier subconjunto):
--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 agregadaInstall for all N detected+ cada CLI detectada individualmente) y una secciónNot installed (M) · install hooks ahead of timeque 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.
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:
.failproofai/policies-config.local.json (ignorado por git) para sus anulaciones personales sin afectar a sus compañeros de equipo.
