> ## 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.

# 配置

> 配置文件格式、三层作用域系统及合并规则

failproofai 使用 JSON 配置文件来控制哪些策略处于激活状态、它们的行为方式以及从何处加载自定义策略。配置设计上便于与团队共享——将其提交到代码仓库，每位开发者都能获得相同的 Agent 安全防护。

***

## 配置作用域

共有三个配置作用域，按优先级顺序依次评估：

| 作用域         | 文件路径                                      | 用途                       |
| ----------- | ----------------------------------------- | ------------------------ |
| **project** | `.failproofai/policies-config.json`       | 每个仓库的配置，提交到版本控制          |
| **local**   | `.failproofai/policies-config.local.json` | 个人的仓库级覆盖配置，已加入 gitignore |
| **global**  | `~/.failproofai/policies-config.json`     | 适用于所有项目的用户级默认配置          |

当 failproofai 收到 hook 事件时，它会加载并合并当前工作目录下所有存在的三个文件。

### 合并规则

**`enabledPolicies`** — 取三个作用域的并集。任意级别启用的策略均处于激活状态。

```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"]  ← 去重后的并集
```

**`policyParams`** — 最先为某个策略定义参数的作用域完全优先。策略参数内部的值不会进行深度合并。

```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 优先，global 被忽略
```

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

