Repository navigation
fix: 权限清扫改为丢弃连接而非 deny,修复并行子代理场景的误拒 - #13
Merged
Merged
Conversation
sweepForSessionEvent 原先在收到 PostToolUse/PostToolUseFailure/Stop/ UserPromptSubmit/SessionEnd 时,把该会话所有待处理权限请求一律裁决为 deny("User answered in terminal")。但这些事件在同一 session_id 的 并发活动里同样会触发——后台/并行子代理每完成一个工具就发 PostToolUse, 主会话的工具完成也会扫到子代理正在等待的气泡——导致真正还在等用户点击 的请求被误拒:CC 端显示 "Error: User answered in terminal / Denied by PermissionRequest hook",Claude 被迫反复重试同一工具。 改为 no-decision:清扫只丢弃挂起的连接(CC 回退到终端自己的权限提示), 保留「清掉过期气泡」的本意,且从不替用户做拒绝决定。用户若真在终端作答, CC 早已关闭该连接,丢弃为无副作用的空操作。 test/smoke.js 的 [7] 用例同步改为断言「连接被丢弃、无裁决」;结算收集器 在创建时即挂载,避免清扫断连先于 /state 应答到达而触发 unhandledRejection。 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
myunwang
approved these changes
Jul 27, 2026
myunwang
left a comment
Owner
There was a problem hiding this comment.
感谢这次非常扎实的定位,尤其是 229 次权限裁决及 86 次误拒的实测数据,把并行子代理共享 session_id 导致误杀的问题说明得很清楚。
我重新审阅了完整权限生命周期,并在独立 worktree 中跑过全量 npm test;另外补做了同一 session 同时存在两个不同 pending 权限请求的实验,确认清扫后两条连接都以 no-decision 结束,没有返回或暗中产生 deny。
这份改动正确消除了当前最严重的问题:生命周期事件不能再替用户作出拒绝决定。并行事件仍可能让桌宠授权卡回退到终端,这属于后续体验优化,不阻塞本次止血修复;我会另开 issue 跟踪权限卡保留和正式的双 pending 回归测试。
Approved,感谢贡献!
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
问题
会话中存在并行/后台子代理(async Agent)时,正在等待用户点击的权限气泡会在弹出后 1~数秒内被自动拒绝,CC 端显示
Error: User answered in terminal / Denied by PermissionRequest hook,Claude 被迫反复重试同一工具。原因
sweepForSessionEvent把PostToolUse / PostToolUseFailure / Stop / UserPromptSubmit / SessionEnd一律当作"用户已在终端作答",将该会话所有待处理权限请求裁决为deny。但后台/并行子代理与主会话共用同一session_id:子代理每完成一个工具就发PostToolUse,主会话的工具完成也会扫到子代理正在等待的气泡——任何并发工具完成都会误杀仍在等点击的请求。单线程会话中该 bug 潜伏,并行代理场景下近乎必然触发。实测一个含两个后台代理的会话:229 次权限裁决中 86 次(37%)为此类误拒,时间戳与并发工具完成逐条对齐。修复
清扫裁决由
deny改为no-decision:只丢弃挂起的连接(CC 回退到终端自己的权限提示,与免打扰路径行为一致),保留"清掉过期气泡"的本意,且从不替用户做拒绝决定。用户若真在终端作答,CC 早已关闭该连接,丢弃为无副作用的空操作。test/smoke.js[7] 同步改为断言"连接被丢弃、无裁决、无 pending 残留"。npm test全量通过。