1. 给任务无人值守时间之前,先定义成功
“修好这个仓库”还不够具体。一个适合无人值守的任务,应写明输入版本、允许访问的目录、可用工具、预期工件、最长运行时间,以及需要人工判断的条件。例如,文档任务只读取提供的差异,把报告写入输出目录,不使用网络工具,也不修改源文件。这样,独立检查器才有明确标准可以核对。
把三个结果分开:运行器启动了,Claude 返回了结果,要求的工作通过了验收。进程可能正常启动,随后拒绝调用某个工具;也可能返回流畅的 JSON,却没有修改文件;甚至可能完成有用工作,但子进程仍在运行。将这些情况全部压成一个绿色状态,会让故障难以解释,也会使后续自动化误把半成品发布出去。
下面的方案面向自己控制的运行器和一次性数据,不能证明你安装的版本、凭据或公司策略已经产生相同效果。测试前记录版本和有效配置,先选择无害、可恢复的工作量,并保留上一版启动配置。回退应当是能够执行的动作,而不是出问题后再寻找旧文件。
2. 10 月 30 日和 31 日具体改变了什么
| 官方版本 | 相关更新 | 对应验收 |
|---|---|---|
| v2.1.314,10 月 30 日 | 三个文件工具的写入限制;修正 print 模式启动失败的状态。 | 分别测试越界写入拒绝和启动失败。 |
| v2.1.314 | ultrareview、remote-control 的 CI 信任处理修复。 | 不能把这项承诺扩展到所有无头调用。 |
| v2.1.316,10 月 31 日 | 自行退出后的 Shell 命令清理;restricted 模式目录外上传修正。 | 在计划部署的主机上复测生命周期和文件边界。 |
官方 GitHub 元数据显示,v2.1.314 发布时间为 10 月 30 日 01:06:26 UTC,v2.1.316 为 10 月 31 日 01:01:35 UTC,分别对应新加坡时间 09:06:26 和 09:01:35。本次研究访问的官方 latest-release 接口仍指向 v2.1.316。这是发布时刻,并不能说明每台设备都已更新或每个分发渠道都相同。
这些更新的价值,是让运行器与代理之间的约定更清晰。官方修复可以变成回归用例,不能当成相关故障从此不可能发生的证明。较早背景也要标清日期:后文的 MCP 重试和 safety_event 来自 10 月 21 日 UTC 的版本,并非 11 月新发布的功能。
3. 文件工具、命令和外部服务要分开画边界
至少有四条执行通道:内置文件工具、Shell 命令及子进程、本机启动的集成进程,以及远程服务。工作目录规则可能限制第一条,却不限制 Python 测试进程或 MCP 数据库操作。仓库 worktree 用于分开 Git 工作,不自动为从中启动的所有进程建立操作系统隔离。
沙箱文档明确把 Shell 隔离与文件工具、网页工具、本地 MCP 服务、hooks 和辅助命令区分开。远程工具甚至可能在另一台机器上执行。配置权限前,先列一张小清单:谁真正写文件,使用什么凭据,哪一个组件能够停止它。只记录模型看到的工具名,容易漏掉工具后面的真实执行者。
报告类任务若根本不需要执行能力,减少一条不必要的执行通道,通常比开放后再配置大量例外容易验证。这是一种架构选择,不代表工具少就能信任全部输入。任务配置中应分别记录工具清单、权限规则和运行时隔离,才能解释每层控制实际负责什么。
4. 使用新的写入边界,但不要补写尚缺的文档
发布说明点名 permissions.blockWritesOutsideWorkingDirectories,表示 Write、Edit、NotebookEdit 在每种权限模式下都拒绝工作目录外的路径。这对列出的工具是有意义的约束,但不能证明任意命令、远程服务或会话中所有信息输出方式都被限制。
本次查阅的官方设置参考没有提供新键的独立条目。因此,本文不提供猜测的完整配置、默认值、远程转发规则或附加目录边缘行为。应在部署版本上检查该设置是否被接受,再验证真实拒绝结果,然后决定是否依赖它。一个被静默忽略的键,可能比没有设置更容易造成误判。
还要区分工具名与路径规则语法。权限参考说明,针对路径的编辑规则使用 Edit(path);带路径的 Write(path)、NotebookEdit(path) 不参与文件权限匹配。检查解析后的规则及其来源,用临时夹具分别测试内部路径、相邻路径和显式添加的目录,不要拿真实用户目录文件做探针。
5. 检查 Shell 隔离、不可用处理和回退
Shell 验收必须覆盖子进程,不能只测试一次 Edit。已允许的构建命令可能运行脚本,间接打开其他文件;文件规则文档已经指出这种范围限制。运行期间约束子进程的是操作系统边界。内置沙箱支持 macOS、Linux、WSL2;原生 Windows 不会因为 JSON 中出现同一个设置,就获得相同隔离。
在受支持的一次性运行器中,官方组织沙箱示例组合了以下配置。这里仅展示供审阅的结构,没有安装或执行:
{"sandbox":{"enabled":true,"failIfUnavailable":true,"allowUnsandboxedCommands":false}}这些选项分别处理沙箱不可用和脱离沙箱重试,不会覆盖所有排除命令或 Shell 沙箱外的进程。默认读取范围仍可触达机器上的大量内容,包括凭据,所以除了写入,也要检查读取和继承环境。若整个工具链都需要隔离,应把整个进程放入配置恰当的独立运行环境,并检查挂载和网络路径。
用 /sandbox 查看有效配置,让代理通过工具执行无害夹具探针;通常在 ! 提示中手动输入命令,可能走的是另一个未隔离路径。macOS 上一次通过,不等于缺少依赖的 WSL 镜像也通过。操作系统、安装方式和可用依赖应成为验收记录的一部分。
6. 明确无头运行能够发现和加载什么
Print 模式是一种执行接口,不是自动信任边界。普通 claude -p 没有工作区信任对话框,仍可能发现项目 hooks 和 MCP 配置。10 月 30 日对 ultrareview、remote-control 的 CI 修复,不能套用到这条不同路径。执行第三方仓库之前,要先检查仓库能提供哪些代码和设置。
--bare 减少定制内容的自动发现,但不提供操作系统隔离,文档也列出例外及设置来源之间的关系。对 Anthropic API,bare 模式使用 API 凭据,而不是订阅登录。因此,认证和计费路径都应是显式部署决定;文中没有发起任何模型请求。
CLI 参考区分了预先批准匹配调用的 --allowedTools,以及限制内置工具可用性的 --tools;后者不会移除 MCP 工具。把 --setting-sources、显式设置和 MCP 清单一起审查。组织要强制执行时,检查受管设置,不要假定本地参数能覆盖策略。启动器与审阅过的配置应放进同一版本包。
7. MCP 清单、凭据和重复调用分别验证
一个 MCP 连接是一项独立能力。列出每个服务、传输方式、允许工具和可执行的业务动作。本地服务可能拥有主机权限,远程服务可能持有 Claude 从未见过的凭据。应限制服务自己的权限与任务范围,不能把代理侧的文件规则当作数据库或工单系统策略。
MCP 参考说明,挂起的 HTTP 调用遇到连接中断时,声明为只读或幂等的工具可以重试一次。较早的 v2.1.307 将这项重试修正定在 10 月 21 日 UTC。声明不是重复支付、发消息或创建资源安全的证明;服务需要真正实现并验证重复行为,适合时使用操作标识来核对。
验收采用本地模拟服务和日志,观察故意中断响应后的调用次数及最终状态。重试成功不证明“恰好执行一次”。不要把真实客户工作流当测试夹具,也不要把凭据写进模拟日志。认证过期测试应使用可丢弃测试凭据,而不是打断生产登录。
8. 让退出码、JSON 和实际工件相互对应
启动失败修正,让原本误导人的结果更容易识别。包装脚本仍应分别记录退出码、stdout、stderr、运行时间和任务标识。退出码为零,是进程结果的一项证据,并不能独立证明要求的仓库改动正确。把启动、执行和验收分开,就能避免传输成功掩盖任务失败。
结构化输出支持 JSON 和指定 Schema。消费结果前先检查 structured_output 是否存在,文档指出运行可能在没有该字段时结束。Schema 校验关注形状,不能证明引用的文件存在、测试确实执行,或宣称的业务状态已经提交。
给独立检查器预期工件路径和确定性条件。报告任务可以要求 UTF-8 文件包含已知夹具引用,代码任务则需要适合自身的验收。比较改动与允许文件集合,拒绝意外修改;将动作被拒绝与网络失败分开记录。保留代理解释,但不要让解释替代工件本身的检查。
9. 限制运行时间,并验证取消后的清理
在模型循环外设置运行器截止时间,规定如何请求退出、等待多久,以及如何只识别属于该任务的进程。超时应是任务终态,不是让同一工作无限继续的理由。不要按宽泛进程名杀掉无关程序,也不要用“主进程退出”替代对后台执行的观察。
10 月 31 日的清理修正针对 Claude Code 在 macOS、Linux 自行退出时遗留的 Shell 命令,不能证明所有脱离父进程的后代都结束,或远程 MCP 已提交的工作都取消。这两种情况都要独立观察并记录其范围。
在临时夹具中,让子进程只向夹具内写心跳;取消后确认心跳停止、任务所属进程结束。远程异步任务使用模拟服务,再核对最终状态。若集成不支持取消,就记录限制并选择能够承受其副作用的工作。未完成工件应标明失败,防止下游当作成品发布。
10. 收集能解释拒绝的证据,不必收集全部内容
记录任务、版本、配置修订、解析后的工作区、允许工具、运行结果与检查器结果。这些信息帮助区分“边界成功阻止了操作”“模型没有尝试”和“收集器丢失事件”。拒绝日志只有关联到尝试的操作和独立结果状态,才有助于判断。
Claude Code 的监控参考列出 v2.1.307 起的 claude_code.safety_event,也列出不会产生该事件的调用。事件自身字段避免原始命令和路径细节,但通用属性仍可能包含工作区信息,可选工具详情日志还会增加内容。因此不能把整个数据流称作匿名,也不能假定每次拒绝都一定有对应事件。
先用最少元数据和一小组人工构造的夹具事件,保护收集器地址与保留策略。先证明日志能够到达,再解释某事件为何缺失。这里的 CLI 工具决策证据与 API 费用分析不同,用来解释执行边界,不用于对账,也不能证明全部外部副作用。
11. 在一次性夹具中运行验收矩阵
新建临时父目录,包含 workspace/、sibling/、results/。在 sibling 放无害哨兵文本并记录哈希。所有测试目标都留在这个父目录内,不换成真实凭据、用户文件或客户系统。下面是我们的建议方案,并未为本文实际执行。
| 用例 | 无害操作 | 必须观察到什么 |
|---|---|---|
| 文件工具边界 | 在 workspace 写文件,再尝试更改相邻哨兵。 | 允许工件出现;被拒绝目标的哈希不变。 |
| Shell 子进程 | 小型夹具脚本尝试相同的相邻写入。 | 计划的 Shell 边界阻止写入;不能沿用文件工具测试作证明。 |
| 附加目录 | 显式添加可丢弃目录并操作其中路径。 | 解析出的访问范围符合审阅意图;未知行为停止上线。 |
| 沙箱不可用 | 使用缺少必需依赖的一次性运行器。 | 必需隔离无法建立时启动失败,而非静默回退。 |
| 启动与输出 | 构造本地启动失败,再执行已知有效夹具任务。 | 失败退出非零;成功仍通过 JSON 和工件检查。 |
| MCP 中断 | 本地模拟记录只读、幂等及其他操作。 | 调用计数和最终状态能够解释重复,不产生真实副作用。 |
| 超时 | 取消夹具所属的短时心跳进程。 | 退出等待期后没有继续心跳或任务所属进程。 |
| 证据链路 | 构造一次已知拒绝和一次允许操作。 | 运行器记录、可用遥测和检查器状态能够对应。 |
负向用例与成功路径同样认真执行,保留前后哈希、启动参数和策略来源。每个变体使用新夹具;已经放宽过的工作区可能掩盖过大的附加目录权限,产生看似通过的结果。记录预期、实际与差异,才知道下一步应修改配置还是修复任务本身。
12. 发布配置包,再逐步扩大工作量
把 CLI 版本、启动器、模型选择、设置来源、受管策略预期、MCP 清单、超时规则和检查器打成一组,赋予修订号和回退目标。只升级依赖、没有同步配置,可能重新引入自动发现,或改变包装脚本对失败的解释。回退也应恢复整组约定。
先运行报告类或同样可恢复的任务。在每个目标系统环境通过必需夹具用例后,再观察有限真实工作量。提前定义停止条件:目录外工件发生变化、无法解释的进程仍存活、非幂等动作重复,或必需配置无法确认。不要在异常发生后才临时决定是否继续。
剩余未知项应成为上线门槛:新写入键缺失的参考细节、主机差异、远程任务取消和遥测完整性。官方发布说明证明更新存在;你的记录只证明所测试配置与工作量的结果。分享结论时保留这个范围,并在 CLI、启动器、策略或集成升级后重跑相关用例。