#OpenClaw #Guardian #模型路由 #FailClosed

记录 OpenClaw、llama-server、路由 controller 与 GPU Guardian 之间的职责拆分、交接协议和真实恢复闭环。基础安装与 provider 配置见《OpenClaw 配置续集》,当前任务状态见《OpenClaw 后续功能规划》。

一、问题边界

desktop 的 RTX 5080 同时服务本地推理和桌面应用。OpenClaw 默认访问
192.168.2.10:11435 上的 llama-server,但游戏、图像生成和模型测评会占用显存。这里需要解决的不是简单的“进程启停”,而是:

  1. 停模型前先把 OpenClaw 切到允许的备用 provider,并排空在途请求;

  2. 恢复本地前确认端口、进程、模型身份和上下文参数均正确;

  3. 任一步失败都保持云端或停止继续动作,不能留下半切换状态;

  4. 人工关闭模型不能被 Guardian 擅自重新拉起。

二、组件职责

组件 唯一职责 明确禁止
Guardian 观察 GPU、冷却时间、所有权和维护窗 直接修改 OpenClaw 配置
Controller 切换默认、agent 和已有 session 的模型路由 启停未知模型或绕过排空
模型切换脚本 启停冻结清单中的 llama-server 在旧实例未停止时启动第二实例
OpenClaw 承载会话和工具调用 自行解释 Guardian 状态并执行系统命令

Controller 是模型路由的唯一所有者。Guardian 即使未来启用真实动作,也只能通过冻结的交接接口发出请求。

三、三阶段交接协议

阶段 成功条件 失败处理
PrepareStop 备用路由生效,活动 run、队列和待发送回复连续为空 保持本地模型,不授权停止
PrepareStart OpenClaw 仍处于安全备用路由 不启动模型
RestoreLocal /health、实际 GGUF、单实例和端口均通过 继续保持备用路由

OpenClaw 本地模型调用与云端回退流程

PrepareStop、PrepareStart 与 RestoreLocal 交接时序

排空不能只检查一次。controller 会核对活动 agent run、后台任务、cron、待发送消息和
session 状态;任何超时或不确定结果都拒绝进入下一阶段。

四、实现中的关键修复

1. Windows 到 N100 的 stdin 挂起

早期实现把 JSON 经 stdin 交给远端 CLI,PowerShell 等待子进程时可能无限挂起。正式脚本改用独立 SSH 进程、固定编码 payload、连接超时和进程硬上限;超时后终止子进程,并且不会继续执行停模型动作。

2. PowerShell 5.1 返回值差异

Windows PowerShell 5.1 与 pwsh 对外部进程属性和 JSON 对象的行为不同。正式覆盖前完成
PS5.1 parser、mock 成功链、本地不健康链和排空超时链验证。

3. Agent 模型配置形态

新增 mail-summary 后,模型配置同时存在字符串和 {primary} 两种形态。controller
只增加这两种已知结构的兼容,不接受任意嵌套对象;未知形态继续 fail closed。

4. 会话规模导致单命令超时

切换十余个 session 可能超过单条远程命令的默认预算。正确方向是为 controller 的受控单命令建立与会话规模相关的预算和固定 harness,而不是增大 OpenClaw 全局超时。

五、真实闭环结果

受控窗口已经完成:

1
2
3
4
5
6
切换备用路由
→ 排空请求
→ 停止 llama-server 释放显存
→ SYSTEM 任务加载正式 UD IQ3_S
→ 核对 11435、单实例、模型身份
→ RestoreLocal

最终状态为 LocalRestored,OpenClaw healthy,正式模型和上下文参数一致。两份正式
controller 脚本均在受限备份后覆盖,哈希与冻结候选一致。

这不等于 Guardian 已进入生产自动模式。当前仍为:

  • dryRun=true;

  • 无 -EnableActions;

  • 旧自动动作任务 Disabled;

  • 人工或外部停止记为 ManualOrExternalStop。

2026-08-11:正式 Windows dry-run 复核

在不加载模型、不访问 11435 的条件下,使用 SHA 固定的 PowerShell 矩阵重新验证了SensorUnknown、maintenance 抑制与去重、生产 PID 排除、临时 SYSTEM ownership、
ACL 和异常清理。两项矩阵均通过,测试任务、pwsh 进程、目录、marker、ownership 与相关监听在结束后全部清零。

