Docs: update zh-CN translations and pipeline

What:
- update zh-CN glossary, TM, and translator prompt
- regenerate zh-CN docs and apply targeted fixes
- add zh-CN AGENTS pipeline guidance

Why:
- address terminology/spacing feedback from #6995

Tests:
- pnpm build && pnpm check && pnpm test
This commit is contained in:
Josh Palmer
2026-02-03 13:23:00 -08:00
parent 9f03791aa9
commit a3ec2d0734
228 changed files with 10651 additions and 10475 deletions
+168 -168
View File
@@ -5,7 +5,7 @@ read_when:
summary: Clawnet 重构:统一网络协议、角色、认证、审批、身份
title: Clawnet 重构
x-i18n:
generated_at: "2026-02-01T21:37:22Z"
generated_at: "2026-02-03T07:55:03Z"
model: claude-opus-4-5
provider: pi
source_hash: 719b219c3b326479658fe6101c80d5273fc56eb3baf50be8535e0d1d2bb7987f
@@ -15,48 +15,48 @@ x-i18n:
# Clawnet 重构(协议 + 认证统一)
## 你好
##
你好 Peter — 方向很;这将带来更简的用户体验更强的安全性。
Peter — 方向很;这将解锁更简的用户体验 + 更强的安全性。
## 目的
一份严谨的统一文档,涵盖
单一、严谨的文档用于
- 现状:协议、流程、信任边界。
- 当前状态:协议、流程、信任边界。
- 痛点:审批、多跳路由、UI 重复。
- 新方案:单一协议、作用域角色、统一认证/配对、TLS 固定。
- 身份模型:稳定 ID + 可爱别名。
- 迁移计划、风险、待解决问题。
- 提议的新状态:一个协议、作用域角色、统一认证/配对、TLS 固定。
- 身份模型:稳定 ID + 可爱别名。
- 迁移计划、风险、开放问题。
## 目标(来自讨论)
- 所有客户端(mac 应用、CLI、iOS、Android、无头节点)使用同一协议
- 每个网络参与者经过认证配对。
- 所有客户端使用一个协议mac 应用、CLI、iOS、Android、无头节点)。
- 每个网络参与者经过认证 + 配对。
- 角色清晰:节点 vs 操作者。
- 中审批路由到用户所在位置。
-审批路由到用户所在位置。
- 所有远程流量使用 TLS 加密 + 可选固定。
- 最小化代码重复。
- 单台机器只显示一次(不出现 UI/节点重复条目)。
- 单台机器应该只显示一次( UI/节点重复条目)。
## 非目标(明确声明
## 非目标(明确)
- 移除能力离(仍需最小权限)。
- 在无作用域检查的情况下暴露完整 Gateway网关控制平面。
- 认证依赖人类标签(别名仍非安全性要素)。
- 移除能力离(仍需最小权限)。
- 不经作用域检查暴露完整 Gateway 网关控制平面。
- 使认证依赖人类标签(别名仍然是非安全性)。
---
# 现状(当前状态)
# 当前状态(现状
## 两协议
## 两协议
### 1) Gateway网关 WebSocket(控制平面)
### 1) Gateway 网关 WebSocket(控制平面)
- 完整 API 接口:配置、渠道、模型、会话、智能体运行、日志、节点等。
- 默认绑定:local loopback。远程访问通过 SSH/Tailscale。
- 认证:通过 `connect` 使用令牌/密码。
- 无 TLS 固定(依赖 local loopback/隧道)。
- 完整 API 表面:配置、渠道、模型、会话、智能体运行、日志、节点等。
- 默认绑定:loopback。通过 SSH/Tailscale 远程访问
- 认证:通过 `connect` 令牌/密码。
- 无 TLS 固定(依赖 loopback/隧道)。
- 代码:
- `src/gateway/server/ws-connection/message-handler.ts`
- `src/gateway/client.ts`
@@ -64,88 +64,88 @@ x-i18n:
### 2) Bridge(节点传输)
-白名单接口,节点身份 + 配对。
- 基于 TCP 的 JSONL;可选 TLS + 证书指纹固定。
- TLS 在发现 TXT 记录中广播指纹。
-允许列表表面,节点身份 + 配对。
- TCP 的 JSONL;可选 TLS + 证书指纹固定。
- TLS 在设备发现 TXT 中公布指纹。
- 代码:
- `src/infra/bridge/server/connection.ts`
- `src/gateway/server-bridge.ts`
- `src/node-host/bridge-client.ts`
- `docs/gateway/bridge-protocol.md`
## 当前控制平面客户端
## 当前控制平面客户端
- CLI → 通过 `callGateway网关` 连接 Gateway网关 WS`src/gateway/call.ts`)。
- macOS 应用 UI → Gateway网关 WS`Gateway网关Connection`)。
- Web 控制 UI → Gateway网关 WS。
- ACP → Gateway网关 WS。
- 浏览器控制使用独立的 HTTP 控制服务器。
- CLI → 通过 `callGateway``src/gateway/call.ts`连接 Gateway 网关 WS
- macOS 应用 UI → Gateway 网关 WS`GatewayConnection`)。
- Web 控制 UI → Gateway 网关 WS。
- ACP → Gateway 网关 WS。
- 浏览器控制使用自己的 HTTP 控制服务器。
## 当前节点
## 当前节点
- macOS 应用在节点模式下连接 Gateway网关 bridge`MacNodeBridgeSession`)。
- iOS/Android 应用连接 Gateway网关 bridge。
- 配对 + 每节点令牌存储在 Gateway网关。
- macOS 应用在节点模式下连接 Gateway 网关 bridge`MacNodeBridgeSession`)。
- iOS/Android 应用连接 Gateway 网关 bridge。
- 配对 + 每节点令牌存储在 Gateway 网关
## 当前审批流程(执行
## 当前审批流程(exec
- 智能体通过 Gateway网关使用 `system.run`
- Gateway网关通过 bridge 调用节点。
- 智能体通过 Gateway 网关使用 `system.run`
- Gateway 网关通过 bridge 调用节点。
- 节点运行时决定审批。
- UI 提示 mac 应用显示(当节点 == mac 应用时)。
- 节点向 Gateway网关返回 `invoke-res`
- 多跳,UI 绑定节点主机
- UI 提示 mac 应用显示(当节点 == mac 应用时)。
- 节点向 Gateway 网关返回 `invoke-res`
- 多跳,UI 绑定节点主机。
## 当前在线状态 + 身份
## 当前在线状态 + 身份
- Gateway网关在线状态条目来自 WS 客户端
- 节点在线状态条目来自 bridge。
- 来自 WS 客户端的 Gateway 网关在线状态条目。
- 来自 bridge 的节点在线状态条目
- mac 应用可能为同一台机器显示两个条目(UI + 节点)。
- 节点身份存储在配对存储中;UI 身份独立存储
- 节点身份存储在配对存储中;UI 身份是分开的
---
# 问题 / 痛点
# 问题/痛点
- 需要维护两协议栈(WS + Bridge)。
- 远程节点的审批:提示出现在节点主机上,而用户所在位置。
- 需要维护两协议栈(WS + Bridge)。
- 远程节点的审批:提示出现在节点主机上,而不是用户所在位置。
- TLS 固定仅存在于 bridgeWS 依赖 SSH/Tailscale。
- 身份重复:同一台机器显示为多个实例。
- 角色模糊:UI + 节点 + CLI 能力未清晰分离。
- 角色模糊:UI + 节点 + CLI 能力没有明确分离。
---
# 新方案Clawnet
# 提议的新状态Clawnet
## 一协议,两角色
## 一协议,两角色
带角色 + 作用域的单一 WS 协议。
角色 + 作用域的单一 WS 协议。
- **角色:node**(能力宿主)
- **角色:operator**(控制平面)
- 操作者可选**作用域**
- 操作者可选**作用域**
- `operator.read`(状态 + 查看)
- `operator.write`(智能体运行、发送)
- `operator.admin`(配置、渠道、模型)
### 角色行为
**节点**
**Node**
- 可注册能力(`caps``commands`权限)。
- 可接收 `invoke` 命令(`system.run``camera.*``canvas.*``screen.record` 等)。
- 可发送事件:`voice.transcript``agent.request``chat.subscribe`
-注册能力(`caps``commands`permissions)。
-接收 `invoke` 命令(`system.run``camera.*``canvas.*``screen.record` 等)。
-发送事件:`voice.transcript``agent.request``chat.subscribe`
- 不能调用配置/模型/渠道/会话/智能体控制平面 API。
**操作者**
**Operator**
- 完整控制平面 API,受作用域限制。
- 接收所有审批请求
- 不直接执行 OS 操作;路由到节点执行
- 接收所有审批。
- 不直接执行 OS 操作;路由到节点。
### 关键规则
角色按连接划分,而非按设备划分。一个设备可以分别打开两角色。
角色按连接的,不是按设备。一个设备可以分别打开两角色。
---
@@ -155,49 +155,49 @@ x-i18n:
每个客户端提供:
- `deviceId`(稳定,从设备密钥派生)。
- `displayName`(人类可读名称)。
- `deviceId`(稳定,从设备密钥派生)。
- `displayName`(人类名称)。
- `role` + `scope` + `caps` + `commands`
## 配对流程(统一)
- 客户端未认证连接。
- Gateway网关为该 `deviceId` 创建**配对请求**。
- Gateway 网关为该 `deviceId` 创建**配对请求**。
- 操作者收到提示;批准/拒绝。
- Gateway网关发绑定以下信息的凭
- Gateway 网关发绑定以下内容的凭
- 设备公钥
- 角色
- 作用域
- 能力/命令
- 客户端持久化令牌,重新认证连接。
## 设备绑定认证(防止持有者令牌重放)
## 设备绑定认证(避免 bearer 令牌重放)
推荐方案:设备密钥对。
首选:设备密钥对。
- 设备一次性生成密钥对。
- `deviceId = fingerprint(publicKey)`
- Gateway网关发送 nonce;设备签名;Gateway网关验证。
- 令牌发给公钥(持有证明),而字符串。
- Gateway 网关发送 nonce;设备签名;Gateway 网关验证。
- 令牌发给公钥(所有权证明),而不是字符串。
替代方案:
- mTLS(客户端证书):最强,运维复杂度更高。
- 短期持有者令牌仅作为临时过渡(尽早轮换 + 撤销)。
- 短期 bearer 令牌仅作为临时阶段(早期轮换 + 撤销)。
## 静默批(SSH 启发式)
## 静默批SSH 启发式)
精确定义以避免薄弱环节。推荐以下方案之一:
精确定义以避免薄弱环节。优选其一:
- **仅限本地**:客户端通过 local loopback/Unix socket 连接时自动配对。
- **SSH 验证**Gateway网关发 nonce;客户端通过获取 nonce 证明 SSH 访问
- **物理存在窗口**:在 Gateway网关主机 UI 上进行本地审批后,在短时间窗口内(如 10 分钟)允许自动配对。
- **仅限本地**客户端通过 loopback/Unix socket 连接时自动配对。
- **通过 SSH 质询**Gateway 网关发 nonce;客户端通过获取它来证明 SSH。
- **物理存在窗口**:在 Gateway 网关主机 UI 上本地批准后,允许在短窗口内(如 10 分钟)自动配对。
始终记录自动审批日志
始终记录 + 记录自动批准
---
# 全面启用 TLS(开发 + 生产)
# TLS 无处不在(开发 + 生产)
## 复用现有 bridge TLS
@@ -206,50 +206,50 @@ x-i18n:
- `src/infra/bridge/server/tls.ts`
- `src/node-host/bridge-client.ts` 中的指纹验证逻辑
## 应用 WS
## 应用 WS
- WS 服务器使用相同证书/密钥 + 指纹支持 TLS。
- WS 客户端可固定指纹(可选)。
- 发现服务为所有端点广播 TLS + 指纹。
- 发现服务仅作为定位提示;绝不作为信任锚
- WS 服务器使用相同证书/密钥 + 指纹支持 TLS。
- WS 客户端可固定指纹(可选)。
- 设备发现为所有端点公布 TLS + 指纹。
- 设备发现仅是定位提示;永远不是信任锚。
## 原因
## 为什么
- 减少对 SSH/Tailscale 的机密性依赖。
- 使远程移动连接默认安全。
- 默认情况下使远程移动连接安全。
---
# 审批重新设计(集中化)
## 现状
## 当前
审批发生在节点主机上(mac 应用节点运行时)。提示出现在节点运行的位置
审批发生在节点主机上(mac 应用节点运行时)。提示出现在节点运行的地方
## 新方案
## 提议
审批 **Gateway网关托管**UI 推送到操作者客户端。
审批 **Gateway 网关托管**UI 传递给操作者客户端。
### 新流程
1. Gateway网关收 `system.run` 意图(智能体)。
2. Gateway网关创建审批记录:`approval.requested`
1. Gateway 网关`system.run` 意图(智能体)。
2. Gateway 网关创建审批记录:`approval.requested`
3. 操作者 UI 显示提示。
4. 审批决定发送到 Gateway网关:`approval.resolve`
5. 如果批准,Gateway网关调用节点命令。
4. 审批决定发送到 Gateway 网关:`approval.resolve`
5. 如果批准,Gateway 网关调用节点命令。
6. 节点执行,返回 `invoke-res`
### 审批语义(加固)
- 广播所有操作者;活跃 UI 显示模态框(其他显示通知提示)。
- 首个决定生效Gateway网关拒绝后续的重复决定
- 默认超时:N 秒后拒绝(如 60 秒),记录原因。
-需要 `operator.approvals` 作用域。
- 广播所有操作者;只有活跃 UI 显示模态框(其他显示 toast)。
- 先解决者获胜Gateway 网关拒绝后续解决为已结算
- 默认超时:N 秒后拒绝(如 60 秒),记录原因。
- 决需要 `operator.approvals` 作用域。
## 优势
## 好处
- 提示出现在用户所在位置(mac/手机)。
- 远程节点的审批行为一致。
- 远程节点的一致审批
- 节点运行时保持无头;无 UI 依赖。
---
@@ -258,20 +258,20 @@ x-i18n:
## iPhone 应用
- **节点角色**用于:麦克风、摄像头、语音聊天、位置、键通话。
- 可选 **operator.read** 用于状态和聊天查看
- 仅在明确启用时才有可选 **operator.write/admin**
- **Node 角色**用于:麦克风、相机、语音聊天、位置、键通话。
- 可选 **operator.read** 用于状态和聊天视图
- 可选 **operator.write/admin** 仅在明确启用时
## macOS 应用
- 默认为操作者角色(控制 UI)。
- 启用"Mac 节点"时为节点角色(system.run、屏幕、摄像头)。
- 两个连接使用相同 deviceId → 合并为一个 UI 条目。
- 默认是 Operator 角色(控制 UI)。
- 启用"Mac 节点"时是 Node 角色(system.run、屏幕、相机)。
- 两个连接使用相同 deviceId → 合并 UI 条目。
## CLI
- 始终为操作者角色。
- 作用域子命令决定
- 始终是 Operator 角色。
- 作用域子命令派生
- `status``logs` → read
- `agent``message` → write
- `config``channels` → admin
@@ -283,142 +283,142 @@ x-i18n:
## 稳定 ID
认证必需;永不改。
推荐方案
认证必需;永不改
首选
- 密钥对指纹(公钥哈希)。
## 可爱别名(龙虾主题)
作为人类标签。
仅人类标签。
- 示例:`scarlet-claw``saltwave``mantis-pinch`
- 存储在 Gateway网关注册表中,可编辑。
- 存储在 Gateway 网关注册表中,可编辑。
- 冲突处理:`-2``-3`
## UI 分组
相同 `deviceId` 跨角色 → 单个"实例"行:
跨角色的相同 `deviceId` → 单个"实例"行:
- 标记`operator``node`
- 显示能力 + 最后在线时间
- 徽章`operator``node`
- 显示能力 + 最后在线。
---
# 迁移策略
## 阶段 0文档 + 对齐
## 阶段 0记录 + 对齐
- 发布文档。
- 发布文档。
- 盘点所有协议调用 + 审批流程。
## 阶段 1 WS 添加角色/作用域
## 阶段 1 WS 添加角色/作用域
- 扩展 `connect` 参数,增加 `role``scope``deviceId`
-节点角色添加白名单控制。
- `role``scope``deviceId` 扩展 `connect` 参数
- node 角色添加允许列表限制。
## 阶段 2Bridge 兼容
## 阶段 2Bridge 兼容
- 保持 bridge 运行。
- 并行添加 WS 节点支持。
- 通过配置开关控制功能。
- 并行添加 WS node 支持。
- 通过配置标志限制功能。
## 阶段 3中审批
## 阶段 3:中审批
- 在 WS 中添加审批请求 + 决事件。
- 更新 mac 应用 UI 以显示提示和响应。
- 节点运行时停止 UI 提示
- 在 WS 中添加审批请求 + 决事件。
- 更新 mac 应用 UI 以提示 + 响应。
- 节点运行时停止提示 UI。
## 阶段 4TLS 统一
- 使用 bridge TLS 运行时为 WS 添加 TLS 配置。
- 客户端添加固定。
- 客户端添加固定。
## 阶段 5:弃用 bridge
- 将 iOS/Android/mac 节点迁移到 WS。
- bridge 作为回退;稳定后移除。
- bridge 作为后备;稳定后移除。
## 阶段 6:设备绑定认证
- 所有非本地连接要基于密钥的身份认证
- 所有非本地连接都需要基于密钥的身份。
- 添加撤销 + 轮换 UI。
---
# 安全说明
- 角色/白名单在 Gateway网关边界强制执行。
- 无操作者作用域的客户端无法获得"完整"API。
- 所有连接均需配对。
- TLS + 固定降低移动端中间人攻击风险。
- SSH 静默批是便利功能;仍记录可撤销。
- 发现服务绝不作为信任锚
- 能力声明由服务器按平台/类型的白名单验证。
- 角色/允许列表在 Gateway 网关边界强制执行。
- 没有客户端可以在没有 operator 作用域的情况下获得"完整"API。
- *所有*连接都需要配对。
- TLS + 固定减少移动设备的 MITM 风险。
- SSH 静默批是便利措施;仍记录 + 可撤销。
- 设备发现永远不是信任锚。
- 能力声明通过按平台/类型的服务器允许列表验证。
# 流式传输 + 大负载(节点媒体)
# 流式传输 + 大负载(节点媒体)
WS 控制平面适合小消息,但节点还需要处理
WS 控制平面对于小消息没问题,但节点还
- 摄像头片段
- 相机剪辑
- 屏幕录制
- 音频流
方案
选项
1. WS 二进制帧 + 分块 + 背压规则。
2. 独立流式端点(仍使用 TLS + 认证)。
3. 对媒体密集型命令保 bridge 更,最后迁移。
2. 单独的流式端点(仍然是 TLS + 认证)。
3.媒体密集型命令保 bridge 更长时间,最后迁移。
实现前选一个方案,避免分歧
实现前选一个以避免漂移
# 能力 + 命令策略
- 节点报告的 caps/commands 视为**声明**。
- Gateway网关执行平台的白名单
- 任何新命令需要操作者批或显式白名单变更
- 时间戳审计更。
- 节点报告的 caps/commands 视为**声明**。
- Gateway 网关强制执行平台允许列表
- 任何新命令需要操作者批或显式允许列表更改
- 时间戳审计更
# 审计 + 速率限制
- 记录:配对请求、批准/拒绝、令牌发/轮换/撤销。
- 对配对请求和审批提示进行速率限制。
- 记录:配对请求、批准/拒绝、令牌发/轮换/撤销。
- 速率限制配对垃圾和审批提示
# 协议规范
# 协议卫生
- 显式协议版本 + 错误码。
- 显式协议版本 + 错误码。
- 重连规则 + 心跳策略。
- 在线状态 TTL 和最后在线语义。
---
# 待解决问题
# 开放问题
1. 单设备运行两角色:令牌模型
- 建议每个角色使用独立令牌(节点 vs 操作者)。
- 相同 deviceId;不同作用域;更清晰的撤销。
1. 同时运行两角色的单个设备:令牌模型
- 建议每个角色单独的令牌(node vs operator)。
- 相同 deviceId;不同作用域;更清晰的撤销。
2. 操作者作用域粒度
- read/write/admin + 审批 + 配对(最小可行方案)。
-考虑功能划分作用域。
- read/write/admin + approvals + pairing(最小可行)。
- 后考虑功能作用域。
3. 令牌轮换 + 撤销用户体验
- 角色更时自动轮换。
3. 令牌轮换 + 撤销 UX
- 角色更时自动轮换。
- 按 deviceId + 角色撤销的 UI。
4. 发现服务
4. 设备发现
- 扩展当前 Bonjour TXT 以包含 WS TLS 指纹 + 角色提示。
- 仅作为定位提示。
- 仅作为定位提示处理
5. 跨网络审批
- 广播所有操作者客户端;活跃 UI 显示模态框。
- 首个响应生效Gateway网关保证原子性。
- 广播所有操作者客户端;活跃 UI 显示模态框。
- 先响应者获胜Gateway 网关强制原子性。
---
# 摘要(简述
# 总结(TL;DR
- 现状WS 控制平面 + Bridge 节点传输。
- 痛点:审批 + 重复 + 两套协议栈。
- 方案:带显式角色 + 作用域的单一 WS 协议,统一配对 + TLS 固定,Gateway网关托管审批,稳定设备 ID + 可爱别名。
- 果:更简洁的用户体验、更强的安全性更少的重复更好的移动路由。
- 当前WS 控制平面 + Bridge 节点传输。
- 痛点:审批 + 重复 + 两栈。
- 提议:一个带有显式角色 + 作用域的 WS 协议,统一配对 + TLS 固定,Gateway 网关托管审批,稳定设备 ID + 可爱别名。
- 果:更简单的 UX更强的安全性更少的重复更好的移动路由。
+102 -102
View File
@@ -1,12 +1,12 @@
---
read_when:
- 设计执行主机路由或执行审批
- 设计 exec 主机路由或 exec 批准
- 实现节点运行器 + UI IPC
- 添加执行主机安全模式和斜杠命令
summary: 重构计划:执行主机路由、节点批和无头运行器
title: 执行主机重构
- 添加 exec 主机安全模式和斜杠命令
summary: 重构计划:exec 主机路由、节点批和无头运行器
title: Exec 主机重构
x-i18n:
generated_at: "2026-02-01T21:36:56Z"
generated_at: "2026-02-03T07:54:43Z"
model: claude-opus-4-5
provider: pi
source_hash: 53a9059cbeb1f3f1dbb48c2b5345f88ca92372654fef26f8481e651609e45e3a
@@ -14,49 +14,49 @@ x-i18n:
workflow: 15
---
# 执行主机重构计划
# Exec 主机重构计划
## 目标
- 添加 `exec.host` + `exec.security` 以在 **sandbox**、**gateway** 和 **node** 之间路由执行。
- 保持默认**安全**:除非明确启用,否则不进行跨主机执行。
- 将执行拆分为**无头运行器服务**通过本地 IPC 提供可选 UImacOS 应用)。
- 提供**智能体**策略、允许列表、询问模式和节点绑定。
- 支持与允许列表*配合*或*不配合*使用的**询问模式**。
- 添加 `exec.host` + `exec.security` 以在**沙箱**、**Gateway 网关**和**节点**之间路由执行。
- 保持默认**安全**:除非明确启用,否则不进行跨主机执行。
- 将执行拆分为**无头运行器服务**,通过本地 IPC 连接可选 UImacOS 应用)。
- 提供**智能体**策略、允许列表、询问模式和节点绑定。
- 支持*与*或*不与*允许列表一起使用的**询问模式**。
- 跨平台:Unix socket + token 认证(macOS/Linux/Windows 一致性)。
## 非目标
- 不进行旧版允许列表迁移或旧版 schema 支持。
- 不为节点执行提供 PTY/流式输出(仅支持聚合输出)。
- 不在现有 Bridge + Gateway网关之外新增网络层。
- 无遗留允许列表迁移或遗留 schema 支持。
- 节点 exec 无 PTY/流式传输(仅聚合输出)。
- 现有 Bridge + Gateway 网关外无新网络层。
## 决(已锁定)
## 决(已锁定)
- **配置键:**`exec.host` + `exec.security`(允许智能体覆盖)。
- **提**保留 `/elevated` 作为 gateway 完全访问的别名。
- **询问默认**`on-miss`
- **批存储:**`~/.openclaw/exec-approvals.json`JSON不迁移旧版)。
- **运行器:**无头系统服务;UI 应用托管 Unix socket 用于批。
- **节点身份:**使用现有 `nodeId`
- **Socket 认证:**Unix socket + token(跨平台);后续需要时再拆分。
- **节点主机状态:**`~/.openclaw/node.json`(节点 ID + 配对 token)。
- **macOS 执行主机:**在 macOS 应用内运行 `system.run`;节点主机服务通过本地 IPC 转发请求。
- **不使用 XPC helper**坚持使用 Unix socket + token + 对检查。
- **配置键:** `exec.host` + `exec.security`(允许智能体覆盖)。
- **提** 保留 `/elevated` 作为 Gateway 网关完全访问的别名。
- **询问默认:** `on-miss`
- **批存储:** `~/.openclaw/exec-approvals.json`JSON无遗留迁移)。
- **运行器:** 无头系统服务;UI 应用托管 Unix socket 用于批
- **节点身份:** 使用现有 `nodeId`
- **Socket 认证:** Unix socket + token(跨平台);如需要稍后拆分。
- **节点主机状态:** `~/.openclaw/node.json`(节点 id + 配对 token)。
- **macOS exec 主机:** 在 macOS 应用内运行 `system.run`;节点主机服务通过本地 IPC 转发请求。
- ** XPC helper** 坚持使用 Unix socket + token + 对检查。
## 核心概念
## 关键概念
### 主机
- `sandbox`Docker 执行(当前行为)。
- `gateway`:在 gateway 主机上执行。
- `sandbox`Docker exec(当前行为)。
- `gateway`:在 Gateway 网关主机上执行。
- `node`:通过 Bridge 在节点运行器上执行(`system.run`)。
### 安全模式
- `deny`:始终阻止。
- `allowlist`:仅允许匹配项。
- `full`:允许所有(等同于提模式)。
- `full`:允许一切(等同于提模式)。
### 询问模式
@@ -64,30 +64,30 @@ x-i18n:
- `on-miss`:仅在允许列表不匹配时询问。
- `always`:每次都询问。
询问与允许列表**相互独立**;允许列表可与 `always``on-miss` 配合使用。
询问**独立**允许列表;允许列表可与 `always``on-miss` 一起使用。
### 策略解析(每次执行)
1. 解析 `exec.host`(工具参数 → 智能体覆盖 → 全局默认)。
1. 解析 `exec.host`(工具参数 → 智能体覆盖 → 全局默认)。
2. 解析 `exec.security``exec.ask`(相同优先级)。
3. 如果主机是 `sandbox`使用本地沙箱执行。
3. 如果主机是 `sandbox`继续本地沙箱执行。
4. 如果主机是 `gateway``node`,在该主机上应用安全 + 询问策略。
## 默认安全
- 默认 `exec.host = sandbox`
- `gateway``node` 默认 `exec.security = deny`
- 默认 `exec.ask = on-miss`(仅在安全策略允许时相关)。
- 如果未设置节点绑定,**智能体可以向任何节点**,但仅在策略允许时。
- 默认 `exec.ask = on-miss`(仅在安全允许时相关)。
- 如果未设置节点绑定,**智能体可以向任何节点**,但仅在策略允许时。
## 配置接口
## 配置表面
### 工具参数
- `exec.host`(可选):`sandbox | gateway | node`
- `exec.security`(可选):`deny | allowlist | full`
- `exec.ask`(可选):`off | on-miss | always`
- `exec.node`(可选):当 `host=node` 时使用的节点 ID/名称。
- `exec.node`(可选):当 `host=node` 时使用的节点 id/名称。
### 配置键(全局)
@@ -96,7 +96,7 @@ x-i18n:
- `tools.exec.ask`
- `tools.exec.node`(默认节点绑定)
### 配置键(智能体)
### 配置键(智能体)
- `agents.list[].tools.exec.host`
- `agents.list[].tools.exec.security`
@@ -106,17 +106,17 @@ x-i18n:
### 别名
- `/elevated on` = 为智能体会话设置 `tools.exec.host=gateway``tools.exec.security=full`
- `/elevated off` = 为智能体会话恢复之前的执行设置。
- `/elevated off` = 为智能体会话恢复之前的 exec 设置。
## 批存储(JSON
## 批存储(JSON
路径:`~/.openclaw/exec-approvals.json`
用途:
- **执行主机**gateway 或节点运行器)的本地策略 + 允许列表。
- **执行主机**Gateway 网关或节点运行器)的本地策略 + 允许列表。
- 无 UI 可用时的询问回退。
- UI 客户端的 IPC 凭
- UI 客户端的 IPC 凭
建议的 schemav1):
@@ -151,8 +151,8 @@ x-i18n:
注意事项:
- 不支持旧版允许列表格式。
- `askFallback` 仅在需要询问但无 UI 可达时生效
- 无遗留允许列表格式。
- `askFallback` 仅在需要 `ask` 且无法访问 UI 时应用
- 文件权限:`0600`
## 运行器服务(无头)
@@ -161,12 +161,12 @@ x-i18n:
- 在本地强制执行 `exec.security` + `exec.ask`
- 执行系统命令并返回输出。
- 发送 Bridge 事件用于执行生命周期(可选但建议启用)。
- 为 exec 生命周期发出 Bridge 事件(可选但推荐)。
### 服务生命周期
- macOS 上 Launchd/daemonLinux/Windows 上系统服务。
- 批 JSON 执行主机本地文件
- macOS 上 Launchd/daemonLinux/Windows 上系统服务。
- JSON 执行主机本地
- UI 托管本地 Unix socket;运行器按需连接。
## UI 集成(macOS 应用)
@@ -175,26 +175,26 @@ x-i18n:
- Unix socket 位于 `~/.openclaw/exec-approvals.sock`0600)。
- Token 存储在 `exec-approvals.json`0600)中。
-检查:仅限相同 UID。
- 质询/响应:nonce + HMAC(token, request-hash) 防止重放。
- 短 TTL(例如 10+ 最大负载 + 速率限制。
-检查:仅同 UID。
- 挑战/响应:nonce + HMAC(token, request-hash) 防止重放。
- 短 TTL(例如 10s+ 最大负载 + 速率限制。
### 询问流程(macOS 应用执行主机)
### 询问流程(macOS 应用 exec 主机)
1. 节点服务从 gateway 接收 `system.run`
2. 节点服务连接本地 socket 并发送提示/执行请求。
3. 应用验证对 + token + HMAC + TTL,然后在需要时显示对话框。
1. 节点服务从 Gateway 网关接收 `system.run`
2. 节点服务连接本地 socket 并发送提示/exec 请求。
3. 应用验证对 + token + HMAC + TTL,然后在需要时显示对话框。
4. 应用在 UI 上下文中执行命令并返回输出。
5. 节点服务将输出返回给 gateway。
5. 节点服务将输出返回给 Gateway 网关
如果 UI 不可用
如果 UI 缺失
- 应用 `askFallback``deny|allowlist|full`)。
### 图示(SCI
```
Agent -> Gateway网关 -> Bridge -> Node Service (TS)
Agent -> Gateway -> Bridge -> Node Service (TS)
| IPC (UDS + token + HMAC + TTL)
v
Mac App (UI + TCC + system.run)
@@ -202,122 +202,122 @@ Agent -> Gateway网关 -> Bridge -> Node Service (TS)
## 节点身份 + 绑定
- 使用 Bridge 配对中现有 `nodeId`
- 使用 Bridge 配对中现有 `nodeId`
- 绑定模型:
- `tools.exec.node` 将智能体限制特定节点。
- 如果未设置,智能体可以选择任何节点(策略仍强制执行默认值)。
- `tools.exec.node` 将智能体限制特定节点。
- 如果未设置,智能体可以选择任何节点(策略仍强制执行默认值)。
- 节点选择解析:
- `nodeId` 精确匹配
- `displayName`(规范化)
- `remoteIp`
- `nodeId` 前缀(>= 6 字符)
- `nodeId` 前缀(>= 6 字符)
## 事件
### 谁可以看到事件
### 谁看到事件
- 系统事件是**会话**的,在下一个提示时示给智能体。
- 存储在 gateway 内存队列中(`enqueueSystemEvent`)。
- 系统事件是**会话**的,在下一个提示时示给智能体。
- 存储在 Gateway 网关内存队列中(`enqueueSystemEvent`)。
### 事件文本
- `Exec started (node=<id>, id=<runId>)`
- `Exec finished (node=<id>, id=<runId>, code=<code>)` + 可选输出尾部
- `Exec finished (node=<id>, id=<runId>, code=<code>)` + 可选输出尾部
- `Exec denied (node=<id>, id=<runId>, <reason>)`
### 传输
方案 A(推荐):
选项 A(推荐):
- 运行器发送 Bridge `event``exec.started` / `exec.finished`
- Gateway网关 `handleBridgeEvent`映射 `enqueueSystemEvent`
- Gateway 网关 `handleBridgeEvent`这些映射 `enqueueSystemEvent`
方案 B
选项 B
- Gateway网关 `exec` 工具直接处理生命周期(仅同步)。
- Gateway 网关 `exec` 工具直接处理生命周期(仅同步)。
## 执行流程
## Exec 流程
### Sandbox 主机
### 沙箱主机
- 现有 `exec` 行为(Docker 或沙箱时的主机执行)。
- 现有 `exec` 行为(Docker 或沙箱时的主机)。
- 仅在非沙箱模式下支持 PTY。
### Gateway网关主机
### Gateway 网关主机
- Gateway网关进程在自身机器上执行。
- Gateway 网关进程在其自己的机器上执行。
- 强制执行本地 `exec-approvals.json`(安全/询问/允许列表)。
### Node 主机
### 节点主机
- Gateway网关通过 `node.invoke` 调用 `system.run`
- 运行器强制执行本地批。
- Gateway 网关调用 `node.invoke` 配合 `system.run`
- 运行器强制执行本地批
- 运行器返回聚合的 stdout/stderr。
- 可选的 Bridge 事件用于启动/完成/拒绝。
- 可选的 Bridge 事件用于开始/完成/拒绝。
## 输出限
## 输出
- stdout+stderr 合计上限为 **200k**;事件保留**尾部 20k**。
- 截断时添加明确后缀(例如 `"… (truncated)"`)。
- 组合 stdout+stderr 上限为 **200k**事件保留**尾部 20k**。
- 使用清晰的后缀截断(例如 `"… (truncated)"`)。
## 斜杠命令
- `/exec host=<sandbox|gateway|node> security=<deny|allowlist|full> ask=<off|on-miss|always> node=<id>`
- 智能体、会话覆盖;除非通过配置保存,否则持久
- `/elevated on|off|ask|full`作为 `host=gateway security=full` 的快捷方式(`full` 跳过批)。
- 智能体、会话覆盖;除非通过配置保存,否则持久。
- `/elevated on|off|ask|full`然是 `host=gateway security=full` 的快捷方式(`full` 跳过批)。
## 跨平台方案
- 运行器服务是可移植的执行目标。
- UI 是可选的;如果不可用,则应用 `askFallback`
- Windows/Linux 支持相同的批 JSON + socket 协议。
- UI 是可选的;如果缺失,应用 `askFallback`
- Windows/Linux 支持相同的批 JSON + socket 协议。
## 实阶段
## 实阶段
### 阶段 1:配置 + 执行路由
### 阶段 1:配置 + exec 路由
- 添加 `exec.host``exec.security``exec.ask``exec.node` 配置 schema。
- 更新工具管道以遵 `exec.host`
- `exec.host``exec.security``exec.ask``exec.node` 添加配置 schema。
- 更新工具管道以遵 `exec.host`
- 添加 `/exec` 斜杠命令并保留 `/elevated` 别名。
### 阶段 2批存储 + gateway 强制执行
### 阶段 2:批存储 + Gateway 网关强制执行
- 实现 `exec-approvals.json`器。
- 实现 `exec-approvals.json`取器/写入器。
-`gateway` 主机强制执行允许列表 + 询问模式。
- 添加输出限
- 添加输出限。
### 阶段 3:节点运行器强制执行
- 更新节点运行器以强制执行允许列表 + 询问。
- 添加 Unix socket 提示桥接到 macOS 应用 UI。
- `askFallback`
- `askFallback`
### 阶段 4:事件
- 添加节点 → gateway Bridge 事件用于执行生命周期
- 为 exec 生命周期添加节点 → Gateway 网关 Bridge 事件。
- 映射到 `enqueueSystemEvent` 用于智能体提示。
### 阶段 5UI 完善
- Mac 应用:允许列表编辑器、智能体切换器、询问策略 UI。
- Mac 应用:允许列表编辑器、智能体切换器、询问策略 UI。
- 节点绑定控制(可选)。
## 测试计划
- 单元测试:允许列表匹配(glob + 大小写不敏感)。
- 单元测试:允许列表匹配(glob + 不区分大小写)。
- 单元测试:策略解析优先级(工具参数 → 智能体覆盖 → 全局)。
- 集成测试:节点运行器拒绝/允许/询问流程。
- Bridge 事件测试:节点事件 → 系统事件路由。
## 未解决风险
## 开放风险
- UI 不可用:确保 `askFallback` 被正确执行
- 长时间运行的命令:依赖超时 + 输出限
- 多节点歧义:除非有节点绑定或明确的节点参数,否则报错。
- UI 不可用:确保遵守 `askFallback`
- 长时间运行的命令:依赖超时 + 输出限。
- 多节点歧义:除非有节点绑定或显式节点参数,否则报错。
## 相关文档
- [执行工具](/tools/exec)
- [执行](/tools/exec-approvals)
- [Exec 工具](/tools/exec)
- [执行批](/tools/exec-approvals)
- [节点](/nodes)
- [模式](/tools/elevated)
- [模式](/tools/elevated)
@@ -2,7 +2,7 @@
description: Track outbound session mirroring refactor notes, decisions, tests, and open items.
title: 出站会话镜像重构(Issue
x-i18n:
generated_at: "2026-02-01T21:36:30Z"
generated_at: "2026-02-03T07:53:51Z"
model: claude-opus-4-5
provider: pi
source_hash: b88a72f36f7b6d8a71fde9d014c0a87e9a8b8b0d449b67119cf3b6f414fa2b81
@@ -15,69 +15,69 @@ x-i18n:
## 状态
- 进行中。
- 核心 + 插件渠道路由已针对出站镜像进行更新。
- Gateway网关发送现在在省略 sessionKey 时自动推导目标会话。
- 核心 + 插件渠道路由已更新以支持出站镜像
- Gateway 网关发送现在在省略 sessionKey 时派生目标会话。
## 背景
出站发送过去被镜像到*当前*智能体会话(工具会话键)而目标渠道会话。入站路由使用渠道/对会话键,因此出站响应落入了错误的会话,首次联系的目标通常缺少会话条目。
出站发送被镜像到*当前*智能体会话(工具会话键)而不是目标渠道会话。入站路由使用渠道/对等方会话键,因此出站响应落错误的会话,首次联系的目标通常缺少会话条目。
## 目标
- 将出站消息镜像到目标渠道会话键。
- 在缺少会话条目时,于出站创建会话条目。
- 在缺失时为出站创建会话条目。
- 保持线程/话题作用域与入站会话键对齐。
- 盖核心渠道及捆绑扩展。
- 盖核心渠道加内置扩展。
## 实现摘要
-出站会话路由辅助模块
-出站会话路由辅助
- `src/infra/outbound/outbound-session.ts`
- `resolveOutboundSessionRoute` 使用 `buildAgentSessionKey`dmScope + identityLinks)构建目标 sessionKey。
- `ensureOutboundSessionEntry` 通过 `recordSessionMetaFromInbound` 写入最小`MsgContext`
- `runMessageAction`(发送)推导目标 sessionKey 并传递给 `executeSendAction` 用于镜像。
- `message-tool` 不再直接镜像;它从当前会话键解析 agentId。
- 插件发送路径使用推导的 sessionKey 通过 `appendAssistantMessageToSessionTranscript` 进行镜像。
- Gateway网关发送在未提供 sessionKey 时推导目标会话键(默认智能体),并确保会话条目存在
- `ensureOutboundSessionEntry` 通过 `recordSessionMetaFromInbound` 写入最小的 `MsgContext`
- `runMessageAction`(发送)派生目标 sessionKey 并将其传递给 `executeSendAction` 进行镜像。
- `message-tool` 不再直接镜像;它从当前会话键解析 agentId。
- 插件发送路径使用派生的 sessionKey 通过 `appendAssistantMessageToSessionTranscript` 进行镜像。
- Gateway 网关发送在未提供时派生目标会话键(默认智能体),并确保会话条目。
## 线程/话题处理
- SlackreplyTo/threadId -> `resolveThreadSessionKeys`(后缀)。
- DiscordthreadId/replyTo -> `resolveThreadSessionKeys``useSuffix=false` 以匹配入站(线程频道 ID 已限定会话作用域)。
- Telegram:话题 ID 通过 `buildTelegramGroupPeerId` 映射 `chatId:topic:<id>`
- DiscordthreadId/replyTo -> `resolveThreadSessionKeys``useSuffix=false` 以匹配入站(线程频道 id 已经作用域会话)。
- Telegram:话题 ID 通过 `buildTelegramGroupPeerId` 映射 `chatId:topic:<id>`
## 已覆盖的扩展
## 盖的扩展
- Matrix、MS Teams、Mattermost、BlueBubbles、Nextcloud Talk、Zalo、Zalo Personal、Nostr、Tlon。
- 注:
- Mattermost 目标现在为 私信 会话键路由去除 `@` 前缀
- Zalo Personal 对 1:1 目标使用 私信 对端类型(仅存在 `group:` 时使用群组)。
-
- Mattermost 目标现在为私信会话键路由去除 `@`
- Zalo Personal 对 1:1 目标使用私信对等方类型(仅存在 `group:`使用群组)。
- BlueBubbles 群组目标去除 `chat_*` 前缀以匹配入站会话键。
- Slack 自动线程镜像不区分频道 ID 大小写进行匹配
- Gateway网关发送在镜像前将提供的会话键转为小写。
- Slack 自动线程镜像不区分大小写地匹配频道 id
- Gateway 网关发送在镜像前将提供的会话键转为小写。
## 决策
- **Gateway网关发送会话推导**:如果提供了 `sessionKey`,则直接使用。如果省略,从目标 + 默认智能体推导 sessionKey 并镜像到该会话
- **会话条目创建**:始终使用 `recordSessionMetaFromInbound``Provider/From/To/ChatType/AccountId/Originating*` 与入站格式对齐。
- **目标规范化**:出站路由在可用时使用解析的目标(经过 `resolveChannelTarget` 处理后)。
- **会话键大小写**:在写入和迁移将会话键规范化为小写。
- **Gateway 网关发送会话派生**:如果提供了 `sessionKey`,则使用。如果省略,从目标 + 默认智能体派生 sessionKey 并镜像到那里
- **会话条目创建**:始终使用 `recordSessionMetaFromInbound``Provider/From/To/ChatType/AccountId/Originating*` 与入站格式对齐。
- **目标规范化**:出站路由在可用时使用解析的目标(`resolveChannelTarget` 后)。
- **会话键大小写**:在写入和迁移期间将会话键规范化为小写。
## 新增/更新的测试
## 添加/更新的测试
- `src/infra/outbound/outbound-session.test.ts`
- Slack 线程会话键。
- Telegram 话题会话键。
- 使用 Discord 的 dmScope identityLinks。
- dmScope identityLinks 与 Discord
- `src/agents/tools/message-tool.test.ts`
- 从会话键推导 agentId(不传递 sessionKey)。
- 从会话键派生 agentId(不传递 sessionKey)。
- `src/gateway/server-methods/send.test.ts`
- 省略时推导会话键并创建会话条目。
- 省略时派生会话键并创建会话条目。
## 待办事项 / 后续跟进
## 待处理项目 / 后续跟进
- 语音通话插件使用自定义 `voice:<phone>` 会话键。此处的出站映射尚未标准化;如果 message-tool 需要支持语音通话发送,添加显式映射。
- 确认是否有外部插件使用超出捆绑集合的非标准 `From/To` 格式。
- 语音通话插件使用自定义 `voice:<phone>` 会话键。出站映射在这里没有标准化;如果 message-tool 应该支持语音通话发送,添加显式映射。
- 确认是否有任何外部插件使用内置集之外的非标准 `From/To` 格式。
## 涉及的文件
@@ -86,7 +86,7 @@ x-i18n:
- `src/infra/outbound/message-action-runner.ts`
- `src/agents/tools/message-tool.ts`
- `src/gateway/server-methods/send.ts`
- 测试文件
- 测试:
- `src/infra/outbound/outbound-session.test.ts`
- `src/agents/tools/message-tool.test.ts`
- `src/gateway/server-methods/send.test.ts`
+36 -36
View File
@@ -1,12 +1,12 @@
---
read_when:
- 设计或实现配置验证行为
- 处理配置迁移或 doctor 工作流
- 处理插件配置 schema 或插件加载控制时
summary: 严格配置验证 + 仅通过 doctor 行迁移
- 设计或实现配置验证行为
- 处理配置迁移或 doctor 工作流
- 处理插件配置 schema 或插件加载
summary: 严格配置验证 + 仅通过 doctor 行迁移
title: 严格配置验证
x-i18n:
generated_at: "2026-02-01T21:36:38Z"
generated_at: "2026-02-03T10:08:51Z"
model: claude-opus-4-5
provider: pi
source_hash: 5bc7174a67d2234e763f21330d8fe3afebc23b2e5c728a04abcc648b453a91cc
@@ -14,28 +14,28 @@ x-i18n:
workflow: 15
---
# 严格配置验证(仅通过 doctor 行迁移)
# 严格配置验证(仅通过 doctor 行迁移)
## 目标
- **在所有层级(根级 + 嵌套级)拒绝未知配置键**
- **在所有地方拒绝未知配置键**(根级 + 嵌套)
- **拒绝没有 schema 的插件配置**;不加载该插件。
- **移除加载时的遗留自动迁移**;迁移仅通过 doctor 行。
- **启动时自动运行 doctordry-run 模式**;如果配置无效,阻止非诊断命令。
- **移除加载时的旧版自动迁移**;迁移仅通过 doctor 行。
- **启动时自动运行 doctor(dry-run)**;如果无效,阻止非诊断命令。
## 非目标
- 加载时的向后兼容性(遗留键不会自动迁移)。
- 静默丢弃识别的键。
- 加载时的向后兼容性(旧版键不会自动迁移)。
- 静默丢弃无法识别的键。
## 严格验证规则
- 配置必须在每个层级精确匹配 schema。
- 未知键是验证错误(根级嵌套级均不允许透传)。
- `plugins.entries.<id>.config` 必须由插件的 schema 进行验证。
- 如果插件缺少 schema,**拒绝插件加载**并显示明确的错误信息
- 未知键是验证错误(根级嵌套不允许透传)。
- `plugins.entries.<id>.config` 必须由插件的 schema 验证。
- 如果插件缺少 schema,**拒绝插件加载**并显示清晰的错误。
- 未知的 `channels.<id>` 键是错误,除非插件清单声明了该渠道 id。
- 所有插件都必须提供插件清单(`openclaw.plugin.json`)。
- 所有插件都需要插件清单(`openclaw.plugin.json`)。
## 插件 schema 强制执行
@@ -44,26 +44,26 @@ x-i18n:
1. 解析插件清单 + schema`openclaw.plugin.json`)。
2. 根据 schema 验证配置。
3. 如果缺少 schema 或配置无效:阻止插件加载,记录错误。
- 错误息包括:
- 错误息包括:
- 插件 id
- 原因(缺少 schema / 配置无效)
- 验证失败的路径
- 禁用的插件保留其配置,但 Doctor + 日志会显示警告。
- 禁用的插件保留其配置,但 Doctor + 日志会显示警告。
## Doctor 流程
- 每次加载配置时都会运行 Doctor(默认 dry-run 模式)。
- 每次加载配置时都会运行 Doctor(默认 dry-run)。
- 如果配置无效:
- 打印摘要 + 可操作的错误信息
- 示:`openclaw doctor --fix`
- 打印摘要 + 可操作的错误。
- 示:`openclaw doctor --fix`
- `openclaw doctor --fix`
- 应用迁移。
- 移除未知键。
- 写入更新后的配置。
## 命令控制(配置无效时)
## 命令门控(当配置无效时)
允许执行(仅诊断命令):
允许的命令(仅诊断):
- `openclaw doctor`
- `openclaw logs`
@@ -72,29 +72,29 @@ x-i18n:
- `openclaw status`
- `openclaw gateway status`
其他所有命令必须直接失败并示:"Config invalid. Run `openclaw doctor --fix`."
其他所有命令必须失败并示:"Config invalid. Run `openclaw doctor --fix`."
## 错误用户体验格式
- 单个摘要标题。
- 分组展示
- 分组部分
- 未知键(完整路径)
- 遗留键 / 需要迁移
- 旧版键/需要迁移
- 插件加载失败(插件 id + 原因 + 路径)
## 实现涉及的文件
## 实现接触点
- `src/config/zod-schema.ts`:移除根级 passthrough;所有对象使用 strict 模式
- `src/config/zod-schema.providers.ts`:确保渠道 schema 为 strict 模式
- `src/config/validation.ts`遇到未知键时失败;不应用遗留迁移。
- `src/config/io.ts`:移除遗留自动迁移;始终运行 doctor dry-run。
- `src/config/legacy*.ts`:将用法迁移到仅限 doctor 使用
- `src/plugins/*`:添加 schema 注册表 + 加载控制
- `src/cli` 中的 CLI 命令控
- `src/config/zod-schema.ts`:移除根级透传;所有地方使用严格对象
- `src/config/zod-schema.providers.ts`:确保严格的渠道 schema。
- `src/config/validation.ts`:未知键时失败;不应用旧版迁移。
- `src/config/io.ts`:移除旧版自动迁移;始终运行 doctor dry-run。
- `src/config/legacy*.ts`:将用法移至仅 doctor。
- `src/plugins/*`:添加 schema 注册表 + 门控
- `src/cli` 中的 CLI 命令控。
## 测试
- 未知键拒绝(根级 + 嵌套)。
- 插件缺少 schema → 插件加载被阻止并显示明确错误。
- 配置无效 → Gateway网关启动被阻止,诊断命令除外。
- 未知键拒绝(根级 + 嵌套)。
- 插件缺少 schema → 插件加载被阻止并显示清晰错误。
- 无效配置 → Gateway 网关启动被阻止,诊断命令除外。
- Doctor dry-run 自动运行;`doctor --fix` 写入修正后的配置。