ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

Pilot Shell auto_approve_plan详解:模型切换流程中的ExitPlanMode授权

Pilot Shell auto_approve_plan详解:模型切换流程中的ExitPlanMode授权 Pilot Shell auto_approve_plan详解模型切换流程中的ExitPlanMode授权【免费下载链接】pilot-shellProfessional context and harness engineering for Claude Code and OpenAI Codex. Build production-grade software with spec-driven development, TDD, persistent memory, quality gates, code intelligence, human oversight, and end-to-end verification.项目地址: https://gitcode.com/GitHub_Trending/cl/pilot-shell如果你在用 Pilot Shell 搭配 Claude Code 跑 spec 驱动开发大概率遇到过这个场景规划阶段用上了更聪明的模型opusplan计划批准后却要再点一次退出计划模式的确认框——多此一举甚至可能让权限模式被意外降级。Pilot Shell 的auto_approve_planhook 就是为了解决这个 ExitPlanMode 授权问题而生的它精准识别这次退出是模型切换流程的一部分自动放行冗余确认同时绝不替用户批准计划本身。一、先理清背景为什么需要 auto_approve_planPilot Shell 的/spec工作流分两条腿规划腿planning leg在计划模式下由更强的模型如 Opus负责探索代码库、撰写计划文档实现腿implementation leg计划获批后切换回日常模型开始写代码。在自动模型切换Automated Model Switching模式下这两条腿的切换依赖 Claude Code 原生的计划模式工具EnterPlanMode和ExitPlanMode。问题在于ExitPlanMode属于必须用户交互的工具它自带一个确认对话框。而在/spec流程里用户已经在独立的审批环节批准过计划退出时的这个对话框就成了冗余的二次确认——更麻烦的是退出计划模式时 Claude Code 会把会话权限模式顺带降级上游行为如果处理不当用户的bypassPermissions设置会在规划结束后悄悄丢失。auto_approve_plan就注册在PermissionRequest事件上见 hooks.json对每一次权限请求做守门判断但它的第一原则是拿不准就闭嘴——不输出任何决策把决定权交还给 Claude Code 原生的对话框。二、核心逻辑三条决策分支主逻辑在_exit_plan_mode_decision中按优先级走三条分支分支 1已预置的原生计划交接prepared native handoff如果/spec在规划前就通过native_plan_capture.py预置了原生草稿native-spec-planning.jsonhook 会先用 SHA256 校验草稿内容与绑定关系是否一致若用户配置保留审批approval_required: true→ 什么都不做让原生审批对话框出现Pilot 绝不越权若用户明确关闭了审批门槛且退出内容与预置草稿完全匹配 → 自动放行并回显updatedInput告诉运行时交互已收集从而跳过冗余对话框。分支 2Pilot spec 规划腿的退出经典场景判断条件是_is_spec_plan_leg这个ExitPlanMode必须属于一个在入口处就已登记归属的 Pilot 规划腿且对应计划文件可读、状态为已批准。满足则输出behavior: allow并在tool_input完整时回显updatedInput以抑制冗余对话框。关键设计计划归属是在EnterPlanMode触发时由plan_mode_tracker.py的record_plan_leg_owner提前写入的而不是在退出时靠当前会话状态反推——因为一个正在实施中、已批准的计划和一个等待退出的规划腿在退出瞬间的状态长得一模一样事后推断必然出错。分支 3其他一切情况 → 保持沉默原生的计划模式比如你手动按 ShiftTab 进入的、/buildBuildout 中出现的计划、兄弟会话的状态、任何读不出来的计划文件一律返回None。此时 hook 不打印任何输出Claude Code 自己的计划对话框照常出现——这永远是最安全的兜底。三、细节里的安全设计也是测试重点这个 hook 的测试文件 有 700 多行几乎每行注释都在讲一个真实踩过的坑值得新手借鉴放行消息从不宣称计划已批准。测试test_allow_message_does_not_claim_plan_approval强制要求消息里必须带有 NOT plan approval 的免责声明——早期版本输出过 Plan auto-approved 字样导致模型误以为用户批准了计划直接跳过了真正的审批环节updatedInput只在 Pilot 规划腿出现。这个字段会告诉运行时必需的交互已收集等于替用户点了确认一旦泄漏到原生计划模式就等于 hook 替用户批准了计划bypassPermissions 恢复只认正向证据。只有plan_mode_tracker在规划前明确记录了进入计划模式前就是 bypass 模式退出后才会挂上恢复标记marker并在下一次权限请求时回放setMode恢复没有证据就绝不动权限设置。恢复标记是单次消耗的且会话隔离防止一个会话的标记误伤兄弟会话见_restore_decision失败开放fail-open但开放的是沉默而非放行。辅助库缺失、计划文件解码失败、项目根路径不确定时hook 一律退回到原生对话框既不把用户困死在计划模式里也不替用户做决定。四、如何自己动手验证想深入理解建议按这条路径读源码都很短入口分发auto_approve_plan.py 的 main 函数只看ExitPlanMode/EnterPlanMode/ 其他三种分流状态登记plan_mode_tracker.py 中PreToolUse(EnterPlanMode)如何记录归属与前置权限模式审批语义12-approval.md 描述了/spec流程中人工审批与已预置原生计划路径的关系以及 spec-native-plan.md 这份自动模式下的交接 runbook行为契约通读 test_auto_approve_plan.py每个测试名就是一个安全不变量。五、小结auto_approve_plan展示了 hook 工程里一个非常克制的姿态它只做减法——在确认用户已经批准过的前提下移除模型切换流程中冗余的那一次ExitPlanMode确认并小心地维护会话的权限模式在所有模糊地带它选择闭嘴把决定权还给人和运行时。对于希望在自己的 Claude Code 工作流里做类似智能授权的同学这套入口登记归属 正向证据 失败沉默的三板斧比任何激进的全局放行都更值得抄作业。【免费下载链接】pilot-shellProfessional context and harness engineering for Claude Code and OpenAI Codex. Build production-grade software with spec-driven development, TDD, persistent memory, quality gates, code intelligence, human oversight, and end-to-end verification.项目地址: https://gitcode.com/GitHub_Trending/cl/pilot-shell创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进