Mount the host root SSH directory into codex-queue read-only and include SSH key readiness in dev-ready health checks and docs.
30 KiB
UniDesk Microservices Reference
UniDesk microservice 是挂载到主 server 控制面的非核心业务后端。业务容器运行在计算节点 Docker 中,主 server 只保存仓库引用、commit id、Dockerfile/docker-compose 引用、provider 映射和前端集成配置,不把业务仓库整体复制进 UniDesk。
Boundary
- microservice 后端端口默认只绑定计算节点本机地址,例如
127.0.0.1:<port>,不得直接暴露公网。 - 浏览器只访问 UniDesk frontend;frontend 通过同源
/api/microservices/*代理到 backend-core,backend-core 再通过目标 provider-gateway 的microservice.http能力访问计算节点本机后端。 - backend-core REST API、database 和计算节点 microservice 后端都不得新增公网端口;公网入口仍只有 frontend 和 provider ingress。
microservice.http只允许 provider-gateway 访问http://127.0.0.1、http://localhost、http://host.docker.internal这类节点本地地址;主 server 内置 microservice 可使用同一 Compose 网络内的显式服务名,例如todo-note:4211或codex-queue:4222。backend-core 还必须用allowedPathPrefixes和allowedMethods同时限制可代理路径和 HTTP 方法。
Config Contract
config.json 的 microservices 是 microservice 的唯一登记来源。每个条目必须包含:
id、name、providerId和description,用于 CLI、backend-core 和 frontend 统一识别。repository.url与repository.commitId,用于记录业务代码的外部权威来源;UniDesk 不 vendoring 业务全量代码。repository.dockerfile、repository.composeFile、repository.composeService和repository.containerName,用于说明部署应复用业务仓库自身维护的 Dockerfile/docker-compose。backend.nodeBaseUrl、backend.nodeBindHost、backend.nodePort、backend.proxyMode、backend.public=false、backend.frontendOnly=true、backend.allowedMethods、backend.allowedPathPrefixes和backend.healthPath,用于定义计算节点端口到 UniDesk frontend-only 代理的映射。development.providerId、development.sshPassthrough=true和development.worktreePath,用于说明开发调试入口必须在计算节点上通过 UniDesk SSH 透传完成。frontend.route和frontend.integrated=true,用于说明该业务前端已经整合到 UniDesk React 控制台,而不是继续公开业务自身前端。
Compute-Node Development Convention
主 server 本地开发边界固定为只开发 UniDesk frontend 与必要的 UniDesk 配置/代理登记;非 UniDesk 核心功能的后端、Dockerfile、GPU/训练容器、业务数据迁移和业务调试不得默认占用主 server 有限主机资源。涉及 findjob、pipeline、MET Nonlinear 这类业务功能时,应通过 bun scripts/cli.ts ssh <PROVIDER_ID> ... 或 remote CLI SSH 透传进入计算节点,在计算节点本地业务仓库中开发、构建和调试;开发完成后,只把业务服务以 microservice 形式登记到 UniDesk。
业务仓库由业务系统自己维护,包括源码、Dockerfile、docker-compose、配置模板和业务测试。UniDesk 只引用业务仓库 URL、commit id、Dockerfile/docker-compose 路径和运行容器名;不得把业务全量代码复制到 src/components/microservices/ 形成双维护。src/components/microservices/ 只能放通用示例或 UniDesk 自有示例,不作为业务仓库镜像。
Main Server Microservices
主 server 只承载对统一入口、状态迁移或控制面自动化有明确必要的 microservice。该类服务仍遵守不暴露公网端口、前端统一 React 控件化展示的规则;业务持久状态优先写入主 PostgreSQL,控制队列这类运行态可使用 .state/ 文件并必须提供 /logs 与结构化状态端点。
Todo Note On Main Server
当前 Todo Note 作为 id=todo-note 的 microservice 登记在 config.json:
- 来源工作树:D518 的
/mnt/d/work/todo_note;主 server 工作树固定放在/root/todo_note,用于 Docker build 和后端维护。 - Provider:
main-server,由本机 provider-gateway 通过microservice.http访问同一 Compose 网络内的http://todo-note:4211。 - 代码引用:
https://gitee.com/Lyon1998/todo_note与配置中的repository.commitId;UniDesk 仓库只记录引用,不 vendoring Todo Note 全量业务代码。 - 部署引用:
/root/todo_note/Dockerfile构建纯后端镜像,Compose service 为todo-note,容器名为todo-note-backend。 - 数据库:Todo Note 不再使用 JSON 文件作为运行时权威存储;必须把 D518
data/registry.json和data/instances/*.todo.json、*.history.jsonl迁移到主 server PostgreSQL 的todo_note_instances和todo_note_history表。 - 代理路径:只允许
/api/前缀;允许方法为GET、HEAD、POST、DELETE,用于保持 Todo Note 原有清单创建/删除、任务增删改、提醒、展开/收起、移动、撤销/重做等功能。 - UniDesk 前端:
微服务 / Todo NoteReact 页面负责展示清单列表、树形任务、筛选、提醒、拖放/上移下移、撤销/重做、字号控制和显式原始 JSON 按钮。
Todo Note 在 UniDesk 语境中按纯后端服务管理:不得继续公开 Todo Note 自身 Vite/Web 前端,也不得把 4211 映射为公网端口。浏览器只能通过 UniDesk frontend 的 /api/microservices/todo-note/... 同源代理访问 Todo Note 后端。
Todo Note 首次迁移或源 JSON 修复时,在主 server 通过 Docker 内网执行 /root/todo_note/scripts/migrate-json-to-pg.ts,并显式指向主 PostgreSQL:docker run --rm --network unidesk_default -v /root/todo_note:/app -w /app -e DATABASE_URL='postgres://unidesk:unidesk_dev_password@database:5432/unidesk' oven/bun:1-alpine bun scripts/migrate-json-to-pg.ts。迁移脚本必须输出 importedInstances: 5、totalTodos: 100、completedTodos: 54 这一类可审计摘要,不能只依赖前端页面观察。
Todo Note 数据迁移后必须验证:microservice proxy todo-note /api/instances 至少能看到 CONSTAR、大论文、找工作、小论文、事务 五个迁移清单,总任务数不低于源数据的 100 条;再通过代理创建临时清单、添加任务、切换完成、撤销并删除临时清单,证明写入路径走 PostgreSQL 且不会污染长期数据。
Codex Queue On Main Server
当前 Codex Queue 作为 id=codex-queue 的 microservice 登记在 config.json:
- Provider:
main-server,由本机 provider-gateway 通过microservice.http访问同一 Compose 网络内的http://codex-queue:4222。 - 代码引用:
https://github.com/pikasTech/unidesk与配置中的repository.commitId;服务源码位于src/components/microservices/codex-queue,属于 UniDesk 自有控制面组件。 - 部署引用:UniDesk 根仓库
docker-compose.yml中的codex-queueservice,Dockerfile 为src/components/microservices/codex-queue/Dockerfile,容器名为codex-queue-backend。 - Codex 认证:容器只从主 server 的
/root/.codex/config.toml同步 Codex provider 配置到.state/codex-queue/codex-home,并通过运行时环境透传OPENAI_API_KEY、CRS_OAI_KEY等 provider 所需变量;新增 provider 的env_key时必须增加同类运行时透传,禁止把 Codex 或 MiniMax 密钥写入仓库文件。Codex Queue 开发容器必须只读挂载 host 的 root SSH 目录到/root/.ssh(默认${UNIDESK_HOST_ROOT_SSH_DIR:-/root/.ssh}),让容器内git push、ssh -T git@github.com与 host 使用同一套 GitHub SSH key/known_hosts;不得把私钥复制进镜像或仓库。 - Develop-ready 镜像:Codex Queue 镜像必须在启动前预装 UniDesk/Pipeline 调试所需工具,至少包含
codex、bun、node、npm/npx、git、rg、curl、python3/pip3、docker、docker compose、docker-compose、jq、ssh、rsync、make、gcc/g++、tar、gzip和unzip;不得依赖 Codex 任务运行时再apt-get install这些基础环境。 - Codex 控制:服务内部启动
codex app-server --listen stdio://,用 JSON-RPC 调用thread/start、turn/start、turn/steer和turn/interrupt,并监听turn/completed、assistant delta、reasoning delta、command output delta、file diff delta 等通知生成前端可轮询的 transcript。 - 队列语义:
POST /api/tasks或/api/tasks/batch入队,服务始终只运行一个 Codex turn;当前任务真正终止后才推进下一个任务。GET /api/tasks与GET /api/tasks/{id}返回队列、attempt、judge 和输出;POST /api/tasks/{id}/steer向运行中 turn 推入 prompt;POST /api/tasks/{id}/interrupt或DELETE /api/tasks/{id}打断/取消;POST /api/tasks/{id}/retry手动重试。队列 worker 必须隔离单个 task 的异常,不能因为某个 app-server 或 judge 异常让后续 queued 任务停止;当存在 queued/retry_wait 且 worker 空闲时,watchdog 必须自动重新调度。 - 完成判定:app-server
turn/completed的turn.status=completed|interrupted|failed只代表 Codex turn 已结束;即使completed也必须把原始任务、assistant 最终回复、command/file-change 事件、stderr tail 和 recent events 组成 execution record 交给 judge 判断是否真的完成。配置了UNIDESK_CODEX_QUEUE_MINIMAX_API_KEY时使用 MiniMaxMiniMax-M2.7判定complete|retry|fail,否则使用 fallback 规则。MiniMax 返回必须先做 JSON 去噪,支持去除 Markdown fence、json标签和从夹杂文本中提取平衡 JSON object;如果去噪后仍无法解析,服务必须把解析错误和上一轮去噪前原始回答反馈给 MiniMax 做 JSON repair 重试,重试次数由UNIDESK_CODEX_QUEUE_MINIMAX_JUDGE_REPAIR_ATTEMPTS控制,默认2,耗尽后才进入 fallback,并在 fallback 原因中保留 MiniMax 失败信息。 - Retry/推进语义:
retry不是新开一个独立任务或完全新 session;只要已有codexThreadId,服务必须thread/resume原 thread 并 append 一个继续执行 prompt。只有 judge 判定complete后,队列 worker 才把当前任务标为成功并推进下一个 queued/retry_wait 任务。 - Judge 探针:
GET|POST /api/judge/probe使用同一套 judge 逻辑跑内置 synthetic execution records,覆盖正常完成、正常结束但只给计划、传输中断和用户打断四类样本,返回hits、total、hitRate、每例expected与decision;该接口不得回显 MiniMax API key。 - 模型选择:默认 Codex 模型是
gpt-5.4-mini,内置模型队列包含gpt-5.4-mini、gpt-5.4、gpt-5.5;每个入队任务可通过前端模型下拉菜单或 API 覆盖model、cwd、reasoningEffort和maxAttempts。 - 状态与日志:默认工作目录为容器内
/root/unidesk,该路径映射主 server 的~/unidesk;同时保留/workspace映射以兼容历史任务。队列状态保存在.state/codex-queue/state.json对应的容器挂载路径,日志写入 UniDesklogs/{YYYYMMDD}/..._codex-queue.jsonl,/logs端点返回最近结构化日志。/health的queue.devReady和/api/dev-ready必须暴露 develop-ready 自检,包括必需工具、Docker socket、docker compose、默认工作目录、Codex config 状态和/root/.ssh共享 SSH key 状态。Codex CLI-like 输出可能很大,服务必须对输出条数设上限并节流状态持久化,禁止对每个 output delta 同步重写完整 state 导致/health和控制 API 卡死;容器 healthcheck 必须使用带超时的 HTTP 探针,不能留下堆积的无超时探针进程。 - 代理路径:只允许
/health、/logs和/api/前缀;允许方法为GET、HEAD、POST、DELETE。Codex Queue 只在 Compose 内网暴露4222/tcp,不得映射或开放到公网。 - UniDesk 前端:
微服务 / Codex QueueReact 页面负责展示队列卡片、默认模型、模型下拉、显式入队份数、MiniMax judge 状态、Codex CLI-like 输出流、attempt 终态、追加 prompt、打断和手动重试控件;连续执行同一 prompt 应使用入队份数一次性生成多条队列任务,而不是依赖快速连点按钮;原始任务 JSON 只能通过显式查看原始JSON打开。
D601 Microservices
当前 D601 同时承载以下 UniDesk microservice:
findjob:FindJob 纯后端服务,UniDesk frontend 渲染岗位指标、岗位预览和草稿报告。pipeline:Pipeline v2 控制与观测服务,UniDesk frontend 渲染组件矩阵、React Flow 控制图、epoch 甘特图、运行材料索引和 node 精细控制面板。met-nonlinear:MET Nonlinear 训练编排服务,UniDesk frontend 渲染 GPU/镜像、训练队列、Project config 预览、训练进度、ETA 和历史记录。
FindJob On D601
当前 FindJob 作为 id=findjob 的 microservice 登记在 config.json:
- Provider:
D601。 - 开发工作树:
/home/ubuntu/findjob,开发和调试必须通过 UniDesk SSH 透传进入 D601。 - 代码引用:
https://gitee.com/Lyon1998/findjob与配置中的repository.commitId。 - 部署引用:业务仓库自身
Dockerfile、docker-compose.yml、composeService=server、containerName=findjob-server。 - 节点后端:D601 上
127.0.0.1:3254,provider-gateway 容器内通过http://host.docker.internal:3254访问。 - 代理路径:只允许
/api/前缀;/上的业务旧前端即使仍存在,也不作为 UniDesk microservice 入口使用。 - UniDesk 前端:
微服务 / FindJobReact 页面负责展示指标、岗位预览、草稿报告和原始 JSON 显式查看按钮。
FindJob 在 UniDesk 语境中按纯后端服务管理:默认页面不得 iframe 或跳转到 findjob 自身前端,也不得直接暴露 D601 的 3254 到公网。UniDesk frontend 只能通过 /api/microservices/findjob/health 和 /api/microservices/findjob/proxy/api/... 访问 FindJob 后端。
Pipeline On D601
当前 Pipeline v2 作为 id=pipeline 的 microservice 登记在 config.json:
- Provider:
D601。 - 开发工作树:
/home/ubuntu/pipeline,开发和调试必须通过 UniDesk SSH 透传进入 D601。 - 代码引用:
https://github.com/pikasTech/pipeline与配置中的repository.commitId。 - 部署引用:业务仓库自身
Dockerfile、docker-compose.yml、composeService=pipeline-control、containerName=pipeline-v2-control。 - 节点后端:D601 上
127.0.0.1:18082,provider-gateway 容器内通过http://host.docker.internal:18082访问。 - 代理路径:只允许
/health和/api/前缀;允许方法为GET、HEAD、POST,其中POST仅用于/api/node-control/...这类 node 控制动作;Pipeline 自身 WebUI 前端已废弃,UniDesk 只访问 Pipeline control backend。 - UniDesk 前端:
微服务 / PipelineReact 页面负责展示 health、组件数量、React Flow pipeline 控制图框图、epoch 列表、epoch 甘特图、OA/procedure 结构化摘要、运行材料索引、点击 node 后的执行过程抓取、append prompt、guide 和 redo/restart 控件,以及显式原始 JSON 按钮。
Pipeline 在 UniDesk 语境中按控制与观测后端服务管理:默认页面不得 iframe 或跳转到 Pipeline 自身 WebUI,也不得直接暴露 D601 的 18082 到公网。UniDesk frontend 只能通过 /api/microservices/pipeline/health、/api/microservices/pipeline/proxy/api/snapshot?... 和 /api/microservices/pipeline/proxy/api/node-control/... 访问 Pipeline control backend;超大 snapshot 必须使用 __unideskArrayLimit=registry.components:<limit>,runs:<limit> 做展示级裁剪。node 控制入口必须走 Pipeline 后端 OA control API,前端不得直接写 .state、runner prompt 文件或命令队列;scorer 结果必须在 UniDesk Pipeline UI 中以结构化 score 卡片展示。Pipeline 控制与观测的最终态必须 100% 由 OA 事件流驱动,不得保留点对点控制、旧审核事件或旧 batch 推进逻辑,权威规则见 docs/reference/pipeline-oa-event-flow.md。
Pipeline 的一个 epoch 是同一个 pipeline 从入口到终态完整执行一遍,UniDesk 前端把同一 pipelineId 下的多个 run 作为多个 epoch 管理。甘特图必须从 Pipeline snapshot 中的 startedAt、finishedAt、durationMs 和 procedure run 摘要生成,不得按某个 pipeline 实例或 node 名称硬编码布局。甘特图纵轴按时间从上到下排列,左侧固定时间列,后续每列对应一个 node;当前可见时间窗口内没有工作区间的 node 列应自动隐藏。默认页面不得展示裸 JSON、JSONL、worker log 或 control event 行;运行材料和 node 过程只能作为一组一行的结构化索引展示,完整原始内容只能在操作员点击 查看原始JSON 后显示。
MET Nonlinear On D601
当前 MET Nonlinear 作为 id=met-nonlinear 的 microservice 登记在 config.json:
- Provider:
D601。 - 开发工作树:
/home/ubuntu/met_nonlinear,后端、Dockerfile、训练队列和训练容器都必须通过 UniDesk SSH 透传在 D601 开发调试;主 server 本地只允许开发 UniDesk frontend 与代理登记。 - 数据挂载:D601 的
/mnt/f/BaiduSyncdisk/data挂载为训练容器内/data/data,并设置MET_DATA_BASE=/data,让旧配置中的data/M50解析为/data/data/M50;WSL 本机不安装 TensorFlow 训练环境。 - 代码引用:
https://github.com/pikasTech/met_nonlinear与配置中的repository.commitId。 - 部署引用:业务仓库内
docker-compose.unidesk.yml、docker/unidesk/Dockerfile.server、docker/unidesk/Dockerfile.ml、composeService=met-nonlinear-ts、containerName=met-nonlinear-ts。 - 节点后端:D601 上
127.0.0.1:3288,provider-gateway 容器内通过http://host.docker.internal:3288访问。 - 代理路径:只允许
/health和/api/前缀;允许GET、HEAD、POST、PUT,用于读取队列/历史、从已有 Project fork 新 Project、保存队列设置、加入待启动队列和启动队列。 - UniDesk 前端:
微服务 / MET NonlinearReact 页面采用类似下载器的工作台交互,负责从项目库选择已有 Project、fork 新 Project、加入待启动队列、启动队列、调整最大并发、分标签展示当前队列/已完成/失败诊断/GPU 与镜像,并展示训练进度、ETA、训练速度epoch/h、历史训练记录和显式原始 JSON 按钮。项目库必须按projects/、ex_projects/的真实目录层级渲染文件树,文件夹计数等于子树 Project 数;项目库和任务列表行都必须可点击打开结构化详情,详情以控件展示config.json与data/中的训练状态、模型参数量、模型层和指标,不默认展示裸 JSON。
MET Nonlinear 的长期服务边界写在业务仓库 ~/met_nonlinear/docs/reference/unidesk_microservice.md:met-nonlinear-ts 是长驻 Bun TypeScript 编排后端,met-nonlinear-ml:tf26 是按需训练镜像,每个训练任务用一个 docker run --rm 容器执行 python cli.py -t <projectPath>,训练完成后容器自动销毁。训练镜像 Dockerfile 必须使用中国大陆可达的软件源;当前固定使用 Huawei Cloud mirror 的 nvidia/cuda:11.2.2-cudnn8-runtime-ubuntu20.04、Aliyun apt mirror、Tsinghua PyPI mirror、Ubuntu Python 3.8 和 tensorflow==2.6.0,避免官方 TensorFlow 2.6 GPU 镜像 Python 3.6 与业务源码类型注解不兼容。
MET Nonlinear 验收必须通过公网 UniDesk frontend 的交互式 UI 完成:选择已有 source Project,设置训练轮数和最大并发,使用 Fork Project 创建新的 projects/unidesk_forks/ Project,确认新 Project 只是被选中而不会直接训练,再加入待启动队列并点击 启动队列。验收时必须确认项目库的 projects/ 与 ex_projects/ 按文件树层级展开、文件夹 Project 计数与后端返回数量一致;点击项目行后详情显示 config.json、data/ 训练状态、模型参数量和指标;待启动、排队中、训练中、已完成和失败诊断分标签可见;训练队列和已完成行显示 epoch/h 训练速度且可点击打开任务详情。最大并发必须按 UI 设置生效,运行中行显示训练进度和 ETA,目标 GPU 为 2080Ti,2080Ti 显存余量低于 20% 时自动限制并发,并确认训练容器结束后不残留。批量规模由 UI 输入框决定,完整验收可以通过输入 Fork 数量=10、训练轮数=200、最大并发=3 执行,但不得把该规模做成专用硬编码按钮。CLI /api/queue/server-test 仅保留为后端兼容入口,不作为 frontend 操作入口。
CLI
bun scripts/cli.ts microservice list:列出全部 microservice、provider 映射、仓库引用、后端映射和运行态容器摘要。bun scripts/cli.ts microservice status findjob:查看单个 microservice 的配置与运行态。bun scripts/cli.ts microservice health findjob:通过 backend-core -> provider-gateway -> D601 本机后端链路探测 FindJob/api/health。bun scripts/cli.ts microservice proxy findjob /api/summary:通过同一私有代理读取业务 API,适合人工验证,不用于公开业务端口。bun scripts/cli.ts microservice health pipeline:通过 backend-core -> provider-gateway -> D601 本机后端链路探测 Pipeline/health。bun scripts/cli.ts microservice proxy pipeline '/api/snapshot?__unideskArrayLimit=registry.components:8,runs:3':读取 Pipeline snapshot 的有界预览,适合人工验证,不用于公开业务端口;验证甘特图时应确认 run 和 procedureRun 摘要包含startedAt、finishedAt或durationMs;若 body 仍超过 CLI 阈值,默认只输出bodyPreview,需要完整 body 时显式追加--raw。- Pipeline node 控制写入由 UniDesk frontend 调用同源
/api/microservices/pipeline/proxy/api/node-control/...完成;通用 CLImicroservice proxy仍主要作为读取验证入口,不作为人工批量写入工具。 bun scripts/cli.ts microservice health met-nonlinear:通过 backend-core -> provider-gateway -> D601 本机 TS 编排后端链路探测 MET Nonlinear/health。bun scripts/cli.ts microservice proxy met-nonlinear /api/queue与bun scripts/cli.ts microservice proxy met-nonlinear /api/images:读取 MET Nonlinear 队列、GPU 策略和训练镜像状态,适合人工验证,不用于公开业务端口。bun scripts/cli.ts microservice proxy met-nonlinear '/api/projects?root=projects&limit=500'与bun scripts/cli.ts microservice proxy met-nonlinear '/api/projects/config?path=projects/<name>' --raw:验证项目库文件树输入和结构化项目详情;详情应包含 config、progress、data、model、metrics 字段,供前端渲染训练状态、模型参数量和指标。bun scripts/cli.ts microservice health todo-note与bun scripts/cli.ts microservice proxy todo-note /api/instances:验证主 server Todo Note 后端、PostgreSQL 存储和本机 provider-gateway 私有代理链路。bun scripts/cli.ts microservice health codex-queue与bun scripts/cli.ts microservice proxy codex-queue /api/tasks:验证主 server Codex Queue 后端、队列状态文件和本机 provider-gateway 私有代理链路;写入、追加 prompt 和打断由 frontend 同源代理或直接 HTTP API 发起。bun scripts/cli.ts --main-server-ip 74.48.78.17 microservice health findjob:在计算节点或其他非主 server 主机上通过公网 frontend remote CLI 进行同一验证,不需要主 server SSH key。
debug dispatch D601 microservice.http --payload-json ... 仅用于开发调试 provider-gateway 代理能力;正式验收和用户入口应优先使用 microservice 命令与 frontend 页面。
Frontend Rules
microservice 前端必须整合到 src/components/frontend/src/ 下的 TypeScript + React 模块中。app.tsx 只做 shell/router 和导入分发,业务页面必须拆成独立 TSX,例如 todo-note.tsx、findjob.tsx、pipeline.tsx、met-nonlinear.tsx、codex-queue.tsx。默认展示必须是业务控件:指标卡、状态徽标、表格、草稿卡片、运行卡片、树形任务、表单控件、结构化材料索引、链接和字段摘要;只有操作员点击 查看原始JSON 时才允许打开原始 JSON 弹窗。日志、JSONL 和大块 JSON 不得在主界面按行展示,避免把裸数据伪装成 UI。
对于超大业务 JSON,backend-core 可把 __unideskArrayLimit=<path>:<limit> 作为 frontend-only 代理参数传给 provider-gateway,由 provider-gateway 在返回前裁剪指定 JSON 数组并写入 _unidesk.arrayLimits 元数据。该参数只用于控制 UniDesk 展示预览,不能替代业务后端自身分页 API 的长期设计。CLI 的 microservice proxy 还会对超过默认阈值的 body 做二次有界预览,防止人工验证时输出爆炸;只有显式 --raw 才允许倾倒完整 body。
Verification
microservice 交付必须同时通过后端、CLI 和公网 frontend 验证:
- 在主 server 运行
bun scripts/cli.ts microservice list,确认findjob的providerId=D601、public=false、frontendOnly=true、仓库 URL、commit id、127.0.0.1:3254映射和findjob-server容器摘要可见。 - 在主 server 运行
bun scripts/cli.ts microservice list,确认pipeline的providerId=D601、public=false、frontendOnly=true、仓库 URL、commit id、127.0.0.1:18082映射和pipeline-v2-control容器摘要可见。 - 在主 server 运行
bun scripts/cli.ts microservice list,确认met-nonlinear的providerId=D601、public=false、frontendOnly=true、仓库 URL、commit id、127.0.0.1:3288映射和met-nonlinear-ts容器摘要可见。 - 在主 server 运行
bun scripts/cli.ts microservice list,确认codex-queue的providerId=main-server、public=false、frontendOnly=true、UniDesk 仓库 URL、codex-queue:4222映射和codex-queue-backend容器摘要可见。 - 运行
bun scripts/cli.ts microservice health findjob与bun scripts/cli.ts microservice proxy findjob /api/summary,确认真实链路经过 backend-core、WebSocket、D601 provider-gateway 和 D601 本机 FindJob 后端。 - 运行
bun scripts/cli.ts microservice health pipeline与bun scripts/cli.ts microservice proxy pipeline '/api/snapshot?__unideskArrayLimit=registry.components:8,runs:3',确认真实链路经过 backend-core、WebSocket、D601 provider-gateway 和 D601 本机 Pipeline 后端,且 run/procedure 摘要包含甘特图所需时间字段。 - 运行
bun scripts/cli.ts microservice health met-nonlinear、bun scripts/cli.ts microservice proxy met-nonlinear /api/queue、bun scripts/cli.ts microservice proxy met-nonlinear '/api/projects?root=projects&limit=20'和bun scripts/cli.ts microservice proxy met-nonlinear /api/images,确认真实链路经过 backend-core、WebSocket、D601 provider-gateway 和 D601 本机 MET Nonlinear TS 后端。 - 运行
bun scripts/cli.ts microservice health todo-note与bun scripts/cli.ts microservice proxy todo-note /api/instances,确认真实链路经过 backend-core、WebSocket、main-server provider-gateway 和主 servertodo-note-backend后端;输出中必须包含五个迁移清单和 PostgreSQL 存储健康状态。 - 运行
bun scripts/cli.ts microservice health codex-queue与bun scripts/cli.ts microservice proxy codex-queue /api/tasks,确认真实链路经过 backend-core、WebSocket、main-server provider-gateway 和主 servercodex-queue-backend后端;再通过公网 frontend 提交一个gpt-5.4-mini小任务,确认队列串行推进、输出实时更新、结束后有 judge 判定,且运行中可追加 prompt 或打断。批量验收必须通过公网 frontend 设置入队份数=5或使用多段 prompt 分隔,一次性入队 5 条任务,并确认 5 条任务按顺序进入 running/judging/succeeded,而不是只运行第一条。 - 在 D601 上用
bun scripts/cli.ts ssh D601 ...调试业务仓库和容器,确认curl http://127.0.0.1:3254/api/health可用;不要把调试服务部署到主 server。 - 在 D601 上用
bun scripts/cli.ts ssh D601 ...调试业务仓库和容器,确认curl http://127.0.0.1:18082/health和curl http://127.0.0.1:18082/api/snapshot可用;不要把 Pipeline 调试服务部署到主 server。 - 在 D601 上用
bun scripts/cli.ts ssh D601 ...调试~/met_nonlinear,确认curl http://127.0.0.1:3288/health可用;最终验收必须回到公网 UniDesk frontend,通过项目库选择、Fork、加入待启动队列和启动队列完成,不要把 MET Nonlinear 后端、Docker build 或训练任务部署到主 server。 - 运行
bun scripts/cli.ts e2e run,确认 microservice 相关检查 passed,并确认 Playwright 访问的是公网http://74.48.78.17:18081/。 - 登录公网 frontend,进入
微服务 / 服务目录、微服务 / Todo Note、微服务 / FindJob、微服务 / Pipeline和微服务 / MET Nonlinear,确认能看到主 server 与 D601 provider、仓库引用、后端私有映射、Todo Note 迁移清单与树形任务、FindJob 指标和岗位预览、Pipeline 组件矩阵、React Flow 控制图、epoch 列表、epoch 甘特图和运行材料索引、MET Nonlinear 队列/GPU/镜像/Project config/训练历史;Todo Note 页面必须能创建临时清单、添加任务并删除临时清单,删除前必须按唯一临时清单名称重新选中对应行,禁止用未确认的当前 active 清单执行删除,FindJob 页面必须显示真实数字指标、HEALTH OK和非空岗位预览,Pipeline 页面必须显示Pipeline v2 工作台、Health OK、组件数、epoch 甘特图和结构化运行材料索引,MET Nonlinear 页面必须显示Health OK、Fork Project、启动队列、当前队列、最大并发设置和 GPU/镜像面板,不能只停留在 loading 骨架;页面默认不得出现裸 JSON、JSONL 或逐行日志。