计划任务历史中的 0xC000013A 对应外部终止语义;同时间窗 Guardian 日志只记录dryRun=True、EnableActions=False 和“没有 Guardian ownership 就拒绝启动”,没有真实动作或 handoff。该结果证明 fail-closed 与人工停机保护按设计生效,但不授权把
Guardian 切换为真实动作模式,也不等同于生产自动化已启用。

2026-08-31:实际采样链与未知进程门禁收口

后续复核把测试从独立决策模型推进到实际 Guardian 候选函数。测试通过结构化边界模拟nvidia-smi、CIM 和签名查询,实际执行候选的 GPU snapshot、身份分类与决策链:

  • 进程必须同时匹配名称、完整路径、进程签名和签名指纹;配置了 launcher 时,父进程的名称、路径、签名和指纹也必须匹配;

  • pmon 报告的每个 PID 都先保留为记录,即使 CIM、路径或签名解析失败也分类为
    Unknown,不能从采样集合中静默消失;

  • 批准进程与 Unknown 并发高负载时严格 NoAction;pmon 自身失败则整个样本归一为SensorUnknown;

  • maintenance、人工/外部停机 ownership、连续样本和 cooldown 仍保持原有 fail-closed
    语义。

验证窗口中,用户手动关闭的生产模型只通过既有 SYSTEM 计划任务恢复一次。恢复后保持单实例、唯一 11435、正式 UD 模型和 49,152 context;OpenClaw 的容器身份、健康、重启计数和 drain 状态前后不变。测试 staging、临时任务、进程和端口最终全部清零,三轮独立只读审核最终为 P0/P1/P2=0。

这次通过的是 staging 候选的无动作阶段。候选没有覆盖生产 Guardian,生产仍是
dryRun=true 且没有 EnableActions;production shadow、身份清单落地和真实动作继续需要独立授权。

2026-09-03:TimeTrigger 注册规范化合同

真实 canary 在 Task Scheduler 注册后曾出现非 Action 语义哈希漂移。由于当时没有保留完整注册后 XML,无法证明差异是系统默认补全还是安全字段变化,因此在 /Run 前停止,没有启动任务、测试进程或模型动作。

后续使用三个全新、同形的 TimeTrigger registration-only 随机任务建立证据合同。每个对象都严格按“注册 → 保存完整 XML、结构/安全投影与 ACL → 比较 → 删除”的顺序串行执行,任一时刻最多存在一个对象,三个对象均从未运行且最终计数为零。

采集期使用旧合同得到的失败比较被原样保留为墓碑;三样本完成后,才用最终冻结的规范化器对同一批原始 XML 重算。最终合同只归约三次一致、可证明由系统派生的 URI、空节点表示和 Settings 默认值/顺序差异。Action、Principal、RunLevel、Trigger 时间、
ACL、重复节点和未知字段仍严格 fail closed。PowerShell 5.1/7 双运行时的 normalized 与
security projection 哈希一致,独立只读终审为 P0/P1/P2=0。

这证明可以安全解释该类注册派生差异,但不等于 Guardian 已获生产动作权限。新的最终
canary 必须使用全新 generation、重新冻结现场身份和证据,并取得单独授权;旧任务、旧账本和旧动作预算均不得复用。

2026-09-07:外部 canary supervisor 与新 generation 就绪

第一次 production generation 在 canary 启动前暴露了一个失败路径缺口:canary 自己负责执行动作时,如果在停模后遇到采样、超时或结果写入异常,只能记录失败,无法保证路由、模型和计划任务都恢复到明确状态。该 generation 因此在实际 canary 动作前撤回,旧任务恢复为 Disabled/Enabled 的原始组合并保持不运行,旧文件只作为证据保留。

新的设计把运行与收容拆成两个主体。canary 只产生结果;外部 supervisor 持有独立的持久 journal,并按固定顺序恢复:

1
2
3
4
PrepareStart
→ 必要时启动唯一正式 llama-server
→ RestoreLocal
→ 恢复原计划任务并删除临时任务

canary 和每个恢复动作在执行前都先写入 INTENT,各自预算最多一次。进程重启后只在固定结果文件或完整可观察效果与原意图一致时采用既有动作;没有证据、只完成一部分、顺序错误、任务参数或 ACL 漂移都会进入 CONTAINMENT_UNPROVEN,不会重发动作。

安装、arming、canary 和 acceptance 也分成独立事务。安装只部署 generation-bound
payload、注册未运行的 canary,并保持正式 Guardian Disabled;arming 在安装 transaction
哈希确定后注册 supervisor,仍不运行;唯一的 supervisor 启动才拥有唯一 canary start。
acceptance 只接受 CANARY_ACCEPTED,不会把“失败但已安全收容”的 CONTAINED 当成成功。

