# PJ2026-010405 云端控制台

## 修改历史

| 版本 | 对应 commit id | 更新日期 | 变更说明 |
| --- | --- | --- | --- |

当前正文仍在规格治理草稿中；未定稿前不新增版本号，不为单次编辑追加 `待提交` 版本。

## 正文

## PJ2026-010405 云端控制台需求规格

## 1. 文档控制

| 字段 | 内容 |
| --- | --- |
| 编号 | PJ2026-010405 |
| 短名 | 云端控制台 |
| 层级 | L2 课题 |
| 状态 | 已生效 |
| 实现引用版本 | draft-2026-07-13-p0-cloud-console |
| 需求规格模板 | [ISO/IEC/IEEE 29148 需求规格模板](../../templates/iso-iec-ieee-29148-requirements-spec-template.md) |
| 上级规格 | [PJ2026-0104 客户端](PJ2026-0104-client.md) |
| 关联规格 | [HWPOD服务](PJ2026-010103-hwpod-service.md)、[AI网关](PJ2026-010104-ai-gateway.md)、[项目管理](PJ2026-010404-project-management.md)、[用户管理](PJ2026-0105-user-management.md)、[Workbench 实时权威](PJ2026-010401080313-workbench-realtime-authority.md) |
| 规格治理索引 | [规格治理](spec-governance.md) |

本文采用 ISO/IEC/IEEE 29148 需求规格模板的项目裁剪版，定义 HWLAB Cloud Web 除 Workbench 主工作流之外的统一产品壳、页面能力、数据消费边界和原入口验收。

## 2. 目的和范围

### 2.1 目的

云端控制台负责把项目、任务、硬件资源、用户运营、管理和系统状态投影为一致、可理解、可操作的 Web 工作界面，使用户在进入 Workbench 前后都能确认当前上下文、资源 readiness、主要 blocker 和下一步动作。

本课题服务 HWLAB 从单用户本地验证走向多人、多端、云端开箱即用的阶段目标。页面重写不是孤立视觉美化，而是把已有领域事实收敛为工业风、高信息密度、渐进披露且支持深链恢复的统一入口。

### 2.2 范围内

- 登录、注册、404 和登录后应用壳。
- Dashboard、Projects、MDTODO、HWPOD、HWPOD Node 和节点接入。
- API Keys、Usage、Billing、Settings、Help 和组织/用户协同入口。
- Users、Access、Secrets、External Secret、Admin Billing 和 Provider Profiles。
- Performance、Gate、Skills 和 OpenCode 外壳等非 Workbench 工具页。
- 页面共享的工业设计系统、集合、Overlay、Viewer、异步状态和有界工作区组件。
- 页面所需的 typed DTO、同源 BFF/read model、服务端搜索、排序、cursor 和详情查询。
- 卡片/列表或合理密度切换、URL view state、响应式、无障碍和 reduced-motion。

### 2.3 范围外

- `/workbench*` 主工作流由 [PJ2026-010401 Web工作台](PJ2026-010401-web-workbench.md) 负责；本规格只要求共享应用壳不使其回退。
- 项目和 MDTODO source-of-truth、任务投影与 Workbench launch context 由 [项目管理](PJ2026-010404-project-management.md) 负责。
- HWPOD 资源、node topology、租约、路由和 operation result 由 [HWPOD服务](PJ2026-010103-hwpod-service.md) 负责。
- 节点连接、能力、adapter 执行和原始硬件事实由 [AI网关](PJ2026-010104-ai-gateway.md) 负责。
- 用户、组织、权限、API key、额度、usage 和 billing 事实由 [用户管理](PJ2026-0105-user-management.md) 负责。
- 为视觉展示虚构支付、scope、轮换、claim、授权、硬件状态或系统能力。

## 3. 术语表

| 术语 | 定义 |
| --- | --- |
| 云端控制台 | HWLAB Cloud Web 中除 Workbench 主工作流外的统一用户与管理页面集合。 |
| 应用壳 | 负责导航、用户/组织上下文、命令区、状态区、路由出口和主滚动所有者的共享页面框架。 |
| 资源集合 | 以同一数据和选择合同提供图标卡片、列表或表格视图的实体集合。 |
| Inspector | 在不离开集合上下文的情况下渐进披露实体详情、诊断和低频动作的侧边详情区域。 |
| blocker | 由后端业务域返回、能够解释当前能力不可用或下一步动作的结构化阻塞。 |
| view state | 纯显示状态，包括视图、密度、筛选、排序、cursor、选中对象和详情标签。 |
| PCB 设备卡片 | 用电路板拓扑表达 HWPOD 四要素及真实状态的 SVG 实体卡片，不是装饰插画。 |
| 节点接入阶段 | `downloaded`、`installed`、`desktop-visible`、`registered`、`workspace-ready` 和 `hwpod-ready` 的分阶段 readiness。 |
| 智能体运行观察 | 以 AgentRun/HWLAB Kafka 产品事件为唯一事实流，统一观察 task、run、command、attempt、runner 和 session 的工作页。 |

