该版本修复了两类静默失效的 guardrail 配置:指令式 hooks 会错误放行应阻止的命令,以及通过 Bash 命令查看文件时路径规则和嵌套 CLAUDE.md 不会加载。
本周 Claude Code 有两个静默的修复落地,两者都与同一件事有关:看起来生效了的 guardrail 配置实际上并没有生效。2.1.294 版本于 10 月 8 日 03:42 UTC 发布到 npm,修复了"指令式钩子允许本应拦截的内容"的问题——这是项目自身的措辞。同一个版本还修复了路径作用域规则和嵌套 CLAUDE.md 文件在 Claude 通过 Bash 命令而非 Read 工具查看文件时完全不加载的问题。如果你为活跃的代码库维护规则文件或钩子,这两个 bug 都不会产生错误信息。你的测试可能通过,审计可能通过,但 guard 根本不存在。
我为团队的 agent kits 编写规则文件和钩子配置,所以当这样的修复发布时,我不会问"我受影响了吗",我会问"我怎么能发现"。对于这两个 bug,诚实的答案是:只能通过测试行为来发现,从配置文本上永远看不出来。这件事值得展开说说,因为审计很简单,而这种失败类型的影响范围远不止一个补丁。
摘自官方变更日志,版本 2.1.294:
"修复了以指令形式编写的 prompt 和 agent 钩子(如 'Block commands that..')允许本应拦截的内容"
"修复了路径作用域规则和嵌套 CLAUDE.md 文件在 Claude 使用 Bash 工具中的单文件 cat、head、tail、sed -n 或 grep 命令查看文件时完全不加载的问题"
再往上翻一行,2.1.293(npm,10 月 7 日 17:18 UTC):
"改进了以指令形式编写的 Stop 和 SubagentStop 上的 prompt 钩子(如 'Carry on if the build is broken')的评判方式,使 Claude 不太可能提前停止"
如果你写钩子,再读一遍第一行。某个钩子存在、已注册、每次匹配事件都会运行,却可能允许它本应拦截的命令。不是报错,而是 fail open。
Claude Code 钩子有两种形式。决策钩子是一个检查事件并返回裁定的脚本,裁定会被机械地执行。指令钩子,即 prompt 和 agent 两种,是被注入到上下文中由模型评判的散文。"Block commands that touch the deploy bucket." 这是一条写成长句子的策略,而在 2.1.294 之前,对这个句子的评判在恰好针对你写它的那个输入上可能出错。
强制执行的表单是这样的:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{ "type": "command", "command": "./guards/block-pattern.sh" }
]
}
]
}
}
其中 block-pattern.sh 在匹配时以非零退出,并返回一个 JSON body:{"decision": "block", "reason": ".."}。那是代码,不是评判。2.1.294 中的修复是真实且受欢迎的,但它是对一个评判者的补丁,而评判者会再次被打补丁。这周之后我的原则是:任何绝对不能发生的事都应该放在有退出码的脚本里,散文钩子只适用于偏好而非禁止。这是我在一个 7 行的 Claude Code mod 覆盖了 deny 规则时得出的同样结论,而这条变更日志是进一步的证据。
第二个 bug 更隐蔽,因为它取决于 Claude 读取文件的方式。你为 src/payments/** 设置的路径作用域规则在 Claude 使用 Read 工具时加载。当 Claude 改用 Bash 工具中的单个 cat、head、tail、sed -n 或 grep 来查看文件时,规则完全不加载。所以同一个文件、同一个会话,只是工具路径不同,规则集就不一样了。
想想这对验证意味着什么。你通过询问 Claude 关于某个文件来测试你的规则,它加载了,行为正确。之后,Claude 通过管道中的 grep 访问同一个文件,而你关于支付代码、迁移安全性或密钥处理的规则就消失了。没人看到错误,因为不加载文件不会产生错误。我之前整理了 agent 忽略规则文件的七种方式,每个都有修复方案,而这是列表中的新条目:规则本身没问题,加载路径把它吃掉了。
升级到 2.1.294 后,运行两个探测可以在你自己的 setup 中捕获这两类问题。
首先,清点你的指令钩子,找出形似禁止语的散文:
grep -rn -iE 'block|never|forbid|do not|dont' .claude/settings*.json .claude/hooks/ 2>/dev/null
prompt 或 agent 钩子中的每个匹配项都是转换为决策脚本的候选。脚本不需要多聪明,一个对命令字符串做 case 分支的语句就能捕捉散文试图捕捉的大部分内容,而且它的裁定不依赖于某天模型如何读一个句子。
其次,通过两种读取路径测试规则加载。选一条你认为生效的规则、一条能产生可见行为的规则,然后触发它两次:一次在全新会话中显式要求 Claude 读取文件,一次让文件通过 Bash grep 出现。如果行为出现在一次而不在另一次,你就发现了一个加载路径缺口,现在你知道你的哪些规则以工具选择为条件了。每当客户端版本变更时重新运行这个测试,因为加载行为正是那种会被悄悄修复然后又悄悄打破的东西,这周的事实证明了这一点。
两个 bug 有一个共同特性,应该改变你审查 agent 配置的方式:搭建时的检查通过了。钩子运行了,规则存在了,理性的人会说配置是正确的。失败发生在运行时评判和运行时加载路径上,从文件本身无从察觉。这就是为什么我不再把配置审查当作阅读练习,而是当作测试练习,用探测来检验行为,而不是检验文本。这和我在扫描 agent 配置寻找静默失败时采用的策略一样:磁盘上的文件是声明,探测是证据。我们在 AgentConfig Studio 发货的版本锁定 kits 存在的原因与此相关,这样当客户端在你的规则之下发生变化时,你可以知道什么变了、什么时候变的,而不是事后才发现 guard 缺失。
2.1.293 还修复了一个内存泄漏:HTTP MCP 连接在关闭前保留它发送的每个请求,如果你长时间连接远程服务器运行会话就有影响。此外还添加了 Claude Haiku 5.5(claude-haiku-5-5),拥有 1M 上下文窗口,价格 $0.10/$0.50 每 Mtok,是 Anthropic API 上新的默认 Haiku。对于 mod 作者,isDeferred 在 $.tool.register 中现在控制工具的模式是从一开始就列在 prompt 中还是置于工具搜索之后,这是一个上下文预算杠杆,穿着注册标志的外衣。另外如果你错过了,2.1.292 将 stdio MCP 默认值切换到了 2026-07-28 协议,我在这里逐个服务器探测过。
升级,然后在两个地方重新赢得你的信任:将禁止类钩子从散文转换为带退出码的脚本,以及通过两种读取路径探测你的路径作用域规则。十分钟,你就不再依赖一个你看不见的评判者的补丁了。