当前候选已冻结《三角洲行动》主进程、WeGame 祖先、背景 GPU owner 与唯一 GPU LUID,完整工具链通过 Windows PowerShell 5.1、PowerShell 7 和独立安全复核。新 generation
OC55-20260907-d8ced4f8 目前只存在于 Mac 和 desktop staging;生产目录、canary 与
supervisor 任务均不存在,安装、运行、路由和模型动作计数仍为零。

下一步不是复用这次退出信号,而是等待用户再次通过 WeGame 进入稳定高 GPU 场景。收到新的 ready 信号后,先做同一窗口的 desktop/N100 只读门,再为 install-only、arming、
canary 和 acceptance 分别冻结动态哈希与一次性授权。

2026-09-14:Route A 回滚闭合与新代际

后续验证已把固定进程白名单收敛为“受控应用配置档 + 运行时身份绑定”:配置档负责限定签名发布者、安装根、可执行模式和启动器祖先,每次运行再动态绑定 PID、创建时间、文件身份与签名。GPU 使用率只作为遥测和排序信号,不再单独决定是否停模。

Route A G2 曾在有界 ACL 目录完成生产交付,但 Windows PowerShell 5.1 的回执构造失败,因此没有继续进入动作链,而是按既定路径完成回滚。只读恢复检查随后经历了多轮采集器兼容修正;最终 V10 直接依据实际对象计数闭合投影,证明保留对象、缺失对象、ACL、租约、账本和回滚终态一致,且检查过程没有新增副作用。G2 已永久冻结,相关租约已经释放。

新的 G3 已在 staging 中完成修复与独立审核,P0/P1/P2 均为 0;当前明确停在新的生产
generation 用户授权门。Guardian 仍未正式启用生产动作,不能复用 G2 的动作预算,也不能把“已安全回滚”或“staging 审核通过”误记成“生产 canary 通过”。

2026-09-23:恢复本地路由并重建 G7 预像

G7 执行前发现冻结预像已不再代表生产现场:OpenClaw 已经历容器与配置更新,controller
保存的历史快照含 31 个会话,而当前会话集合只有 28 个。旧实现会把三个已自然消失的历史会话视为恢复失败;直接重放旧 G7 或强行补造会话都不安全。

本轮只修复这一项确定性兼容问题:恢复时仅校验仍存在的会话,不重新创建已缺席的历史会话,也不放宽默认路由、agent override 或显式 session override 的检查。候选经过原
reviewer 独立审核后,执行了一次 controller 单文件安装和一次 RestoreLocal。终态为:

  • controller 回到 LocalRestored;

  • 默认路由、5 个 agent 与当前 28 个会话均恢复到既定本地模型;

  • 缺席的 3 个历史会话没有被重建;

  • llama-server 保持单实例、唯一 11435、正确模型与上下文参数;

  • OpenClaw 保持原容器健康、restart=0、drain=0;

  • 安装回滚与云端收容均未触发,两项临时资源租约已经释放。

这次闭合的是 G7 前置恢复链,不是最终 canary。安装和 RestoreLocal 的动作预算已经消耗,禁止重放。下一步必须基于当前 LocalRestored 现场重新生成本地预像、完成同一
reviewer 的有界复审并取得 fresh 资源窗口,才允许进入 G7 的单次隔离 canary。

六、近期手动 GPU 模式

近期 GPU 会被游戏占用,llama-server 由用户手动关闭。此时:

  • Guardian 不自动拉起模型;

  • 健康检查应把它识别为计划停机,而不是 Guardian 故障;

  • OpenClaw 是否使用云端 fallback 由独立的错误与隐私矩阵决定;

  • 邮件、照片、文件和家庭内部状态不得因本地模型离线而自动上云。

后续 OC-25 会补齐 compaction、session drain、错误分类和 fallback 矩阵。在此之前,不要把“本地端口不可达”简化为“所有请求均可安全转云”。

七、回滚与验收原则

每次变更前备份正式脚本和活动配置,恢复时至少核对:

  • llama-server 仅有一个正式实例;

  • 11435 listener 的进程和模型身份正确;

  • /health 与 /v1/models 一致;

  • OpenClaw defaults、agent 和 session 路由恢复;

  • cron、Guardian ownership 与 maintenance marker 无残留。

完整的工具审批边界见《OpenClaw Exec 审批与生命周期治理》。