## 4. 系统边界和目标架构

### 4.1 边界

| 边界项 | 内容 |
| --- | --- |
| 外部使用者 | 硬件研发用户、组织管理员、平台管理员。 |
| 外部输入 | 用户操作、路由、筛选、实体 ID、任务操作、资源选择和低频管理动作。 |
| 受控资源 | 页面壳、组件、客户端路由状态、同源 API 调用和可访问性语义。 |
| 外部输出 | 项目/任务/资源集合、详情、readiness、blocker、日志/证据摘要和用户动作结果。 |
| 系统边界 | 云端控制台负责用户入口和展示合同，不拥有硬件、任务、身份、权限、账本或评价事实。 |

### 4.2 目标架构

```mermaid
flowchart LR
    User[用户或管理员] --> Shell[Cloud Web 应用壳]
    Shell --> Pages[领域页面]
    Pages --> UI[共享 UI 与 view state]
    Pages --> BFF[Cloud API 同源 BFF]
    BFF --> PM[Project Management]
    BFF --> HWPOD[HWPOD Service]
    BFF --> UserDomain[User Management]
    BFF --> Agent[AgentRun/HarnessRL]
    HWPOD --> Gateway[AI Gateway / Python Node]
    PM -. launchContext .-> Workbench[Workbench]
```

- Cloud API 只承担同源会话、ACL、路由、错误和 correlation 映射。
- 领域 read model 由拥有事实的服务产出；浏览器不得并发调用多个服务后猜测关键状态。
- 前端组件只接收 typed DTO，不用 `Record<string, unknown>`、字段名候选、名称去重或临时拼装定义业务真相。

### 4.3 页面信息架构

- 工作入口：
  - Dashboard；
  - Projects；
  - MDTODO；
  - Workbench 公共入口。
- 硬件资源：
  - HWPOD 设备资源；
  - HWPOD Node；
  - 节点接入。
- 用户与运营：
  - 组织/用户上下文；
  - API Keys；
  - Usage；
  - Billing；
  - Settings；
  - Help。
- 管理与系统：
  - Users、Access、Secrets、Admin Billing 和 Provider Profiles；
  - Performance、Gate、Skills 和 OpenCode 外壳。

## 5. 通用前端能力

### 5.1 视觉与布局

- 采用工业控制台方向：深石墨主色、暖白工作面、琥珀或电气青状态强调、细边界和克制层次。
- 字体、颜色、间距、圆角、边界、阴影、状态和动效必须由 tokens 统一拥有。
- 首屏直接显示可操作对象、主状态、主要 blocker 和高频动作，不放营销式 hero 或装饰指标墙。
- AppShell、PageCommandBar、StatusStrip、SectionFrame、Inspector 和 BoundedWorkspace 统一页面骨架。
- 根容器和工作区使用稳定高度、`min-height: 0` 和内部滚动，禁止 document 级横向溢出。

### 5.2 集合与切换

- `DataGrid<T>`、`VirtualList<T>` 和 `ResourceCollection<T>` 共享同一查询、选择、详情和动作合同。
- 实体集合默认提供图标卡片与列表/表格切换。
- 非实体集合页面提供紧凑/舒适密度或内容显示模式，不制造无意义图标视图。
- 支持服务端搜索、排序、cursor、列显隐、sticky header、键盘选择和大集合窗口化。
- 卡片与列表必须显示相同的身份、主状态、blocker 和动作，不得形成两套业务逻辑。

### 5.3 Overlay、内容和异步状态

- Dialog、Drawer、Popover 和 ConfirmDialog 统一 Portal、Esc、focus trap、焦点恢复、scroll lock、busy 和 ARIA。
- Log、Markdown、JSON、Text 和 Trace Viewer 统一搜索、复制、换行、行号、下载和全屏能力。
- 页面统一表达 `initial-loading`、`refreshing`、`partial`、`empty`、`error` 和 `ready`。
- 后台刷新保留上一份成功数据；错误主界面显示原因和动作，code、requestId 和 traceId 进入详情。

### 5.4 路由和状态

