跳转到主要内容
failproofai 内置了 39 条策略,用于捕获常见的代理失败模式。每条策略会在特定的钩子事件类型和工具名称上触发。十九条策略支持参数配置,让你无需编写代码即可调整其行为。五条工作流策略会在 Claude 停止之前强制执行提交 → 推送 → PR → CI 的流水线。

概览

策略按类别分组:
类别策略钩子类型
危险命令block-sudo, block-rm-rf, block-curl-pipe-sh, block-failproofai-commandsPreToolUse
基础设施命令block-kubectl, block-terraform, block-aws-cli, block-gcloud, block-az-cli, block-helm, block-gh-pipelinePreToolUse
密钥(清理器)sanitize-jwt, sanitize-api-keys, sanitize-connection-strings, sanitize-private-key-content, sanitize-bearer-tokensPostToolUse
环境block-env-files, protect-env-varsPreToolUse
文件访问block-read-outside-cwd, block-secrets-writePreToolUse
Gitblock-push-master, block-work-on-main, block-force-push, warn-git-amend, warn-git-stash-drop, warn-all-files-stagedPreToolUse
数据库warn-destructive-sql, warn-schema-alterationPreToolUse
警告warn-large-file-write, warn-package-publish, warn-background-process, warn-global-package-installPreToolUse
包管理器prefer-package-managerPreToolUse
工作流require-commit-before-stop, require-push-before-stop, require-pr-before-stop, require-no-conflicts-before-stop, require-ci-green-before-stopStop
  • block- — 阻止代理继续执行。
  • warn- — 向代理提供额外上下文,使其能够自我纠正。
  • sanitize- — 在代理看到工具输出之前清除其中的敏感数据。

命名空间

每条策略都位于 <namespace>/<name> 插槽中。内置策略属于 failproofai/ 命名空间——例如 failproofai/sanitize-jwt。当你同时加载具有相似短名称的自定义或第三方策略时,命名空间可防止命名冲突。 在配置中,你可以通过短名称或完整限定名称来引用内置策略;两种形式解析到同一条策略:
{
  "enabledPolicies": [
    "sanitize-jwt",
    "failproofai/block-rm-rf"
  ]
}
如果名称中不含 /,failproofai 会将其视为属于默认命名空间 failproofai。已包含 / 的名称(如 myorg/foocustom/my-hook)将保持原样。
  • require- — 阻止 Stop 事件,直到满足条件为止。

每条策略在 policyParams 中都支持可选的 hint 字段。该提示会附加到 Claude 看到的 deny 或 instruct 消息中,在不修改策略代码的情况下提供可操作的指导。适用于内置策略、自定义策略和约定策略。详见配置 → hint

危险命令

防止代理运行难以撤销或可能损害宿主系统的操作。

block-sudo

事件: PreToolUse (Bash)
默认行为: 拒绝任何包含 sudo 的命令。
阻止包含 sudo 关键字的调用。模式匹配基于解析后的命令令牌,而非原始字符串,以防止通过 Shell 运算符注入绕过。 参数:
参数类型默认值描述
allowPatternsstring[][]允许的精确命令前缀。每个条目与解析后的 argv 令牌进行匹配。
示例:
{
  "policyParams": {
    "block-sudo": {
      "allowPatterns": ["sudo systemctl status", "sudo journalctl"]
    }
  }
}
使用此配置,sudo systemctl status nginx 会被允许,但 sudo rm /etc/hosts 会被拒绝。
模式匹配基于解析后的令牌,而非原始命令字符串。这可防止通过附加 Shell 运算符进行绕过(例如,sudo systemctl status x; rm -rf / 不会匹配 sudo systemctl status *)。

block-rm-rf

事件: PreToolUse (Bash)
默认行为: 拒绝 rm -rfrm -fr 及类似的递归删除形式。
参数:
参数类型默认值描述
allowPathsstring[][]允许递归删除的安全路径(例如 /tmp)。
示例:
{
  "policyParams": {
    "block-rm-rf": {
      "allowPaths": ["/tmp", "/var/cache"]
    }
  }
}

block-curl-pipe-sh

事件: PreToolUse (Bash)
默认行为: 拒绝 curl <url> | bashcurl <url> | shwget <url> | bash 及类似模式。
无参数。

block-failproofai-commands

事件: PreToolUse (Bash)
默认行为: 拒绝会卸载或禁用 failproofai 本身的命令(例如 npm uninstall failproofaifailproofai policies --uninstall)。
无参数。

基础设施命令

