跳转到内容

Clawnet 重构

嗨 Peter — 方向很好;这将解锁更简单的用户体验 + 更强的安全性。

单一、严谨的文档用于:

  • 当前状态:协议、流程、信任边界。
  • 痛点:审批、多跳路由、UI 重复。
  • 提议的新状态:一个协议、作用域角色、统一的认证/配对、TLS 固定。
  • 身份模型:稳定 ID + 可爱的别名。
  • 迁移计划、风险、开放问题。
  • 所有客户端使用一个协议(mac 应用、CLI、iOS、Android、无头节点)。
  • 每个网络参与者都经过认证 + 配对。
  • 角色清晰:节点 vs 操作者。
  • 中央审批路由到用户所在位置。
  • 所有远程流量使用 TLS 加密 + 可选固定。
  • 最小化代码重复。
  • 单台机器应该只显示一次(无 UI/节点重复条目)。
  • 移除能力分离(仍需要最小权限)。
  • 不经作用域检查就暴露完整的 Gateway 网关控制平面。
  • 使认证依赖于人类标签(别名仍然是非安全性的)。

1) Gateway 网关 WebSocket(控制平面)

Section titled “1) Gateway 网关 WebSocket(控制平面)”
  • 完整 API 表面:配置、渠道、模型、会话、智能体运行、日志、节点等。
  • 默认绑定:loopback。通过 SSH/Tailscale 远程访问。
  • 认证:通过 connect 的令牌/密码。
  • 无 TLS 固定(依赖 loopback/隧道)。
  • 代码:
    • src/gateway/server/ws-connection/message-handler.ts
    • src/gateway/client.ts
    • docs/gateway/protocol.md
  • 窄允许列表表面,节点身份 + 配对。
  • 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 → 通过 callGatewaysrc/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 网关上。
  • 智能体通过 Gateway 网关使用 system.run
  • Gateway 网关通过 bridge 调用节点。
  • 节点运行时决定审批。
  • UI 提示由 mac 应用显示(当节点 == mac 应用时)。
  • 节点向 Gateway 网关返回 invoke-res
  • 多跳,UI 绑定到节点主机。
  • 来自 WS 客户端的 Gateway 网关在线状态条目。
  • 来自 bridge 的节点在线状态条目。
  • mac 应用可能为同一台机器显示两个条目(UI + 节点)。
  • 节点身份存储在配对存储中;UI 身份是分开的。

  • 需要维护两个协议栈(WS + Bridge)。
  • 远程节点上的审批:提示出现在节点主机上,而不是用户所在位置。
  • TLS 固定仅存在于 bridge;WS 依赖 SSH/Tailscale。
  • 身份重复:同一台机器显示为多个实例。
  • 角色模糊:UI + 节点 + CLI 能力没有明确分离。

带有角色 + 作用域的单一 WS 协议。

  • 角色:node(能力宿主)
  • 角色:operator(控制平面)
  • 操作者的可选作用域
    • operator.read(状态 + 查看)
    • operator.write(智能体运行、发送)
    • operator.admin(配置、渠道、模型)

Node

  • 可以注册能力(capscommands、permissions)。
  • 可以接收 invoke 命令(system.runcamera.*canvas.*screen.record 等)。
  • 可以发送事件:voice.transcriptagent.requestchat.subscribe
  • 不能调用配置/模型/渠道/会话/智能体控制平面 API。

Operator

  • 完整控制平面 API,受作用域限制。
  • 接收所有审批。
  • 不直接执行 OS 操作;路由到节点。

角色是按连接的,不是按设备。一个设备可以分别打开两个角色。


每个客户端提供:

  • deviceId(稳定的,从设备密钥派生)。
  • displayName(人类名称)。
  • role + scope + caps + commands
  • 客户端未认证连接。
  • Gateway 网关为该 deviceId 创建配对请求
  • 操作者收到提示;批准/拒绝。
  • Gateway 网关颁发绑定到以下内容的凭证:
    • 设备公钥
    • 角色
    • 作用域
    • 能力/命令
  • 客户端持久化令牌,重新认证连接。

设备绑定认证(避免 bearer 令牌重放)

Section titled “设备绑定认证(避免 bearer 令牌重放)”

首选:设备密钥对。

  • 设备一次性生成密钥对。
  • deviceId = fingerprint(publicKey)
  • Gateway 网关发送 nonce;设备签名;Gateway 网关验证。
  • 令牌颁发给公钥(所有权证明),而不是字符串。

替代方案:

  • mTLS(客户端证书):最强,运维复杂度更高。
  • 短期 bearer 令牌仅作为临时阶段(早期轮换 + 撤销)。

精确定义以避免薄弱环节。优选其一:

  • 仅限本地:当客户端通过 loopback/Unix socket 连接时自动配对。
  • 通过 SSH 质询:Gateway 网关颁发 nonce;客户端通过获取它来证明 SSH。
  • 物理存在窗口:在 Gateway 网关主机 UI 上本地批准后,允许在短窗口内(例如 10 分钟)自动配对。

始终记录 + 记录自动批准。


使用当前 TLS 运行时 + 指纹固定:

  • src/infra/bridge/server/tls.ts
  • src/node-host/bridge-client.ts 中的指纹验证逻辑
  • WS 服务器使用相同的证书/密钥 + 指纹支持 TLS。
  • WS 客户端可以固定指纹(可选)。
  • 设备发现为所有端点公布 TLS + 指纹。
    • 设备发现仅是定位器提示;永远不是信任锚。
  • 减少对 SSH/Tailscale 的机密性依赖。
  • 默认情况下使远程移动连接安全。