- 实体身份和选择进入 REST path。
- `view`、`density`、`q`、`filter`、`sort`、`cursor` 和详情标签进入 query。
- 路由必须支持刷新、前进、后退和直接打开恢复。
- localStorage 只能保存纯显示偏好，不能成为实体、权限或业务状态 authority。

## 6. HWPOD 用户入口

### 6.1 数据流

```mermaid
sequenceDiagram
    participant Web as HWPOD 页面
    participant BFF as Cloud API BFF
    participant Svc as HWPOD Service
    participant Node as AI Gateway Node
    Web->>BFF: GET inventory/topology
    BFF->>Svc: 带主体与 correlation 的 typed query
    Svc-->>BFF: devices + nodes + blockers + cursor
    BFF-->>Web: 有界 DTO
    Web->>BFF: POST operation
    BFF->>Svc: 授权后的 operation request
    Svc->>Node: 按 nodeId 路由
    Node-->>Svc: in-flight / result / diagnostics
    Svc-->>Web: operationId 和可查询终态
```

### 6.2 设备资源

- 每个 HWPOD 必须显示稳定 hwpodId、nodeId、四要素、声明/实际能力、可用/占用/busy、主要 blocker 和最近 operation。
- PCB 设备卡片以四条可辨识链路表达 target、workspace、debug probe 和 io probe。
- 动效只能由真实连接、单 node in-flight、operation 进度或 capability mismatch 驱动。
- `prefers-reduced-motion` 下停止非必要循环动画；状态不得只依赖颜色。
- 列表模式必须保留相同状态语义，并提供服务端排序、筛选和详情深链。
- 设备深链必须提供工作区和操作工作面：
  - 左侧使用支持虚拟列表、键盘导航和按需展开的成熟 Vue 文件树组件；
  - 中间区域预览选中文本文件、路径、大小和不可预览原因；
  - 右侧或底部显示 build、download 和 UART operation 的状态、结果、artifact、
    returnCode 与结构化 blocker；
  - 工作区目录和文件选择进入 URL query，刷新、前进和后退后能够恢复；
  - 文件树只消费 HWPOD 服务的 typed workspace DTO，不直连 Windows 文件系统、
    SSH、共享目录或节点私有地址。
- 高频操作区必须支持编译、下载和串口：
  - 编译使用 spec 声明的 project 和 target，允许用户在声明集合内选择 target；
  - 下载只能消费成功编译产生或 spec 声明的 artifact，并要求明确确认；
  - 串口支持打开、关闭、发送文本和查看有界接收尾部，端口与波特率来自 spec；
  - 所有动作提交同一 HWPOD operation API，页面按 operationId 查询终态，
    不得将 accepted 或本地按钮反馈显示为执行成功。

### 6.3 HWPOD Node

- Node 集合同时展示已连接节点和 owning 配置声明但离线的节点。
- 每个 node 显示 nodeId、平台、版本、首见/末见、心跳、实际能力、in-flight、并发上限、诊断和挂载的零到多个 HWPOD。
- `service-ready`、`node-online`、`hwpod-available`、`leased/busy` 和 `capability-mismatch` 必须分别呈现。
- 在线但没有 spec、invalid spec 和声明/实际能力不一致必须形成可行动 blocker。

### 6.4 节点接入

- 页面消费 `/v1/hwlab-node/update` 和 `/v1/hwlab-node/download/hwlab-node.py` 的公开元数据。
- 下载区显示版本、文件名、大小、SHA-256、发布说明和安装条件。
- readiness 必须按 `downloaded`、`installed`、`desktop-visible`、`registered`、`workspace-ready` 和 `hwpod-ready` 分阶段展示。
- 节点使用主动出站 WebSocket，不为用户 PC 增加入站端口或直连地址兜底。
- 凭据仍只通过 YAML `sourceRef`/受控 CLI 下发；网页不得展示或生成可复用凭据。

## 7. 项目、用户和管理页面

### 7.1 Projects 与 MDTODO

- Projects 提供项目卡片/表格、状态/来源筛选、详情、任务活动和 blocker 深链。
- MDTODO 保留有界三栏、Rxx 树到正文到报告、Source/File 工具栏、inline edit、报告关闭/调宽/全屏和 RESTful 深链。
- MDTODO 只能通过公共 Project Management API 和 Workbench Launch API 联动，不 import Workbench 私有 store。
- 页面迁移不得改变 revision/fingerprint 冲突保护、source probe、reindex 和 launch context 语义。

### 7.2 用户与运营