resolved: { allowPatterns: ["sudo systemctl status"] }  ← 向下回退至 global
```

**`customPoliciesPath`** — 最先定义的作用域优先。

**`llm`** — 最先定义的作用域优先。

***

## 配置文件格式

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

***

## 字段参考

### `enabledPolicies`

类型：`string[]`

要启用的策略名称列表。名称必须与 `failproofai policies` 显示的策略标识符完全匹配。完整列表请参阅[内置策略](/zh/built-in-policies)。

不在 `enabledPolicies` 中的策略处于非激活状态，即使它们在 `policyParams` 中有条目也是如此。

### `policyParams`

类型：`Record<string, Record<string, unknown>>`

各策略的参数覆盖配置。外层键为策略名称，内层键为各策略专属的参数。每个策略的可用参数详见[内置策略](/zh/built-in-policies)。

如果某个策略有参数但你未指定，则使用该策略的内置默认值。未配置 `policyParams` 的用户与之前版本的行为完全一致。

策略参数块中未知的键在 hook 触发时会被静默忽略，但在运行 `failproofai policies` 时会以警告形式标出。

#### `hint`（通用参数）

类型：`string`（可选）

当策略返回 deny 或 instruct 时，附加到原因说明中的消息。使用它可以在不修改策略本身的情况下，为 Claude 提供可操作的指导。

适用于任何类型的策略——内置策略、自定义策略（`custom/`）、项目约定策略（`.failproofai-project/`）或用户约定策略（`.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."
    }
  }
}
```

当 block-force-push 拒绝操作时，Claude 会看到：*"Force-pushing is blocked. Try creating a fresh branch instead."*

非字符串值和空字符串会被静默忽略。如果未设置 `hint`，行为保持不变（向后兼容）。

### `customPoliciesPath`

类型：`string`（绝对路径）

包含自定义 hook 策略的 JavaScript 文件路径。此路径由 `failproofai policies --install --custom <path>` 自动设置（路径在存储前会被解析为绝对路径）。

每次 hook 事件触发时都会重新加载该文件，不使用缓存。自定义策略的编写详情请参阅[自定义策略](/zh/custom-policies)。

### 基于约定的策略

除了显式指定的 `customPoliciesPath` 外，failproofai 还会自动从 `.failproofai/policies/` 目录中发现并加载策略文件：

| 级别  | 目录                         | 作用域          |
| --- | -------------------------- | ------------ |
| 项目级 | `.failproofai/policies/`   | 通过版本控制与团队共享  |
| 用户级 | `~/.failproofai/policies/` | 个人使用，适用于所有项目 |

**文件匹配规则：** 仅加载匹配 `*policies.{js,mjs,ts}` 的文件（例如 `security-policies.mjs`、`workflow-policies.js`），目录中的其他文件会被忽略。

**无需配置：** 约定策略不需要在 `policies-config.json` 中添加任何条目。只需将文件放入对应目录，下次 hook 事件触发时即会自动加载。

**联合加载：** 项目级和用户级约定目录都会被扫描。两个级别的所有匹配文件都会被加载（与 `customPoliciesPath` 遵循先定义者优先的规则不同）。

更多详情和示例请参阅[自定义策略](/zh/custom-policies)。

### `llm`

类型：`object`（可选）

供需要进行 AI 调用的策略使用的 LLM 客户端配置。大多数场景下无需配置。

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

***

## 通过 CLI 管理配置

`policies --install` 和 `policies --uninstall` 命令会写入 Agent CLI 的 hook 设置文件（hook 入口点），而 `policies-config.json` 是你直接管理的文件。两者是相互独立的：

* **Agent CLI 设置** — 指示 Agent 在每次工具调用时执行 `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` 记录的 schema（公开文档中未予说明）。
  * **Cursor Agent *(beta)***：`~/.cursor/hooks.json`（用户级）、`<cwd>/.cursor/hooks.json`（项目级）—— Cursor 没有 `local` 作用域。Hook 条目使用 Claude 格式的 `{type, command, timeout}`（无 `bash`/`powershell` 分割），但按照 Cursor 的 [hooks schema](https://cursor.com/docs/hooks) 以驼峰式事件键（`preToolUse`、`beforeSubmitPrompt` 等）存储在平铺数组中；文件顶层包含 `version: 1` 标记。处理程序通过 `CURSOR_EVENT_MAP` 将驼峰式名称规范化为 PascalCase，因此现有内置策略无需改动即可正常触发。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 在转发给二进制文件之前，会将工具名称（小写 → PascalCase，通过 `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 工具调用时无需修改即可正常触发。会话保存在 OpenCode 的 SQLite 数据库 `~/.local/share/opencode/opencode.db` 中；仪表盘的会话查看器通过 `opencode db --format json` 和 `opencode export <id>` 读取这些数据。OpenCode 支持目前处于 **beta** 阶段，我们正在对照更多真实场景跨版本验证其行为。详见 [OpenCode 插件文档](https://opencode.ai/docs/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` 将下划线小写命名规范化为 PascalCase，因此现有内置策略无需改动即可正常触发。工具输入参数也通过 `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 和会话日志格式趋于稳定。
  * **Gemini CLI *(beta)***：`~/.gemini/settings.json`（用户级）、`<cwd>/.gemini/settings.json`（项目级）—— Gemini 没有 `local` 作用域（其文档中有位于 `/etc/gemini-cli/settings.json` 的 `system` 作用域，failproofai 不对外暴露该作用域）。Hook 条目使用 Claude 的 `{type, command, timeout}` 格式，包裹在 Gemini 的 `{matcher, hooks: [...]}` matcher schema 中，默认 `matcher: "*"`。事件名称为 PascalCase（`SessionStart`、`BeforeAgent`、`AfterAgent`、`BeforeModel`、`AfterModel`、`BeforeToolSelection`、`BeforeTool`、`AfterTool`、`PreCompress`、`Notification`、`SessionEnd`）；处理程序通过 `GEMINI_EVENT_MAP` 映射到 Claude 规范名称。工具名称为 snake\_case（`run_shell_command`、`read_file`、`write_file`、`replace` 等）——处理程序通过 `GEMINI_TOOL_MAP` 规范化，使现有内置策略无需改动即可正常触发。策略评估器输出 Gemini 的平铺 `{decision: "deny", reason}` 格式（符合 Gemini 的"黄金规则"退出码 0 约定），在 BeforeAgent / AfterTool / SessionStart 时输出 `{hookSpecificOutput: {hookEventName, additionalContext}}` 进行上下文注入，在 AfterAgent 时输出 `{decision: "block", reason}` 以实现强制重试语义。Gemini CLI 支持目前处于 **beta** 阶段，我们正在扩大真实场景的覆盖范围。详见 [Gemini CLI hooks 文档](https://geminicli.com/docs/hooks/)。
* **`policies-config.json`** — 告知 failproofai 要评估哪些策略及其参数（在所有 Agent CLI 之间共享）

通过 `--cli claude|codex|copilot|cursor|opencode|pi|gemini` 指定目标 Agent（空格分隔或重复指定，可选任意组合）：

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

省略 `--cli` 时，`failproofai` 会自动检测已安装的 Agent CLI（`which claude` / `which codex` / `which copilot` / `which cursor-agent` / `which opencode` / `which pi` / `which gemini`）：

* **检测到一个 CLI** — 自动选择该 CLI，无需提示。
* **检测到多个 CLI**（交互式终端）— 显示方向键单选提示，分组展示：`已检测 (N)` 部分（包含一个"为所有 N 个已检测 CLI 安装"的聚合选项，以及各已检测 CLI 的单独选项）和`未安装 (M) · 提前安装 hooks` 部分（列出每个未检测到的受支持 CLI 作为预安装选项；↑↓ 移动，Enter 选择，^C 退出）。卸载流程只显示已检测部分。
* **检测到多个 CLI**（非交互式运行，如 CI 或无 TTY）— 为所有已检测 CLI 安装，无需提示。
* **未检测到任何 CLI** — 回退至 `claude`，并警告 PATH 中未找到 Agent 二进制文件；hook 命令仍会写入，待安装后即可激活。

你可以随时直接编辑 `policies-config.json`，更改在下次 hook 事件触发时立即生效，无需重启。

***

## 示例：包含团队默认配置的项目级配置

将 `.failproofai/policies-config.json` 提交到代码仓库：

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

每位开发者可以在本地创建 `.failproofai/policies-config.local.json`（已加入 gitignore），用于个人覆盖配置，而不会影响其他团队成员。