防止编码代理运行基础设施 CLI 或触发 CI/CD 流水线。此类别中的所有策略均为按需启用defaultEnabled: false)——合法需要调用 kubectlterraform 等工具的代理不会受到干扰,除非你主动启用该策略。启用后,匹配 CLI 的每次调用都会被拒绝,除非命令与 allowPatterns 中的某个条目匹配。 模式语法与 block-sudo 相同:令牌与解析后的 argv 进行匹配,* 是单个令牌的通配符,任何包含独立 Shell 运算符(&&|||;)或嵌入 Shell 元字符令牌的命令,在白名单匹配之前都会被拒绝,以防止注入绕过。

block-kubectl

事件: PreToolUse (Bash)
默认行为: 拒绝任何 kubectl 调用。
参数:
参数类型默认值描述
allowPatternsstring[][]允许的 kubectl 命令前缀。
示例:
{
  "policyParams": {
    "block-kubectl": {
      "allowPatterns": ["kubectl get *", "kubectl describe *", "kubectl logs *"]
    }
  }
}
使用此配置,kubectl get pods 会被允许,但 kubectl apply -f deploy.yaml 会被拒绝。

block-terraform

事件: PreToolUse (Bash)
默认行为: 拒绝任何 terraformtofu(OpenTofu)调用。
参数:
参数类型默认值描述
allowPatternsstring[][]允许的 terraform/tofu 命令前缀。
示例:
{
  "policyParams": {
    "block-terraform": {
      "allowPatterns": ["terraform plan", "terraform validate", "terraform show *"]
    }
  }
}

block-aws-cli

事件: PreToolUse (Bash)
默认行为: 拒绝任何 aws CLI 调用。
参数:
参数类型默认值描述
allowPatternsstring[][]允许的 aws CLI 命令前缀。
示例:
{
  "policyParams": {
    "block-aws-cli": {
      "allowPatterns": ["aws s3 ls *", "aws sts get-caller-identity"]
    }
  }
}

block-gcloud

事件: PreToolUse (Bash)
默认行为: 拒绝任何 gcloud(Google Cloud)CLI 调用。
参数:
参数类型默认值描述
allowPatternsstring[][]允许的 gcloud 命令前缀。
示例:
{
  "policyParams": {
    "block-gcloud": {
      "allowPatterns": ["gcloud auth list", "gcloud config list"]
    }
  }
}

block-az-cli

事件: PreToolUse (Bash)
默认行为: 拒绝任何 az(Azure)CLI 调用。
参数:
参数类型默认值描述
allowPatternsstring[][]允许的 az CLI 命令前缀。
示例:
{
  "policyParams": {
    "block-az-cli": {
      "allowPatterns": ["az account show", "az group list"]
    }
  }
}

block-helm

事件: PreToolUse (Bash)
默认行为: 拒绝任何 helm 调用。
参数:
参数类型默认值描述
allowPatternsstring[][]允许的 helm 命令前缀。
示例:
{
  "policyParams": {
    "block-helm": {
      "allowPatterns": ["helm list", "helm status *"]
    }
  }
}

block-gh-pipeline

事件: PreToolUse (Bash)
默认行为: 拒绝以下会修改状态或触发流水线的 gh CLI 子命令:
  • gh workflow rungh workflow enablegh workflow disable
  • gh run rerungh run cancel
  • gh pr merge
  • gh release creategh release delete
  • gh cache delete
  • gh secret setgh secret delete
只读的 gh 子命令(如 gh pr viewgh pr listgh run listgh release viewgh api repos/.../...在此策略的匹配范围内——这些命令通常用于工作流检查(包括 failproofai 自身的 require-ci-green-before-stop)。 参数:
参数类型默认值描述
allowPatternsstring[][]即使会被拒绝,也允许的特定脚本调用。
示例:
{
  "policyParams": {
    "block-gh-pipeline": {
      "allowPatterns": ["gh run rerun *"]
    }
  }
}

密钥(清理器)

防止代理将凭据泄露到其上下文或输出中。清理器策略在 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 }[][]额外需要视为密钥的正则表达式模式。
示例:
{
  "policyParams": {
    "sanitize-api-keys": {
      "additionalPatterns": [
        { "regex": "myco_[A-Za-z0-9]{32}", "label": "MyCo internal API key" },
        { "regex": "pat_[0-9a-f]{40}", "label": "Internal PAT" }
      ]
    }
  }
}

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)
默认行为: 拒绝打印环境变量的命令:printenvenvecho $VAR
无参数。