- Dashboard 通过后端聚合 read model 提供继续项目/任务、HWPOD、额度和主要异常。
- API Keys、Usage、Billing 和用户集合统一使用服务端分页、筛选、深链和低频 Dialog。
- 未落地的支付、scope、轮换和跨设备偏好不得由前端占位成可用能力。

### 7.3 管理与系统工具

- Users、Access、Secrets、Billing 和 Provider Profiles 使用集合到 Inspector/详情到低频 Dialog 的一致路径。
- Secret 只展示对象、key、presence、fingerprint 和摘要，保留 dry-run/plan 与 YAML-first 边界。
- Performance、Gate、Skills 和 OpenCode 外壳按“状态到问题到证据到动作”渐进披露。
- Skills 不在缺少正式 API 时虚构删除或启停；OpenCode 保留同源 ticket、认证和安全 URL。

### 7.4 AgentRun 智能体运行观察

- 智能体运行观察属于“智能体管理”下的单一工作页：
  - 默认使用高密度表格；
  - 可切换图标卡片与关系树；
  - 三种视图共用同一查询、选择、排序、详情 Inspector 和 URL 深链。
- 页面事实流固定复用 [Workbench 实时权威](PJ2026-010401080313-workbench-realtime-authority.md)：
  - AgentRun 把规范事件写入 `agentrun.event.v1`；
  - HWLAB mapper 映射并写入 `hwlab.event.v1`；
  - Cloud API 从 Kafka retention 提供有界 replay SSE，并无缝交接 live SSE；
  - 浏览器使用单一 `agentObserver` reducer/store 归一化 task、run、command、attempt、runner 和 session；
  - 表格、卡片、树和 Inspector 只消费该 store 的共享 selector。
- 页面刷新和恢复只能通过 Kafka retention replay 到 live handoff 完成：
  - 浏览器断线后从已确认事件位置继续 replay；
  - 切换视图、打开 Inspector、调整密度或本地筛选不得新建请求源；
  - 后台恢复只重连同一产品事件流，不执行 snapshot 补偿；
  - reducer 按稳定 event identity 幂等，transport 状态与 AgentRun 业务状态分层表达。
- 本页面不得引入以下路径：
  - snapshot polling、定时轮询或页面级轮询 controller；
  - Cloud API 直查 AgentRun manager、queue、session 或其他 HTTP read model 补投影；
  - 数据库 projector、schema migration 或数据库 readiness 前置；
  - SSE 失败时切换 HTTP snapshot、旧 API、mock、字段猜测或第二 authority；
  - 表格、卡片、树或 Inspector 各自持有 EventSource、store 或状态推断。
- 防过载参数由 owning YAML 唯一声明：
  - Kafka retention 与 replay 有界窗口；
  - SSE heartbeat、重连、批次和客户端缓冲上限；
  - reducer 事件窗口、实体上限、树节点上限和详情尾部上限；
  - 页面只读取渲染配置，不在组件、store 或 API client 中保存第二套默认值。
- 页面状态必须区分：
  - 首次 replay、retention-to-live 交接、live、reconnecting、stale 和 error；
  - AgentRun admission、等待 runner、运行中、业务失败和终态；
  - transport 失败不得改写业务终态，最后成功投影不得伪装为当前 live。

## 8. 后端与服务边界

- 页面所需聚合优先由 typed BFF/read model 提供，不让前端跨服务猜测事实。
- 7.4 定义的智能体运行观察是事件流投影：
  - 只复用既有 Kafka retention replay SSE 与 live SSE；
  - 不为页面新增 snapshot BFF、AgentRun HTTP 聚合或数据库 read model。
- 只有独立数据所有权、生命周期、伸缩或连接故障域、权限边界成立时才拆微服务。
- 项目管理继续由独立 `hwlab-project-management` 拥有。
- 用户和账本事实继续由用户管理域拥有。
- HWPOD registry、topology、租约、operation 和诊断摘要由 HWPOD 服务域拥有。
- AI 网关拥有 node 连接、心跳、实际能力、adapter 执行和原始硬件事实。
- 若从 Cloud API 抽取 `hwlab-hwpod-service`：
  - Cloud API 只保留同源鉴权、路由和 correlation；
  - connection gateway 初期作为 HWPOD 服务内部模块；
  - 只有 socket 规模和 churn 构成独立故障域时再拆连接服务；
  - Python 文件继续通过版本化静态 artifact 交付，不创建独立安装服务。

## 9. 原子需求

### 9.1 CONSOLE-REQ-001 统一应用壳

云端控制台应提供按用户工作流组织的统一应用壳，并保留或原子迁移稳定 `navId`、ACL、同源 HttpOnly 会话和安全 redirect。

