<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>护栏 on Codexer</title><link>https://codexer.com/tags/%E6%8A%A4%E6%A0%8F/</link><description>Recent content in 护栏 on Codexer</description><generator>Hugo</generator><language>zh-cn</language><lastBuildDate>Fri, 16 Oct 2026 07:45:00 +0800</lastBuildDate><atom:link href="https://codexer.com/tags/%E6%8A%A4%E6%A0%8F/index.xml" rel="self" type="application/rss+xml"/><item><title>Codex hooks 的静默失效：你配的护栏可能一次都没跑过</title><link>https://codexer.com/posts/2026-10-16-codex-hooks-silent-failure/</link><pubDate>Fri, 16 Oct 2026 07:45:00 +0800</pubDate><guid>https://codexer.com/posts/2026-10-16-codex-hooks-silent-failure/</guid><description>&lt;p&gt;你在 &lt;code&gt;~/.codex/hooks.json&lt;/code&gt; 里写了几个钩子：&lt;code&gt;PreToolUse&lt;/code&gt; 拦住 &lt;code&gt;rm -rf&lt;/code&gt;，拦住读 &lt;code&gt;.env&lt;/code&gt;，&lt;code&gt;PostToolUse&lt;/code&gt; 跑一遍格式化，&lt;code&gt;Stop&lt;/code&gt; 要求测试通过才准收工。头两天日志里能看到钩子输出，你觉得这事就算配好了。&lt;/p&gt;
&lt;p&gt;三个月后复盘，你回头翻记录，发现那几行输出最后一次出现是一个半月前。&lt;/p&gt;
&lt;p&gt;hooks 麻烦的地方不在能不能配，而在它坏掉的样子。它坏的时候不会报错：配置在、信任哈希在、别的插件的钩子还在打印日志，所有表面信号都是对的。下面这些是我在 openai/codex 的 issue 里翻到的案例，都能复现，共同点是安静。&lt;/p&gt;
&lt;h2 id="先记住-hooks-的几个设定"&gt;先记住 hooks 的几个设定&lt;/h2&gt;
&lt;p&gt;官方文档里值得先划出来的几条：&lt;/p&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;位置&lt;/th&gt;
 &lt;th&gt;说明&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;~/.codex/hooks.json&lt;/code&gt;、&lt;code&gt;~/.codex/config.toml&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;用户级&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;&amp;lt;repo&amp;gt;/.codex/hooks.json&lt;/code&gt;、&lt;code&gt;&amp;lt;repo&amp;gt;/.codex/config.toml&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;项目级，只在该项目的 &lt;code&gt;.codex/&lt;/code&gt; 层被信任时加载&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;插件自带的 &lt;code&gt;hooks/hooks.json&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;随插件启用而加载，走同样的信任流程&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;requirements.toml&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;托管钩子，按策略视为已信任，用户没法在钩子浏览器里禁用&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;事件分三组：回合内的有 &lt;code&gt;PreToolUse&lt;/code&gt;、&lt;code&gt;PermissionRequest&lt;/code&gt;、&lt;code&gt;PostToolUse&lt;/code&gt;、&lt;code&gt;PreCompact&lt;/code&gt;、&lt;code&gt;PostCompact&lt;/code&gt;、&lt;code&gt;UserPromptSubmit&lt;/code&gt;、&lt;code&gt;Stop&lt;/code&gt;、&lt;code&gt;SubagentStop&lt;/code&gt;；会话或子 agent 启动时有 &lt;code&gt;SessionStart&lt;/code&gt;、&lt;code&gt;SubagentStart&lt;/code&gt;；主线程结束时是 &lt;code&gt;SessionEnd&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;几条运行时规则：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;多个文件里匹配上的钩子都会跑。高优先级的层不替换低优先级的层，只做叠加。同一层里同时写了 &lt;code&gt;hooks.json&lt;/code&gt; 和内联 &lt;code&gt;[hooks]&lt;/code&gt;，Codex 会合并并在启动时给一条警告，所以一层里挑一种写法。&lt;/li&gt;
&lt;li&gt;非托管的命令钩子要先审阅并信任才会跑。信任记在钩子定义的哈希上，新增或改动过的钩子会被标成待审阅然后跳过。用 &lt;code&gt;/hooks&lt;/code&gt; 看来源、审阅、信任或禁用。&lt;/li&gt;
&lt;li&gt;同一个事件上多个匹配的命令钩子并发启动，一个钩子拦不住另一个。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;还有一条最重要的：钩子崩了、超时了、返回了不合法的 JSON，操作照常进行，钩子只被标成 &lt;code&gt;Failed&lt;/code&gt;。这个设计叫 fail-open，好处是钩子不会把 agent 卡死，代价是护栏失灵的时候没有任何东西会喊出来。&lt;/p&gt;
&lt;p&gt;官方文档自己也是这个调子：工具钩子是有用的护栏，不是完整的执行边界，有些特殊工具路径不走默认的钩子。&lt;/p&gt;
&lt;h2 id="改完配置没重启这次会话的钩子全灭"&gt;改完配置没重启，这次会话的钩子全灭&lt;/h2&gt;
&lt;p&gt;openai/codex#21160，2026 年 5 月 5 日开的，报的是 &lt;code&gt;codex-cli 0.128.0&lt;/code&gt;，Ubuntu 24.04 on WSL2。两个场景：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;会话撞到限流停下时，本该跑的那条 stop 钩子不跑。&lt;/li&gt;
&lt;li&gt;会话还活着的时候改 &lt;code&gt;hooks.json&lt;/code&gt;，只要文件本身是合法 JSON（&lt;code&gt;jq&lt;/code&gt; 验证通过），这个会话后面所有钩子都不再触发，重启会话才恢复。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;报告者的诉求很朴素：要么在限流停下时也跑钩子，要么明说这种情况会跳过；改配置可以继续用旧的那份，也可以热加载，或者至少提示一句需要重启。不能接受的是整个会话静默失去钩子。&lt;/p&gt;</description></item></channel></rss>