docs(windows-node): 完善节点架构与内网MVP方案
This commit is contained in:
parent
641a69455d
commit
a720306b16
|
|
@ -0,0 +1,636 @@
|
||||||
|
# zcbot Windows Node 技术方案
|
||||||
|
|
||||||
|
> 状态:方案设计,待云环境和 Origin 版本确认后实施
|
||||||
|
> 首期能力:Origin 科研绘图
|
||||||
|
> 云端:Ubuntu 上运行的 zcbot
|
||||||
|
> Windows 端:.NET 10 LTS / ASP.NET Core Worker Service
|
||||||
|
> 目标系统:Windows 11 Enterprise 优先;经兼容性验证并具备安全更新的 Windows 10 亦可
|
||||||
|
|
||||||
|
## 1. 决策摘要
|
||||||
|
|
||||||
|
Windows 端采用 **zcbot Windows Node**,由节点主动连接云端 zcbot。云端是唯一的用户入口、智能决策者和任务控制面;Windows Node 是受控执行节点,负责本机工业软件、交互式桌面、截图视频和产物回传。
|
||||||
|
|
||||||
|
Windows Node 不是完整的本地 zcbot:
|
||||||
|
|
||||||
|
- 不直接与用户对话;
|
||||||
|
- 不保存主会话和用户长期记忆;
|
||||||
|
- 不持有云端模型密钥;
|
||||||
|
- 不自主扩大任务范围;
|
||||||
|
- 不接受任意命令、任意脚本或任意桌面动作;
|
||||||
|
- 只执行云端下发且本地能力清单允许的任务。
|
||||||
|
|
||||||
|
核心技术决策:
|
||||||
|
|
||||||
|
1. **连接方向**:Windows Node 通过出站 WSS/HTTPS 主动连接云端,Windows 不开放业务入站端口。
|
||||||
|
2. **Windows 主体**:使用 .NET 10 LTS、Worker Service、ASP.NET Core 本机诊断 API。
|
||||||
|
3. **双进程边界**:Windows Service 管控制面;`DesktopRunner.exe` 在持续登录的交互式会话中管 GUI、COM 和截图。
|
||||||
|
4. **软件适配器**:Origin/Fluent 使用固定 Python Worker;Aspen/CAD 优先使用 C# COM/.NET;GUI 仅作补充。
|
||||||
|
5. **状态分工**:云端 PG 保存任务所有权与期望状态;节点 SQLite/终态文件保存本机执行证据。二者通过租约和重连对账,不构成两个业务事实源。
|
||||||
|
6. **产物分工**:Windows 本地文件是计算现场事实;上传到云端后,zcbot 用户工作目录中的文件是用户交付事实。
|
||||||
|
7. **首批 Origin**:主流程使用 Origin 官方推荐的外部 Python `originpro`,Computer Use 只做视觉验收和异常处理。
|
||||||
|
|
||||||
|
## 2. 目标与非目标
|
||||||
|
|
||||||
|
### 2.1 目标
|
||||||
|
|
||||||
|
- 云端 zcbot 可以发现节点能力、容量、软件版本和在线状态。
|
||||||
|
- 用户可以提交、查询、取消长时间 Windows 计算任务。
|
||||||
|
- 网络中断、云端重启或节点重启后,任务可以确定性对账。
|
||||||
|
- 节点可以上报阶段、进度、结构化指标、日志摘要和事件截图。
|
||||||
|
- 中间产物和最终产物支持校验、断点上传与按需导入工作目录。
|
||||||
|
- 单台节点可以逐步增加 Origin、Fluent、Aspen、CAD 等适配器。
|
||||||
|
- Computer Use 在独立低权限桌面会话运行,并经过能力白名单和动作策略约束。
|
||||||
|
- 节点不暴露用户工作区、云端凭据或其他用户任务。
|
||||||
|
|
||||||
|
### 2.2 首期非目标
|
||||||
|
|
||||||
|
- 不把 Windows Node 做成第二个聊天机器人或子 agent。
|
||||||
|
- 不开放任意 PowerShell、Python、LabTalk、COM、URL 或 Windows 路径。
|
||||||
|
- 不实现节点之间迁移已经开始执行的软件任务。
|
||||||
|
- 不实现通用 HPC 调度器、工作流 DAG 或自动重跑整个计算。
|
||||||
|
- 不持续把完整桌面视频发送给模型。
|
||||||
|
- 不依赖 SMB 共享目录作为任务协议。
|
||||||
|
- 不在首期实现自动更新、WebRTC 和多节点智能负载均衡。
|
||||||
|
|
||||||
|
## 3. 总体架构
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
flowchart LR
|
||||||
|
User["用户"] --> Z["zcbot Web / 渠道"]
|
||||||
|
Z --> Agent["Agent Loop"]
|
||||||
|
Agent --> Tools["Compute Tools"]
|
||||||
|
Tools --> CP["云端 Node Control Plane<br/>PG + Connection Manager"]
|
||||||
|
Node["Windows Node Service<br/>.NET Worker"] -->|"出站 WSS + mTLS"| CP
|
||||||
|
CP -->|"任务 offer / cancel / config"| Node
|
||||||
|
Node -->|"heartbeat / event / terminal"| CP
|
||||||
|
Node --> Pipe["ACL Named Pipe"]
|
||||||
|
Pipe --> Desktop["DesktopRunner.exe<br/>交互式用户会话"]
|
||||||
|
Desktop --> Origin["Origin / OriginPro"]
|
||||||
|
Desktop --> Other["Fluent / Aspen / CAD"]
|
||||||
|
Node --> Local["本机 SQLite + Job Directories"]
|
||||||
|
Desktop --> Local
|
||||||
|
Node -->|"HTTPS 分块上传"| Cache["云端隐藏计算缓存"]
|
||||||
|
Cache --> Workspace["用户 working_dir"]
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3.1 云端组件
|
||||||
|
|
||||||
|
| 组件 | 职责 |
|
||||||
|
|---|---|
|
||||||
|
| `NodeRegistry` | 节点注册、证书指纹、启停、能力和管理员标签 |
|
||||||
|
| `NodeConnectionManager` | WSS 连接、心跳、消息 ACK、同节点单活连接 |
|
||||||
|
| `ComputeJobService` | 用户授权、幂等提交、节点选择、租约、取消和终态 |
|
||||||
|
| `ComputeTransferService` | 输入下载凭证、分块上传、SHA-256、容量与保留期 |
|
||||||
|
| `ComputeBroker` | 把任务事件推送到 Web UI;不承担持久化事实源 |
|
||||||
|
| `ComputeTools` | agent 可调用的能力发现、提交、查询、取消、产物导入工具 |
|
||||||
|
|
||||||
|
节点机制不复用现有 `generic_openapi` 外部系统定义。外部系统表达“用户凭据下的受控请求”;Windows Node 表达“平台托管设备、持久连接、执行租约与本机容量”。两者可以复用认证、审计、大结果和 ActionPolicy 原则,但不共用运行状态模型。
|
||||||
|
|
||||||
|
### 3.2 Windows 组件
|
||||||
|
|
||||||
|
| 进程 | 运行身份 | 职责 | 禁止事项 |
|
||||||
|
|---|---|---|---|
|
||||||
|
| `Zcbot.WindowsNode.Service` | 低权限服务账号 | 云连接、任务台账、租约、调度、传输、日志、进程控制 | 点击桌面、持有用户密码、执行任意脚本 |
|
||||||
|
| `Zcbot.DesktopRunner.exe` | 专用持续登录账号 | 会话内启动软件、UI Automation、截图、视频、弹窗检测 | 对外监听、决定用户任务、访问其他任务 |
|
||||||
|
| `OriginAdapter.Worker` | 由 DesktopRunner 启动 | 读取固定 schema、调用 `originpro`、导出和验证 | 网络访问、解释自然语言、加载用户代码 |
|
||||||
|
| 后续软件 Worker | 按适配器定义 | PyFluent、Aspen COM、CAD .NET/COM | 绕过 Node 能力与路径边界 |
|
||||||
|
|
||||||
|
Windows Service 位于 Session 0,不能可靠操作用户可见桌面。所有需要用户 profile、COM 桌面对象、可见窗口或截图的动作都由 `DesktopRunner.exe` 执行。Service 与 DesktopRunner 只使用本机命名管道通信,命名管道 ACL 仅允许两个指定账号。
|
||||||
|
|
||||||
|
## 4. Windows 技术栈
|
||||||
|
|
||||||
|
### 4.1 Node Service
|
||||||
|
|
||||||
|
- .NET 10 LTS
|
||||||
|
- `Microsoft.NET.Sdk.Worker`
|
||||||
|
- `BackgroundService`
|
||||||
|
- `ClientWebSocket` / `HttpClient`
|
||||||
|
- ASP.NET Core Minimal API,仅绑定 `127.0.0.1` 提供诊断接口
|
||||||
|
- `System.Threading.Channels` 管理本机有界任务队列
|
||||||
|
- SQLite WAL 保存执行台账
|
||||||
|
- Serilog 写结构化滚动日志和 Windows Event Log
|
||||||
|
- Windows Certificate Store 保存节点私钥和客户端证书
|
||||||
|
- Windows Job Objects 或受控 PID 树负责取消和超时回收
|
||||||
|
- Named Pipes 连接 DesktopRunner
|
||||||
|
|
||||||
|
ASP.NET Core 在这里仍是正确选型,但职责已经变化:它不是等云端调用的公开业务网关,而是 Windows Node 的宿主、诊断端点和基础设施框架。跨机业务通信由 Node 主动发起。
|
||||||
|
|
||||||
|
### 4.2 本机诊断 API
|
||||||
|
|
||||||
|
仅监听 loopback:
|
||||||
|
|
||||||
|
```text
|
||||||
|
GET /health/live
|
||||||
|
GET /health/ready
|
||||||
|
GET /diagnostics/node
|
||||||
|
GET /diagnostics/jobs
|
||||||
|
GET /diagnostics/jobs/{job_id}
|
||||||
|
POST /diagnostics/reconnect
|
||||||
|
```
|
||||||
|
|
||||||
|
诊断 API 不提供提交任务、任意命令或软件操作。远程运维通过 VPN/堡垒机登录 Windows 后在本机访问,避免形成第二个业务入口。
|
||||||
|
|
||||||
|
### 4.3 Python 适配器运行时
|
||||||
|
|
||||||
|
Origin 和 Fluent 使用独立、固定版本、离线部署的 Python 运行时。Node 不在任务执行期间安装依赖,不接受请求指定解释器或包版本。
|
||||||
|
|
||||||
|
```text
|
||||||
|
D:\ZcbotNode\runtimes\
|
||||||
|
├── origin\
|
||||||
|
│ ├── python.exe
|
||||||
|
│ └── adapter\
|
||||||
|
└── fluent\
|
||||||
|
├── python.exe
|
||||||
|
└── adapter\
|
||||||
|
```
|
||||||
|
|
||||||
|
Node 生成规范化 `request.json`,固定 Worker 读取请求;事件写 `events.jsonl`,产物写 `artifacts.json`,终态原子写 `terminal.json`。标准输出只用于诊断,不作为任务状态事实源。
|
||||||
|
|
||||||
|
## 5. 节点身份与连接
|
||||||
|
|
||||||
|
### 5.1 注册流程
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
sequenceDiagram
|
||||||
|
participant Admin as 管理员
|
||||||
|
participant Cloud as zcbot 云端
|
||||||
|
participant Node as Windows Node
|
||||||
|
Admin->>Cloud: 创建一次性 enrollment token
|
||||||
|
Node->>Node: 生成设备密钥对
|
||||||
|
Node->>Cloud: POST /v1/compute/nodes/enroll
|
||||||
|
Cloud->>Cloud: 消耗 token,创建 node_id
|
||||||
|
Cloud-->>Node: 客户端证书、CA、云端地址
|
||||||
|
Node->>Node: 私钥写入 Windows Certificate Store
|
||||||
|
Node->>Cloud: mTLS 建立 WSS
|
||||||
|
Cloud-->>Node: 注册成功与当前配置 revision
|
||||||
|
```
|
||||||
|
|
||||||
|
约束:
|
||||||
|
|
||||||
|
- enrollment token 一次性、短期有效,并绑定预期节点名称;
|
||||||
|
- 私钥在 Windows 本机生成且不可导出;
|
||||||
|
- 云端只保存证书指纹和公钥身份;
|
||||||
|
- 节点证书支持轮换、吊销和管理员禁用;
|
||||||
|
- 重装节点必须重新注册,不复用复制出来的私钥。
|
||||||
|
|
||||||
|
### 5.2 长连接
|
||||||
|
|
||||||
|
节点连接:
|
||||||
|
|
||||||
|
```text
|
||||||
|
WSS /v1/compute/nodes/connect
|
||||||
|
```
|
||||||
|
|
||||||
|
统一消息 envelope:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"protocol_version": 1,
|
||||||
|
"message_id": "019...",
|
||||||
|
"type": "heartbeat",
|
||||||
|
"sent_at": "2026-08-12T08:00:00Z",
|
||||||
|
"payload": {}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
| 方向 | 类型 | 语义 |
|
||||||
|
|---|---|---|
|
||||||
|
| Node → Cloud | `hello` | Node 版本、OS、boot ID、本机配置 revision |
|
||||||
|
| Node → Cloud | `heartbeat` | 容量、软件健康、运行任务摘要、磁盘 |
|
||||||
|
| Node → Cloud | `job_accept` / `job_reject` | 是否已原子接收 offer |
|
||||||
|
| Node → Cloud | `job_state` | 阶段、进度和结构化指标 |
|
||||||
|
| Node → Cloud | `job_event` | 重要事件、警告和截图引用 |
|
||||||
|
| Node → Cloud | `job_terminal` | 成功、失败、取消的唯一远端终态消息 |
|
||||||
|
| Node → Cloud | `lease_renew` | 续租仍在本机执行的任务 |
|
||||||
|
| Cloud → Node | `job_offer` | 带租约的任务候选,不等于已分派 |
|
||||||
|
| Cloud → Node | `job_cancel` | 请求协作式取消 |
|
||||||
|
| Cloud → Node | `config_changed` | 提示节点拉取新配置 |
|
||||||
|
| 双向 | `ack` / `ping` / `pong` | 去重、保活和连接质量 |
|
||||||
|
|
||||||
|
消息按 `message_id` 幂等。重要消息在发送方保存到收到 ACK;心跳和高频进度允许覆盖,不进入无限重放队列。
|
||||||
|
|
||||||
|
### 5.3 单活连接
|
||||||
|
|
||||||
|
同一 `node_id` 只允许一个活动连接。新连接带 `boot_id` 和递增 `connection_epoch`;云端原子替换旧连接。旧连接收到 fencing 后不得继续接受新任务,防止快照克隆或网络分区导致双执行。
|
||||||
|
|
||||||
|
## 6. 能力与容量模型
|
||||||
|
|
||||||
|
Node 在 `hello` 和心跳中声明由本机可信配置生成的能力:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"node_id": "019...",
|
||||||
|
"node_version": "0.1.0",
|
||||||
|
"os": "windows-11-enterprise-24h2",
|
||||||
|
"capabilities": [
|
||||||
|
{
|
||||||
|
"name": "origin.plot",
|
||||||
|
"adapter_version": "0.1.0",
|
||||||
|
"software": "OriginPro",
|
||||||
|
"software_version": "2026",
|
||||||
|
"schema_version": 1,
|
||||||
|
"max_concurrency": 1,
|
||||||
|
"available_slots": 1,
|
||||||
|
"health": "ready"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "computer.windows.capture",
|
||||||
|
"schema_version": 1,
|
||||||
|
"max_concurrency": 1,
|
||||||
|
"available_slots": 1,
|
||||||
|
"health": "ready"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"disk_free_bytes": 536870912000
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
能力清单来自管理员部署的适配器 manifest,不能由模型或用户请求自行添加。云端 definition 约束允许哪些用户、角色或任务使用某项能力;节点再次校验 capability、schema version、文件配额和本机 slot,形成双层防护。
|
||||||
|
|
||||||
|
## 7. 云端数据模型
|
||||||
|
|
||||||
|
建议新增三张表,不复用外部系统连接表:
|
||||||
|
|
||||||
|
```text
|
||||||
|
compute_nodes(
|
||||||
|
node_id pk, name, cert_fingerprint, status,
|
||||||
|
labels jsonb, capabilities jsonb, config_revision,
|
||||||
|
last_seen_at, disabled_at, created_at, updated_at
|
||||||
|
)
|
||||||
|
|
||||||
|
compute_jobs(
|
||||||
|
job_id pk, user_id fk, task_id fk, tool_call_id,
|
||||||
|
capability, schema_version, request jsonb,
|
||||||
|
idempotency_key, request_digest,
|
||||||
|
node_id fk null, lease_id, lease_expires_at,
|
||||||
|
status, stage, progress, metrics jsonb,
|
||||||
|
error jsonb, artifact_manifest jsonb,
|
||||||
|
created_at, started_at, terminal_at, updated_at
|
||||||
|
)
|
||||||
|
|
||||||
|
compute_job_events(
|
||||||
|
event_id pk, job_id fk, sequence,
|
||||||
|
kind, level, payload jsonb, created_at
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
约束:
|
||||||
|
|
||||||
|
- `(user_id, idempotency_key)` 唯一;
|
||||||
|
- request 只保存规范化业务参数和文件引用,不保存二进制内容或密钥;
|
||||||
|
- events 只保存阶段变化、警告、错误、用户可见事件和产物事件,不保存视频帧和全部原始日志;
|
||||||
|
- 原始日志、截图和上传中产物进入隐藏文件缓存;
|
||||||
|
- 事件按配置保留,终态任务和用户交付文件遵守 zcbot 通用保留策略。
|
||||||
|
|
||||||
|
## 8. 任务状态、租约与恢复
|
||||||
|
|
||||||
|
### 8.1 云端状态机
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
stateDiagram-v2
|
||||||
|
[*] --> queued
|
||||||
|
queued --> offered
|
||||||
|
offered --> dispatched: node accept
|
||||||
|
offered --> queued: reject / offer timeout
|
||||||
|
dispatched --> running
|
||||||
|
running --> succeeded
|
||||||
|
running --> failed
|
||||||
|
running --> cancelling
|
||||||
|
cancelling --> cancelled
|
||||||
|
queued --> cancelled
|
||||||
|
offered --> cancelled
|
||||||
|
dispatched --> unknown: lease expired
|
||||||
|
running --> unknown: lease expired
|
||||||
|
cancelling --> unknown: lease expired
|
||||||
|
unknown --> running: node reconnect + proof
|
||||||
|
unknown --> succeeded: terminal reconciliation
|
||||||
|
unknown --> failed: operator reconciliation
|
||||||
|
```
|
||||||
|
|
||||||
|
`unknown` 表示云端不知道现场状态,不等于失败,也不得立即把任务分派给另一台节点。
|
||||||
|
|
||||||
|
### 8.2 分派协议
|
||||||
|
|
||||||
|
1. 云端按 capability、schema、管理员授权、健康、空闲 slot 和标签选择候选节点。
|
||||||
|
2. 云端创建短期 offer lease,发送 `job_offer`。
|
||||||
|
3. Node 完成 schema、容量、磁盘、许可证和输入可用性预检。
|
||||||
|
4. Node 先把 job 和 lease 原子写入本地 SQLite,再发送 `job_accept`。
|
||||||
|
5. 云端以相同 lease ID 把状态改为 `dispatched`。
|
||||||
|
6. Node 下载输入并启动 Worker,持续续租。
|
||||||
|
|
||||||
|
节点收到重复 offer 时,根据本地 `job_id + request_digest` 返回原 accept/reject,不重复执行。
|
||||||
|
|
||||||
|
### 8.3 断线与租约
|
||||||
|
|
||||||
|
- 运行任务每 15 秒续租,默认租约 60 秒;参数可配置。
|
||||||
|
- 连接断开后,节点继续运行已开始任务,并把重要事件保存在本地 outbox。
|
||||||
|
- 租约过期后云端标记 `unknown`,进入恢复宽限期,不自动重派。
|
||||||
|
- 节点重连时上报所有非终态任务的 job、request digest、lease、本机阶段、PID、心跳和终态文件摘要。
|
||||||
|
- 云端对账后续租、接收终态,或要求节点停止孤儿任务。
|
||||||
|
- 只有明确证明 Worker 尚未开始,任务才能安全回到 `queued`。
|
||||||
|
- 已进入外部软件执行阶段的任务不自动跨节点重试。
|
||||||
|
|
||||||
|
### 8.4 节点重启
|
||||||
|
|
||||||
|
本地 SQLite 记录任务台账;任务目录的 `terminal.json` 是本机唯一终态文件。Node 启动时:
|
||||||
|
|
||||||
|
1. 扫描本地非终态台账;
|
||||||
|
2. 检查 Worker PID、boot ID、进程创建时间和任务目录;
|
||||||
|
3. 读取 `terminal.json`;
|
||||||
|
4. 能证明仍在运行则恢复监控;
|
||||||
|
5. 有终态文件则加入 outbox 等待回传;
|
||||||
|
6. 无进程无终态则标记 `NODE_RESTARTED_DURING_JOB`,不伪造成功。
|
||||||
|
|
||||||
|
## 9. 文件与产物传输
|
||||||
|
|
||||||
|
### 9.1 输入
|
||||||
|
|
||||||
|
Node 不访问整个用户 workspace。云端只为显式引用的文件创建短期、单任务、只读下载凭证。Node 下载后校验 SHA-256、声明大小、扩展名和内容类型。凭证不能列目录、不能换路径、不能用于其他 job。
|
||||||
|
|
||||||
|
### 9.2 上传
|
||||||
|
|
||||||
|
大产物不通过 WSS 消息传输。Node 使用 HTTPS 分块上传:
|
||||||
|
|
||||||
|
```text
|
||||||
|
POST /v1/compute/jobs/{job_id}/artifacts/upload-session
|
||||||
|
PUT /v1/compute/transfers/{transfer_id}/parts/{part_number}
|
||||||
|
POST /v1/compute/transfers/{transfer_id}/complete
|
||||||
|
```
|
||||||
|
|
||||||
|
上传校验 artifact ID、job 与租约、文件大小、分块摘要、最终 SHA-256、配额、允许类型及压缩包安全。
|
||||||
|
|
||||||
|
### 9.3 云端生命周期
|
||||||
|
|
||||||
|
Node 上传完成后先进入:
|
||||||
|
|
||||||
|
```text
|
||||||
|
<user_root>/.zcbot_cache/<task_id>/compute_jobs/<job_id>/
|
||||||
|
```
|
||||||
|
|
||||||
|
该目录默认隐藏且有 TTL。用户或 agent 明确导入后复制到:
|
||||||
|
|
||||||
|
```text
|
||||||
|
<working_dir>/materials/simulation/<job_id>/
|
||||||
|
```
|
||||||
|
|
||||||
|
最终图、PDF、视频和可编辑工程可通过 `publish_artifacts` 提升为对话产物。真实文件仍是事实源。
|
||||||
|
|
||||||
|
## 10. zcbot 工具面
|
||||||
|
|
||||||
|
```text
|
||||||
|
compute_capability_list
|
||||||
|
compute_job_submit
|
||||||
|
compute_job_status
|
||||||
|
compute_job_cancel
|
||||||
|
compute_job_artifact_import
|
||||||
|
```
|
||||||
|
|
||||||
|
- capability list 只返回用户有权使用且有健康节点承载的能力;
|
||||||
|
- submit 只接受 capability schema,不接受 node ID、命令和路径;
|
||||||
|
- 节点选择由平台完成;
|
||||||
|
- status 返回阶段、进度、指标、重要事件和产物 manifest;
|
||||||
|
- cancel 按 ActionPolicy 分类并审计;
|
||||||
|
- artifact import 只接受 manifest 中的 artifact ID。
|
||||||
|
|
||||||
|
长任务不得让 agent 持续空等。完成时更新 Web 任务卡并通知用户,但不自动启动新 LLM run;用户点击“分析结果”或回复继续后再查询并导入产物。
|
||||||
|
|
||||||
|
## 11. Computer Use 与屏幕采集
|
||||||
|
|
||||||
|
优先级:软件官方 API/SDK → Windows UI Automation → 截图视觉坐标 → 暂停人工处理。Computer Use 不是工业计算主协议,结构化进度和结果始终优先。
|
||||||
|
|
||||||
|
首期 DesktopRunner 内部能力:
|
||||||
|
|
||||||
|
```text
|
||||||
|
session.health
|
||||||
|
window.list
|
||||||
|
window.capture
|
||||||
|
window.wait
|
||||||
|
popup.detect
|
||||||
|
process.launch_adapter
|
||||||
|
process.cancel_adapter
|
||||||
|
```
|
||||||
|
|
||||||
|
后续经安全评审后才开放点击、输入、快捷键和视频控制。优先使用 `automation_id + control name + window identity`,坐标点击只作最后手段。
|
||||||
|
|
||||||
|
截图与视频规则:
|
||||||
|
|
||||||
|
- 默认只采集关键事件截图;
|
||||||
|
- 优先捕获目标窗口;
|
||||||
|
- 敏感信息上传前遮罩;
|
||||||
|
- 视频默认关闭,显式启用时建议 1280×720、5–10 FPS、H.264 分段;
|
||||||
|
- 采集失败不得使计算任务失败;
|
||||||
|
- 模型只按需读取关键帧,不持续消费完整视频。
|
||||||
|
|
||||||
|
## 12. Origin 首批适配器
|
||||||
|
|
||||||
|
### 12.1 接口与执行位置
|
||||||
|
|
||||||
|
首期使用 Origin 官方推荐的外部 Python `originpro`。它能读写数据、创建和修改图形、导出图形,并启动可见或隐藏的 Origin;需要 Windows 本机安装并授权 Origin 2021 或更高版本。
|
||||||
|
|
||||||
|
- [Origin External Python](https://docs.originlab.com/externalpython/)
|
||||||
|
- [Origin Automation Server](https://docs.originlab.com/com/)
|
||||||
|
- [Origin 图形导出](https://docs.originlab.com/user-guide/publishing-and-export/)
|
||||||
|
|
||||||
|
C# COM 只作未覆盖能力或旧版本备用,并与实际 Origin 版本匹配。Origin Worker 由 DesktopRunner 在专用登录账号会话内启动,以统一用户 profile、许可证上下文、COM 会话和截图来源。默认隐藏执行;视觉验收时使用可见模式。
|
||||||
|
|
||||||
|
### 12.2 首期 capability
|
||||||
|
|
||||||
|
只开放 `origin.plot@v1`,接受 CSV、XLSX 或规范化 JSON,不接受任意 Python、LabTalk、模板文件或宏。
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"schema_version": 1,
|
||||||
|
"input": {"input_id": "data-01", "sheet": "Sheet1"},
|
||||||
|
"plot": {
|
||||||
|
"type": "line_scatter",
|
||||||
|
"x": "Temperature",
|
||||||
|
"y": ["Strength_7d", "Strength_28d"],
|
||||||
|
"template": "publication_double_column",
|
||||||
|
"title": "温度对抗压强度的影响",
|
||||||
|
"x_axis": {"title": "温度", "unit": "°C", "scale": "linear"},
|
||||||
|
"y_axis": {"title": "抗压强度", "unit": "MPa", "scale": "linear"},
|
||||||
|
"legend": {"enabled": true, "position": "top_right"},
|
||||||
|
"error_bars": null
|
||||||
|
},
|
||||||
|
"output": {
|
||||||
|
"formats": ["opju", "png", "svg", "pdf"],
|
||||||
|
"dpi": 600,
|
||||||
|
"capture_screenshots": true,
|
||||||
|
"record_video": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
首期图形类型:line、scatter、line_scatter、grouped_bar、box、histogram、heatmap。后续增加误差棒组合、三元图、等高线、三维曲面、XRD 堆叠图、热分析联图和多面板布局。
|
||||||
|
|
||||||
|
### 12.3 模板与产物
|
||||||
|
|
||||||
|
字体、线宽、配色、图幅和导出参数由管理员审核的模板定义。请求只引用模板 ID,provenance 记录模板、Origin、适配器版本和输入 SHA-256。
|
||||||
|
|
||||||
|
```text
|
||||||
|
D:\ZcbotNode\jobs\<job_id>\
|
||||||
|
├── request\request.json
|
||||||
|
├── input\
|
||||||
|
├── work\
|
||||||
|
├── logs\events.jsonl
|
||||||
|
├── screenshots\
|
||||||
|
├── recordings\
|
||||||
|
├── output\
|
||||||
|
│ ├── project.opju
|
||||||
|
│ ├── figure.png
|
||||||
|
│ ├── figure.svg
|
||||||
|
│ ├── figure.pdf
|
||||||
|
│ ├── plot-spec.json
|
||||||
|
│ └── provenance.json
|
||||||
|
├── artifacts.json
|
||||||
|
└── terminal.json
|
||||||
|
```
|
||||||
|
|
||||||
|
`terminal.json` 使用临时文件、flush 和原子 replace。成功前必须完成产物校验和 manifest 写入。
|
||||||
|
|
||||||
|
自动验收包括:输出存在且非空、PNG 尺寸/DPI、SVG/PDF 可解析、系列数量、轴标题/单位/图例、OPJU 保存、provenance 完整、Origin 正常退出且无许可证泄漏。
|
||||||
|
|
||||||
|
## 13. 并发、资源与许可证
|
||||||
|
|
||||||
|
- 每项 capability 独立声明 `max_concurrency`;
|
||||||
|
- Origin 默认并发 1;
|
||||||
|
- Origin 实例不跨 job 共享;
|
||||||
|
- 启动前检查内存、磁盘、桌面会话和许可证;
|
||||||
|
- Node 使用有界队列,云端只向有空闲 slot 的节点发 offer;
|
||||||
|
- 超时区分启动、无进展、总运行和取消宽限期;
|
||||||
|
- 取消先协作式退出,超时后回收精确进程树;
|
||||||
|
- PID、创建时间、可执行文件摘要与 job 绑定,避免误杀。
|
||||||
|
|
||||||
|
## 14. 安全与审计
|
||||||
|
|
||||||
|
- Node 只需出站 HTTPS/WSS,Windows 不开放业务端口;
|
||||||
|
- RDP 通过 VPN/堡垒机,不暴露公网;
|
||||||
|
- mTLS 验证节点,禁止跳过服务端 TLS;
|
||||||
|
- Service、DesktopRunner、运维账号分离且不授予管理员权限;
|
||||||
|
- 节点私钥存 Windows Certificate Store 并限制 ACL;
|
||||||
|
- capability schema 是唯一业务输入入口;
|
||||||
|
- 不接受命令、脚本、URL、绝对路径、UNC 和环境变量覆盖;
|
||||||
|
- 适配器与模板只由管理员部署;
|
||||||
|
- Worker 默认无外网,许可证服务器单独放行;
|
||||||
|
- 未知 capability 和未知 UI 动作 fail closed。
|
||||||
|
|
||||||
|
审计记录提交人、task、capability、node、软件/模板/适配器版本、分派、续租、取消、重连、终态、Computer Use 动作、输入输出摘要和导入位置。不得记录密码、Token、许可证密钥或未脱敏截图。
|
||||||
|
|
||||||
|
## 15. 可观测性与错误码
|
||||||
|
|
||||||
|
Node 心跳上报版本、OS、boot ID、connection epoch、CPU、内存、磁盘、上传队列、DesktopRunner 状态、软件版本、许可证健康、slot、运行 job 和 outbox 积压。
|
||||||
|
|
||||||
|
稳定错误码:
|
||||||
|
|
||||||
|
```text
|
||||||
|
NODE_OFFLINE
|
||||||
|
NODE_CAPABILITY_UNAVAILABLE
|
||||||
|
NODE_DISK_INSUFFICIENT
|
||||||
|
DESKTOP_SESSION_UNAVAILABLE
|
||||||
|
ADAPTER_VERSION_MISMATCH
|
||||||
|
INPUT_HASH_MISMATCH
|
||||||
|
ORIGIN_NOT_INSTALLED
|
||||||
|
ORIGIN_LICENSE_UNAVAILABLE
|
||||||
|
ORIGIN_START_TIMEOUT
|
||||||
|
ORIGIN_AUTOMATION_FAILED
|
||||||
|
OUTPUT_VALIDATION_FAILED
|
||||||
|
ARTIFACT_UPLOAD_FAILED
|
||||||
|
JOB_CANCELLED
|
||||||
|
NODE_RESTARTED_DURING_JOB
|
||||||
|
```
|
||||||
|
|
||||||
|
用户侧只返回可操作说明、是否可重试和 retry-after;完整诊断留在节点和管理员日志。
|
||||||
|
|
||||||
|
## 16. 部署建议
|
||||||
|
|
||||||
|
```text
|
||||||
|
D:\ZcbotNode\
|
||||||
|
├── app\
|
||||||
|
├── config\node.json
|
||||||
|
├── state\node.db
|
||||||
|
├── logs\
|
||||||
|
├── jobs\
|
||||||
|
├── runtimes\
|
||||||
|
├── adapters\
|
||||||
|
├── templates\
|
||||||
|
└── updates\
|
||||||
|
```
|
||||||
|
|
||||||
|
首期云主机建议:Windows 11 Enterprise 或经验证且有安全更新的 Windows 10 Enterprise、8 vCPU、32 GB RAM、200 GB 系统盘、500 GB 独立数据盘、CPU 实例。Origin 二维科研绘图不要求独立 GPU。
|
||||||
|
|
||||||
|
Windows 基线:固定版本并受控更新;禁止休眠和自动锁屏;固定分辨率与缩放;数据盘固定盘符;完成 Origin 人工基线任务;创建三个独立账号;DesktopRunner 登录后自动启动;仅允许必要出站和受控运维;稳定后制作镜像和恢复手册。
|
||||||
|
|
||||||
|
## 17. 实施阶段
|
||||||
|
|
||||||
|
### Phase 0:环境探针
|
||||||
|
|
||||||
|
- 确认 Windows、Origin/OriginPro 精确版本和许可证;
|
||||||
|
- 手工导入并导出 OPJU、PNG、SVG、PDF;
|
||||||
|
- 验证外部 `originpro` 可见/隐藏实例;
|
||||||
|
- 验证账号、RDP 断开、锁屏策略和截图;
|
||||||
|
- 连续运行 24 小时,确认许可证和残留进程;
|
||||||
|
- 测量典型任务时间、文件和磁盘占用。
|
||||||
|
|
||||||
|
### Phase 1:最小闭环
|
||||||
|
|
||||||
|
- enrollment、节点表、WSS Connection Manager;
|
||||||
|
- Node 注册、证书、心跳、能力上报;
|
||||||
|
- job 表、幂等提交、offer/accept 和基本租约;
|
||||||
|
- Origin line/scatter/line_scatter;
|
||||||
|
- 输入下载、分块上传、SHA-256;
|
||||||
|
- zcbot 查询、取消、导入和发布;
|
||||||
|
- 最终截图与稳定错误码。
|
||||||
|
|
||||||
|
### Phase 2:可靠性与绘图可用性
|
||||||
|
|
||||||
|
- outbox、重连对账、unknown 状态和节点重启恢复;
|
||||||
|
- bar、box、histogram、heatmap、误差棒、多系列;
|
||||||
|
- 模板版本、自动机检、视觉验收;
|
||||||
|
- Web 任务卡、完成通知和渠道通知;
|
||||||
|
- 事件截图和可选录像;
|
||||||
|
- Origin 内置 skill 和回归样例集。
|
||||||
|
|
||||||
|
### Phase 3:平台化
|
||||||
|
|
||||||
|
- 经审核的 Computer Use 动作;
|
||||||
|
- 节点禁用、证书轮换、配置 revision、自动升级;
|
||||||
|
- 多节点选择、标签和许可证容量;
|
||||||
|
- Fluent、Aspen、CAD 适配器;
|
||||||
|
- 根据真实负载决定 GPU 节点或统一调度器。
|
||||||
|
|
||||||
|
## 18. 首期验收标准
|
||||||
|
|
||||||
|
1. Windows 不开放业务入站端口,Node 能通过 mTLS WSS 注册、重连和心跳。
|
||||||
|
2. 云端能发现 `origin.plot@v1`、软件版本、健康和 slot。
|
||||||
|
3. 同一幂等键不会创建两个任务。
|
||||||
|
4. 双连接时只有最新 epoch 能接受任务。
|
||||||
|
5. zcbot 能用 CSV 生成指定模板图并获得 `job_id`。
|
||||||
|
6. OPJU、PNG、SVG、PDF 均可打开并通过自动检查。
|
||||||
|
7. zcbot 能校验、导入和发布结果。
|
||||||
|
8. 连续执行 50 个任务,无残留进程、跨任务污染或许可证泄漏。
|
||||||
|
9. WSS 断开时任务继续,重连后能对账。
|
||||||
|
10. 云端或 Node 重启不会重复执行或误报终态。
|
||||||
|
11. 取消能结束精确进程树,不误杀其他实例。
|
||||||
|
12. 截图/录像失败不影响主任务。
|
||||||
|
13. 非法路径、脚本、越权 job、超限文件和伪造 artifact ID 被拒绝。
|
||||||
|
14. 提交、分派、取消、Computer Use 和产物导入均有审计。
|
||||||
|
|
||||||
|
## 19. 已否决方案
|
||||||
|
|
||||||
|
- **云端直调 Windows OpenAPI**:首版简单,但入站网络、设备身份、租约和多节点仍需重做;只保留 loopback 诊断 API。
|
||||||
|
- **Windows 安装完整 zcbot**:形成两套会话、模型、权限和状态;Node 只做执行。
|
||||||
|
- **全程 Computer Use**:对窗口和会话敏感且不适合数值结果;官方 API/SDK 为主。
|
||||||
|
- **Go 编写 Node**:Windows Service、COM/.NET、UI Automation、Named Pipes 更适合 .NET;Python 仅作固定适配器。
|
||||||
|
- **SMB + WinRM**:任意命令、共享权限、恢复和审计边界较差。
|
||||||
|
|
||||||
|
## 20. 实施前待确认
|
||||||
|
|
||||||
|
- 云厂商、Windows 镜像、网络出口和授权;
|
||||||
|
- Origin/OriginPro 精确版本;
|
||||||
|
- 节点锁或浮动许可证及并发数;
|
||||||
|
- 典型 Origin 输入和期望结果;
|
||||||
|
- 首批图形类型与现有绘图模板;
|
||||||
|
- 输入、产物、任务容量和保留期;
|
||||||
|
- 云端域名、内部 CA/mTLS 和 enrollment 管理;
|
||||||
|
- 首期完成通知范围;
|
||||||
|
- Windows 维护责任人与操作窗口。
|
||||||
|
|
@ -0,0 +1,262 @@
|
||||||
|
# Windows Node MVP 实施方案(内网版)
|
||||||
|
|
||||||
|
> **当前有效的第一阶段开发依据。**本文件取代 `windows-node-mvp.md` 中的 MVP 通信与注册方案。
|
||||||
|
> 长期演进边界见 `windows-node-design.md`。
|
||||||
|
> 首批能力:`origin.plot@v1`。
|
||||||
|
|
||||||
|
## 1. 适用边界
|
||||||
|
|
||||||
|
本方案成立的前提:
|
||||||
|
|
||||||
|
- zcbot 与 Windows Node 位于同一受控内网、云 VPC 或专用 VPN;
|
||||||
|
- 两端使用固定私网地址或内网 DNS;
|
||||||
|
- zcbot 的 Node 接口只监听私网地址;
|
||||||
|
- 安全组仅允许指定 Node IP 访问指定 zcbot 端口;
|
||||||
|
- 通信不经过公网、访客网或不可信办公终端所在网络。
|
||||||
|
|
||||||
|
MVP 使用:
|
||||||
|
|
||||||
|
```text
|
||||||
|
注册、状态和文件:HTTP
|
||||||
|
任务控制长连接:WS
|
||||||
|
节点认证:每个 Node 独立的长期 Bearer Token
|
||||||
|
```
|
||||||
|
|
||||||
|
HTTP/WS 不加密传输,Node Token、输入数据、截图和产物在链路上均为明文。如果上述网络边界发生变化,必须先升级 HTTPS/WSS。
|
||||||
|
|
||||||
|
## 2. MVP 架构
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
flowchart LR
|
||||||
|
Z["内网 zcbot"] <-->|"HTTP + WS<br/>独立 Node Token"| N["Windows Node.exe<br/>登录会话自动启动"]
|
||||||
|
N --> P["Origin Python Worker"]
|
||||||
|
P --> O["Origin / OriginPro"]
|
||||||
|
P --> F["独立任务目录"]
|
||||||
|
N -->|"状态、截图、产物"| Z
|
||||||
|
```
|
||||||
|
|
||||||
|
第一版只有两个进程:
|
||||||
|
|
||||||
|
- `Zcbot.WindowsNode.exe`:.NET 10,负责注册、自动连接、任务状态、进程控制、截图和上传;
|
||||||
|
- `OriginAdapter.Worker`:固定 Python 环境,使用 `originpro` 生成 OPJU、PNG、SVG 和 PDF。
|
||||||
|
|
||||||
|
Node 首期运行在持续登录的专用 Windows 用户会话,通过计划任务在登录后自动启动。暂不拆 Windows Service 与 DesktopRunner。
|
||||||
|
|
||||||
|
## 3. Node 注册
|
||||||
|
|
||||||
|
### 3.1 操作流程
|
||||||
|
|
||||||
|
1. 管理员在 zcbot 管理端创建一次性注册码,默认 10 分钟有效。
|
||||||
|
2. Windows Node 首次启动时输入 zcbot 内网地址、节点名称和注册码。
|
||||||
|
3. Node 调用内网注册接口。
|
||||||
|
4. zcbot 原子消费注册码并返回 `node_id + node_token`。
|
||||||
|
5. Node 使用 Windows DPAPI 加密保存 Token。
|
||||||
|
6. 此后 Node 或 Windows 重启时自动建立 WS 连接,不再要求人工输入。
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
sequenceDiagram
|
||||||
|
participant A as 管理员
|
||||||
|
participant Z as zcbot
|
||||||
|
participant N as Windows Node
|
||||||
|
A->>Z: 创建一次性注册码
|
||||||
|
A->>N: 输入内网地址和注册码
|
||||||
|
N->>Z: HTTP POST /v1/compute/nodes/enroll
|
||||||
|
Z->>Z: 校验并原子消费注册码
|
||||||
|
Z-->>N: node_id + node_token + 配置
|
||||||
|
N->>N: DPAPI 加密保存 node_token
|
||||||
|
N->>Z: 携带 Bearer Token 建立 WS
|
||||||
|
Z-->>N: active
|
||||||
|
```
|
||||||
|
|
||||||
|
注册请求:
|
||||||
|
|
||||||
|
```http
|
||||||
|
POST http://zcbot.internal:8765/v1/compute/nodes/enroll
|
||||||
|
Content-Type: application/json
|
||||||
|
```
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"enrollment_code": "ZCN-7H4K-9P2M",
|
||||||
|
"node_name": "win-origin-01",
|
||||||
|
"install_id": "019...",
|
||||||
|
"node_version": "0.1.0",
|
||||||
|
"os_version": "Windows 11 Enterprise 24H2",
|
||||||
|
"capabilities": ["origin.plot@v1"]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
注册响应:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"node_id": "019...",
|
||||||
|
"node_token": "仅返回一次的高熵随机 Token",
|
||||||
|
"heartbeat_seconds": 15,
|
||||||
|
"max_concurrency": 1
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3.2 注册与 Token 底线
|
||||||
|
|
||||||
|
- 注册码一次性、短期有效,云端只保存哈希;
|
||||||
|
- 注册码可以绑定预期节点名称和允许能力;
|
||||||
|
- 注册成功或达到失败尝试上限后立即失效;
|
||||||
|
- 每个 Node 使用不同 Token,禁止共享全局永久 Token;
|
||||||
|
- Token 至少包含 32 字节密码学安全随机数;
|
||||||
|
- zcbot 数据库只保存 Token 强哈希,明文仅在注册响应返回一次;
|
||||||
|
- Node 使用 Windows DPAPI `LocalMachine` 加密 Token,并用文件 ACL 限制为 Node 运行账号可读;
|
||||||
|
- Token 只放 `Authorization` Header,不进入 URL、查询参数或日志;
|
||||||
|
- Node 不上传 Windows 密码、许可证密钥或完整硬件指纹;
|
||||||
|
- 管理员可以禁用 Node 或轮换 Token;禁用后立即拒绝连接、任务和上传;
|
||||||
|
- Windows 重装、本地身份丢失或克隆云盘后必须重新注册。
|
||||||
|
|
||||||
|
## 4. 自动连接与重连
|
||||||
|
|
||||||
|
### 4.1 WS 连接
|
||||||
|
|
||||||
|
```http
|
||||||
|
GET ws://zcbot.internal:8765/v1/compute/nodes/connect
|
||||||
|
Authorization: Bearer <node_token>
|
||||||
|
X-Node-Id: <node_id>
|
||||||
|
Upgrade: websocket
|
||||||
|
```
|
||||||
|
|
||||||
|
HTTP 注册、状态、文件上传下载和 WS 长连接使用相同的 Node Token,不增加短期 connection token、HMAC、nonce、时间戳签名或证书体系。
|
||||||
|
|
||||||
|
连接后 Node 上报:
|
||||||
|
|
||||||
|
- Node、OS 和 Origin 版本;
|
||||||
|
- capability 和可用 slot;
|
||||||
|
- 本机磁盘和桌面会话状态;
|
||||||
|
- 本地运行中或尚未确认终态的 job 摘要。
|
||||||
|
|
||||||
|
同一 `node_id` 只保留一个活动连接。新连接成功后关闭旧连接。MVP 单节点场景下,发现相同身份来自不同 `install_id` 时拒绝新连接并提示重新注册,避免云盘克隆产生双执行者。
|
||||||
|
|
||||||
|
### 4.2 重连策略
|
||||||
|
|
||||||
|
- 断线后按 1、2、5、10、30、60 秒并加随机抖动重连;
|
||||||
|
- 最大间隔 60 秒;
|
||||||
|
- 正在运行的 Origin 任务不因 WS 断开而终止;
|
||||||
|
- 重要终态与上传状态写入本地 SQLite,重连后补报;
|
||||||
|
- `401/403` 表示 Token 失效,停止高频重试并显示“需要重新注册”;
|
||||||
|
- 连接超时和 `5xx` 继续退避重试;
|
||||||
|
- Windows 网络恢复时立即触发连接尝试。
|
||||||
|
|
||||||
|
## 5. 内网安全配置
|
||||||
|
|
||||||
|
最低网络规则:
|
||||||
|
|
||||||
|
```text
|
||||||
|
zcbot Node API 绑定:zcbot 私网 IP:8765(示例)
|
||||||
|
zcbot 入站安全组:只允许 Windows Node 私网 IP → TCP 8765
|
||||||
|
Windows Node 出站:只允许 zcbot 私网 IP → TCP 8765
|
||||||
|
Windows Node 入站:不开放 Node 业务端口
|
||||||
|
RDP:不向公网开放,使用 VPN、堡垒机或云安全登录
|
||||||
|
```
|
||||||
|
|
||||||
|
即使在内网,应用层仍拒绝:
|
||||||
|
|
||||||
|
- 任意 PowerShell、Python、LabTalk 和命令行;
|
||||||
|
- 任意 URL、绝对路径和 UNC 路径;
|
||||||
|
- 未声明 capability;
|
||||||
|
- 越权 job 和伪造 artifact ID;
|
||||||
|
- 超出大小、类型和配额限制的文件。
|
||||||
|
|
||||||
|
建议在日志中记录 Node、job、用户、动作和结果,但不得记录注册码或 Token。
|
||||||
|
|
||||||
|
## 6. MVP 状态与数据
|
||||||
|
|
||||||
|
云端首期只增加:
|
||||||
|
|
||||||
|
```text
|
||||||
|
compute_nodes(
|
||||||
|
node_id pk, name, install_id, token_hash, status,
|
||||||
|
capabilities jsonb, last_seen_at,
|
||||||
|
created_at, updated_at
|
||||||
|
)
|
||||||
|
|
||||||
|
compute_jobs(
|
||||||
|
job_id pk, user_id fk, task_id fk,
|
||||||
|
idempotency_key, capability, request jsonb,
|
||||||
|
node_id fk, status, progress,
|
||||||
|
error jsonb, artifact_manifest jsonb,
|
||||||
|
created_at, terminal_at, updated_at
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
MVP 状态:
|
||||||
|
|
||||||
|
```text
|
||||||
|
queued
|
||||||
|
running
|
||||||
|
succeeded
|
||||||
|
failed
|
||||||
|
cancelled
|
||||||
|
disconnected
|
||||||
|
```
|
||||||
|
|
||||||
|
Node 断线且本地任务可能仍在执行时标记 `disconnected`,不得自动重派。Node 重连后按 `job_id + request_digest` 和本地终态对账。
|
||||||
|
|
||||||
|
## 7. Origin 任务闭环
|
||||||
|
|
||||||
|
```text
|
||||||
|
用户上传 CSV/XLSX
|
||||||
|
→ zcbot 生成受控 plot spec
|
||||||
|
→ Node 接收 origin.plot@v1
|
||||||
|
→ 先持久化 job,再启动 Origin Worker
|
||||||
|
→ originpro 生成 OPJU/PNG/SVG/PDF
|
||||||
|
→ terminal.json 原子记录终态
|
||||||
|
→ Node 通过 HTTP 上传最终截图和产物
|
||||||
|
→ zcbot 导入 working_dir 并发布
|
||||||
|
```
|
||||||
|
|
||||||
|
MVP 保留:
|
||||||
|
|
||||||
|
- 一次性注册与自动连接;
|
||||||
|
- 每 Node 独立 Token、DPAPI、禁用和轮换;
|
||||||
|
- 幂等提交;
|
||||||
|
- 独立任务目录;
|
||||||
|
- 断线不终止计算;
|
||||||
|
- SQLite 和 `terminal.json`;
|
||||||
|
- SHA-256 校验;
|
||||||
|
- 协作取消与精确进程回收;
|
||||||
|
- 最终截图和产物上传。
|
||||||
|
|
||||||
|
MVP 暂缓:
|
||||||
|
|
||||||
|
- HTTPS/WSS;
|
||||||
|
- 短期连接令牌、HMAC、nonce;
|
||||||
|
- 客户端证书和 mTLS;
|
||||||
|
- 完整任务租约和多节点调度;
|
||||||
|
- 独立 DesktopRunner;
|
||||||
|
- 分块断点上传;
|
||||||
|
- 自动更新;
|
||||||
|
- 任意 Computer Use;
|
||||||
|
- 视频直播。
|
||||||
|
|
||||||
|
## 8. 验收标准
|
||||||
|
|
||||||
|
1. 新 Node 能凭一次性注册码完成注册。
|
||||||
|
2. Node 或 Windows 重启后无需人工操作即可自动连接。
|
||||||
|
3. zcbot 能显示在线状态、最后心跳、Origin 版本和 slot。
|
||||||
|
4. Token 不出现在 URL、日志或 zcbot 数据库明文中。
|
||||||
|
5. 禁用 Node 后,现有连接关闭且无法重新连接或上传。
|
||||||
|
6. 复制 Node 配置到不同 `install_id` 的机器不能形成两个活动执行者。
|
||||||
|
7. 同一幂等键不会创建两个 Origin 任务。
|
||||||
|
8. WS 中断时 Origin 继续运行,重连后能补报状态和产物。
|
||||||
|
9. Node 重启后能识别已有终态,不重复绘图。
|
||||||
|
10. zcbot 能接收并发布 OPJU、PNG、SVG 和 PDF。
|
||||||
|
11. 连续运行 50 个任务,无残留 Origin 进程或许可证泄漏。
|
||||||
|
12. 从非白名单内网 IP 访问 Node API 被安全组拒绝。
|
||||||
|
|
||||||
|
## 9. 升级触发条件
|
||||||
|
|
||||||
|
出现以下任一情况,先将通信升级到 HTTPS/WSS:
|
||||||
|
|
||||||
|
- Node 与 zcbot 跨 VPC、跨安全域或经过公网;
|
||||||
|
- 同一网络出现不受信任终端;
|
||||||
|
- 输入、截图或产物属于敏感数据并要求链路加密;
|
||||||
|
- 安全审计明确要求传输加密。
|
||||||
|
|
||||||
|
升级时保持 URL path、Node ID、Bearer Header 和任务协议不变,只把 `http/ws` scheme 改为 `https/wss` 并部署服务端证书。设备身份治理进一步提高时,再升级客户端证书和 mTLS。
|
||||||
Loading…
Reference in New Issue