配置作用域
共有三个配置作用域,按优先级顺序评估:
当 failproofai 收到 hook 事件时,会加载并合并当前工作目录下所有已存在的三个文件。
合并规则
enabledPolicies — 取三个作用域的并集。任意级别启用的策略都会生效。
policyParams — 对某个策略最先定义其参数的作用域完全胜出,不会对策略参数内的值进行深度合并。
customPoliciesPath — 最先定义该字段的作用域胜出。
llm — 最先定义该字段的作用域胜出。
配置文件格式
字段参考
enabledPolicies
类型:string[]
需要启用的策略名称列表。名称必须与 failproofai policies 显示的策略标识符完全匹配。完整列表请参见内置策略。
不在 enabledPolicies 中的策略将处于非活跃状态,即便在 policyParams 中为其配置了条目也不例外。
policyParams
类型:Record<string, Record<string, unknown>>
各策略的参数覆盖配置。外层键为策略名称,内层键为各策略专属的配置项。每个策略的可用参数请参见内置策略。
如果策略有参数但未指定,则使用策略的内置默认值。未配置 policyParams 的用户其行为与之前版本完全一致。
策略参数块中未知的键在 hook 触发时会被静默忽略,但在运行 failproofai policies 时会作为警告标记出来。
hint(通用配置项)
类型:string(可选)
当策略返回 deny 或 instruct 时,附加到原因后面的消息。可用于在不修改策略本身的情况下,向 Claude 提供可操作的指引。
适用于任何类型的策略——内置策略、自定义策略(custom/)、项目约定策略(.failproofai-project/)或用户约定策略(.failproofai-user/)。
hint,行为保持不变(向后兼容)。
customPoliciesPath
类型:string(绝对路径)
包含自定义 hook 策略的 JavaScript 文件路径。该值由 failproofai policies --install --custom <path> 自动设置(路径在存储前会被解析为绝对路径)。
每次 hook 事件触发时都会重新加载该文件,不进行缓存。有关编写自定义策略的详情,请参见自定义策略。
基于约定的策略
除了显式的customPoliciesPath 外,failproofai 还会自动发现并加载 .failproofai/policies/ 目录中的策略文件:
文件匹配: 仅加载匹配
*policies.{js,mjs,ts} 的文件(例如 security-policies.mjs、workflow-policies.js),目录中的其他文件会被忽略。
无需配置: 约定策略无需在 policies-config.json 中添加任何条目,只需将文件放入对应目录,下次 hook 事件触发时即可自动生效。
联合加载: 项目和用户约定目录都会被扫描,两个级别中所有匹配的文件都会被加载(与 customPoliciesPath 采用首个作用域胜出的方式不同)。
更多详情和示例请参见自定义策略。
llm
类型:object(可选)
供策略进行 AI 调用的 LLM 客户端配置,大多数场景下无需配置。
通过 CLI 管理配置
policies --install 和 policies --uninstall 命令会写入代理 CLI 的 hook 设置文件(hook 入口点),而 policies-config.json 是由你直接管理的文件,两者相互独立:
- 代理 CLI 设置 — 告知代理在每次工具调用时执行
failproofai --hook <event>:- Claude Code:
~/.claude/settings.json(用户级)、<cwd>/.claude/settings.json(项目级)、<cwd>/.claude/settings.local.json(本地级) - OpenAI Codex:
~/.codex/hooks.json(用户级)、<cwd>/.codex/hooks.json(项目级)——Codex 没有local作用域 - GitHub Copilot CLI (beta):
~/.copilot/hooks/failproofai.json(用户级)、<cwd>/.github/hooks/failproofai.json(项目级)——Copilot 没有local作用域。Hook 条目使用 Copilot 基于操作系统的bash/powershell命令字段,并带有timeoutSec;文件顶层包含version: 1标记。Copilot CLI 支持目前为 beta 版本,我们正在针对更多实际会话验证events.jsonl记录模式(公开文档中未作说明)。 - Cursor Agent (beta):
~/.cursor/hooks.json(用户级)、<cwd>/.cursor/hooks.json(项目级)——Cursor 没有local作用域。Hook 条目使用 Claude 风格的{type, command, timeout}格式(无bash/powershell拆分),但按照 Cursor 的 hooks schema 以驼峰式事件键(preToolUse、beforeSubmitPrompt等)存储在扁平数组中;文件顶层包含version: 1标记。处理器通过CURSOR_EVENT_MAP将驼峰式键规范化为帕斯卡式,使现有内置策略能够正常触发。Cursor Agent 支持目前为 beta 版本,我们正在针对更多实际安装验证 Cursor 的磁盘上转录格式(公开文档未作说明)。 - OpenCode (beta):
~/.config/opencode/opencode.json+~/.config/opencode/plugins/failproofai.mjs(用户级)、<cwd>/.opencode/opencode.json+<cwd>/.opencode/plugins/failproofai.mjs(项目级)——OpenCode 没有local作用域。与其他五种 CLI 不同,OpenCode 没有外部命令 hook 系统:它通过opencode.json的plugin: []数组显式注册来加载进程内 JS/TS 插件(自动发现.opencode/plugins/目录不是 opencode v1.14.33 插件的加载方式)。安装时会生成一个小型插件 shim,以子进程方式调用 failproofai 二进制文件,并将二进制文件的 Claude 风格 JSON 响应转换回插件语义:工具事件拒绝时throw new Error()(取消工具调用);instruct 以及Stop/SubagentStop拒绝时调用client.session.prompt(...)(将拒绝原因作为下一条用户消息提交——这是唯一的强制重试通道,因为session.idle仅用于通知,从中抛出异常无效);allow 时不执行任何操作。该 shim 在转发给二进制文件前会规范化工具名称(小写 → 帕斯卡式,通过OPENCODE_TOOL_MAP)和工具输入参数键(驼峰式 → 下划线式,通过OPENCODE_TOOL_INPUT_MAP适用于Read/Write/Edit,例如filePath→file_path、oldString→old_string),从而使block-read-outside-cwd、block-env-files和block-secrets-write等路径检查内置策略在 OpenCode 工具调用中正常触发。会话存储在~/.local/share/opencode/opencode.db的 SQLite 数据库中;仪表盘的会话查看器通过opencode db --format json和opencode export <id>读取它们。OpenCode 支持目前为 beta 版本,我们正在跨版本和更多实际会话中验证其行为。详见 OpenCode plugins 文档。 - Pi (beta):
~/.pi/agent/settings.json(用户级)、<cwd>/.pi/settings.json(项目级)——Pi 没有local作用域。Pi 在启动时加载 TypeScript 扩展包;设置文件是一个扁平字符串数组{"packages": ["./relative/path", …]}。failproofai 在 packages 数组中写入一个指向其捆绑的pi-extension/目录的条目。该扩展内部订阅 Pi 的tool_call/user_bash/input/session_start事件,并调用failproofai --hook <Event> --cli pi;处理器通过PI_EVENT_MAP将下划线小写蛇形命名规范化为帕斯卡式,使现有内置策略正常触发。工具输入参数也通过PI_TOOL_INPUT_MAP规范化(Pi 的 Read / Write / Edit 使用path而非file_path;映射顶层键后block-env-files和block-secrets-write可正常触发——block-read-outside-cwd本身已有path的回退逻辑)。Pi 支持目前为 beta 版本,有待 Pi 的扩展 API 和会话日志格式稳定。 - Hermes (hermes-agent):
~/.hermes/config.yaml(仅用户作用域——Hermes 没有项目/本地配置)。Hermes 是一个 Slack/Telegram 网关,因此一次安装即可拦截来自所有平台(Slack/Telegram/cli/cron)以及内部子代理的工具调用。Hook 条目是hooks:映射下的{command, timeout}对(timeout 单位为秒),以 Hermes 的蛇形命名事件为键(pre_tool_call/post_tool_call/on_session_start/on_session_end/subagent_stop);处理器通过HERMES_EVENT_MAP规范化事件,通过HERMES_TOOL_MAP规范化工具名称,使内置策略正常触发。配置通过保留注释的 YAMLDocument往返编辑,以确保操作者的其他设置不受影响;安装时将hooks_auto_accept: true设置为 true,以便无头网关(无 TTY)在无需确认提示的情况下运行 hook。评估器输出 Hermes 的{"decision":"block","reason"}stdout 约定(Hermes 忽略退出码)。限制: Hermes 没有会话结束Stop事件,因此require-*-before-stop内置策略永远不会为其触发(不适用,并非故障);instruct降级为允许并记录日志(无额外上下文通道);输出密钥清理(sanitize-*)无法通过 shell hook 约定重写工具输出。Hermes 同时也是一个离线审计数据源——仪表盘直接从~/.hermes/state.db读取其网关会话。
- Claude Code:
policies-config.json— 告知 failproofai 评估哪些策略及其参数(在所有代理 CLI 之间共享)
--cli claude|codex|copilot|cursor|opencode|pi|hermes 指定目标代理(可用空格分隔或重复指定多个):
--cli 时,failproofai 会自动检测已安装的代理 CLI(which claude / which codex / which copilot / which cursor-agent / which opencode / which pi / which hermes):
- 检测到一个 CLI — 自动选择该 CLI,无需提示。
- 在交互式终端中检测到多个 CLI — 显示方向键单选菜单,分为
Detected (N)区域(包含一个”为所有 N 个已检测到的 CLI 安装”的聚合行及各个已检测 CLI)和Not installed (M) · install hooks ahead of time区域(列出所有未检测到的受支持 CLI 作为提前安装选项)(↑↓ 移动,回车选择,^C 退出)。卸载流程仅显示 Detected 区域。 - 在非交互式运行中检测到多个 CLI(CI、无 TTY)— 无需提示,为所有检测到的 CLI 安装。
- 未检测到任何 CLI — 回退到
claude,并显示在 PATH 中未找到代理二进制文件的警告;hook 命令仍会被写入,一旦安装代理即可生效。
policies-config.json,修改将在下一次 hook 事件触发时立即生效,无需重启。
示例:带团队默认配置的项目级配置
将.failproofai/policies-config.json 提交到你的仓库:
.failproofai/policies-config.local.json(已加入 gitignore)进行个人覆盖配置,而不影响其他团队成员。
