Niveaux de configuration
Il existe trois niveaux de configuration, évalués par ordre de priorité :
Lorsque failproofai reçoit un événement de hook, il charge et fusionne les trois fichiers qui existent pour le répertoire de travail courant.
Règles de fusion
enabledPolicies — union des trois niveaux. Une politique activée à n’importe quel niveau est active.
policyParams — le premier niveau qui définit des paramètres pour une politique donnée l’emporte entièrement. Il n’y a pas de fusion profonde des valeurs au sein des paramètres d’une politique.
customPoliciesPath — le premier niveau qui le définit l’emporte.
llm — le premier niveau qui le définit l’emporte.
Format du fichier de configuration
Référence des champs
enabledPolicies
Type : string[]
Liste des noms de politiques à activer. Les noms doivent correspondre exactement aux identifiants de politique affichés par failproofai policies. Consultez Built-in Policies pour la liste complète.
Les politiques absentes de enabledPolicies sont inactives, même si elles ont des entrées dans policyParams.
policyParams
Type : Record<string, Record<string, unknown>>
Substitutions de paramètres par politique. La clé externe est le nom de la politique ; les clés internes sont spécifiques à chaque politique. Chaque politique documente ses paramètres disponibles dans Built-in Policies.
Si une politique possède des paramètres mais que vous ne les spécifiez pas, les valeurs par défaut intégrées de la politique sont utilisées. Les utilisateurs qui ne configurent pas policyParams du tout obtiennent un comportement identique aux versions précédentes.
Les clés inconnues dans le bloc de paramètres d’une politique sont silencieusement ignorées lors du déclenchement du hook, mais signalées comme avertissements lorsque vous exécutez failproofai policies.
hint (transversal)
Type : string (optionnel)
Un message ajouté à la raison lorsqu’une politique renvoie deny ou instruct. Utilisez-le pour donner à Claude des indications exploitables sans modifier la politique elle-même.
Fonctionne avec n’importe quel type de politique — intégrée, personnalisée (custom/), convention de projet (.failproofai-project/) ou convention utilisateur (.failproofai-user/).
block-force-push refuse, Claude voit : « Force-pushing is blocked. Try creating a fresh branch instead. »
Les valeurs non-chaînes et les chaînes vides sont silencieusement ignorées. Si hint n’est pas défini, le comportement reste inchangé (rétrocompatible).
customPoliciesPath
Type : string (chemin absolu)
Chemin vers un fichier JavaScript contenant des politiques de hook personnalisées. Ce champ est défini automatiquement par failproofai policies --install --custom <path> (le chemin est résolu en absolu avant d’être stocké).
Le fichier est chargé à nouveau à chaque événement de hook — il n’y a pas de mise en cache. Consultez Custom Policies pour les détails de création.
Politiques basées sur les conventions
En plus ducustomPoliciesPath explicite, failproofai découvre et charge automatiquement les fichiers de politiques depuis les répertoires .failproofai/policies/ :
Correspondance de fichiers : Seuls les fichiers correspondant à
*policies.{js,mjs,ts} sont chargés (par exemple security-policies.mjs, workflow-policies.js). Les autres fichiers du répertoire sont ignorés.
Aucune configuration requise : Les politiques de convention ne nécessitent aucune entrée dans policies-config.json. Déposez simplement des fichiers dans le répertoire et ils seront pris en compte au prochain événement de hook.
Chargement par union : Les répertoires de convention du projet et de l’utilisateur sont tous deux analysés. Tous les fichiers correspondants des deux niveaux sont chargés (contrairement à customPoliciesPath qui utilise la règle premier-niveau-gagnant).
Consultez Custom Policies pour plus de détails et d’exemples.
llm
Type : object (optionnel)
Configuration du client LLM pour les politiques qui effectuent des appels IA. Non requis pour la plupart des configurations.
Gestion de la configuration depuis la CLI
Les commandespolicies --install et policies --uninstall écrivent dans le fichier de paramètres des hooks de votre CLI agent (les points d’entrée des hooks), tandis que policies-config.json est le fichier que vous gérez directement. Les deux sont distincts :
- Paramètres de la CLI agent — indique à l’agent d’appeler
failproofai --hook <event>à chaque utilisation d’outil :- Claude Code :
~/.claude/settings.json(utilisateur),<cwd>/.claude/settings.json(projet),<cwd>/.claude/settings.local.json(local) - OpenAI Codex :
~/.codex/hooks.json(utilisateur),<cwd>/.codex/hooks.json(projet) — Codex n’a pas de niveaulocal - GitHub Copilot CLI (bêta) :
~/.copilot/hooks/failproofai.json(utilisateur),<cwd>/.github/hooks/failproofai.json(projet) — Copilot n’a pas de niveaulocal. Les entrées de hook utilisent les champs de commandebash/powershellà clé OS de Copilot avectimeoutSec; le fichier porte un marqueurversion: 1au niveau racine. La prise en charge de Copilot CLI est en bêta pendant que nous vérifions le schéma d’enregistrementevents.jsonl(que la documentation publique ne spécifie pas) contre davantage de sessions réelles. - Cursor Agent (bêta) :
~/.cursor/hooks.json(utilisateur),<cwd>/.cursor/hooks.json(projet) — Cursor n’a pas de niveaulocal. Les entrées de hook utilisent la forme{type, command, timeout}inspirée de Claude (sans séparationbash/powershell), mais stockées sous des clés d’événement en camelCase (preToolUse,beforeSubmitPrompt, …) dans un tableau plat selon le schéma de hooks de Cursor ; le fichier porte un marqueurversion: 1au niveau racine. Le gestionnaire canonicalise camelCase → PascalCase viaCURSOR_EVENT_MAPafin que les politiques intégrées existantes se déclenchent sans modification. La prise en charge de Cursor Agent est en bêta pendant que nous vérifions le format de transcription sur disque de Cursor (non spécifié dans la documentation publique) contre davantage d’installations réelles. - OpenCode (bêta) :
~/.config/opencode/opencode.json+~/.config/opencode/plugins/failproofai.mjs(utilisateur),<cwd>/.opencode/opencode.json+<cwd>/.opencode/plugins/failproofai.mjs(projet) — OpenCode n’a pas de niveaulocal. Contrairement aux cinq autres CLI, OpenCode n’a pas de système de hook par commande externe : il charge des plugins JS/TS en cours de processus explicitement enregistrés via le tableauplugin: []dansopencode.json(la découverte automatique depuis.opencode/plugins/n’est pas le mode de chargement des plugins sur opencode v1.14.33). L’installation dépose un petit shim de plugin généré qui appelle le binaire failproofai en sous-processus et traduit la réponse JSON en forme Claude du binaire vers la sémantique du plugin :throw new Error()pour le refus d’événement outil (annule l’appel d’outil),client.session.prompt(...)pour instruct ET pour le refusStop/SubagentStop(soumet le motif de refus comme prochain message utilisateur — le seul canal de nouvelle tentative forcée puisquesession.idleest uniquement pour les notifications et qu’une exception levée depuis celui-ci est un no-op), et no-op pour allow. Le shim canonicalise les noms d’outils (minuscules → PascalCase viaOPENCODE_TOOL_MAP) et les clés d’arguments d’entrée d’outil (camelCase → snake_case viaOPENCODE_TOOL_INPUT_MAPpourRead/Write/Edit, par exemplefilePath→file_path,oldString→old_string) avant de transmettre au binaire, de sorte que les politiques intégrées de vérification de chemin commeblock-read-outside-cwd,block-env-filesetblock-secrets-writese déclenchent sans modification sur les appels d’outils OpenCode. Les sessions vivent dans la base de données SQLite d’opencode à~/.local/share/opencode/opencode.db; la visionneuse de sessions du tableau de bord les lit viaopencode db --format jsonetopencode export <id>. La prise en charge d’OpenCode est en bêta pendant que nous vérifions le comportement entre les versions et contre davantage de sessions réelles. Consultez la documentation des plugins OpenCode. - Pi (bêta) :
~/.pi/agent/settings.json(utilisateur),<cwd>/.pi/settings.json(projet) — Pi n’a pas de niveaulocal. Pi charge des packages d’extension TypeScript au démarrage ; le fichier de paramètres est un tableau de chaînes plat{"packages": ["./relative/path", …]}. failproofai écrit une seule entrée dans le tableau packages pointant vers son répertoirepi-extension/intégré. L’extension s’abonne en interne aux événementstool_call/user_bash/input/session_startde Pi et exécutefailproofai --hook <Event> --cli pien shell ; le gestionnaire canonicalise les événements underscore_lower_snake_case → PascalCase viaPI_EVENT_MAPafin que les politiques intégrées existantes se déclenchent sans modification. Les arguments d’entrée d’outil sont également canonicalisés viaPI_TOOL_INPUT_MAP(les commandes Read / Write / Edit de Pi livrentpathplutôt quefile_path; mapper la clé de niveau supérieur permet àblock-env-filesetblock-secrets-writede se déclencher —block-read-outside-cwdavait déjà un fallbackpath). La prise en charge de Pi est en bêta pendant que l’API d’extension de Pi et la disposition du journal de session se stabilisent. - Hermes (hermes-agent) :
~/.hermes/config.yaml(niveau utilisateur uniquement — Hermes n’a pas de configuration projet/local). Hermes est une passerelle Slack/Telegram, donc une seule installation intercepte les appels d’outils de toutes les plateformes (Slack/Telegram/cli/cron) et des sous-agents internes. Les entrées de hook sont une paire{command, timeout}(timeout en secondes) sous une maphooks:indexée par les événements snake_case de Hermes (pre_tool_call/post_tool_call/on_session_start/on_session_end/subagent_stop) ; le gestionnaire canonicalise les événements viaHERMES_EVENT_MAPet les noms d’outils viaHERMES_TOOL_MAPafin que les politiques intégrées se déclenchent sans modification. La configuration est modifiée via un aller-retourDocumentYAML préservant les commentaires, de sorte que les autres paramètres de l’opérateur survivent, et l’installation définithooks_auto_accept: truepour que la passerelle sans tête (sans TTY) exécute les hooks sans invite de consentement. L’évaluateur émet le contrat stdout{"decision":"block","reason"}de Hermes (Hermes ignore les codes de sortie). Limitations : Hermes n’a pas d’événementStopde fin de tour, donc les politiques intégréesrequire-*-before-stopne se déclenchent jamais pour lui (non applicable, pas cassé) ;instructse dégrade en allow-avec-note-journalisée (pas de canal de contexte supplémentaire) ; et la redaction des secrets en sortie (sanitize-*) ne peut pas réécrire la sortie d’outil via le contrat de hook shell. Hermes est également une source d’audit hors ligne — le tableau de bord lit ses sessions de passerelle directement depuis~/.hermes/state.db.
- Claude Code :
policies-config.json— indique à failproofai quelles politiques évaluer et avec quels paramètres (partagé entre toutes les CLI agent)
--cli claude|codex|copilot|cursor|opencode|pi|hermes pour cibler un agent spécifique (séparé par des espaces ou répété pour tout sous-ensemble) :
--cli est omis, failproofai détecte quelles CLI agent sont installées (which claude / which codex / which copilot / which cursor-agent / which opencode / which pi / which hermes) :
- Une CLI détectée — sélectionne automatiquement cette CLI sans demander de confirmation.
- Plusieurs CLI détectées dans un terminal interactif — affiche une invite de sélection unique par touches fléchées regroupée en une section
Detected (N)(avec une ligne agrégéeInstall for all N detected+ chaque CLI détectée individuellement) et une sectionNot installed (M) · install hooks ahead of timelistant chaque CLI prise en charge non détectée comme option d’installation anticipée (↑↓ pour déplacer, Entrée pour sélectionner, ^C pour quitter). Le flux de désinstallation n’affiche que la section Detected. - Plusieurs CLI détectées lors d’une exécution non interactive (CI, sans TTY) — installe pour toutes les CLI détectées sans demander de confirmation.
- Aucune détectée — revient à
claude, avec un avertissement qu’aucun binaire agent n’a été trouvé dans PATH ; la commande de hook est tout de même écrite afin qu’elle s’active dès que vous en installez un.
policies-config.json directement à tout moment ; les modifications prennent effet immédiatement au prochain événement de hook, sans redémarrage nécessaire.
Exemple : configuration au niveau projet avec les valeurs par défaut de l’équipe
Committez.failproofai/policies-config.json dans votre dépôt :
.failproofai/policies-config.local.json (ignoré par git) pour des substitutions personnelles sans affecter ses coéquipiers.
