概览
策略按类别分组:| 类别 | 策略 | 钩子类型 |
|---|---|---|
| 危险命令 | block-sudo, block-rm-rf, block-curl-pipe-sh, block-failproofai-commands | PreToolUse |
| 基础设施命令 | block-kubectl, block-terraform, block-aws-cli, block-gcloud, block-az-cli, block-helm, block-gh-pipeline | PreToolUse |
| 密钥(清理器) | sanitize-jwt, sanitize-api-keys, sanitize-connection-strings, sanitize-private-key-content, sanitize-bearer-tokens | PostToolUse |
| 环境 | block-env-files, protect-env-vars | PreToolUse |
| 文件访问 | block-read-outside-cwd, block-secrets-write | PreToolUse |
| Git | block-push-master, block-work-on-main, block-force-push, warn-git-amend, warn-git-stash-drop, warn-all-files-staged | PreToolUse |
| 数据库 | warn-destructive-sql, warn-schema-alteration | PreToolUse |
| 警告 | warn-large-file-write, warn-package-publish, warn-background-process, warn-global-package-install | PreToolUse |
| 包管理器 | prefer-package-manager | PreToolUse |
| 工作流 | require-commit-before-stop, require-push-before-stop, require-pr-before-stop, require-no-conflicts-before-stop, require-ci-green-before-stop | Stop |
block-— 阻止代理继续执行。warn-— 向代理提供额外上下文,使其能够自我纠正。sanitize-— 在代理看到工具输出之前清除其中的敏感数据。
命名空间
每条策略都位于<namespace>/<name> 插槽中。内置策略属于 failproofai/ 命名空间——例如 failproofai/sanitize-jwt。当你同时加载具有相似短名称的自定义或第三方策略时,命名空间可防止命名冲突。
在配置中,你可以通过短名称或完整限定名称来引用内置策略;两种形式解析到同一条策略:
/,failproofai 会将其视为属于默认命名空间 failproofai。已包含 / 的名称(如 myorg/foo、custom/my-hook)将保持原样。
require-— 阻止 Stop 事件,直到满足条件为止。
危险命令
防止代理运行难以撤销或可能损害宿主系统的操作。block-sudo
事件: PreToolUse (Bash)默认行为: 拒绝任何包含
sudo 的命令。
阻止包含 sudo 关键字的调用。模式匹配基于解析后的命令令牌,而非原始字符串,以防止通过 Shell 运算符注入绕过。
参数:
| 参数 | 类型 | 默认值 | 描述 |
|---|---|---|---|
allowPatterns | string[] | [] | 允许的精确命令前缀。每个条目与解析后的 argv 令牌进行匹配。 |
sudo systemctl status nginx 会被允许,但 sudo rm /etc/hosts 会被拒绝。
模式匹配基于解析后的令牌,而非原始命令字符串。这可防止通过附加 Shell 运算符进行绕过(例如,
sudo systemctl status x; rm -rf / 不会匹配 sudo systemctl status *)。block-rm-rf
事件: PreToolUse (Bash)默认行为: 拒绝
rm -rf、rm -fr 及类似的递归删除形式。
参数:
| 参数 | 类型 | 默认值 | 描述 |
|---|---|---|---|
allowPaths | string[] | [] | 允许递归删除的安全路径(例如 /tmp)。 |
block-curl-pipe-sh
事件: PreToolUse (Bash)默认行为: 拒绝
curl <url> | bash、curl <url> | sh、wget <url> | bash 及类似模式。
无参数。
block-failproofai-commands
事件: PreToolUse (Bash)默认行为: 拒绝会卸载或禁用 failproofai 本身的命令(例如
npm uninstall failproofai、failproofai policies --uninstall)。
无参数。
基础设施命令
防止编码代理运行基础设施 CLI 或触发 CI/CD 流水线。此类别中的所有策略均为按需启用(defaultEnabled: false)——合法需要调用 kubectl、terraform 等工具的代理不会受到干扰,除非你主动启用该策略。启用后,匹配 CLI 的每次调用都会被拒绝,除非命令与 allowPatterns 中的某个条目匹配。
模式语法与 block-sudo 相同:令牌与解析后的 argv 进行匹配,* 是单个令牌的通配符,任何包含独立 Shell 运算符(&&、||、|、;)或嵌入 Shell 元字符令牌的命令,在白名单匹配之前都会被拒绝,以防止注入绕过。
block-kubectl
事件: PreToolUse (Bash)默认行为: 拒绝任何
kubectl 调用。
参数:
| 参数 | 类型 | 默认值 | 描述 |
|---|---|---|---|
allowPatterns | string[] | [] | 允许的 kubectl 命令前缀。 |
kubectl get pods 会被允许,但 kubectl apply -f deploy.yaml 会被拒绝。
block-terraform
事件: PreToolUse (Bash)默认行为: 拒绝任何
terraform 或 tofu(OpenTofu)调用。
参数:
| 参数 | 类型 | 默认值 | 描述 |
|---|---|---|---|
allowPatterns | string[] | [] | 允许的 terraform/tofu 命令前缀。 |
block-aws-cli
事件: PreToolUse (Bash)默认行为: 拒绝任何
aws CLI 调用。
参数:
| 参数 | 类型 | 默认值 | 描述 |
|---|---|---|---|
allowPatterns | string[] | [] | 允许的 aws CLI 命令前缀。 |
block-gcloud
事件: PreToolUse (Bash)默认行为: 拒绝任何
gcloud(Google Cloud)CLI 调用。
参数:
| 参数 | 类型 | 默认值 | 描述 |
|---|---|---|---|
allowPatterns | string[] | [] | 允许的 gcloud 命令前缀。 |
block-az-cli
事件: PreToolUse (Bash)默认行为: 拒绝任何
az(Azure)CLI 调用。
参数:
| 参数 | 类型 | 默认值 | 描述 |
|---|---|---|---|
allowPatterns | string[] | [] | 允许的 az CLI 命令前缀。 |
block-helm
事件: PreToolUse (Bash)默认行为: 拒绝任何
helm 调用。
参数:
| 参数 | 类型 | 默认值 | 描述 |
|---|---|---|---|
allowPatterns | string[] | [] | 允许的 helm 命令前缀。 |
block-gh-pipeline
事件: PreToolUse (Bash)默认行为: 拒绝以下会修改状态或触发流水线的
gh CLI 子命令:
gh workflow run、gh workflow enable、gh workflow disablegh run rerun、gh run cancelgh pr mergegh release create、gh release deletegh cache deletegh secret set、gh secret delete
gh 子命令(如 gh pr view、gh pr list、gh run list、gh release view 和 gh api repos/.../...)不在此策略的匹配范围内——这些命令通常用于工作流检查(包括 failproofai 自身的 require-ci-green-before-stop)。
参数:
| 参数 | 类型 | 默认值 | 描述 |
|---|---|---|---|
allowPatterns | string[] | [] | 即使会被拒绝,也允许的特定脚本调用。 |
密钥(清理器)
防止代理将凭据泄露到其上下文或输出中。清理器策略在 PostToolUse 事件上触发。当 Claude 运行 Bash 命令、读取文件或调用任何工具时,这些策略会在输出返回给 Claude 之前对其进行检查。如果检测到密钥模式,策略会返回拒绝决策,阻止输出被传回。sanitize-jwt
事件: PostToolUse(所有工具)默认行为: 脱敏 JWT 令牌(由
. 分隔的三段 base64url 内容)。
无参数。
sanitize-api-keys
事件: PostToolUse(所有工具)默认行为: 脱敏常见的 API 密钥格式:Anthropic(
sk-ant-)、OpenAI(sk-)、GitHub PAT(ghp_)、AWS 访问密钥(AKIA)、Stripe 密钥(sk_live_、sk_test_)以及 Google API 密钥(AIza)。
参数:
| 参数 | 类型 | 默认值 | 描述 |
|---|---|---|---|
additionalPatterns | { regex: string; label: string }[] | [] | 额外需要视为密钥的正则表达式模式。 |
sanitize-connection-strings
事件: PostToolUse(所有工具)默认行为: 脱敏包含嵌入凭据的数据库连接字符串(例如
postgresql://user:password@host/db)。
无参数。
sanitize-private-key-content
事件: PostToolUse(所有工具)默认行为: 脱敏 PEM 块(
-----BEGIN PRIVATE KEY-----、-----BEGIN RSA PRIVATE KEY----- 等)。
无参数。
sanitize-bearer-tokens
事件: PostToolUse(所有工具)默认行为: 脱敏
Authorization: Bearer <token> 请求头中令牌长度达到 20 个字符或以上的内容。
无参数。
环境
防止代理读取或暴露敏感的环境配置。block-env-files
事件: PreToolUse (Bash, Read)默认行为: 拒绝通过
cat .env、以 .env 为文件路径的 Read 工具调用等方式读取 .env 文件。
不会阻止 .envrc 或其他与环境相关的文件——仅阻止名称恰好为 .env 的文件。
无参数。
protect-env-vars
事件: PreToolUse (Bash)默认行为: 拒绝打印环境变量的命令:
printenv、env、echo $VAR。
无参数。
文件访问
将代理限制在项目边界内,并使其远离敏感文件。block-read-outside-cwd
事件: PreToolUse (Read, Bash)默认行为: 拒绝读取项目根目录之外的文件。边界由
CLAUDE_PROJECT_DIR(由 Claude Code 在每次会话开始时设置)确定,当该变量未设置时,回退到会话的当前工作目录。使用项目根目录而非实时的 cwd,意味着即使 Claude cd 进入子目录后,边界仍然保持稳定。
参数:
| 参数 | 类型 | 默认值 | 描述 |
|---|---|---|---|
allowPaths | string[] | [] | 即使位于项目根目录之外,也允许访问的绝对路径前缀。 |
block-secrets-write
事件: PreToolUse (Write, Edit)默认行为: 拒绝写入常用于私钥和证书的文件:
id_rsa、id_ed25519、*.key、*.pem、*.p12、*.pfx。
参数:
| 参数 | 类型 | 默认值 | 描述 |
|---|---|---|---|
additionalPatterns | string[] | [] | 额外需要阻止的文件名模式(glob 风格)。 |
Git
防止意外推送、强制推送以及难以撤销的分支操作失误。block-push-master
事件: PreToolUse (Bash)默认行为: 拒绝
git push origin main 和 git push origin master。
参数:
| 参数 | 类型 | 默认值 | 描述 |
|---|---|---|---|
protectedBranches | string[] | ["main", "master"] | 不能直接推送的分支名称。 |
block-work-on-main
事件: PreToolUse (Bash)默认行为: 当工作树处于
main 或 master 分支时,拒绝 git commit、git merge、git rebase 和 git cherry-pick。分支创建和切换(git checkout、git checkout -b、git switch、git switch -c)不受影响。
参数:
| 参数 | 类型 | 默认值 | 描述 |
|---|---|---|---|
protectedBranches | string[] | ["main", "master"] | 禁止执行 commit/merge/rebase/cherry-pick 的分支名称。 |
block-force-push
事件: PreToolUse (Bash)默认行为: 拒绝
git push --force 和 git push -f。
无特定策略参数。使用通用 hint 建议替代方案:
warn-git-amend
事件: PreToolUse (Bash)默认行为: 在运行
git commit --amend 时指示 Claude 谨慎操作。不会阻止该命令。
无参数。
warn-git-stash-drop
事件: PreToolUse (Bash)默认行为: 在运行
git stash drop 前指示 Claude 进行确认。不会阻止该命令。
无参数。
warn-all-files-staged
事件: PreToolUse (Bash)默认行为: 在运行
git add -A 或 git add . 时指示 Claude 检查所暂存的内容。不会阻止该命令。
无参数。
数据库
在破坏性 SQL 操作对数据库执行前将其拦截。warn-destructive-sql
事件: PreToolUse (Bash)默认行为: 在运行包含
DROP TABLE、DROP DATABASE 或不带 WHERE 子句的 DELETE 的 SQL 前,指示 Claude 进行确认。
无参数。
warn-schema-alteration
事件: PreToolUse (Bash)默认行为: 在运行
ALTER TABLE 语句前,指示 Claude 进行确认。
无参数。
警告
在执行可能存在风险但非破坏性的操作前,为代理提供额外上下文。warn-large-file-write
事件: PreToolUse (Write)默认行为: 在写入大于 1024 KB 的文件前,指示 Claude 进行确认。 参数:
| 参数 | 类型 | 默认值 | 描述 |
|---|---|---|---|
thresholdKb | number | 1024 | 触发警告的文件大小阈值(以千字节为单位)。 |
钩子处理程序对 stdin 载荷强制执行 1 MB 的限制。若要使用较小内容测试此策略,请将
thresholdKb 设置为远低于 1024 的值。warn-package-publish
事件: PreToolUse (Bash)默认行为: 在运行
npm publish 前,指示 Claude 进行确认。
无参数。
warn-background-process
事件: PreToolUse (Bash)默认行为: 在通过
nohup、&、disown 或 screen 启动后台进程时,指示 Claude 保持谨慎。
无参数。
warn-global-package-install
事件: PreToolUse (Bash)默认行为: 在运行
npm install -g、yarn global add 或在没有虚拟环境的情况下运行 pip install 前,指示 Claude 进行确认。
无参数。
包管理器
强制代理只能使用被允许的包管理器。prefer-package-manager
事件: PreToolUse (Bash)默认行为: 禁用。启用后,阻止任何不在
allowed 列表中的包管理器命令,并告知 Claude 使用允许的管理器重写该命令。
可检测:pip、pip3、python -m pip、npm、npx、yarn、pnpm、pnpx、bun、bunx、uv、poetry、pipenv、conda、cargo。
| 参数 | 类型 | 默认值 | 描述 |
|---|---|---|---|
allowed | string[] | [] | 允许的包管理器名称。任何未在此列表中的已检测管理器都会被阻止。为空时,该策略不执行任何操作。 |
blocked | string[] | [] | 除内置列表之外额外需要阻止的管理器名称(例如 ['pdm', 'pipx'])。 |
blocked 追加不在此列表中的管理器。
示例配置:
pip install flask 和 pdm install flask 都会被拒绝,并提示 Claude 改用 uv 或 bun。而 uv pip install flask 则会被允许,因为 uv 在白名单中且会被优先检查。
AI 行为
检测代理陷入循环或行为异常的情况。warn-repeated-tool-calls
事件: PreToolUse(所有工具)默认行为: 当同一工具以相同参数被调用 3 次或以上时,指示 Claude 重新考虑——这通常是代理陷入循环的标志。 无参数。
工作流
强制执行规范的会话结束工作流。这些策略在 Stop 事件上触发,并阻止代理停止,直到每个条件都满足为止。它们遵循自然的依赖链:提交 → 推送 → PR → CI。如果某条策略拒绝,链中后续的策略将被跳过(拒绝会短路)。 所有工作流策略均为开放失败模式:如果所需工具不可用(例如未安装gh,或没有 git 远程仓库),策略会允许通过,并附上说明跳过检查原因的信息提示。
各 CLI 的 Stop 语义
由于七种支持的 CLI 各自暴露不同的”代理完成”钩子契约,Stop 强制执行的方式略有不同。结果是相同的——代理无法在工作流关卡未通过的情况下停止——但机制有所不同。下表作出了说明;在启用require-*-before-stop 策略之前,只有 Pi 存在一个值得了解的用户可见差异。
| CLI | 关卡触发时机 | 你看到的现象 |
|---|---|---|
| Claude Code | 同一代理循环,立即触发 | Claude 继续工作——修复问题后再次尝试完成。对你不可见。 |
| Codex | 同一代理循环,立即触发 | 与 Claude 相同。 |
| GitHub Copilot CLI | 同一代理循环,立即触发 | 与 Claude 相同(使用 Copilot 的 {decision:"block", reason} 重试通道——经 Copilot CLI 1.0.41 实测验证)。 |
| Cursor Agent | 同一代理循环,立即触发 | 与 Claude 相同(使用 Cursor 的 {followup_message} 通道——上限为 loop_limit,默认 5 次重试)。 |
| Gemini CLI | 同一代理循环,立即触发 | 与 Claude 相同(在 AfterAgent 上使用 Gemini 的 {decision:"block", reason} 通道)。 |
| OpenCode | 同一代理循环,立即触发 | 与 Claude 相同(使用 OpenCode 的 client.session.prompt(...) SDK 调用,通过 hookSpecificOutput.additionalContext 路由)。 |
| Pi (pi-coding-agent) | 下一个用户轮次 | Pi 会明显停止——当关卡触发时,其代理循环退出并返回到提示符。该关卡将在你下次提交提示时触发:failproofai 会在该轮次的系统提示前添加一条 MANDATORY ACTION REQUIRED 指令,要求 LLM 在执行你的请求之前完成工作流步骤(提交、推送等)。 |
Pi 的限制。 Pi 的
AgentEndEvent(相当于 Claude 的 Stop 钩子的上游等价物)没有 Result 类型——当其触发时,Pi 的代理循环已经退出。Pi 无法像 Claude / Copilot / Cursor / Gemini / OpenCode 那样被强制重试同一循环。failproofai 将关卡转移到 Pi 的 before_agent_start 事件(在下一个用户提示后触发),从而确保工作流检查仍然有效,只是在下一轮而非当前轮次执行。实际影响:- Pi 停止后,拒绝原因会以 Pi session id 为键存储在内存中。在同一 Pi 进程中,你提交的下一个提示会消耗它:LLM 会在系统提示顶部看到
MANDATORY ACTION REQUIRED指令,先提交(或推送/创建 PR/等待 CI),然后再继续处理你的请求。该拒绝原因是一次性的——消耗后关卡即清除。 - 关卡的生命周期与 Pi 进程绑定。如果你在两次轮次之间
Ctrl+C终止 Pi 或退出,内存中的条目会随进程一同销毁,关卡会被跳过。Claude、Copilot、Cursor、Gemini 和 OpenCode 也有同样的限制(终止代理则跳过关卡)——Pi 只是让这一点更加明显,因为代理在关卡触发前就已经可见地退出了。 - 待处理的拒绝也会在任何原因的
session_shutdown时清除(new/resume/fork/quit),因此先前会话的陈旧关卡不会泄漏到同一 Pi 进程中启动的新会话。
Stop 策略。我们正在跟踪 Pi 上游,等待 AgentEndEvent 未来支持 Result 类型,届时我们将能弥合这一差距。require-commit-before-stop
事件: Stop默认行为: 当存在未提交的更改(已修改、已暂存或未跟踪的文件)时,拒绝停止。工作目录干净时返回提示信息。 无参数。
require-push-before-stop
事件: Stop默认行为: 当存在未推送的提交,或当前分支没有远程跟踪分支时,拒绝停止。必要时建议使用
git push -u 创建跟踪分支。如果未配置远程仓库,则开放失败。
参数:
| 参数 | 类型 | 默认值 | 描述 |
|---|---|---|---|
remote | string | "origin" | 推送目标的远程名称。 |
require-pr-before-stop
事件: Stop默认行为: 当当前分支不存在拉取请求,或现有 PR 已关闭且未合并时,拒绝停止。指示 Claude 使用
gh pr create 创建 PR。当 PR 已合并时,策略允许通过(工作已发布),并提示切换回分支(git checkout main && git pull)。
无参数。
此策略需要安装并通过身份验证的 GitHub CLI(
gh)。
运行 gh auth login,使用具有 repo 权限(用于读取拉取请求)的个人访问令牌。如果未安装 gh 或未通过身份验证,策略会开放失败,并将原因报告给 Claude。require-no-conflicts-before-stop
事件: Stop默认行为: 当当前分支无法干净地合并到基础分支时,拒绝停止。该策略首先确认 GitHub 上是否存在该分支的
OPEN PR——如果没有,则没有可强制执行的合并目标,整个策略短路为允许。确认存在 OPEN PR 后,会运行两个独立探测:
- 本地 —
git merge-tree --write-tree --name-only origin/<baseBranch> HEAD。发生冲突时,拒绝消息会列出冲突文件,让 Claude 明确知道需要解决哪些问题。 - GitHub — 复用预检时已获取的
gh pr view --json mergeable,state结果。可捕获本地陈旧的origin/<baseBranch>会遗漏的冲突(例如,自上次 fetch 以来,有人将一个冲突的 PR 合并到了main)。CONFLICTING结果会触发拒绝。UNKNOWN结果也会触发拒绝,并指示 Claude 等待约 10 秒后重新检查再尝试停止——这可防止 GitHub 重新计算期间出现假阴性。
gh、该分支不存在 PR、PR 状态不为 OPEN(如 MERGED、CLOSED),或 gh pr view 返回无法解析的输出。当本地缺少 origin/<baseBranch> 或没有超前于基础的提交时也会开放失败——这些第一层回退仍会在允许前参考缓存的 PR 可合并性。
参数:
| 参数 | 类型 | 默认值 | 描述 |
|---|---|---|---|
baseBranch | string | "main" | 用于检查冲突的基础分支。 |
此策略需要 GitHub CLI(
gh)。策略会使用 gh pr view 确认存在 OPEN PR,然后再运行任何冲突探测——没有 gh 则策略短路为允许。运行 gh auth login,使用具有 repo 权限(用于读取拉取请求)的个人访问令牌。require-ci-green-before-stop
事件: Stop默认行为: 当当前分支的 CI 检查失败或仍在运行时,拒绝停止。同时检查 GitHub Actions 工作流运行和第三方机器人检查(如 CodeRabbit、SonarCloud、Codecov)。将
skipped、cancelled 和 neutral 结论视为非失败(后者涵盖了例如外部贡献者 PR 上的 Socket Security 告警,此时应用程序有意报告 neutral 而非 success/failure)。所有检查通过时返回提示信息。
无参数。
此策略需要安装并通过身份验证的 GitHub CLI(
gh)。
运行 gh auth login,使用具有 repo 权限(用于读取 Actions 工作流运行和 Checks API)的个人访问令牌。如果未安装 gh 或未通过身份验证,策略会开放失败,并将原因报告给 Claude。禁用单条策略
从配置的enabledPolicies 中移除特定策略,或在控制台的策略选项卡中将其关闭。
enabledPolicies 中的策略不会运行,即使存在对应的 policyParams 条目也是如此。