### 9.2 CONSOLE-REQ-002 通用页面能力

所有非 Workbench 页面应复用本规格定义的布局、集合、Overlay、Viewer、异步状态和路由能力；旧页面私有 Panel、Table、Dialog、Viewer 和重复 CSS 在迁移后删除。

### 9.3 CONSOLE-REQ-003 HWPOD 控制台

云端控制台应提供设备资源、HWPOD Node 和节点接入三个可深链子标签，并以 HWPOD 服务与 AI 网关的 typed 事实表达 node 到设备拓扑、readiness、blocker 和 operation。

设备资源深链应提供成熟文件树驱动的工作区浏览、文件预览、编译、下载和串口操作，
并与 CLI 复用同一 HWPOD operation、节点路由和终态结果合同。

### 9.4 CONSOLE-REQ-004 领域事实隔离

云端控制台不得通过字段猜测、名称去重、浏览器多接口拼装或 localStorage 生成硬件、任务、用户、权限、账本和评价事实。

### 9.5 CONSOLE-REQ-005 渐进披露与显示模式

集合页面应支持卡片与列表/表格切换；低频详情、诊断、日志、原始 JSON、配置和危险动作应进入 Inspector、Drawer 或 Dialog，并保持键盘和屏幕阅读器可达。

### 9.6 CONSOLE-REQ-006 响应式与性能

控制台应在桌面、紧凑桌面和手机宽度保持明确导航、滚动所有者与可操作主路径；长表、长树和长日志 DOM 必须有界，隐藏 pane 停止高频更新。

### 9.7 CONSOLE-REQ-007 智能体观察实时权威

AgentRun 智能体运行观察页应只消费 `agentrun.event.v1` 经 HWLAB mapper 进入 `hwlab.event.v1` 后形成的 Kafka retention replay SSE 与 live SSE，并由单一 reducer/store 投影表格、卡片、树和 Inspector；不得以 snapshot polling、AgentRun HTTP、数据库 projector、migration、fallback 或第二 authority 补齐页面状态。

## 10. 验收

- 规格与契约：
  - 每个页面组可追溯到唯一主责规格和稳定业务 ID；
  - typed API 不再向页面暴露关键事实的字段猜测；
  - Workbench 与 MDTODO 公共启动语义不回退。
- 视口与无障碍：
  - 覆盖 `1920x1080`、`960x600` 和约 `390px`；
  - 覆盖键盘、焦点圈定/恢复、Esc、ARIA 和 reduced-motion；
  - 无 document 级横向溢出。
- 状态与性能：
  - 覆盖 loading、refreshing、partial、empty、error 和 ready；
  - 覆盖大表、长树、长日志和隐藏 pane；
  - 卡片/列表共享同一状态和 blocker。
- 智能体运行观察：
  - 校对 `agentrun.event.v1` 到 `hwlab.event.v1` 的 lineage；
  - 校对 retention replay 到 live handoff、断线恢复、幂等去重和终态保持；
  - table/cards/tree 切换期间不得增加产品 EventSource 或请求源；
  - 页面不得访问 snapshot polling、AgentRun HTTP 或数据库投影入口；
  - 覆盖 replay、handoff、live、reconnecting、stale 和 transport error 的用户可见状态。
- HWPOD：
  - 覆盖一 node 多设备、声明离线 node、在线无 spec、invalid spec、capability mismatch、busy、update available 和诊断错误；
  - 验证 PCB 动效只由真实状态驱动；
  - 验证 Python 下载元数据和分阶段 readiness。
  - 验证工作区目录按需展开、文件预览、路径深链恢复和越界拒绝；
  - 验证 Web 编译、下载和串口动作提交 operation、显示 running 状态并取得真实终态；
  - 验证 accepted、节点离线、能力不匹配和节点执行失败不会被页面显示为成功。
- 原入口：
  - 使用 YAML 选中的 NC01/v03 Cloud Web origin；
  - 使用 `web-probe observe/command/collect/analyze` 保存 command、observer、截图和报告摘要；
  - 源码检查、构建通过和局部截图不能单独关闭执行任务。

## 11. 实现引用

- 本规格范围内新增或实质修改的源码文件应在文件头标注：
  - `SPEC: PJ2026-010405 云端控制台`；
  - `Implementation reference: draft-2026-07-13-p0-cloud-console`。
- 自动生成文件、第三方 vendored 文件、纯配置、锁文件和不能承载注释头的产物可例外；其生成器或入口必须能够追溯本规格。
