111 lines
34 KiB
Markdown
111 lines
34 KiB
Markdown
# UniDesk Manual Test Plan
|
||
|
||
## T1 CLI 可观测性与配置校验
|
||
|
||
阅读 `AGENTS.md`(本项目 `AGENTS.md` 同时承担 `SKILL.md` 对 `scripts/cli.ts` 的解释职责),然后用 cli 手动测试以下内容:运行 `bun scripts/cli.ts help`、`bun scripts/cli.ts config show`、`bun scripts/cli.ts check`,确认每条命令都有 JSON 输出、失败时包含错误对象、`config.json` 是唯一配置来源,且 TypeScript 检查覆盖 `scripts/` 与 `src/components/`。
|
||
|
||
## T2 Docker 栈异步启动
|
||
|
||
阅读 `AGENTS.md`(本项目 `AGENTS.md` 同时承担 `SKILL.md` 对 `scripts/cli.ts` 的解释职责),然后用 cli 手动测试以下内容:运行 `bun scripts/cli.ts server start`,确认命令立即返回 job id;随后运行 `bun scripts/cli.ts job status latest` 观察构建和启动进度,直到 job 状态为 `succeeded`,且输出包含 `.state/jobs/` 日志路径和 `logs/{YYYYMMDD}/` 服务日志路径。
|
||
|
||
## T3 主 server 自接入 Provider Gateway
|
||
|
||
阅读 `AGENTS.md`(本项目 `AGENTS.md` 同时承担 `SKILL.md` 对 `scripts/cli.ts` 的解释职责),然后用 cli 手动测试以下内容:运行 `bun scripts/cli.ts server status` 和 `bun scripts/cli.ts debug health`,确认公网只监听 frontend 与 provider ingress,backend-core 和 database 显示为 Docker 内部端口,`/api/nodes` 中存在 `main-server` provider,状态为 `online`,`/api/nodes/system-status` 中存在 CPU/内存/硬盘采样,`/api/nodes/docker-status` 中存在 `main-server` 的 Docker 快照,且 provider 标签中能看到 Docker socket 可用性。
|
||
|
||
## T4 前端控制台连通
|
||
|
||
阅读 `AGENTS.md`(本项目 `AGENTS.md` 同时承担 `SKILL.md` 对 `scripts/cli.ts` 的解释职责),然后用 cli 手动测试以下内容:先用 `bun scripts/cli.ts server status` 获取 frontend URL,再用浏览器访问该 URL,使用默认账号 `admin` 和默认密码 `Liang6516.` 登录,确认左侧主模块、顶部当前模块子标签、核心指标、Provider 控件和事件流可见;页面布局应紧凑、信息密度高、字体不过大,且移动端宽度下左侧栏转为高度一致、较窄、单行不换行的横向模块条,内容较少的主内容页和空状态也必须从顶部向下排列,不得上下居中留白。
|
||
|
||
## T5 真实任务下发链路
|
||
|
||
阅读 `AGENTS.md`(本项目 `AGENTS.md` 同时承担 `SKILL.md` 对 `scripts/cli.ts` 的解释职责),然后用 cli 手动测试以下内容:运行 `bun scripts/cli.ts debug dispatch main-server docker.ps`,随后运行 `bun scripts/cli.ts debug health` 或在前端事件流中确认任务状态经历 `accepted`、`running`、`succeeded`,并能看到 provider 通过 Docker socket 返回容器列表摘要。
|
||
|
||
## T6 日志第一现场验证
|
||
|
||
阅读 `AGENTS.md`(本项目 `AGENTS.md` 同时承担 `SKILL.md` 对 `scripts/cli.ts` 的解释职责),然后用 cli 手动测试以下内容:运行 `bun scripts/cli.ts server logs --tail-bytes 20000`,实际读取输出中列出的 `logs/{YYYYMMDD}/` 文件,确认 backend-core、frontend、provider-gateway、database 都有实时日志;backend-core 与 Code Queue/Codex app-server 日志必须按 `logs/{YYYYMMDD}/{startStamp}_{YYYYMMDD}_{HH}_{service}.jsonl` 小时切片,默认日志族总量不得超过 `1GiB`,超过后会删除最旧切片;日志不得只有启动行,错误日志必须包含可定位的错误消息或 stack。
|
||
|
||
## T7 停止与端口释放
|
||
|
||
阅读 `AGENTS.md`(本项目 `AGENTS.md` 同时承担 `SKILL.md` 对 `scripts/cli.ts` 的解释职责),然后用 cli 手动测试以下内容:运行 `bun scripts/cli.ts server stop`,确认立即返回 job id;等待 `bun scripts/cli.ts job status latest` 成功后运行 `bun scripts/cli.ts server status`,确认 frontend 与 provider ingress 公网端口不再监听,backend-core 与 database 没有宿主机端口映射,容器状态不再运行。
|
||
|
||
## Issue 记录
|
||
|
||
测试发现的问题写入 `docs/issue/`,文件命名为 `{NN}_{issue_title}_{YYYYMMDD}.md`,其中 `NN` 从 `01` 递增;问题文档必须包含复现命令、实际输出摘要、期望行为和修复判定标准。
|
||
|
||
## T8 Playwright 公网前端 E2E
|
||
|
||
阅读 `AGENTS.md`(本项目 `AGENTS.md` 同时承担 `SKILL.md` 对 `scripts/cli.ts` 的解释职责),然后用 cli 手动测试以下内容:确认 `config.json` 的 `network.publicHost` 是主 server 公网地址,运行 `bun scripts/cli.ts e2e run`,要求 JSON 中 `network:only-frontend-provider-ports`、`network:core-public-blocked`、`network:database-public-blocked`、`network:findjob-public-blocked`、`network:met-nonlinear-public-blocked`、`network:todo-note-public-blocked`、`network:code-queue-public-blocked`、`core:internal-overview`、`core:pgdata-usage`、`core:performance-api`、`provider:self-node-online`、`provider:gateway-version-label`、`provider:system-status`、`provider:docker-status`、`provider:upgrade-plan`、`provider-ingress:public-health`、`microservice:catalog-findjob`、`microservice:catalog-pipeline`、`microservice:catalog-met-nonlinear`、`microservice:catalog-todo-note`、`microservice:catalog-code-queue`、`microservice:todo-note-health`、`microservice:todo-note-migrated-data`、`microservice:todo-note-write-path`、`microservice:code-queue-status`、`microservice:code-queue-health`、`microservice:code-queue-tasks`、`microservice:findjob-health`、`microservice:findjob-summary`、`microservice:findjob-jobs-preview`、`microservice:pipeline-status`、`microservice:pipeline-health`、`microservice:pipeline-snapshot`、`microservice:pipeline-oa-event-flow`、`microservice:met-nonlinear-status`、`microservice:met-nonlinear-health`、`microservice:met-nonlinear-queue`、`microservice:met-nonlinear-projects`、`microservice:met-nonlinear-image`、`database:named-volume-write`、`database:todo-note-pg-storage`、`frontend:login-provider-visible`、`frontend:public-provider-info-visible`、`frontend:sidebar-collapse`、`frontend:overview-pgdata-visible`、`frontend:no-naked-json-before-click`、`frontend:performance-panel-visible`、`frontend:system-monitor-visible`、`frontend:upgrade-plan-dispatch`、`frontend:docker-status-visible`、`frontend:gateway-version-records-visible`、`frontend:gateway-duration-subsecond-visible`、`frontend:provider-operation-availability-visible`、`frontend:microservice-catalog-visible`、`frontend:todo-note-integrated-visible`、`frontend:findjob-integrated-visible`、`frontend:code-queue-integrated-visible`、`frontend:pipeline-integrated-visible`、`frontend:pipeline-react-flow-visible`、`frontend:pipeline-step-timeline-visible`、`frontend:pipeline-oa-event-flow-visible`、`frontend:met-nonlinear-integrated-visible`、`frontend:met-nonlinear-project-tree-detail`、`frontend:met-nonlinear-queue-detail-speed` 全部 passed;打开输出的 screenshotPath,确认 Playwright 访问的是公网 frontend,页面上能看到 `main-server`、`Main Server Provider`、`D601`、`FindJob`、`Pipeline`、`MET Nonlinear`、`Code Queue`、`性能面板`、`SSH 透传`、`远程更新` 和结构化控件。
|
||
|
||
## T9 Database 命名卷持久化
|
||
|
||
阅读 `AGENTS.md`(本项目 `AGENTS.md` 同时承担 `SKILL.md` 对 `scripts/cli.ts` 的解释职责),然后用 cli 手动测试以下内容:向 `unidesk_e2e_markers` 插入一个唯一 marker,运行 `bun scripts/cli.ts server start` 并等待 `job status latest` 为 `succeeded`,再用 `docker exec unidesk-database psql -U unidesk -d unidesk` 查询该 marker 仍存在;同时审查 `docker-compose.yml` 和 `scripts/src/docker.ts`,确认 CLI server 控制没有使用 `down -v` 或 volume 删除命令。
|
||
|
||
## T10 前端 JSON 控件化展示
|
||
|
||
阅读 `AGENTS.md`(本项目 `AGENTS.md` 同时承担 `SKILL.md` 对 `scripts/cli.ts` 的解释职责),然后用 cli 手动测试以下内容:运行 `bun scripts/cli.ts e2e run`,确认 `frontend:no-naked-json-before-click` passed;再用浏览器登录 frontend,确认节点标签、事件 payload、任务 payload/result 都渲染为徽标、字段摘要、表格或卡片,页面初始状态没有裸 JSON,只有点击 `查看原始JSON` 后才出现原始 JSON 弹窗或高级编辑区。
|
||
|
||
## T11 资源节点 Docker 状态
|
||
|
||
阅读 `AGENTS.md`(本项目 `AGENTS.md` 同时承担 `SKILL.md` 对 `scripts/cli.ts` 的解释职责),然后用 cli 手动测试以下内容:运行 `bun scripts/cli.ts e2e run`,确认 `provider:docker-status`、`provider:gateway-restart-policy` 和 `frontend:docker-status-visible` passed;再用浏览器登录 frontend,进入左侧 `资源节点` 和顶部 `Docker 状态` 子标签,确认可以像 Docker Desktop 一样看到当前节点的 Containers、Images、Volumes、Networks 指标、容器表格、镜像/卷/网络侧栏和 Docker daemon 摘要,所有 running 的 provider-gateway 容器都在 Docker 快照或节点 labels 中显示 `restartPolicy=always` 且 `pidMode=host`,并确认在 `main-server` 节点下数据库命名卷 `unidesk_pgdata_10gb` 在 Volumes 区域和数据库命名卷卡片中显式可见;切换到 D518/D601 等计算节点时不应要求存在 pgdata 数据库卷,也不应显示数据库命名卷缺失告警。
|
||
|
||
## T12 前端 TypeScript + React 源码约束
|
||
|
||
阅读 `AGENTS.md`(本项目 `AGENTS.md` 同时承担 `SKILL.md` 对 `scripts/cli.ts` 的解释职责),然后用 cli 手动测试以下内容:运行 `find src/components/frontend -type f \\( -name '*.js' -o -name '*.jsx' \\) -print`,确认没有手写 frontend JS/JSX 源码;确认 `src/components/frontend/src/app.tsx` 只承担 shell/router,Todo Note、FindJob、Pipeline、MET Nonlinear、ClaudeQQ、Code Queue 分别在 `src/components/frontend/src/todo-note.tsx`、`src/components/frontend/src/findjob.tsx`、`src/components/frontend/src/pipeline.tsx`、`src/components/frontend/src/met-nonlinear.tsx`、`src/components/frontend/src/claudeqq.tsx`、`src/components/frontend/src/code-queue.tsx` 中维护;运行 `bun scripts/cli.ts check`,确认这些 TSX 模块全部纳入 TypeScript 检查,且浏览器请求 `/app.js` 由 frontend Bun server 从 TSX imports 转译生成。
|
||
|
||
## T13 资源节点任务管理器曲线
|
||
|
||
阅读 `AGENTS.md`(本项目 `AGENTS.md` 同时承担 `SKILL.md` 对 `scripts/cli.ts` 的解释职责),然后用 cli 手动测试以下内容:运行 `bun scripts/cli.ts e2e run`,确认 `provider:system-status`、`provider:process-resource-status`、`frontend:system-monitor-visible` 和 `frontend:process-resource-sorting` passed;再用浏览器登录 frontend,进入左侧 `资源节点` 和顶部 `资源监控` 子标签,确认可以像 Windows 任务管理器一样看到 CPU、Memory、Disk 当前用量和历史曲线,Memory 明确显示为不含 Linux page cache / buffer 的实际内存占用;确认 `进程资源占用` 表默认按内存 RSS 降序,能点击 CPU、PID、用户、磁盘 I/O 等表头切换排序,且只通过 `查看原始JSON` 查看完整进程快照;最后确认能执行 `Provider Gateway 升级` 的 `预检升级`。
|
||
|
||
## T13A 通用性能面板
|
||
|
||
阅读 `AGENTS.md`(本项目 `AGENTS.md` 同时承担 `SKILL.md` 对 `scripts/cli.ts` 的解释职责),然后用 cli 手动测试以下内容:运行 `bun scripts/cli.ts e2e run --only core:performance-api,frontend:performance-panel-visible`,确认 backend-core `/api/performance` 返回组件请求统计、内部操作统计、PGDATA 和 Code Queue PostgreSQL 存储摘要;再用浏览器登录 frontend,进入左侧 `运行总览` 和顶部 `性能面板` 子标签,确认页面能看到 `Bwebui` MB 趋势图、组件汇总、最近失败请求、内部操作汇总和最近慢操作,且没有失败请求时明确显示“最近没有失败请求”;完整性能 JSON 只能通过 `查看原始JSON` 打开。
|
||
|
||
## T14 Provider Gateway 远程升级
|
||
|
||
阅读 `AGENTS.md`(本项目 `AGENTS.md` 同时承担 `SKILL.md` 对 `scripts/cli.ts` 的解释职责),然后用 cli 手动测试以下内容:如果本次变更修改了 `src/components/provider-gateway` 代码或行为,先确认 `src/components/provider-gateway/package.json` 的 `version` 已递增;运行 `bun scripts/cli.ts debug dispatch main-server provider.upgrade`,随后查看任务历史或 `bun scripts/cli.ts debug health`,确认 `provider.upgrade` 通过真实 WebSocket 下发并以 `mode: plan` 成功返回升级计划且计划中包含 `providerId`、`providerName`、`providerGatewayVersion`、`targetProviderGatewayVersion`、`policy: "always-enabled"`、`--no-deps`、`--force-recreate`、`oldGatewaySleepMs`、`promoteOnlyAfterCandidateValidation`、`candidateRestartPolicyAfterPromotion: "always"`、`candidateUsesOldContainerEnvironment` 和 `candidateUsesHostPidNamespace`;对明确要升级或重建 `provider-gateway` 容器的计算节点,必须再运行 `bun scripts/cli.ts debug dispatch <PROVIDER_ID> provider.upgrade --mode schedule --wait-ms 15000`,确认任务成功、result 包含 updater 容器信息、候选 gateway 验证后节点重新上线,`providerGatewayVersion` 已上报目标新版本,且最终 provider-gateway 容器 Docker restart policy 是 `always` 并使用宿主 PID namespace。在非主 server 的计算节点上,必须使用 `bun scripts/cli.ts --main-server-ip 74.48.78.17 debug dispatch <PROVIDER_ID> provider.upgrade --mode schedule --wait-ms 15000` 做同一验证,证明该节点能通过公网 frontend remote CLI 自测自动升级,且不需要指定 `--main-server-key`。正式执行计算节点 `provider-gateway` 重建/升级只能通过前端 `资源监控` 的 `执行升级` 或等价的 `provider.upgrade mode=schedule` 显式调度完成,不能通过 `bun scripts/cli.ts ssh <PROVIDER_ID>` 或 Host SSH 维护桥同步执行自重建命令,也不能通过 `PROVIDER_UPGRADE_ENABLED` 或等价开关禁用远程升级。
|
||
|
||
## T15 待处理任务可追溯
|
||
|
||
阅读 `AGENTS.md`(本项目 `AGENTS.md` 同时承担 `SKILL.md` 对 `scripts/cli.ts` 的解释职责),然后用 cli 手动测试以下内容:运行 `bun scripts/cli.ts e2e run`,确认 `frontend:pending-task-drilldown`、`frontend:mobile-nav-fixed-height` 和 `frontend:mobile-content-top-aligned` passed;再登录 frontend,点击 `态势总览` 的 `待处理任务` 指标,确认会进入 `任务调度 / 待处理任务` 子标签,并能看到每个 queued、dispatched、running 任务的 Provider、已等待时间、payload 摘要和 `查看原始JSON` 按钮。backend-core 超过 `TASK_PENDING_TIMEOUT_MS` 的待处理任务必须自动转为 failed,避免总览数字长期卡住。
|
||
|
||
## T16 任务历史诊断信息
|
||
|
||
阅读 `AGENTS.md`(本项目 `AGENTS.md` 同时承担 `SKILL.md` 对 `scripts/cli.ts` 的解释职责),然后用 cli 手动测试以下内容:运行 `bun scripts/cli.ts e2e run`,确认 `frontend:task-history-diagnostics` passed;再登录 frontend,进入 `任务调度 / 任务历史`,确认每个任务行都能看到状态、任务命令和 id、Provider、任务耗时、载荷摘要、诊断信息、更新时间和 `查看原始JSON` 按钮。真实亚秒级耗时必须显示为小数秒或 `<0.01s`,不得显示成 `0s`。失败任务必须在默认表格中显示失败原因以及 exit code、timeout、previous status 等关键字段,完整 result 只能点击 `查看原始JSON` 查看。
|
||
|
||
## T17 Provider Gateway Host SSH / WSL SSH 维护桥
|
||
|
||
阅读 `AGENTS.md`(本项目 `AGENTS.md` 同时承担 `SKILL.md` 对 `scripts/cli.ts` 的解释职责),然后用 cli 手动测试以下内容:确认目标 provider-gateway 已只读挂载维护私钥目录到 `/run/host-ssh`,目标宿主或 WSL 的 sshd 已启动且 `authorized_keys` 包含对应公钥;运行 `bun scripts/cli.ts debug dispatch main-server host.ssh --wait-ms 15000`,再运行 `bun scripts/cli.ts debug task latest`,确认任务通过真实 WebSocket 下发、状态为 `succeeded`、result 中 `probeLine` 包含 `UNIDESK_SSH_TEST`、`exitCode` 为 0、`hostSshKeyPresent` 为 true。随后运行 `bun scripts/cli.ts ssh main-server hostname`,确认输出是远端 hostname 且进程 exit code 为 0;运行 `bun scripts/cli.ts ssh main-server find /home/ubuntu --max-depth 2 --type d --icontains unidesk --limit 5 --sort`,确认结构化 `find` 能返回远端目录且不需要手写括号或嵌套引号;运行 `bun scripts/cli.ts ssh main-server glob --root /home/ubuntu --icontains unidesk --type d --limit 5 --sort`,确认远端注入 `glob` 能返回目录;运行 `bun scripts/cli.ts ssh main-server rg -n UniDesk /home/ubuntu/unidesk/AGENTS.md`,确认 `rg` 直接子命令可用;再用 `printf 'pwd\nexit\n' | bun scripts/cli.ts ssh main-server` 验证无命令参数时能进入并退出远端登录 shell。对 D518 这类无公网 SSH 的 WSL 节点,使用同一命令替换 Provider ID 为 `D518`,必要时先用 debug dispatch 加 `--cwd /home/ubuntu` 覆盖远端工作目录,只能通过 provider-gateway 自连维护桥验证,不得把主 server 直连节点公网 22 端口作为通过标准;在计算节点本机还必须用 `bun scripts/cli.ts --main-server-ip 74.48.78.17 debug dispatch <PROVIDER_ID> host.ssh --wait-ms 15000` 和 `bun scripts/cli.ts --main-server-ip 74.48.78.17 ssh <PROVIDER_ID> hostname` 自测 remote CLI 透传,命令不得要求 `--main-server-key`。
|
||
|
||
## T18 Provider Gateway 版本与远程更新记录
|
||
|
||
阅读 `AGENTS.md`(本项目 `AGENTS.md` 同时承担 `SKILL.md` 对 `scripts/cli.ts` 的解释职责),然后用 cli 手动测试以下内容:运行 `bun scripts/cli.ts e2e run`,确认 `provider:gateway-version-label`、`frontend:gateway-version-records-visible`、`frontend:gateway-duration-subsecond-visible` 和 `frontend:provider-operation-availability-visible` passed;再登录公网 frontend,进入 `资源节点 / 网关版本`,确认每个 Provider 行都显示 provider-gateway 版本号、升级策略、SSH 透传可用性、远程更新可用性、能力摘要、最近远程更新记录,并在下方以表格记录 `provider.upgrade` 的状态、模式、任务 id、来源、耗时、策略、指定 Provider 的 gateway 版本号、结果摘要和更新时间。远程更新记录的真实亚秒级耗时必须显示小数秒,不得显示成 `0s`;远程更新记录默认必须是结构化控件,不得展示裸 JSON;完整 task/result 只能通过 `查看原始JSON` 按钮查看。
|
||
|
||
## T19 前端单服务重建
|
||
|
||
阅读 `AGENTS.md`(本项目 `AGENTS.md` 同时承担 `SKILL.md` 对 `scripts/cli.ts` 的解释职责),然后用 cli 手动测试以下内容:运行 `bun scripts/cli.ts server rebuild frontend`,确认命令立即返回 `server_rebuild` job id;随后运行 `bun scripts/cli.ts job status latest` 直到状态为 `succeeded`,stdout 中必须能看到先 build、再按 `frontend` 服务容器 label 移除、最后 `--no-deps frontend` 启动的过程。重建后运行 `bun scripts/cli.ts server status` 和 `bun scripts/cli.ts e2e run`,确认公网 frontend 恢复健康、Playwright 登录通过、database 命名卷未被删除;正式验收不得要求人工执行 `docker rm` 作为兜底。
|
||
|
||
## T20 D601 FindJob User Service
|
||
|
||
阅读 `AGENTS.md`(本项目 `AGENTS.md` 同时承担 `SKILL.md` 对 `scripts/cli.ts` 的解释职责),然后用 cli 手动测试以下内容:运行 `bun scripts/cli.ts microservice list`,确认 `findjob` 显示为 `providerId=D601`、`public=false`、`frontendOnly=true`、仓库 URL、commit id、`127.0.0.1:3254` 后端映射和 `findjob-server` 容器摘要;运行 `bun scripts/cli.ts microservice health findjob` 和 `bun scripts/cli.ts microservice proxy findjob /api/summary`,确认链路通过 backend-core、D601 provider-gateway 和 D601 本机 FindJob 后端;运行 `bun scripts/cli.ts --main-server-ip 74.48.78.17 microservice health findjob`,确认非主 server 也能通过公网 frontend remote CLI 验证同一链路且不需要 `--main-server-key`。随后运行 `bun scripts/cli.ts e2e run`,确认用户服务和 frontend FindJob 检查全部 passed;再登录公网 frontend `http://74.48.78.17:18081/`,进入 `用户服务 / 服务目录` 和 `用户服务 / FindJob`,确认页面以 React 控件显示 D601、仓库引用、私有后端映射、FindJob 指标、岗位预览和草稿报告,默认没有裸 JSON,只有点击 `查看原始JSON` 才显示原始数据。FindJob 业务代码开发和调试必须用 `bun scripts/cli.ts ssh D601 ...` 进入 D601 的 `/home/ubuntu/findjob`,不得把 findjob 全量代码复制进 UniDesk 仓库,也不得占用主 server 部署调试服务。
|
||
|
||
## T21 D601 Pipeline User Service
|
||
|
||
阅读 `AGENTS.md`(本项目 `AGENTS.md` 同时承担 `SKILL.md` 对 `scripts/cli.ts` 的解释职责),然后用 cli 手动测试以下内容:运行 `bun scripts/cli.ts microservice list`,确认 `pipeline` 显示为 `providerId=D601`、`public=false`、`frontendOnly=true`、仓库 URL `https://github.com/pikasTech/pipeline`、commit id、`127.0.0.1:18082` 后端映射、`allowedMethods` 包含 `GET/HEAD/POST` 和 `pipeline-v2-control` 容器摘要;运行 `bun scripts/cli.ts microservice health pipeline`、`bun scripts/cli.ts microservice proxy pipeline '/api/snapshot?__unideskArrayLimit=registry.components:8,runs:3'` 和 `bun scripts/cli.ts microservice proxy pipeline /api/oa-event-flow/diagnostics`,确认链路通过 backend-core、D601 provider-gateway 和 D601 本机 Pipeline 后端,snapshot 返回 `ok=true`、组件 registry、Pipeline run 预览,diagnostics 返回 `mode=oa-event-flow-100`、禁止残留为 0、有无审核与 monitor 审核证据、node 完成事件不携带流程策略字段,且运行代码中不存在 `control-prompts.jsonl`、`monitor-prompts.jsonl`、`monitor-control`、`control-events.jsonl`、monitor stop 文件、`PIPELINE_*_APPEND_FILE`、本地 JSONL append/read helper 或 monitor `/pipeline-state` 挂载等旧文件传输残留;运行 `bun scripts/cli.ts --main-server-ip 74.48.78.17 microservice health pipeline`,确认非主 server 也能通过公网 frontend remote CLI 验证同一链路且不需要 `--main-server-key`。随后运行 `bun scripts/cli.ts e2e run --only microservice:pipeline,frontend:pipeline`,确认定向 Pipeline 验收通过;若没有正在运行且已产生 `node-long-running-observation` 的候选 run,E2E 会先通过 D601 SSH 透传启动 `monitor-management-behavior-test` 作为真实长任务观察种子,再由公网 frontend Playwright 验证甘特图连线和实时 running 条。再运行 `bun scripts/cli.ts e2e run`,确认 `microservice:pipeline-oa-event-flow`、`frontend:pipeline-oa-event-flow-visible` 和其他用户服务/frontend Pipeline 检查全部 passed;再登录公网 frontend `http://74.48.78.17:18081/`,进入 `用户服务 / 服务目录` 和 `用户服务 / Pipeline`,确认页面以 React 控件显示 D601、仓库引用、私有后端映射、Pipeline 组件矩阵、React Flow 控制图框图、评分器 score 卡片、结构化 `OA 事件流` 诊断面板、epoch 列表、epoch 甘特图和运行材料索引,点击控制图中的 node 后会打开 node 精细控制面板,能通过“抓取过程”读取 node 执行过程,并显示 append prompt、guide 和 redo/restart 操作入口;甘特图必须按纵向时间轴绘制 node 工作竖条,滚动到某个时间窗口时自动隐藏该窗口内无工作的 node 列;点击甘特图执行线后必须显示 `OpenCode Trace`,Trace 正文必须复用 Code Queue 的公共 Trace 样式和 opencode port,废弃旧 Pipeline step/message/tool 卡片风格;Pipeline OA 事件流验收必须证明有审核和无审核流程都由 OA 从 `node-finished` 事实、config policy、monitor 控制事件和 runner control result 串起,不能保留独立审核请求事件、旧批次推进、runner 私有 JSONL 取证或 frontend/CLI 直写 `.state`;默认没有裸 JSON、JSONL 或逐行日志,只有点击 `查看原始JSON` 才显示原始数据。Pipeline 业务代码开发和调试必须用 `bun scripts/cli.ts ssh D601 ...` 进入 D601 的 `/home/ubuntu/pipeline`,不得把 pipeline 全量代码复制进 UniDesk 仓库,也不得占用主 server 部署调试服务。
|
||
|
||
|
||
## T22 Main Server Todo Note User Service
|
||
|
||
阅读 `AGENTS.md`(本项目 `AGENTS.md` 同时承担 `SKILL.md` 对 `scripts/cli.ts` 的解释职责),然后用 cli 手动测试以下内容:确认 D518 `/mnt/d/work/todo_note` 已复制到主 server `/root/todo_note`,运行 `bun scripts/cli.ts microservice list`,确认 `todo-note` 显示为 `providerId=main-server`、`public=false`、`frontendOnly=true`、仓库 URL `https://gitee.com/Lyon1998/todo_note`、`todo-note:4211` 后端映射和 `todo-note-backend` 容器摘要;运行 `bun scripts/cli.ts microservice health todo-note`,确认返回 `storage=postgres`;运行 `bun scripts/cli.ts microservice proxy todo-note /api/instances --max-body-bytes 8000`,确认能看到 `CONSTAR`、`大论文`、`找工作`、`小论文`、`事务` 五个迁移清单,总任务数不低于 100。随后通过 backend-core 或 `bun scripts/cli.ts e2e run` 执行临时清单 create/add/toggle/undo/delete 写入循环,确认 Todo Note 写入真实经过 backend-core、main-server provider-gateway、`todo-note-backend` 和主 PostgreSQL,且删除前必须按唯一临时清单名称重新选中临时清单,不能误删迁移清单。最后登录公网 frontend `http://74.48.78.17:18081/`,进入 `用户服务 / Todo Note`,确认清单、树形任务、筛选、提醒、移动、撤销/重做、字号控制都以 React 控件展示,默认没有裸 JSON,只有点击 `查看原始JSON` 才显示原始数据。
|
||
|
||
## T23 Main Server Code Queue User Service
|
||
|
||
阅读 `AGENTS.md`(本项目 `AGENTS.md` 同时承担 `SKILL.md` 对 `scripts/cli.ts` 的解释职责),然后用 cli 手动测试以下内容:运行 `bun scripts/cli.ts microservice list`,确认 `code-queue` 显示为 `providerId=main-server`、`public=false`、`frontendOnly=true`、仓库 URL `https://github.com/pikasTech/unidesk`、`code-queue:4222` 后端映射和 `code-queue-backend` 容器摘要;运行 `bun scripts/cli.ts server rebuild code-queue` 并用 `bun scripts/cli.ts job status <jobId>` 等待该 job 成功且输出 post-up validation,再运行 `bun scripts/cli.ts microservice health code-queue`、`bun scripts/cli.ts microservice proxy code-queue /api/dev-ready --raw`、`bun scripts/cli.ts microservice proxy code-queue /api/tasks` 和 `bun scripts/cli.ts codex task <已有taskId>`,确认链路通过 backend-core、main-server provider-gateway 和 Code Queue 后端,且 task id 查询返回初始 prompt、最后 assistant message、工具调用摘要、attempt/judge/error 和耗时,且 `queue.devReady.ok=true`、`devReady.missingTools=[]`、`docker.versionOk=true`、`docker.composeOk=true`,必需工具包含 `docker`、`docker-compose`、`jq`、`ssh`、`rsync`、`pip3` 和 `unzip`;提交会产生较多命令输出的小任务后,`/health` 和 `/api/tasks` 仍必须在常规 CLI 超时内返回,容器内不得堆积无超时 healthcheck 进程。运行 `bun scripts/cli.ts microservice proxy code-queue /api/dev-containers/D601/start --method POST --raw`(或等价同源 POST),确认 Code Queue 拉起 D601 `unidesk-codex-dev-D601` 开发容器,返回 JSON 中 `masterProxy.mode=ssh-tun-nat`、`verification.pingGoogleOk=true`、`directPingEvidence` 表明建隧道前直连失败、`pingGoogleLog` 包含 `PING google.com` 和 `0% packet loss`,且 `masterProxyEvidenceAfter` 中 `UNIDESK-CODEX-DEV-D601` NAT 链或 `tun601` 计数比 ping 前增长,证明开发容器网络经 master server 全局代理而不是 D601 本地出网。再用 `bun scripts/cli.ts microservice proxy code-queue /api/tasks --raw` 确认返回的 `queue.executionProviders` 至少包含 `main-server` 和 `D601`,`main-server` 的 `defaultWorkdir=/root/unidesk`,`D601` 的 `defaultWorkdir=/home/ubuntu`;通过 API 提交任务时 `providerId=main-server` 必须在本机容器执行,`providerId=D601` 必须自动复用/拉起 D601 开发容器并在任务 JSON、Trace summary 和日志中显示 `providerId=D601`、`cwd=/home/ubuntu`。随后登录公网 frontend `http://74.48.78.17:18081/`,进入 `用户服务 / Code Queue`,确认页面显示默认模型 `gpt-5.5`、默认执行 Provider `main-server`、默认工作目录 `/root/unidesk`、Provider 下拉菜单包含 `D601 · /home/ubuntu`、模型下拉菜单包含 `gpt-5.4-mini`/`gpt-5.4`/`gpt-5.5`、入队份数、队列指标、任务 ID、复制任务 ID、引用按钮、任务耗时、引用任务 ID、清空输入、创建成功提示、任务提交表单、Codex CLI-like 输出、attempt 表、MiniMax/fallback judge 状态、追加 prompt、打断和重试控件;通过页面提交一个小任务,确认任务进入 queued/running/succeeded 或可解释的 failed 状态,并且输出区能看到运行中的 Codex 消息。批量验收时设置 `入队份数=5` 或用 `---` 分隔 5 段 prompt,一次性入队 5 条任务,确认 5 条任务按顺序运行并全部进入 succeeded 或可解释的非成功终态,不能只运行第一条后停止;其中任一任务被 judge 判定 `fail` 时只能把当前任务标为 failed,后续 queued 任务仍必须继续推进。测试异常中断时可以提交长任务后点击 `打断`,确认任务变为 canceled 或被 judge 标记为非成功终态;自动重试只应在服务端/传输异常、任务正常结束但 execution record 显示未完成、或 judge 判定 retry 时发生;retry 必须复用已有 Codex thread 并 append 继续执行 prompt,只有当前任务 complete 后才推进队列中的下一个任务。MiniMax judge 必须能处理 Markdown fence/夹杂文本等 JSON 去噪;若去噪后仍失败,必须把解析错误和上一轮去噪前原始回答反馈给 MiniMax 修复后重试,日志中应出现 `judge_json_parse_retry`,且 repair 成功时仍以 `source=minimax` 返回。Codex provider key 只能通过 `OPENAI_API_KEY`、`CRS_OAI_KEY` 这类运行时环境透传,MiniMax API key 只能通过 `UNIDESK_CODE_QUEUE_MINIMAX_API_KEY` 这类运行时环境传入,禁止写入 `config.json`、Dockerfile、源码或测试文档。
|
||
|
||
## T24 MET Nonlinear D601 GPU User Service
|
||
|
||
阅读 `AGENTS.md`(本项目 `AGENTS.md` 同时承担 `SKILL.md` 对 `scripts/cli.ts` 的解释职责),然后用 cli 手动测试以下内容:确认 D601 `~/met_nonlinear` 中存在 `docker-compose.unidesk.yml`、`docker/unidesk/Dockerfile.ml`、`unidesk/server/src/index.ts` 和 `docs/reference/unidesk_microservice.md`;运行 `bun scripts/cli.ts microservice list`,确认 `met-nonlinear` 显示为 `providerId=D601`、`public=false`、`frontendOnly=true`、`127.0.0.1:3288` 后端映射和 `met-nonlinear-ts` 容器摘要;运行 `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=500'`、`bun scripts/cli.ts microservice proxy met-nonlinear '/api/projects?root=ex_projects&limit=500'`、`bun scripts/cli.ts microservice proxy met-nonlinear '/api/projects/config?path=projects/<name>' --raw` 和 `bun scripts/cli.ts microservice proxy met-nonlinear /api/images`,确认链路通过 backend-core、D601 provider-gateway 和 D601 本机 TS 后端,项目详情包含 `config`、`progress`、`data`、`model`、`metrics` 字段;最后登录公网 frontend `http://74.48.78.17:18081/`,进入 `用户服务 / MET Nonlinear`,确认项目库按 `projects/` 和 `ex_projects/` 文件树层级展示且文件夹 Project 数与后端返回数量一致,点击项目行能看到结构化 `config.json`、`data/` 训练状态、模型参数量和指标;通过 UI 选择已有 source Project,设置训练轮数和最大并发,使用 `Fork Project` 创建新的 `projects/unidesk_forks/` Project,确认新 Project 被自动勾选但不会直接训练,再点击 `加入待启动队列` 和 `启动队列`;完整验收可用 UI 输入 `Fork 数量=10`、`训练轮数=200`、`最大并发=3`,但这个规模只能由输入框配置,不能作为硬编码按钮。确认最多按 UI 设置的并发数运行、目标 GPU 是 2080Ti、显存余量低于 20% 时自动限制并发、任务最终进入已完成或失败诊断标签且训练容器自动销毁。页面必须以 React 控件显示项目库、待启动/排队/训练中、已完成、失败诊断、GPU/镜像、训练进度、ETA、`epoch/h` 训练速度和历史记录;项目库、当前队列、已完成和失败列表中的项目必须可点击打开详情;默认没有裸 JSON,只有点击 `查看原始JSON` 才显示原始数据;前端不得再提供 `创建10个10轮任务` 这类硬编码测试按钮。
|
||
|
||
## T25 ClaudeQQ D601 QQ Gateway User Service
|
||
|
||
阅读 `AGENTS.md`(本项目 `AGENTS.md` 同时承担 `SKILL.md` 对 `scripts/cli.ts` 的解释职责),然后用 cli 手动测试以下内容:确认 D601 `/home/ubuntu/.agents/skills/claudeqq` 中存在 `Dockerfile`、`docker-compose.unidesk.yml`、`napcat/config/onebot11.json` 和 `scripts/src/server_ts/src/server/event_bus.ts`;运行 `bun scripts/cli.ts microservice list`,确认 `claudeqq` 显示为 `providerId=D601`、`public=false`、`frontendOnly=true`、仓库 URL `https://gitee.com/lyon1998/agent_skills`、`127.0.0.1:3290` 后端映射和 `claudeqq-backend` 容器摘要,并在 D601 上确认 `claudeqq-napcat` 容器运行且只绑定 `127.0.0.1:3000/3001/6099`;运行 `bun scripts/cli.ts microservice health claudeqq`、`bun scripts/cli.ts microservice proxy claudeqq /api/napcat/login`、`bun scripts/cli.ts microservice proxy claudeqq /api/events/recent` 和 `bun scripts/cli.ts microservice proxy claudeqq /api/events/subscriptions`,确认链路通过 backend-core、D601 provider-gateway 和 D601 本机 ClaudeQQ 后端,health 返回 `service=claudeqq`、`pureBackend=true`、`napcat.containerized=true`、NapCat HTTP/WS 状态、登录状态/二维码、`/api/push/text` 与 `/api/events/subscriptions` 端点;通过 `POST /api/events/subscriptions` 创建临时 webhook 订阅再删除,确认 main server 和其他用户服务可订阅 QQ 消息事件;通过 `POST /api/push/text` 发送消息时若 NapCat 未登录必须返回可解释错误,NapCat 在线时必须返回消息 ID,人工推送验收只允许发给主用户私聊账号 `645275593`。最后登录公网 frontend `http://74.48.78.17:18081/`,进入 `用户服务 / ClaudeQQ`,确认页面以 React 控件显示 D601、仓库引用、私有后端映射、NapCat 容器登录二维码、NapCat 状态、QQ 事件订阅、消息推送、主用户私聊账号 `645275593`、最近 QQ 事件和已发送记录,默认没有裸 JSON,只有点击 `查看原始JSON` 才显示原始数据;不得把 D601 `3290/3000/3001/6099` 暴露到公网,也不得 iframe ClaudeQQ 旧 WebUI。
|