技术 · 熟练
拦住它之后,还要知道是谁在问、要到哪一档
同一个工具,主会话问一次、子代理问一次,不该是同一个答案
「危险动作先拦下来等你点头」已经有一页讲过了,连「批准那一刻要把参数冻结」也讲过了 —— 但真实跑起来还差三样东西:① 你不知道这次检查是谁发起的(主会话,还是它派出去的子代理);② 你不知道平台对这个工具要求的档位是什么(组织要求到哪一级、是不是本来就不该弹给你);③ 你没法确认那道钩子真的会兜底(它抛异常时有没有兜底分支)。这一页只补这三样,全是官方 changelog 里已经可用的字段:让审批门带身份(`agentId`)、带档位(`ceiling`)、并可被验证(每个在门位上注册的钩子是否带 `.catch`)。另外一条原则要单独记住:「全放行」不等于「对不可逆动作也放行」。
方法 · 一图看懂
1
先认出是谁在问 — 同一条检查,主会话与子代理要能分开,否则你会替一个看不见的代理签字
2
再对齐「平台要求的档位」 — 组织已经定了某一级审批,你的门就别再自己发明一套
3
「全放行」要对不可逆动作除外 — 放行模式是效率设定,不是对危险动作的许可
4
把门自身的失败也算进去 — 钩子异常时要显式拒绝,并且这条要能被校验出来
原理 · 为什么有效
为什么「谁在问」这件事必须先解决。一个多代理系统的权限检查里,请求可能来自主会话,也可能来自它派出去的子代理 —— 这两件事的风险完全不同:主会话背后是你在看着屏幕,子代理往往是在你离开之后自己跑。同一条规则如果分不清两者,你其实是在替一个你看不见的代理签字。官方已经把这件事做成了字段(`tool.check` 事件里的 `agentId`),所以这一步不需要新造机制,只需要在策略里把它用起来:子代理发起的检查,按更严的一档处理,或者干脆规定「这类动作子代理一律不许」。
为什么「档位」不该由你的门自己发明。审批的分寸在不同的组织、不同的环境里本来就不一样:同一个「删文件」,个人机器上可能只要一句确认,公司的生产环境上可能要求走变更流程。官方把这条差异做成了 question / verdict 里可读的 `ceiling` —— 也就是组织对该工具要求的审批档位。拿到它之后,你的钩子只需要做一件事:不高于这个档位的一律不要弹给人。这一条直接决定了审批门会不会变成摆设 —— 把低风险动作也塞进人工确认,人两天就学会了无脑点同意,那时门还在,作用没了。
为什么「全放行」也需要一个例外。2026-10-02 的一条修复很说明问题:`bash -c` 脚本里的危险 `rm`,现在即使在 bypassPermissions 模式下也会弹确认。这条改动的含义不是「平台不信你」,而是把两件事分开了:放行模式管的是「常规动作不要烦我」,不是「不可逆动作也算常规」。你自己的门也该照这个口径写:放行清单里可以有很多东西,但删除、覆盖、对外发布这三类不进放行清单,永远单独确认。
最后一条最少人做:把门自己的失败也算进去。一个在 gating 位注册的钩子,如果它会抛异常、而你没有兜底分支,那么「钩子挂了」和「钩子放行」在现场是一样的结果 —— 你甚至不会知道。官方已经在 `claude plugin validate` 里做成可查:逐个列出每个在门位上注册的钩子是否带 `.catch`。这条检查应该进你的上线前清单:没有兜底分支的钩子,等于给门留了一个静默的后门。
适用场景
适用:你已经在用审批门,而且开始遇到「该弹的没弹、不该弹的弹了一堆」;你的 agent 会派子代理干活,而你说不清那些子代理拿的是谁的权限;你要给团队解释「哪些动作必须有人点头、点到什么程度」。
不适用:只有一个 agent、只做本机只读任务 —— 那类先解决回滚,不需要审批分层。也不适用:把审批写在提示词里 —— 那不是门。
自测 · 5 问
我能不能分清这次权限检查是主会话发起的,还是某个子代理发起的?
平台已经给出的「组织要求档位」(ceiling),我是拿来用了,还是自己另定了一套?
我的放行清单里,有没有混进「删除 / 覆盖 / 对外发布」这三类不可逆动作?
在门位上注册的钩子,如果它自己抛异常,会变成「拒绝」还是变成「什么都没发生」?
低风险动作我是不是也塞进了人工确认 —— 人已经养成无脑点同意了吗?
怎么上手 · 验证步骤
三件事,按这个顺序做,每件都能当天完成。
第一步:先给策略加上「谁在问」。翻一遍你现在的审批规则,凡是没有区分主会话 / 子代理的,先按「子代理一律用更严的一档」改一遍;改完拿一次真实运行对照 —— 会不会有子代理的请求因为这一改被拒?那些正是以前看不见的风险面。第二步:把平台给的档位对齐。读一次平台给你的 question / verdict 里那个「组织要求的审批档位」,把你的钩子改成「不高于这个档位的不弹给人」;改完看两个数 —— 每天人工确认的次数降了多少 · 有没有该弹的没弹(对照一次真实事件的回溯)。第三步:验证门自身。对每个在门位上注册的钩子问一句「它抛异常时会怎样」,并让平台把它列出来逐个检查有没有兜底分支;没有的当场补上。⛔ 别跳过第三步:没有兜底的钩子,出事时表现与「放行」完全一样。