文件访问

将代理限制在项目边界内,并使其远离敏感文件。

block-read-outside-cwd

事件: PreToolUse (Read, Bash)
默认行为: 拒绝读取项目根目录之外的文件。边界由 CLAUDE_PROJECT_DIR(由 Claude Code 在每次会话开始时设置)确定,当该变量未设置时,回退到会话的当前工作目录。使用项目根目录而非实时的 cwd,意味着即使 Claude cd 进入子目录后,边界仍然保持稳定。
参数:
参数类型默认值描述
allowPathsstring[][]即使位于项目根目录之外,也允许访问的绝对路径前缀。
示例:
{
  "policyParams": {
    "block-read-outside-cwd": {
      "allowPaths": ["/shared/data", "/opt/company/config"]
    }
  }
}

block-secrets-write

事件: PreToolUse (Write, Edit)
默认行为: 拒绝写入常用于私钥和证书的文件:id_rsaid_ed25519*.key*.pem*.p12*.pfx
参数:
参数类型默认值描述
additionalPatternsstring[][]额外需要阻止的文件名模式(glob 风格)。
示例:
{
  "policyParams": {
    "block-secrets-write": {
      "additionalPatterns": [".token", ".secret"]
    }
  }
}

Git

防止意外推送、强制推送以及难以撤销的分支操作失误。

block-push-master

事件: PreToolUse (Bash)
默认行为: 拒绝 git push origin maingit push origin master
参数:
参数类型默认值描述
protectedBranchesstring[]["main", "master"]不能直接推送的分支名称。
示例:
{
  "policyParams": {
    "block-push-master": {
      "protectedBranches": ["main", "master", "release", "prod"]
    }
  }
}
若要允许推送到所有分支(即在不从 enabledPolicies 中移除此策略的情况下将其实际禁用),请设置 protectedBranches: []

block-work-on-main

事件: PreToolUse (Bash)
默认行为: 当工作树处于 mainmaster 分支时,拒绝 git commitgit mergegit rebasegit cherry-pick。分支创建和切换(git checkoutgit checkout -bgit switchgit switch -c)不受影响。
参数:
参数类型默认值描述
protectedBranchesstring[]["main", "master"]禁止执行 commit/merge/rebase/cherry-pick 的分支名称。

block-force-push

事件: PreToolUse (Bash)
默认行为: 拒绝 git push --forcegit push -f
无特定策略参数。使用通用 hint 建议替代方案:
{
  "policyParams": {
    "block-force-push": {
      "hint": "Create a new branch from your current HEAD (e.g. `git checkout -b <new-branch>`) and push that instead."
    }
  }
}

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 -Agit add . 时指示 Claude 检查所暂存的内容。不会阻止该命令。
无参数。

数据库

在破坏性 SQL 操作对数据库执行前将其拦截。

warn-destructive-sql

事件: PreToolUse (Bash)
默认行为: 在运行包含 DROP TABLEDROP DATABASE 或不带 WHERE 子句的 DELETE 的 SQL 前,指示 Claude 进行确认。
无参数。

warn-schema-alteration

事件: PreToolUse (Bash)
默认行为: 在运行 ALTER TABLE 语句前,指示 Claude 进行确认。
无参数。

警告

在执行可能存在风险但非破坏性的操作前,为代理提供额外上下文。

warn-large-file-write

事件: PreToolUse (Write)
默认行为: 在写入大于 1024 KB 的文件前,指示 Claude 进行确认。
参数:
参数类型默认值描述
thresholdKbnumber1024触发警告的文件大小阈值(以千字节为单位)。
示例:
{
  "policyParams": {
    "warn-large-file-write": {
      "thresholdKb": 256
    }
  }
}
钩子处理程序对 stdin 载荷强制执行 1 MB 的限制。若要使用较小内容测试此策略,请将 thresholdKb 设置为远低于 1024 的值。

warn-package-publish

事件: PreToolUse (Bash)
默认行为: 在运行 npm publish 前,指示 Claude 进行确认。
无参数。

warn-background-process

事件: PreToolUse (Bash)
默认行为: 在通过 nohup&disownscreen 启动后台进程时,指示 Claude 保持谨慎。
无参数。

warn-global-package-install