审批发生在节点主机上(mac 应用节点运行时)。提示出现在节点运行的地方。

审批是 Gateway 网关托管的,UI 传递给操作者客户端。

  1. Gateway 网关接收 system.run 意图(智能体)。
  2. Gateway 网关创建审批记录:approval.requested
  3. 操作者 UI 显示提示。
  4. 审批决定发送到 Gateway 网关:approval.resolve
  5. 如果批准,Gateway 网关调用节点命令。
  6. 节点执行,返回 invoke-res
  • 广播到所有操作者;只有活跃的 UI 显示模态框(其他显示 toast)。
  • 先解决者获胜;Gateway 网关拒绝后续解决为已结算。
  • 默认超时:N 秒后拒绝(例如 60 秒),记录原因。
  • 解决需要 operator.approvals 作用域。
  • 提示出现在用户所在位置(mac/手机)。
  • 远程节点的一致审批。
  • 节点运行时保持无头;无 UI 依赖。

  • Node 角色用于:麦克风、相机、语音聊天、位置、一键通话。
  • 可选的 operator.read 用于状态和聊天视图。
  • 可选的 operator.write/admin 仅在明确启用时。
  • 默认是 Operator 角色(控制 UI)。
  • 启用”Mac 节点”时是 Node 角色(system.run、屏幕、相机)。
  • 两个连接使用相同的 deviceId → 合并的 UI 条目。
  • 始终是 Operator 角色。
  • 作用域按子命令派生:
    • statuslogs → read
    • agentmessage → write
    • configchannels → admin
    • 审批 + 配对 → operator.approvals / operator.pairing

认证必需;永不改变。 首选:

  • 密钥对指纹(公钥哈希)。

仅人类标签。

  • 示例:scarlet-clawsaltwavemantis-pinch
  • 存储在 Gateway 网关注册表中,可编辑。
  • 冲突处理:-2-3

跨角色的相同 deviceId → 单个”实例”行:

  • 徽章:operatornode
  • 显示能力 + 最后在线。

  • 发布此文档。
  • 盘点所有协议调用 + 审批流程。
  • rolescopedeviceId 扩展 connect 参数。
  • 为 node 角色添加允许列表限制。
  • 保持 bridge 运行。
  • 并行添加 WS node 支持。
  • 通过配置标志限制功能。
  • 在 WS 中添加审批请求 + 解决事件。
  • 更新 mac 应用 UI 以提示 + 响应。
  • 节点运行时停止提示 UI。
  • 使用 bridge TLS 运行时为 WS 添加 TLS 配置。
  • 向客户端添加固定。
  • 将 iOS/Android/mac 节点迁移到 WS。
  • 保持 bridge 作为后备;稳定后移除。
  • 所有非本地连接都需要基于密钥的身份。
  • 添加撤销 + 轮换 UI。

  • 角色/允许列表在 Gateway 网关边界强制执行。
  • 没有客户端可以在没有 operator 作用域的情况下获得”完整”API。
  • 所有连接都需要配对。
  • TLS + 固定减少移动设备的 MITM 风险。
  • SSH 静默批准是便利措施;仍然记录 + 可撤销。
  • 设备发现永远不是信任锚。
  • 能力声明通过按平台/类型的服务器允许列表验证。

流式传输 + 大型负载(节点媒体)

Section titled “流式传输 + 大型负载(节点媒体)”

WS 控制平面对于小消息没问题,但节点还做:

  • 相机剪辑
  • 屏幕录制
  • 音频流

选项:

  1. WS 二进制帧 + 分块 + 背压规则。
  2. 单独的流式端点(仍然是 TLS + 认证)。
  3. 对于媒体密集型命令保持 bridge 更长时间,最后迁移。

在实现前选择一个以避免漂移。

  • 节点报告的 caps/commands 被视为声明
  • Gateway 网关强制执行每平台允许列表。
  • 任何新命令都需要操作者批准或显式允许列表更改。
  • 用时间戳审计更改。
  • 记录:配对请求、批准/拒绝、令牌颁发/轮换/撤销。
  • 速率限制配对垃圾和审批提示。
  • 显式协议版本 + 错误代码。
  • 重连规则 + 心跳策略。
  • 在线状态 TTL 和最后在线语义。

  1. 同时运行两个角色的单个设备:令牌模型

    • 建议每个角色单独的令牌(node vs operator)。
    • 相同的 deviceId;不同的作用域;更清晰的撤销。
  2. 操作者作用域粒度

    • read/write/admin + approvals + pairing(最小可行)。
    • 以后考虑每功能作用域。
  3. 令牌轮换 + 撤销 UX

    • 角色更改时自动轮换。
    • 按 deviceId + 角色撤销的 UI。
  4. 设备发现

    • 扩展当前 Bonjour TXT 以包含 WS TLS 指纹 + 角色提示。
    • 仅作为定位器提示处理。
  5. 跨网络审批

    • 广播到所有操作者客户端;活跃的 UI 显示模态框。
    • 先响应者获胜;Gateway 网关强制原子性。

  • 当前:WS 控制平面 + Bridge 节点传输。
  • 痛点:审批 + 重复 + 两个栈。
  • 提议:一个带有显式角色 + 作用域的 WS 协议,统一配对 + TLS 固定,Gateway 网关托管的审批,稳定设备 ID + 可爱别名。
  • 结果:更简单的 UX,更强的安全性,更少的重复,更好的移动路由。