事件: PreToolUse (Bash)
默认行为: 在运行 npm install -gyarn 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。
参数类型默认值描述
allowedstring[][]允许的包管理器名称。任何未在此列表中的已检测管理器都会被阻止。为空时,该策略不执行任何操作。
blockedstring[][]除内置列表之外额外需要阻止的管理器名称(例如 ['pdm', 'pipx'])。
内置阻止列表包括:pip、pip3、npm、npx、yarn、pnpm、pnpx、bun、bunx、uv、poetry、pipenv、conda、cargo。使用 blocked 追加不在此列表中的管理器。 示例配置:
{
  "enabledPolicies": ["prefer-package-manager"],
  "policyParams": {
    "prefer-package-manager": {
      "allowed": ["uv", "bun"],
      "blocked": ["pdm", "pipx"]
    }
  }
}
使用此配置,pip install flaskpdm install flask 都会被拒绝,并提示 Claude 改用 uvbun。而 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 进程中启动的新会话。
如果你需要 Claude 风格的同循环重试,请在其他六种支持的 CLI 下运行你的 Stop 策略。我们正在跟踪 Pi 上游,等待 AgentEndEvent 未来支持 Result 类型,届时我们将能弥合这一差距。

require-commit-before-stop

事件: Stop
默认行为: 当存在未提交的更改(已修改、已暂存或未跟踪的文件)时,拒绝停止。工作目录干净时返回提示信息。
无参数。

require-push-before-stop

事件: Stop
默认行为: 当存在未推送的提交,或当前分支没有远程跟踪分支时,拒绝停止。必要时建议使用 git push -u 创建跟踪分支。如果未配置远程仓库,则开放失败。
参数:
参数类型默认值描述
remotestring"origin"推送目标的远程名称。
示例:
{
  "policyParams": {
    "require-push-before-stop": {
      "remote": "upstream"
    }
  }
}

require-pr-before-stop

事件: Stop
默认行为: 当当前分支不存在拉取请求,或现有 PR 已关闭且未合并时,拒绝停止。指示 Claude 使用 gh pr create 创建 PR。当 PR 已合并时,策略允许通过(工作已发布),并提示切换回分支(git checkout main && git pull)。
无参数。
此策略需要安装并通过身份验证的 GitHub CLIgh)。 运行 gh auth login,使用具有 repo 权限(用于读取拉取请求)的个人访问令牌。如果未安装 gh 或未通过身份验证,策略会开放失败,并将原因报告给 Claude。

require-no-conflicts-before-stop

事件: Stop
默认行为: 当当前分支无法干净地合并到基础分支时,拒绝停止。该策略首先确认 GitHub 上是否存在该分支的 OPEN PR——如果没有,则没有可强制执行的合并目标,整个策略短路为允许。确认存在 OPEN PR 后,会运行两个独立探测:
  1. 本地git merge-tree --write-tree --name-only origin/<baseBranch> HEAD。发生冲突时,拒绝消息会列出冲突文件,让 Claude 明确知道需要解决哪些问题。
  2. GitHub — 复用预检时已获取的 gh pr view --json mergeable,state 结果。可捕获本地陈旧的 origin/<baseBranch> 会遗漏的冲突(例如,自上次 fetch 以来,有人将一个冲突的 PR 合并到了 main)。CONFLICTING 结果会触发拒绝。UNKNOWN 结果也会触发拒绝,并指示 Claude 等待约 10 秒后重新检查再尝试停止——这可防止 GitHub 重新计算期间出现假阴性。
在以下情况下完全跳过(允许通过):未安装 gh、该分支不存在 PR、PR 状态不为 OPEN(如 MERGEDCLOSED),或 gh pr view 返回无法解析的输出。当本地缺少 origin/<baseBranch> 或没有超前于基础的提交时也会开放失败——这些第一层回退仍会在允许前参考缓存的 PR 可合并性。 参数:
参数类型默认值描述
baseBranchstring"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)。将 skippedcancelledneutral 结论视为非失败(后者涵盖了例如外部贡献者 PR 上的 Socket Security 告警,此时应用程序有意报告 neutral 而非 success/failure)。所有检查通过时返回提示信息。
无参数。
此策略需要安装并通过身份验证的 GitHub CLIgh)。 运行 gh auth login,使用具有 repo 权限(用于读取 Actions 工作流运行和 Checks API)的个人访问令牌。如果未安装 gh 或未通过身份验证,策略会开放失败,并将原因报告给 Claude。


禁用单条策略

从配置的 enabledPolicies 中移除特定策略,或在控制台的策略选项卡中将其关闭。
{
  "enabledPolicies": [
    "block-rm-rf",
    "sanitize-api-keys"
  ]
}
未列在 enabledPolicies 中的策略不会运行,即使存在对应的 policyParams 条目也是如此。