# PJ2026-010401 Web工作台

## 修改历史

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

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

## 正文

## PJ2026-010401 Web工作台需求规格

## 1. 文档控制

| 字段 | 内容 |
| --- | --- |
| 编号 | PJ2026-010401 |
| 短名 | Web工作台 |
| 层级 | L2 课题 |
| 状态 | 已生效 |
| 实现引用版本 | draft-2026-06-20-p0-long-running-workbench; draft-2026-06-20-p0-error-diagnostics; draft-2026-06-20-p0-passive-web-probe-observer; draft-2026-06-24-p0-no-ui-timing-fabrication; draft-2026-06-25-p0-web-caserun-e2e; draft-2026-07-17-p0-caserun-native-hmr; PJ2026-010401080313 Workbench实时权威 draft-2026-07-14-p0-pure-kafka-authority |
| 需求规格模板 | [ISO/IEC/IEEE 29148 需求规格模板](../../templates/iso-iec-ieee-29148-requirements-spec-template.md) |
| 上级规格 | [PJ2026-0104 客户端](PJ2026-0104-client.md) |
| 规格治理索引 | [规格治理](spec-governance.md) |

本文采用 ISO/IEC/IEEE 29148 需求规格模板的项目裁剪版：正文只保留 Web 工作台的稳定使命、范围、术语、系统边界、内部分工和原子需求。

## 2. 目的和范围

### 2.1 目的

Web工作台负责 HWLAB 登录后的浏览器主入口，使用户能够在同一 Web 工作面完成会话选择、任务输入、执行状态理解、结果查看和必要诊断。

本课题的目标状态是：主任务入口优先、诊断信息低噪声、状态反馈及时、桌面和移动端都能直接找到输入区，并且用户可以从基本工作台发起最小 Agent 调用并获得可查询执行状态。Web 工作台与 HWLAB CLI 必须共用同源 API、composer policy 和 trace renderer 语义，使浏览器问题可以通过同一运行端点的 CLI 非视觉复现。

长程可靠 Workbench 是本课题的黄金用例：用户在同一 public origin 内新建或选择 session，发送 `hi` 或等价最小任务，等待真实 Agent turn 运行，看到主消息区 final response 和 Trace terminal，随后刷新页面、切换到其他 session、再回到原 session、多标签页打开同一 deep link，仍看到同一组 sessionId、turnId、traceId、messageId、sealed final response 和 trace page。主 timeline 不等待完整长 Trace 全量拉完；Trace detail、projection diagnostic、transport diagnostic 和性能指标只解释可见性，不拥有主消息 lifecycle 或 final response 写权。trace/timeline 顺序、完成行位置、terminal sealed duration 和 SSE replay 必须来自唯一投影的 aggregate event stream revision，不能由浏览器 arrival order、trace detail 到达顺序、session list 刷新或 probe 后处理重排。

命令输入区的 prompt、steer、cancel 和 retry 都必须先成为唯一投影的 serve/session aggregate control command。Web 可以展示 optimistic placeholder，但不得从 DOM active card、session list、trace tail、localStorage 或 request timeout 推断 active turn、final response、running、duration 或 cancel 结果。

### 2.2 范围内

- 登录后 Cloud Web shell、topbar、导航、工作台路由、页面切换反馈和同源 API 状态展示。
- 会话列表、当前 session、用户消息、Agent 消息、命令输入区、发送、引导、取消、重试和 pending 状态展示。
- 基本工作台 Agent 调用，包括最小任务输入、发送、短返回执行标识、状态查询入口和失败原因展示。
- 工作台诊断入口、运行状态摘要、probe/build/HWPOD/Agent 状态的低噪声展示方式。
- CaseRun 用户入口，包括 HWPOD 资源选择、case 列表、run 提交、run stage、Trace、HWPOD evidence、artifact manifest、aggregate 和 blocker 展示。
- Workbench 公共 launch context 消费，包括从项目管理等外部登录后页面创建或选择 session，并把脱敏 `projectId/taskRef` 元数据写入 session projection。
- 桌面多栏布局、侧栏折叠、移动端工作台布局和输入区可达性。
- Web 与 HWLAB CLI 共用的 Code Agent composer policy、trace renderer 和同源 API 行为。
- Web 入口对用户管理、Agent编排、硬件池、HarnessRL 和平台运维输出事实的展示契约。
- Workbench 浏览器回归验证，包括基于真实采集脱敏 fixture 的 Playwright 独立测试、mock server 重放、状态投影断言和截图 artifact。
- Workbench 实时调试台，包括独立根导航、fake SSE/sync/detail fixture、无补洞单步 reducer 驱动、cross-page convergence 对比和请求禁用 ledger。

### 2.3 范围外

- 用户身份、角色、session、API key、额度和账本事实归 [用户管理](PJ2026-0105-user-management.md)。
- Code Agent session、trace、workspace、provider profile 和执行生命周期事实归 [Agent编排](PJ2026-0102-agent-orchestration.md)。
- HWPOD 资源、节点健康和硬件事实归 [硬件池](PJ2026-0101-hardware-pool.md)。
- CaseRun 评价、回放和训练反馈语义归 [HarnessRL](PJ2026-0103-harness-rl.md)。
- 公开入口、CI/CD、GitOps、Secret、FRP、Caddy 和 runtime 健康归 [平台运维](PJ2026-0106-platform-ops.md)。
- CLI 参数、CLI 输出和 HTTP API 契约仍归 [PJ2026-0104 客户端](PJ2026-0104-client.md) 中对应 L2 课题。
- 项目管理根导航、MDTODO source、Markdown 解析、任务投影、ProjectWorkbenchLink 和外部 PM adapter 归 [PJ2026-010404 项目管理](PJ2026-010404-project-management.md)。

## 3. 术语表

| 术语 | 定义 |
| --- | --- |
| Web工作台 | 登录后用于提交任务、管理会话、查看结果和进入辅助诊断的 Cloud Web 主工作面。 |
| 主任务区 | 用户完成主要工作流的区域，包括会话消息和命令输入区。 |
| 命令输入区 | 用户输入新任务、引导运行中任务、取消或重试任务的 Web 控件集合。 |
| 诊断入口 | 用户主动打开的工作台状态详情入口，通常以 topbar 内的小型按钮或状态图标呈现。 |
| Workbench实时调试台 | 独立于真实 Workbench 业务页的调试路由，用 fake fixture 单步驱动 reducer 和 UI 投影，验证高纯度 SSE、Kafka retention replay、detail-only 隔离和禁止补洞规则。 |
| 低噪声展示 | 诊断、trace、状态和辅助信息不抢占主任务区，也不伪装成用户或 Agent 正文。 |
| 响应式工作台 | 同一工作台在桌面和移动端按不同可视空间重排，但仍优先保证任务输入和状态理解。 |
| 同源业务入口 | Cloud Web 与 HWLAB CLI 通过同一 Web origin、相对 REST/JSON API path 和业务标识访问 HWLAB 能力的入口。 |
| Web CaseRun 视图 | Web 工作台或其相邻登录后页面中用于提交、观察和阅读 CaseRun 的用户界面。 |
| CaseRun run 卡 | 展示一次 CaseRun 的 runId、caseId、hwpodId、stage、Trace、HWPOD evidence、artifact manifest、aggregate 和 blocker 的紧凑工作态组件。 |
| WorkbenchLaunchContext | 项目管理等外部页面传给公共 Workbench Launch API 的脱敏启动上下文，Workbench 只把它作为 session metadata 保存和展示，不反解外部任务来源。 |
| ProjectTaskRef | 项目管理 API 返回的 opaque `taskRef`；Workbench 可保存和显示其摘要，但不得解析 Markdown、文件路径或 adapter 内部结构。 |
| selected Web origin | Web 工作台、CLI 和 web-probe 共同使用的 YAML-selected origin；默认 public，D601/v03 端到端验收可由 YAML 切换到 internal IP。 |
| 浏览器登录态 | Cloud Web 随同源请求携带的 `hwlab_session` Web session transport；前端只负责传递，不解释权限、project 归属或资源可见性。 |
| canonical identity | Web 工作台从 `/auth/session` 读取的最小身份结果，包含 actor、`authMethod`、`identityAuthority`、`sessionKind` 和 capability 摘要；它是 Web shell、导航和业务页面的唯一身份输入。 |
| Session权威入口 | Web 工作台按 sessionId 或后端认可的 opaque session handle 恢复当前会话消息、turn 摘要、trace 指针和状态的 RESTful detail API。 |
| 共享 trace renderer | Web trace 面板和 HWLAB CLI `trace --render web` 共用的 trace row 转换语义。 |
| Trace阅读视图 | 工作台中面向用户阅读 Code Agent trace 的默认视图，只展示用户可理解的助手消息、工具调用、命令输出、最终结果和真实耗时，把运行身份、隐藏统计和原始事件收束到消息详情入口。 |
| 消息详情入口 | Agent 消息头部右上角的小型详情按钮，用于按需查看 trace id、session、run、command、raw event、隐藏统计和审计控制等调试信息。 |
| 错误诊断块 | 用户可见错误下方的低噪声诊断信息，展示可复制 OTel `trace_id`、request id、route、错误 code 和脱敏时间戳；它不替代主错误文案，也不改写 Workbench 状态。 |
| Trace Explorer 链接 | 根据运行配置中的 `observability.traceExplorerUrlTemplate` 生成的打开 trace backend 入口；只有模板存在且 `trace_id` 合法时显示，URL 只替换 `{trace_id}`。 |
| Trace生命周期展开/折叠 | Code Agent turn 进入运行态时，Web 自动展开对应 Trace阅读视图；turn 进入终态时，Web 自动折叠该 Trace阅读视图，但仍允许用户手动重新打开。 |
| 工作态高密度 | 面向持续排障、比较和重复操作的工业化界面密度要求：低圆角、低内边距、正文优先、辅助元信息折叠，避免装饰性卡片和大块留白抢占工作内容。 |
| 正式公开入口 | 目标 node/lane 在 YAML 中声明的 Cloud Web public URL，用作用户访问、Playwright 验收、文档说明和故障复现入口。 |
| Workbench Server State | Web 工作台从 REST snapshot、SSE event、trace page 和 submit optimistic 归一化得到的服务端事实缓存。 |
| Timeline Projection | 只从 messages、parts、turn status 和 trace events 派生用户可见 timeline row 的渲染投影，不发请求也不写事实状态。 |
| Kafka event revision | [PJ2026-010401080313 Workbench实时权威](PJ2026-010401080313-workbench-realtime-authority.md) 定义的 Kafka cursor、entity version 或等价 `projectionRevision`；Web reducer 只能用它判断新旧，不得用网络到达顺序或本地时间重排 terminal/final/timing。 |
| 显示层本地 now | 浏览器组件为了展示“最近 X 秒前”和运行中“耗时 X 秒”而读取的当前时间；它只能作为直接渲染输入，不能写回 Server State、投影、session/message/turn lifecycle 或诊断事实，也不能通过平滑、滤波、单调 floor、跳变 cap 或二次缓存伪造一个更好看的时间事实。 |
| 实时权威 | [PJ2026-010401080313 Workbench实时权威](PJ2026-010401080313-workbench-realtime-authority.md) 定义的 `agentrun.event.v1 -> hwlab.event.v1 -> live/replay SSE -> reducer` 单一 Kafka 状态链路。 |
| Serve Session Authority | Workbench 会话级 typed event 权威；Web 的 run-state、message/part、trace/timing 和 final response 由同一 live/replay SSE reducer 收敛。 |
| session execution lane | [PJ2026-010401080313 Workbench实时权威](PJ2026-010401080313-workbench-realtime-authority.md) 定义的会话执行通道；Web 只能展示其 read model 和 diagnostic，不从 DOM active card 或本地 pending 状态推断是否复用了 runner。 |
| sealed final response | 唯一投影 terminal commit 写入的 assistant 主正文、finalResponse、message/turn terminal status 和 sealed 标记；它是主消息区用户结果的唯一权威，不被后续读侧诊断、trace detail 失败、旧 turn polling 失败或 SSE gap 覆盖。 |
| 破坏性投影权 | 删除 session、清空 active session、清空当前消息页、把 composer 改为无 session 或把 session lifecycle 改写为 not-found/archived/deleted 的权力。Web 前端 reducer、selectors、route hydrate、GET/list/detail/messages/SSE consumer 和测试 helper 没有破坏性投影权；只有显式用户 mutation 成功或后端 canonical lifecycle projection 可以改变这些事实。 |
| 读侧推理 | Web、API、CLI、fake-server 或测试根据 trace tail、message text、tool event、result cache、session summary、list row、workspace snapshot、localStorage 或 elapsed timeout 推断 lifecycle、terminal、running 或 final response 的行为；Web工作台禁止该模式。 |
| 0repair | Web 工作台在首次进入、刷新、deep link、session 切换、SSE 重连和 trace 补洞时必须按同一 authority 自然收敛；不得通过 reload、切走再切回、`sessionRepair`、`realignFreshSession`、workspace selection repair、active tab repair、GET read-through、localStorage truth 或测试 helper 自动点击，把已经分裂的 route/session/message/trace 状态补成看起来正确。 |
| 初发刷新一致性 | 同一 prompt 在初次发送、切换 session 后回到该 session、刷新页面和 SSE 重连后，都以同一 userMessageId、assistantMessageId、turnId 和 traceId 还原同一语义结果。 |
| 浏览器回归验证 | 使用 Playwright 在真实浏览器中验证 Workbench 用户可见行为、状态投影和 Trace 阅读正确性的前端端到端单元测试；测试过程使用本地 mock server，不依赖实时 Cloud API、AgentRun、HWPOD 或其他运行组件。 |
| 真实采集 fixture | 从目标 node/lane 的受控样本采集 Workbench REST、SSE、conversation、session、turn 和 trace 响应，经稳定伪 ID 映射与敏感字段脱敏后，用于浏览器回归验证的数据集。 |
| 长程 Web Observer | 在目标 node/lane 正式公开入口上启动真实浏览器并持续观测同一页面的客户端程序，用于发现长 Trace、session 切换、刷新恢复、滚动跟随和瞬态状态竞态。 |
| 纯客户端 web-probe | 只作为本地或目标 host 上的浏览器客户端进程运行的 web-probe 形态；它没有入站 HTTP/WebSocket/gRPC API、监听端口、数据库、队列、平台服务身份或业务状态写权。 |
| 被动采样 | 采样器不主动调用 Workbench 业务 API、不 reload、不自动点击、不修复 session、不拦截或重放网络请求，只读取 DOM、浏览器性能条目、控制台、页面错误和页面自然产生的网络事件。 |
| 命令文件 | `trans` 或受控 CLI 写入目标 host 文件系统的控制请求，例如登录、打开页面、发送 prompt、截图或停止；命令文件本身必须进入观测时间线。 |
| 页面权威 | 同一长程观测 job 中唯一拥有 Playwright browser/context/page 的客户端进程；控制循环和采样循环必须共享同一个 `page` 对象，页面重建必须记录连续性中断。 |
| JSONL 采样流 | 长程观测产物使用追加式 `.jsonl` 文件保存，每行一条带时间戳、单调序号、来源和脱敏标记的采样记录，便于长时间写入、局部复制和后处理分析。 |

## 4. 系统边界和接口

本规格把 Web工作台作为客户端方向下的浏览器入口课题看待；本章只描述输入、输出和责任边界。

| 边界项 | 内容 |
| --- | --- |
| 外部使用者 | 硬件研发用户、平台管理员、需要通过浏览器提交或观察任务的操作人员。 |
| 外部输入 | 登录后访问请求、页面导航、会话选择、任务文本、引导/取消/重试操作、诊断查看操作和管理入口点击。 |
| 受控资源 | Cloud Web shell、工作台路由、会话面板、对话面板、命令输入区、诊断弹窗、导航、响应式布局、composer policy 和共享 trace renderer。 |
| 外部输出 | 页面可见任务入口、会话状态、消息展示、命令反馈、诊断摘要、错误提示、可复制 OTel trace_id、可选 Trace Explorer 链接和可继续操作的 UI 状态。 |
| 用户接口 | 目标 node/lane 的正式公开入口、Cloud Web `/workbench` 及相关登录后页面。 |
| 系统边界 | Web工作台负责浏览器入口的布局、交互和展示契约；不拥有账号、Agent、硬件、评价或发布事实，只消费这些模块的服务端输出并以一致、低噪声、可操作的方式呈现。 |

## 5. 内部分工与规格索引

| 编号 | 模块或课题 | 规格文档 | 主责边界 | 上游依赖 | 下游支撑 |
| --- | --- | --- | --- | --- | --- |
| PJ2026-01040101 | 工作台框架 | 本规格 6.1 | 登录后 shell、topbar、导航、路由和页面切换反馈 | 用户管理、平台运维 | 用户主入口、管理入口 |
| PJ2026-01040102 | 会话输入 | 本规格 6.2 | 会话选择、消息展示、命令输入和任务操作反馈 | Agent编排、用户管理 | 用户任务提交和继续操作 |
| PJ2026-01040103 | 诊断反馈 | 本规格 6.3 | 诊断入口、状态摘要和低噪声详情展示 | Agent编排、硬件池、HarnessRL、平台运维 | 用户排障、管理员观察 |
| PJ2026-01040104 | 响应布局 | 本规格 6.4 | 桌面多栏、侧栏折叠、移动端主任务区优先和输入区可达 | 全部工作台子模块 | 桌面和移动端用户 |
| PJ2026-01040105 | 同源体验 | 本规格 6.5 | Web 与 CLI 共享 composer policy、trace renderer 和同源 REST/JSON API 行为 | HWLAB CLI、API契约、Agent编排 | Web/CLI 排障和内测复现 |
| PJ2026-01040106 | Trace阅读 | 本规格 6.6 | Code Agent trace 去噪、详情收纳、耗时、正文优先和单一主按钮状态 | Agent编排、API契约、用户管理 | 用户排障和任务继续操作 |
| PJ2026-01040107 | 公开入口 | 本规格 6.7 | 正式 Cloud Web public URL、history fallback 和旧入口降级边界 | 平台运维、API契约、用户管理 | 用户访问、Playwright 验收、内测说明 |
| PJ2026-01040108 | 状态投影 | 本规格 6.8 | server-state、reducer、selectors、timeline projection 和初发刷新一致性 | API契约、Agent编排 | Web timeline、session rail、trace detail |
| PJ2026-01040109 | 前端模块 | 本规格 6.9 | API client、event client、server-state、UI state 和组件职责拆分 | API契约、公开入口 | 可维护前端实现 |
| PJ2026-01040110 | 浏览器回归 | 本规格 6.10 | Playwright 独立测试、真实采集 fixture、mock server、截图 artifact 和状态投影断言 | API契约、平台运维 | Workbench 功能回归、防止刷新和会话切换退化 |
| PJ2026-01040111 | 长程观测 | 本规格 6.11 | 纯客户端 web-probe observer、命令文件控制、无副作用采样、JSONL artifact 和后处理分析 | 平台运维、公开入口 | Workbench 长程稳定性、瞬态竞态复现 |
| PJ2026-01040112 | CaseRun入口 | 本规格 6.12 | Web CaseRun 视图、run 卡、证据阅读、blocker 展示和 web-probe 同路径验收 | HarnessRL、API契约、硬件池、Agent编排 | 用户端到端硬件验证 |
| PJ2026-01040113 | 项目启动 | 本规格 6.13 | 公共 Workbench launch context 消费、session metadata 投影和项目任务解耦边界 | 项目管理、API契约、Agent编排 | `/projects/mdtodo` 一键启动 Workbench |
| PJ2026-01040114 | Workbench调试台 | 本规格 6.14 | 根导航调试入口、fake SSE 单步、authority gate、cross-page convergence 和请求 ledger | Workbench实时权威、唯一投影、API契约 | Workbench 状态投影单步排障 |
| PJ2026-01040115 | Native Temporal | 本规格 6.15 | 共享 dispatcher、Temporal workflow/activity、API/worker 分离、CLI 双 transport 和 Web HMR | Agent编排、API契约、平台运维 | Workbench 后端与前端敏捷开发 |

### 5.1 目标数据流程图

```mermaid
flowchart TD
  U[用户 prompt/steer/retry/cancel] --> C[Composer UI]
  C --> A[POST Turn Admission]
  A --> O[Optimistic user/assistant message IDs]
  A --> E[SSE /workbench/events typed events]
  A --> SY[/workbench/Kafka replay when needed]
  E --> R[Workbench Reducer]
  SY --> R
  SNAP[Initial snapshot] --> R
  DETAIL[Explicit detail/history] --> TD[Trace Detail Projection]
  O --> R
  R --> S[Workbench Server State]
  S --> P[Timeline Projection]
  S --> SR[Session Rail Projection]
  S --> TD[Trace Detail Projection]
  P --> UI[主 timeline]
  SR --> UI
  TD --> UI
```

目标数据流必须保证：提交请求只负责 admission 和稳定标识；主状态只接受 initial snapshot、`hwlab.event.v1` live/replay SSE 和可对账的 optimistic echo。显式 detail/history 只进入 detail 或 diagnostic bucket。晚到响应只能更新其声明的 session、turn、message 或 trace bucket，不能改变当前 active session、active route、当前消息区或 composer。

### 5.2 目标架构图

```mermaid
flowchart LR
  subgraph Browser[Cloud Web]
    API[WorkbenchApiClient]
    EVT[WorkbenchEventClient]
    STATE[WorkbenchServerState]
    RED[WorkbenchReducer]
    SEL[Selectors/Projection]
    UI[Session Rail / Timeline / Composer / Trace Detail]
    API --> RED
    EVT --> RED
    RED --> STATE
    STATE --> SEL
    SEL --> UI
  end
  subgraph CloudAPI[HWLAB Cloud API]
    ROUTE[REST/SSE Routes]
    DISP[Workbench Application Dispatcher]
    TC[Temporal Client]
    RM[Workbench Read Model]
    PROJ[Turn/Message/Trace Projection]
  end
  subgraph Temporal[Temporal]
    WF[Workbench Workflow]
    ACT[Workbench Activity]
  end
  ADAPT[AgentRun Adapter]
  subgraph AgentRun[AgentRun]
    RUN[run/command/runner]
    EV[events/result]
  end
  UI --> API
  EVT --> ROUTE
  API --> ROUTE
  ROUTE --> DISP
  DISP --> TC
  TC --> WF
  WF --> ACT
  ACT --> ADAPT
  ROUTE --> RM
  ROUTE --> PROJ
  PROJ --> RM
  ADAPT --> PROJ
  RUN --> EV
  EV --> ADAPT
```

Cloud Web 只拥有浏览器交互和投影；Cloud API 拥有 REST/SSE 合同和 read model；Agent编排和 HWLAB接入拥有执行事实映射；公开入口只负责将 Web/API/health 投递到目标 node/lane。

Temporal 只拥有 Workbench durable orchestration history、activity retry、cancel 和 worker restart recovery。AgentRun 继续拥有 run、command、runner 和最终执行结果；`hwlab.event.v1` live/replay Kafka 链继续拥有 Workbench 用户可见 running、terminal、Final Response 和 Trace 主状态。Temporal workflow、activity result、API 进程内状态和 CLI 不得合成或覆盖这些产品事实。

### 5.3 浏览器回归验证数据流图

```mermaid
flowchart LR
  subgraph Capture[受控真实采集]
    LIVE[D601 v0.3 Workbench REST/SSE]
    REDACT[脱敏与稳定伪 ID 映射]
    FIX[real-captures fixtures]
    LIVE --> REDACT
    REDACT --> FIX
  end
  subgraph Test[独立浏览器回归]
    MOCK[local mock server]
    WEB[Cloud Web build/preview]
    PW[Playwright browser]
    ASSERT[用户可见断言]
    ART[截图和 trace artifact]
    FIX --> MOCK
    MOCK --> WEB
    PW --> WEB
    PW --> ASSERT
    PW --> ART
  end
  OPS[D601 remote Playwright route] --> PW
```

浏览器回归验证的数据流必须保证：fixture 优先来自目标 node/lane 的真实受控样本；脱敏后保留 conversationId、sessionId、turnId、traceId、messageId 和 sourceSeq 之间的关系；mock server 只重放和变形这些事实，不成为新的业务事实来源；D601 远程 Playwright route 只负责执行与截图 artifact 回传，功能正确性仍由 Web工作台规格定义。

### 5.4 长程 web-probe observer 数据流图

```mermaid
flowchart LR
  subgraph Host[D601 或目标 node host]
    TRANS[trans 短连接控制]
    CMD[commands/*.json]
    OBS[web-probe observer 客户端进程]
    ART[.state/web-observe artifacts]
    ANALYZE[离线分析 job]
    TRANS --> CMD
    CMD --> OBS
    OBS --> ART
    ART --> ANALYZE
  end
  subgraph Browser[同一个 Playwright Browser/Context/Page]
    PAGE[Workbench page]
    DOM[DOM/scroll/performance 只读采样]
    NET[自然 request/response/requestfailed 事件]
    CONSOLE[console/pageerror]
    PAGE --> DOM
    PAGE --> NET
    PAGE --> CONSOLE
  end
  OBS --> PAGE
  DOM --> ART
  NET --> ART
  CONSOLE --> ART
```

长程 observer 的数据流必须保证：`trans` 只写命令文件和读取产物，不打开入站控制端口；observer 是目标 host 上的客户端进程，不是 Web 服务、daemon API、数据库消费者或平台状态源。控制命令、采样器和后处理分析共享同一份时间戳化 artifact；控制命令改变页面时必须记录为用户意图来源，采样器本身不得通过主动 API 请求、reload、自动点击、session repair 或网络拦截制造新业务事件。

### 5.5 PJ2026-010401080313 Workbench实时权威专项

[PJ2026-010401080313 Workbench实时权威](PJ2026-010401080313-workbench-realtime-authority.md) 是 Workbench 状态链路的唯一专项规格，集中定义 direct publish、`hwlab.event.v1`、live SSE、Kafka retention replay、同一 reducer、terminal seal、GET 纯读和代码引用规则。

Web工作台在本规格中只保留前端消费边界：Cloud Web reducer、selectors、session rail、timeline、composer 和 Trace detail 只能消费 initial snapshot 与同一 `hwlab.event.v1` live/replay SSE 合同；fake-server fixture 也只重放该合同。浏览器不得通过 `/v1/workbench/sync`、业务 REST fan-out、页面轮询、localStorage 或 trace tail 补写主状态。运行中相对时间只格式化事件提供的 canonical 时间字段，不产生新事实；异常必须暴露 diagnostic 并修 mapper、Kafka/SSE 或 reducer，不得恢复 PostgreSQL outbox authority。

[PJ2026-010401080313 Workbench实时权威](PJ2026-010401080313-workbench-realtime-authority.md) 是 Workbench 高纯度 SSE、Kafka retention replay、detail-only 隔离、禁止前端多源补洞和单步调试台的专项规格。Web 工作台新增或修改 EventSource、Kafka replay、detail/history、Colada key、server-state reducer 或 debug fixture 时，必须先遵守该专项的 authority gate、sealed guard、legacy fan-out 禁止路径和 fake SSE 单步验收。

[PJ2026-0106050514 Workbench实时运行面](PJ2026-0106050514-workbench-realtime-runtime.md) 是 Workbench 浏览器实时链路、防请求风暴和 freeze/blocker 的专项规格。Web 工作台新增或修改 SSE/EventSource、Kafka replay、health probe、explicit snapshot/detail/history refresh、timeline row、storage、scroll 或 runtime diagnostic 逻辑时，必须遵守该专项的 typed error、scoped key、queue/single-flight、SSE transport、browser memory policy 和 no-probe-masking 要求。卡死、内存上涨和请求风暴的修复不得落在 web-probe/Playwright 资源削减、自动刷新或 analyzer 降级上；这些探针只能提供证据和红灯。

长程可靠 Workbench 的用户可见验收矩阵如下，后续实现和回归验证必须直接引用这些稳定场景，而不是用单次 canary 或局部截图替代。

长程可靠 Workbench 还必须覆盖 AgentRun terminal outbox 恢复场景：同一 session 连续两轮提交后，即使 cloud-api 在中途重启、events page 没有 terminal event 或第 2 轮后 `lastTraceId` 已变化，用户仍应在第 1/第 2 轮 message card 看到 sealed terminal final response，并能打开每个历史 trace 的 events page。用户在上游 command 已 terminal 后点击 cancel，不得把 completed final response 改写为 canceled；Web 只能展示 already-terminal/no-op 或真实 terminal projection 的状态。

| 场景 | 权威事实 | 用户可见结果 | 禁止路径 |
| --- | --- | --- | --- |
| 新建 session 并发送最小 prompt | admission 写入稳定 sessionId、turnId、traceId、userMessageId、assistantMessageId | 当前消息区立即显示用户消息、assistant pending 和可追踪 running 状态 | 用 workspace selected snapshot 或本地 stub 伪造 session/message |
| terminal commit 后显示 final response | sealed message/part/turn/trace facts | 主 timeline 显示 sealed final response，Trace detail 显示 terminal | 旧 turn polling、SSE gap、trace detail error 覆盖主正文 |
| 刷新或 fresh deep link | durable session/message/turn/trace projection | 同一 session/turn/trace/message 恢复，composer 可继续操作 | `sessionRepair`、reload 后自动新建 conversation、localStorage truth |
| 切换 session 后返回 | route sessionId 和 read model bucket | 只更新目标 session bucket，不让迟到响应抢 active route | late response 覆盖当前消息区或 session rail |
| 长 Trace 分页 | `projectedSeq` cursor 和 durable terminal 字段 | 首屏消息先可见，Trace 分页继续加载且不丢 terminal | `hasMore=false` 推断 turn terminal 或全量扫描 live trace tail |
| completed/failed/canceled/blocked | sealed terminal result 或 failure result | 每种终态都有主消息 final 或 failure result，并把 transport diagnostic 分仓 | 诊断文案、result cache 或 trace tail 抢占主消息 final |

## 6. 原子需求

### 6.1 CLIENT-WB-REQ-001 工作台框架

| 编号 | 短名 | 主责模块 | 关联模块 |
| --- | --- | --- | --- |
| CLIENT-WB-REQ-001 | 工作台框架 | PJ2026-01040101 工作台框架 | [用户管理](PJ2026-0105-user-management.md)、[平台运维](PJ2026-0106-platform-ops.md) |

Web工作台应提供登录后的稳定 shell，使用户能够在同一浏览器入口看到当前身份、同源 API 状态、主导航、工作台内容和全局操作。

工作台框架负责浏览器层面的布局、导航、topbar 状态和页面切换反馈。用户身份和 session 有效性由用户管理提供；公开入口和运行健康由平台运维提供。工作台不得用旧页面块、临时状态行或原始运行日志替代稳定导航与反馈。

Web 工作台的 auth store 只能从 `/auth/session` 建立 canonical identity。路由 guard、topbar、admin 入口、Workbench、Usage、Billing 和 API keys 页面不得读取 user-billing token、API key secret、cookie prefix、Bearer token、localStorage authority 或旧测试后门。未登录时展示登录入口；已登录但能力不可用时展示后端结构化 blocker；前端不得通过二次登录、API key 输入或 fallback endpoint 修补身份。

### 6.2 CLIENT-WB-REQ-002 会话输入

| 编号 | 短名 | 主责模块 | 关联模块 |
| --- | --- | --- | --- |
| CLIENT-WB-REQ-002 | 会话输入 | PJ2026-01040102 会话输入 | [Agent编排](PJ2026-0102-agent-orchestration.md)、[用户管理](PJ2026-0105-user-management.md) |

Web工作台应让用户在主任务区直接选择或创建会话、阅读用户和 Agent 消息、输入任务、发起基本 Agent 调用、引导运行中任务，并看到发送、取消、重试和 pending 状态。

会话输入只负责用户可见的交互和消息呈现。基本 Agent 调用必须进入 Agent编排提供的执行生命周期，并返回用户可查询的 run、command、session 或等价状态入口；用户权限和会话有效性由用户管理提供。单条用户消息、trace 详情或状态摘要不得在默认视图中抢占主任务区，使用户难以继续输入。

Workbench 业务 API 的可见性只能由后端从 canonical principal 和 Workbench/Code Agent capability 判断。Web 不得把 billing 状态、API key 是否存在、project/workspace localStorage、session tab cache 或 conversation metadata 当作身份 authority；capability 不可用时必须保留当前身份并显示业务 blocker。

Web工作台必须使用显式 Agent session：无 session 时先让用户创建或选择 session，session failed、stale 或 canceled 时保留失败状态并要求用户显式切换或新建。刷新页面、重新打开工作台或短连接 result 轮询只能恢复已选 session、thread 和 trace 状态；除非用户登出或主动清空对话，不得自动生成新 conversation、替换 session 或用历史 prompt 拼接出续跑表象。

会话列表、当前消息头、composer 主按钮和运行态动效必须先确定唯一权威 API，再由 Web 展示该 API 的结果；不得让 workspace selected conversation、snapshot、stub、localStorage、message 派生状态、trace 快照或浏览器临时缓存与权威 API 并列竞争、互相覆盖或按失败路径 fallback 成另一套数据源。已经定下来的 authority 不变量如下：浏览器登录态只作为请求 transport；资源归属、project 可见性和权限由后端从当前 Web session/AuthPrincipal 判定；session rail 会话集合的主入口是 `/v1/workbench/sessions`，当前 session 消息本体的主入口是 `/v1/workbench/sessions/{sessionId}/messages`，session metadata 的主入口是 `/v1/workbench/sessions/{sessionId}`，turn 状态的主入口是 `TurnSnapshot`，Trace 阅读状态的主入口是 `TraceEventPage`。`projectId`、`workspaceId` 和 `conversationId` 可以作为后端返回的上下文字段、显式筛选字段或迁移期 metadata，但不得成为前端鉴权、资源可见性、active session 或 deep link 的 authority。深链恢复、刷新、从其他 session 切回和 route watcher 应走同一 session detail/message page 加显式 select/update 路径，不得先用 workspace selected snapshot、列表摘要或空 stub 覆盖当前 `messages`，再等待另一路请求补齐。

active session 只能由路由中的 sessionId 或用户显式选择产生。REST detail、session list、workspace summary、SSE event、trace page 或 turn snapshot 晚到时，只能更新其声明 `sessionId` 对应的 server-state bucket；不得重新选择 session、替换 URL、覆盖当前消息区、改变 composer 或把另一个 session 的 running/terminal 状态投射到当前页面。若 `routeSessionId`、`activeSessionId`、`activeConversationId`、message session 或 trace session 不一致，Web 必须暴露 authority mismatch/blocker 并让测试失败；不得通过 `sessionRepair`、`realignFreshSession`、reload、切走再切回或测试 helper 自动点击修正后判通过。

显式新建 session、用户点击 session 标签和用户确认删除 session 是 active selection 与 lifecycle 变化的 mutation authority。`POST /v1/agent/sessions` 或等价 create mutation 返回成功后，Web 必须立即把返回的 sessionId 作为当前 active session 投影到 URL、session tab、当前消息区和 composer；后续 `GET /v1/workbench/sessions`、session detail、messages、SSE、route hydrate 或 list refresh 的失败、404、空列表、网络瞬断、迟到响应和投影滞后，都不能删除该 session、清空 active selection、清空当前消息页、把 composer 变成 `session_required`，也不能把“无法读取详情”解释成该 session 不存在。deleted、archived、not-found 只能来自后端 canonical lifecycle projection，或来自用户显式 DELETE mutation 成功后的前端展示更新；前端读侧不得自己拥有破坏 projection 的权力。

用户切换 session 标签、通过深链进入 session 或从其他 session 切回时，若当前主工作区的 session detail/message page 尚未返回并应用，Web 工作台必须在主任务区显示明确的加载中转圈或等价 loading state。该状态表示已有会话正在加载，不等同于 Code Agent 已经加载完但尚未产生第一条可读消息的“思考中...”。Web 不得在主工作区尚未就绪时显示空对话、空 Code Agent 卡片、空 Trace 面板或静默留白，使用户无法判断切换是否生效。

当前 selected session 若需要出现在列表中，必须由 session list API 在显式 `includeSessionId` 或等价稳定业务 id 参数下返回，不得由后端隐藏读取 Web workspace selected 状态实现。Workspace API 只提供工作台选择、composer 配置和稳定业务 id，不作为 session 消息本体 authority；列表 API 只提供 rail 排序和摘要，不作为当前消息面板 authority。Web 只能把 route、用户显式选择或后端返回的稳定 session/turn/trace id 作为权威 API 的显式参数，不得把前端拼接出的 status、final response、markdown、running 动效或 stub 传回后端变成事实。Web 在权威 API 失败时只能保留上一份成功结果或显示未加载/错误态，不得从 workspace selected snapshot、stub 或本地缓存拼出单条 session tab、running 状态或 final response。运行中的 turn 必须同时反映在主任务区和对应 session tab；已进入终态的 turn 不得继续以 `Code Agent 处理中`、running 动效或旧 snapshot 文案呈现。

Agent 请求应采用短连接 submit 加 result/trace 轮询。`POST /v1/agent/chat` 或等价入口返回执行标识后，工作台通过 result 和 trace path 获取终态与可读过程，不持有一次长 HTTP 请求等待整个模型 turn。后端 result 已完成时，消息卡片必须替换为真实 final response；仍在 pending 或 trace 缺失时应显示明确状态，而不是把“result ready for polling”类中间文本当作最终回复。

### 6.3 CLIENT-WB-REQ-003 诊断反馈

| 编号 | 短名 | 主责模块 | 关联模块 |
| --- | --- | --- | --- |
| CLIENT-WB-REQ-003 | 诊断反馈 | PJ2026-01040103 诊断反馈 | [Agent编排](PJ2026-0102-agent-orchestration.md)、[硬件池](PJ2026-0101-hardware-pool.md)、[HarnessRL](PJ2026-0103-harness-rl.md)、[平台运维](PJ2026-0106-platform-ops.md) |

Web工作台应提供低噪声诊断反馈，使用户或管理员可以主动查看运行状态、probe、build、HWPOD 和 Agent 摘要，而默认工作区仍以任务输入和结果阅读为中心。

诊断入口应位于全局工作台区域，例如 topbar 内的小型信息或告警按钮，并通过弹窗或详情面板承载完整状态。诊断内容不得单独占用主任务区一整行，也不得默认插入 conversation 正文；缺失能力仍必须回到对应业务模块修复，不能用诊断文案代替能力实现。

所有用户可见错误都必须使用同一错误诊断块展示脱敏诊断字段。主文案先显示用户可理解的中文错误或业务 blocker；诊断行固定展示 `trace_id` 的复制入口，并在存在 `requestId`、route、error code、layer 或 observedAt 时以低噪声文本展示。没有服务端 trace id 的浏览器离线、DNS、CORS 或 network error 应使用前端 UI OTel trace id，并标记 `source=browser`，不得伪装成服务端 trace。

Trace Explorer 打开入口只由运行配置控制。前端不得在组件内硬编码 Tempo、Jaeger、Grafana 或平台内部地址；当 `observability.traceExplorerUrlTemplate` 缺失、`trace_id` 非 32 位十六进制或配置禁用打开入口时，只显示复制按钮。URL 构造只能替换 `{trace_id}`，不得拼接用户输入、`tracestate`、`baggage`、cookie、token、prompt、assistant 正文或 raw upstream payload。

错误诊断块适用于 Workbench admission 失败、projection blocker、transport timeout、SSE gap、trace detail error、Skills/Gate/Performance 等普通页面 API 错误和全局 route exception。各页面不得各自拼接一套中文诊断文案或只抛出 `Error(response.error)`；API client 应保留结构化 `ApiError` / `ErrorDiagnostic`，字符串只作为最终用户文案。

### 6.4 CLIENT-WB-REQ-004 响应布局

| 编号 | 短名 | 主责模块 | 关联模块 |
| --- | --- | --- | --- |
| CLIENT-WB-REQ-004 | 响应布局 | PJ2026-01040104 响应布局 | [Agent编排](PJ2026-0102-agent-orchestration.md)、[硬件池](PJ2026-0101-hardware-pool.md)、[平台运维](PJ2026-0106-platform-ops.md) |

Web工作台应在桌面和移动端保持主任务区可用：桌面端可以展示会话、对话和辅助资源多栏布局，移动端必须优先展示 topbar、对话和命令输入区。

响应布局负责把辅助面板、侧栏和诊断信息按可视空间收起、折叠或隐藏，使用户不需要滚动穿过导航和辅助面板才能找到输入区。桌面侧栏折叠必须真实释放宽度；移动端应避免页面外层滚动成为主要操作路径，主任务区内部可以按需要滚动。

### 6.5 CLIENT-WB-REQ-005 同源体验

| 编号 | 短名 | 主责模块 | 关联模块 |
| --- | --- | --- | --- |
| CLIENT-WB-REQ-005 | 同源体验 | PJ2026-01040105 同源体验 | [PJ2026-010402 HWLAB CLI](PJ2026-010402-hwlab-cli.md)、[PJ2026-010403 API契约](PJ2026-010403-api-contract.md)、[Agent编排](PJ2026-0102-agent-orchestration.md) |

Web工作台应与 HWLAB CLI 共享 Code Agent composer policy、trace renderer 和同源 REST/JSON API 语义，使浏览器工作流问题能用同一运行端点的 CLI 非视觉复现。

Web只负责浏览器交互与展示；CLI负责命令入口和结构化输出；API契约负责 path、schema 和错误语义；Agent编排负责执行事实。Web trace row 错乱、final response 缺失或发送状态异常等问题，应能先通过 CLI `trace --render web`、同源 REST request 和显式 Agent session 命令定位到共享 renderer、API 契约或浏览器表现层，不能让 Web 和 CLI 各自维护一套 trace 解释。

同源体验中的身份验证以 `/auth/session` 为最小验收端点。D601 线上 web-probe 和 fake-server Playwright 都应先覆盖 fresh login、刷新后 identity 一致、未登录结构化 unauthenticated 和脱敏边界，再进入 Workbench、Usage、Billing 或 API keys 的业务消费回归。业务页面碰巧可用不能替代最小身份验证通过。

工作台在增量刷新 trace、message 或 status 时，应保持用户已展开的详情状态和滚动位置。trace 压缩、sourceSeq 窗口或 event cap 只能影响默认摘要，不得吞掉可读 message、tool call、stderr/error 或 terminal 边界；需要完整事件时，Web 应通过 RESTful trace resource 自动请求完整可读事件，而不是让用户手工从原始日志中恢复上下文。RESTful trace resource 返回 `hasMore`、`nextSinceSeq` 或等价游标时，Web 必须继续通过同一资源入口分片请求，并在每个片段到达后立即合并渲染；不得等所有片段全部拉完才一次性显示，也不得为了补齐事件切换到 JSON-RPC、回放 Trace、内部 manager 或前端 fallback 路径。

### 6.6 CLIENT-WB-REQ-006 Trace阅读

| 编号 | 短名 | 主责模块 | 关联模块 |
| --- | --- | --- | --- |
| CLIENT-WB-REQ-006 | Trace阅读 | PJ2026-01040106 Trace阅读 | [Agent编排](PJ2026-0102-agent-orchestration.md)、[PJ2026-010403 API契约](PJ2026-010403-api-contract.md)、[用户管理](PJ2026-0105-user-management.md) |

Web工作台应提供面向用户的 Trace阅读视图，使用户默认看到从第一条有意义的助手消息、工具调用或最终结果开始的可读执行过程，而不是 request accepted、session reuse、thread/run/command 创建、runner job、backend 状态、token/chunk 或隐藏事件统计。

Trace阅读视图必须把 trace id、session、thread、run、command、event count、hidden count、raw event、follow/pause 和审计类控制收束到 Agent 消息头部右上角的消息详情入口。Trace 展开体只允许展示用户可读的运行记录本体，不得直接渲染 trace meta panel、身份 chip、隐藏事件统计、噪声聚合说明、原始事件开关或跟随/到底部等调试控件；这些内容只有在用户点击消息详情入口后才可见。

Web 工作台在会话恢复、session 切换、turn running、turn completed 或消息卡片重建时，必须按 traceId 自动调用 `GET /v1/agent/traces/{traceId}` 补齐 Trace阅读视图。`pending` 状态应展示加载转圈；completed 消息即使 final response 已可见，也必须自动加载对应 trace events，不得停留在空的“思考中...”记录。分片未拉完属于“加载中”，已经完成加载但仍无可读 Code Agent 消息才属于“思考中”。用户界面不得提供“回放 Trace”作为加载完整 trace 的必要操作。

工具调用和命令输出行必须正文优先：时间、状态、tool 名称和耗时只作为紧凑 header，不得占用独立左列或固定半屏宽度；stdout、stderr、error、patch、命令结果和助手 Markdown 应获得完整可用宽度。终端完成行和 Agent 最终消息应显示真实轮次耗时，耗时来源应使用 trace 事实、首尾事件时间或服务端 elapsed 字段，不得在已完成运行中显示 `00:00:00` 这类伪完成耗时。

运行中的 Agent 消息头部可以用浏览器本地 now 推进“最近”和“耗时”文案，但计算输入只能是唯一投影返回的 `startedAt` 与 `lastEventAt` 时间戳，并且必须是可解释的直接计算。`lastEventAgeMs`、本地 `updatedAt`、trace tail、events 数组长度或轮询间隔不得进入用户可见相对时间显示路径。消息进入 completed、failed、canceled、blocked 等终态后，耗时必须使用 sealed projection 的 `durationMs` 或等价 sealed `finishedAt - startedAt` 口径，且停止随浏览器 now 增长。前端不得保存 per-message timing floor、sealed duration cache、recent age cache 或其他本地状态来修正权威时间；若页面可见时间出现跳秒、归零、非单调或与 trace/轮次完成不一致，web-probe 应报告异常，修复点必须回到 projection writer/finalizer/read model 或上游事件时间戳。

Trace阅读视图属于工作态高密度界面。重复 trace row、message card、trace panel、warning 和 inline code 的圆角、间距和 padding 应保持紧凑；默认视觉层级以内容可扫读为主，不使用大圆角、大留白、嵌套卡片或装饰性布局制造工作区浪费。原始 trace 仍必须可审计，但只能作为消息详情入口中的主动展开内容，不得成为默认阅读面或 Trace 展开体的一部分。

Trace阅读视图必须跟随 Code Agent turn 生命周期自动调整展开状态：任务开始、pending 转 running 或首次出现运行中 trace 时，工作台应自动展开对应 trace，使用户能立即看到进展；运行中的 turn 进入 completed、failed、canceled、timeout、blocked 或出现 final response 等终态时，工作台应自动折叠对应 trace，回到正文和最终结果优先的阅读状态。自动折叠不得删除 trace、隐藏错误或阻止用户手动重新展开查看详情。若会话或 trace 在补拉前已经处于 final/terminal 状态，后续历史分片补拉完成不得触发自动折叠，也不得覆盖用户手动展开或折叠状态。

命令输入区应提供单一主按钮承载当前 turn 的主要动作：没有运行中 turn 时为发送新 Turn；存在运行中 turn 且输入框为空时为取消；存在运行中 turn 且输入框非空时为 Steer。工作台不得在运行已结束后继续显示独立的“取消运行中 Trace”按钮，也不得让发送、取消和 Steer 以多个并列主动作长期同时出现。

### 6.7 CLIENT-WB-REQ-007 公开入口

| 编号 | 短名 | 主责模块 | 关联模块 |
| --- | --- | --- | --- |
| CLIENT-WB-REQ-007 | 公开入口 | PJ2026-01040107 公开入口 | [平台运维](PJ2026-0106-platform-ops.md)、[PJ2026-010403 API契约](PJ2026-010403-api-contract.md)、[用户管理](PJ2026-0105-user-management.md) |

Web工作台的正式浏览器入口必须来自目标 node/lane YAML 声明的 public URL。用户文档、内测说明、Playwright 验收和 issue 复现默认使用该正式公开入口，不使用 FRP remote port、节点直连端口、旧 lane 端口或历史临时域名作为正式入口。

正式公开入口下，`/`、`/login`、`/workbench` 和登录后页面应由 Cloud Web 提供一致的 SPA history fallback。API path 仍由 API契约定义并返回 JSON 语义；Web工作台不得要求 API/edge 端口对浏览器 history route 返回 HTML fallback。

平台运维负责把 YAML 声明的 public URL、FRP、Caddy、TLS 和 health 投递到运行面；Web工作台负责在该入口上完成登录、工作台、导航和错误展示。实现端口可以作为诊断入口暴露给维护者，但不得出现在用户主入口、内测验收入口或客户端默认配置中。

### 6.8 CLIENT-WB-REQ-008 状态投影

| 编号 | 短名 | 主责模块 | 关联模块 |
| --- | --- | --- | --- |
| CLIENT-WB-REQ-008 | 状态投影 | PJ2026-01040108 状态投影 | [PJ2026-010403 API契约](PJ2026-010403-api-contract.md)、[Agent编排](PJ2026-0102-agent-orchestration.md) |

Web工作台应把 initial snapshot、SSE typed event、Kafka retention replay SSE 和 submit optimistic echo 统一归入 Workbench Server State。显式 trace detail/history 读取只进入 detail 或 diagnostic bucket，不拥有主状态写权。Server State 应按 sessionId、messageId、partId、turnId 和 traceId 归一化保存服务端事实；conversationId、projectId 和 workspaceId 只能作为后端 metadata 或兼容映射字段挂接在对应 session/message 上，不得作为 active 对象、权限判断或恢复路径的 authority。UI transient state 只保存 route、显式选择、composer draft、scroll、展开状态和临时交互状态。

Timeline Projection 只能从 messages、parts、turn status 和被主 authority 接受的 trace marker 派生用户可见 rows。Trace detail 只消费 detail/history projection；session rail 只消费同一 durable projection 的 session summary 和 turn summary；composer 只消费当前 route/selected session 与明确 running turn。组件、trace polling、submit/cancel 回调不得直接写 messages、final response、turn status 或 trace authority。

[PJ2026-010401080313 Workbench实时权威](PJ2026-010401080313-workbench-realtime-authority.md) 要求 Web 工作台把 `sessionId`、`messageId`、`partId`、`turnId` 和 `traceId` 作为 reducer 合并键，并同时检查 `realtimeAuthority`、entity family/id/version、Kafka cursor 和 `projectionRevision`。initial snapshot、live/replay SSE、submit optimistic 和 explicit detail/history 的任何 late response 都只能更新其自身 key 与授权 bucket 对应的事实，不得清空当前 selected session、覆盖已存在 sealed message、或用 list summary/localStorage/workspace snapshot 重建当前 timeline。

Message page 在刷新、切换 session、SSE 重连和 Kafka replay 后必须保持同一 turn timeline 顺序：同一轮用户输入应先于对应 assistant/agent terminal，跨轮次按 turn timeline/aggregate seq/事件时间排序，不得按 role、source table、投影写入批次或 `updatedAt desc` 形成 `UUAA`、`UUUAAA` 等用户消息聚簇。前端不得通过 DOM 后处理或本地排序掩盖 read model 聚簇；若 API 已经聚簇，修复点必须回到 WorkbenchReadModel 或 projection writer。

Session rail 的 title/preview 必须来自同一 durable message/part projection 的脱敏摘要，并随 session list/detail 返回稳定字段。仅当 read model 明确缺失 title/preview 时，UI 才能短暂展示 fallback `Session ses_*`；web-probe 与 OTel 必须把 fallback 数量、比例和示例暴露为 projection/read-model 问题，而不是把 fallback 当作正常标题。

Web 工作台严禁读侧推理。`turn.status`、`message.status`、`session.running`、`trace terminal`、`finalResponse` 和 `projectionStatus` 只能来自唯一 durable projection。Trace event row 的 `completed` 只表示该事件或工具行完成，不能终结 turn；message text 为空只表示无可展示正文，不能生成占位 final response；session list summary、workspace selected state、localStorage mirror、轮询耗时或 elapsed timeout 不能改写 running/terminal。若 API 返回缺字段、投影滞后或多字段矛盾，Web 只能展示 loading、degraded、unknown 或 blocker，并把问题暴露给投影层修复，不得在 reducer、selector、组件或测试 helper 中合成“看起来正确”的状态。

浏览器本地 now 只属于 view-layer render input。它不得进入 reducer action、store mutation、projection merge、lifecycle selector、session sorting、terminal 判定、transport diagnostic 或 fake-server fixture 事实生成。前端回归必须覆盖固定 projection timestamp 且无 SSE/API 更新时，运行中“最近”和“耗时”仍随 fake clock 前进；同时覆盖 terminal 消息耗时不随 fake clock 前进。

Web 工作台必须把主消息投影、trace detail、session status 和 transport diagnostics 分仓保存。对已经带有 `sealedAt` 或等价 sealed 标记的 assistant message/turn，旧 turn polling 失败、trace detail 失败、SSE gap、realtime timeout、late compat wrapper error 或 elapsed timeout 只能更新诊断 bucket 或消息详情入口，不得替换主 timeline 的正文、finalResponse、message status 或 turn terminal。`showMessageText()`、message diagnostic selector、Trace 面板和组件模板不得让读侧诊断文案压过 sealed final response；需要修改 sealed 主正文时只能来自同一 durable projection 的新 revision、受控 replay/reprojection 或明确用户 mutation。

错误诊断中的 `trace_id`、requestId、route、layer 和 code 只属于 diagnostic bucket。它们可以驱动复制按钮、Trace Explorer 链接、消息详情感叹号或 transport health 展示，但不得参与 `running`、`completed`、`failed`、`canceled`、`blocked`、finalResponse 选择、自动折叠、session active 选择或主消息正文替换。completed sealed final response 后出现的旧 polling、SSE 或 trace detail 错误只能追加诊断，不得把主消息正文改成“连接上游失败”“等待超时”或同类读侧错误态。

Web reducer/selectors 必须同时遵守无破坏性投影权。读侧路径中的 `forgetSession`、`replaceActiveSessionSelection(null)`、清空 messages、清空 tabs、把 composer 降级为 `session_required` 或把 route session 标记为 not-found/archived/deleted，都是 lifecycle mutation，不能由 GET/list/detail/messages/SSE 失败、空响应、404、route hydrate、refreshSessions 或 late response 触发。读侧只能把目标 session 的 loading、degraded、unknown、blocker 或 canonical lifecycle projection 展示出来；若需要删除、归档或失活，必须走后端 lifecycle projection 或用户显式 mutation 的成功结果。

初发刷新一致性是 Web 工作台的硬约束：同一 prompt 从 admission 开始生成稳定 userMessageId、assistantMessageId、turnId 和 traceId；初发 UI 可以 optimistic 展示这些 ID，但刷新、切换 session、SSE 重连和 Kafka replay 必须用同 ID 的 durable message、part、turn 和 trace projection 确认。若 trace detail events 缺失，只影响 trace detail；主 timeline 的用户消息、assistant final response 和 turn terminal 状态不得因此退化为“思考中”。

OpenCode 的参照边界是职责结构，不是技术栈照搬。可借鉴的边界包括 route/sessionKey 作为当前 session authority、per-session message/part cache、REST message page 与 optimistic message 通过同一 messageID 合并、SSE delta 只作为实时加速、完整 message/part snapshot 可重建刷新结果。HWLAB 不得继续让 workspace snapshot、trace polling、result polling、list summary 和 localStorage 共同竞争当前消息面板。

状态投影正确性必须能被独立浏览器回归验证覆盖。测试应在同一 Web 构建产物上使用 mock server 或 debug harness 重放真实采集 fixture，断言 session rail、主 timeline、workspace card、composer、message card 和 trace detail 在 session 切换、刷新页面、SSE 断线重连、Kafka replay 和 trace detail 分页后保持同一组 sessionId、turnId、traceId、messageId 与终态语义；conversationId/projectId/workspaceId 只可作为 metadata 被展示或调试，不得改变通过条件。测试不得依赖 live AgentRun、Cloud API、HWPOD、数据库或 Kubernetes 状态作为通过条件。

状态投影回归还必须覆盖 sealed final response：completed assistant 正文已经显示后，turn snapshot、trace event page、SSE 或 realtime diagnostic 返回 timeout/500/gap/close 时，主消息正文和终态保持不变，诊断只进入 trace detail、transport diagnostic、session health 或消息详情入口。测试必须用用户可见 DOM 断言，不通过内部 store 或 localStorage 判定通过。

浏览器回归验证必须先覆盖 0repair 红灯：fresh context 直达 session、普通点击切换 session、A session 延迟 detail/turn/trace/SSE 晚到、B session active、无用户新消息时，都不得让 A 的 user/agent 消息、running 状态或 trace 出现在 B。Playwright 和 web-probe 只能观察、连续截图和断言；不得用 reload、切换 session、`sessionRepair`、`realignFreshSession` 或 localStorage 修改把页面修正后再判通过。

### 6.9 CLIENT-WB-REQ-009 前端模块

| 编号 | 短名 | 主责模块 | 关联模块 |
| --- | --- | --- | --- |
| CLIENT-WB-REQ-009 | 前端模块 | PJ2026-01040109 前端模块 | [PJ2026-010403 API契约](PJ2026-010403-api-contract.md)、[PJ2026-010604 公开入口](PJ2026-010604-public-entry.md) |

Web 工作台实现应按职能拆分为 API client、event/SSE client、server-state store、reducer、selectors/projection、trace event projection、composer UI state、session rail UI state 和具体 UI 组件。server-state 模块不得写 UI transient state；UI 组件不得直接合并 REST/SSE 响应；projection 模块不得发请求或写状态。

新增或重构的核心前端文件头部必须标注遵循的 SPEC 编号、短名和实现引用版本，例如 `SPEC: PJ2026-010401080313 Workbench实时权威 draft-2026-07-14-p0-pure-kafka-authority; PJ2026-010401 Web工作台 draft-2026-06-20-p0-long-running-workbench; PJ2026-010403 API契约 draft-2026-06-20-p0-workbench-pure-read-api`，并简述文件职责。实现文件不得只写 issue 编号、`latest` 或 `current` 作为规格引用。

### 6.10 CLIENT-WB-REQ-010 浏览器回归

| 编号 | 短名 | 主责模块 | 关联模块 |
| --- | --- | --- | --- |
| CLIENT-WB-REQ-010 | 浏览器回归 | PJ2026-01040110 浏览器回归 | [PJ2026-010403 API契约](PJ2026-010403-api-contract.md)、[平台运维](PJ2026-0106-platform-ops.md) |

Web 工作台应建立可独立运行的 Playwright 浏览器回归验证，用真实采集脱敏 fixture 和本地 mock server 驱动 Cloud Web 页面，验证 Workbench 用户可见功能正确性。该验证属于 Web 工作台完成标准：平台运维只提供目标 node/lane 上的远程 Playwright 执行、截图和 artifact 回传能力，不定义 session、message、trace 或状态投影的功能断言。

mock 数据应优先来自目标 node/lane 的真实受控样本，而不是从零手写理想数据。采集范围至少覆盖 workspace selection、conversation list、conversation detail、session/turn snapshot、trace event page 和 Workbench event stream；采集产物必须记录 `capturedFrom`、`capturedAt`、schema/redaction 版本和脱敏状态，并删除 API key、cookie、auth header、DSN、provider token、真实用户身份和非公开 prompt。脱敏应使用稳定伪 ID 映射，保留 conversation、session、thread、turn、trace、message 和 sourceSeq 之间的关系，使刷新和事件重放可以验证同一事实链路。

合成 fixture 只能补足真实样本难以稳定覆盖的边界条件，例如延迟响应、SSE 断线、分页缺口、列表缺少当前选中项、可选字段格式异常、空集合和特定 HTTP 错误。每个合成 fixture 必须标明 `derivedFrom` 和 `syntheticReason`，不得替代可从真实运行面采集的常规会话、完成态、失败态或 Trace 数据。

浏览器回归验证至少覆盖以下用户可见路径：切换 session 后主工作区显示 loading 并恢复目标 session；fresh browser context 深链进入 session 后以同一 message、turn 和 trace 标识还原 timeline；SSE 事件重复、乱序、丢失或重连后通过 SSE replay 或Kafka retention replay SSE 收敛，不触发旧 trace/session/turn 多端点补洞；session 标签、workspace card、message card、composer 主按钮和 Trace 终态显示 running、completed、failed、canceled 等状态时保持一致；Trace 阅读视图按 detail/history 事件顺序渲染可读 row，正确处理分页、终态、失败、自动展开和终态折叠；深链进入 session 与普通点击 session 走同一 authority path，删除或归档 session 后 deep link 不得复活 archived active tab。

黄金链路回归必须覆盖完整用户流程：新建 session、发送 `hi`、running 可见、final response 可见、Trace terminal 可见、刷新、切换 session、回到原 session、删除或归档。长程链路回归必须使用真实采集脱敏长 Trace fixture，覆盖 detail 分页、SSE gap、Kafka replay、projection lag、terminal sealed、diagnostic 分仓和截图 artifact。两类回归都必须记录 fixture schema/redaction 版本、capturedFrom、capturedAt、derivedFrom、截图 SHA 或等价 artifact 校验值。

状态投影回归必须覆盖新建 session 后读侧失败的负向用例：用户显式 create mutation 成功并进入新 session 后，即使随后的 session detail、messages、list refresh、SSE、Kafka replay 或 route hydrate 返回失败、404、空列表或网络错误，URL、active tab、当前消息区和 composer 仍归属新 session；页面可以展示该 session 的 loading/degraded/blocker，但不得回退到旧 session、清空 active selection、清空 tabs/messages 或显示 `session_required`。这类用例必须作为 fake-server Playwright 红灯保留，线上 web-probe 只做同一 public origin 的原入口验收，不用 repair helper 修正页面后判通过。

状态投影回归还必须覆盖 completed assistant 已 sealed 后的读侧失败负向用例：fixture 中主 authority 已返回 completed final response，随后 turn snapshot、trace detail page、SSE、Kafka replay 或 realtime diagnostic 失败。主 timeline 的 sealed final response 不变，诊断只显示在详情/感叹号/transport health 区域；Trace detail 延迟返回或分页缺口不得 remount 主消息卡片，也不得重置用户展开/折叠控制。

错误诊断回归必须覆盖 HTTP 400、401、403、404、409、500、proxy timeout、network error、Workbench projection blocker 和 sealed final 后 transport error。fake-server fixture 应按正式 `HwlabErrorEnvelope` 或等价结构重放 `error.diagnostic.traceId`、requestId、route、code 和 `valuesRedacted=true`，并用用户可见 DOM 断言诊断块、复制入口和可选 Trace Explorer 链接；测试不得通过内部 store、localStorage 或测试专用后门读取诊断字段。

测试实现应优先使用用户可见文本、ARIA role 和稳定 DOM 标识断言，不通过内部 store、localStorage 或后端数据库直接判定通过。失败时必须保留 Playwright screenshot、trace 或等价 artifact；关键路径可以生成命名截图用于人工审阅。远程执行默认在目标 node/lane 上通过 UniDesk Playwright route 运行，截图和报告应回传到调用端，但这些 artifact 只是验证证据，不进入业务事实或监控指标。

### 6.11 CLIENT-WB-REQ-011 长程观测

| 编号 | 短名 | 主责模块 | 关联模块 |
| --- | --- | --- | --- |
| CLIENT-WB-REQ-011 | 长程观测 | PJ2026-01040111 长程观测 | [PJ2026-010604 公开入口](PJ2026-010604-public-entry.md)、[平台运维](PJ2026-0106-platform-ops.md) |

Web 工作台应具备长程 web-probe observer 能力，用真实浏览器在目标 node/lane 的正式公开入口上持续观察同一页面，用于复现和分析长 Trace、session 切换、刷新恢复、滚动跟随、final response 闪烁和无用户新消息时状态变化等瞬态问题。该能力只提供观察和证据，不拥有 Workbench 业务状态、身份鉴权、session lifecycle、projection、监控指标或修复权。

长程 observer 必须显式选择运行面。L1 native 使用 `--origin native`，并且只从目标 node/lane owning YAML 的 `nativeDevelopment.workbench.publicExposure.publicBaseUrl` 解析固定 HTTPS 入口；L2/L3 继续使用部署态 `internal` 或 `public` semantic origin。CLI 不得用自定义 URL、部署态 public URL、localhost 或隐藏 fallback 冒充 L1 证据，后续 command、status、collect、analyze 和 stop 必须继承 observer 启动时冻结的运行面与 origin。

web-probe observer 必须保持纯客户端形态。它可以作为目标 host 上的长时间本地进程运行，但不得暴露入站 HTTP/WebSocket/gRPC API、监听控制端口、数据库 schema、消息队列消费者、Kubernetes 常驻服务、平台 daemon 或 Web 管理面。启动、停止、状态查看、命令投递和 artifact 回收只能通过受控 CLI、`trans` 短连接和目标 host 文件系统完成。任何需要长期保留的默认参数必须按 YAML-first 进入 UniDesk 自有配置；一次性控制命令使用命令文件，不得演变为新服务协议。

同一个 observer job 内必须只有一个页面权威。Playwright browser/context/page 由 observer 客户端进程持有；控制循环、采样循环、截图逻辑和网络事件监听共享同一个 `page` 对象。登录、打开 URL、发送 prompt、点击会话、截图和停止等控制动作以命令文件进入 `commands/pending`，处理结果追加到 `control.jsonl`，并带上命令 id、时间戳、操作者来源、执行前后 URL 和页面标识。若浏览器或页面崩溃后必须重建，observer 必须记录 oldPageId/newPageId、原因和连续性中断，不能把重建后的页面当作同一段无缝采样。

采样默认必须无副作用。采样器不得主动 `fetch` Workbench 业务 API、不得 reload 页面、不得自动点击、不得切换 session、不得调用 session repair helper、不得通过 `page.route()` 拦截或改写请求，也不得用 GET 触发 read-through repair。允许采集的默认输入只包括 DOM 快照摘要、可见文本摘要、当前 URL、scroll metrics、focus/selection、`performance` 条目、console/pageerror、Playwright 自然产生的 `request`/`response`/`requestfailed` 事件和用户控制命令造成的页面自然网络事件。网络记录必须标明 `observerInitiated=false`；若未来确需主动 API 探针，必须作为显式非默认模式记录 `observerInitiated=true`，并从被动证据分析中排除。

长程采样产物必须使用时间戳化目录和 JSONL 追加文件。推荐目录形态为 `.state/web-observe/<node>/<lane>/<YYYY>/<MM>/<DD>/<timestamp>_<target>_<jobId>/`，其中 `manifest.json` 记录目标 origin、node、lane、browser 版本、observer 版本、启动参数和脱敏策略；`heartbeat.json` 保存最近心跳；`control.jsonl`、`samples/*.jsonl`、`network/*.jsonl`、`console/*.jsonl`、`pageerrors/*.jsonl`、`anomalies/*.jsonl` 分别承载控制、采样、网络、控制台、页面错误和异常。每条 JSONL 记录必须包含 ISO 时间、单调序号、pageId、url、recordType、source、valuesRedacted 和 schemaVersion，避免长程文件被一次性整块读取或写坏。

截图策略应受预算控制。默认不做高频全页截图；常规 checkpoint 可使用 viewport 或关键区域 JPEG，并配置质量、间隔、最大张数和总字节预算；异常、失败、布局错乱和人工标记证据使用 PNG 或等价无损格式保存。每张截图必须记录触发原因、文件 SHA、字节数、viewport、deviceScaleFactor、关联 sample seq 和脱敏状态。重复截图应通过内容 hash 或视觉 hash 去重；超过预算时优先保留异常、状态切换和人工命令附近的证据。

离线分析 job 只能读取 artifact，不访问 Workbench 业务 API，也不修改浏览器页面。分析至少应覆盖：active session 是否跳转、route/session/message/trace 是否不一致、没有用户命令时是否出现新 agent 消息、final response 是否从 sealed 正文闪回错误态、Trace 是否长时间无 terminal、Trace 窗口和主工作区滚动是否跳顶、运行中“最近/耗时”是否停止刷新、自然网络响应与 DOM 可见状态之间的延迟。分析结果写入 `analysis/report.md` 和结构化 `analysis/report.json`，作为 issue 和回归修复证据，不成为产品业务状态。

长程 observer 不替代 fake-server Playwright 回归。fake-server Playwright 负责确定性功能红灯和修复后回归；observer 负责在线 public origin 的长时间、无副作用、瞬态观测。observer 发现的 bug 必须沉淀成可复现 fixture 或 fake-server 用例后再作为 Web 工作台功能回归闭环；不得用 observer 的自动切换、reload、repair 或人工观察代替功能修复。

### 6.12 CLIENT-WB-REQ-012 CaseRun 入口

| 编号 | 短名 | 主责模块 | 关联模块 |
| --- | --- | --- | --- |
| CLIENT-WB-REQ-012 | CaseRun入口 | PJ2026-01040112 CaseRun入口 | [HarnessRL](PJ2026-0103-harness-rl.md)、[PJ2026-010403 API契约](PJ2026-010403-api-contract.md)、[硬件池](PJ2026-0101-hardware-pool.md)、[Agent编排](PJ2026-0102-agent-orchestration.md) |

Web 工作台应提供 CaseRun 用户入口，使用户能在登录后的 selected Web origin 中查看可用 HWPOD 资源和 case 列表，提交 CaseRun，看到 runId 和短返回状态，并在同一页面或相邻登录后页面观察 run stage、Trace、HWPOD evidence、artifact manifest、aggregate 和失败 blocker。

CaseRun 入口应保持工作态密度。HWPOD 资源卡应展示资源身份、连接/可用状态、能力摘要和关键 blocker；case 列表应展示 caseId、目标硬件和执行范围；run 卡应以 queued、preparing、agent-running、building、downloading、uart-reading、aggregating、completed、failed、canceled、blocked 等状态表达进度。Trace、download/UART 原始片段和 artifact manifest 可以折叠，但 aggregate、终态、主要 blocker 和继续查询标识必须默认可见。

CaseRun 独立页必须能发现并加载共享 registry 中已经存在的运行，包括由 HWLAB CLI `--over-api` 提交并完成的 run。页面应提供最近运行列表和 runId 直达入口；选择历史项、粘贴 runId、直接访问 `/caserun/runs/:runId` 或刷新深链必须读取同一 status、events 和 aggregate 资源，不得复制运行结果、扫描 CLI 本地目录或根据列表摘要合成终态。CLI local 模式的结果只有经过未来独立定义的显式发布合同后才能进入共享 registry，本入口不得静默上传。

Web 工作台只调用 YAML-selected origin 下的同源 CaseRun API 和既有 Trace/aggregate/HWPOD 读侧入口。它不得直接访问 HWPOD node、本地 gateway、旧 v0.2 runner、数据库、Kubernetes、SSH 或未在 YAML 声明的临时内部服务来提交或判断 CaseRun。若 API 返回 HWPOD workspace missing、node offline、capability mismatch、probe mismatch、serial-monitor unavailable、AgentRun blocker 或 aggregate missing，Web 必须展示对应结构化 blocker 和可复制诊断，而不是改写为通用请求失败。

CaseRun 前端必须支持独立 native 开发。Vite HMR 与 repo-owned native CaseRun test API 应能分别启动和热重载，前端不依赖 live Kubernetes、AgentRun、HWPOD 或生产数据库即可验证 queued、running、completed、failed、blocked、canceled、events 和 aggregate 展示。native test API 必须使用与生产 HarnessRL API 相同的 DTO 和相对 path，并显式返回 `mode=native-test`；它不得进入生产配置、selected origin 或线上 fallback。

前端 native fixture 只提供确定的服务端状态序列。store、selector 和组件不得根据 elapsed time、HTTP 200、事件数量、按钮点击或 fixture 名称推断 terminal；Temporal workflow identity、stage、terminal、blocker 和 aggregate 仍只能来自 API read model。native 浏览器 smoke 通过不能替代 selected origin 的线上回归。

线上 web-probe 对 CaseRun 的验收必须从同一 selected Web origin 进入。默认使用正式 public origin；本次 D601/v03 可以由 YAML 切换到 internal IP origin。web-probe 可以点击页面控件或调用页面同源正式 mutation，但不得绕过 Web session、不得使用未被 YAML 选中的内部 service URL、不得直接写 D601 文件系统、不得用 SSH 或手工 CLI 操作补齐硬件证据。web-probe 报告至少应记录 originMode、YAML source path、final URL、截图 SHA、caseId、runId、hwpodId、nodeId、traceId、HWPOD operation result 引用、aggregate 或 artifact manifest hash，以及是否存在用户可见 blocker。

### 6.13 CLIENT-WB-REQ-013 项目启动

| 编号 | 短名 | 主责模块 | 关联模块 |
| --- | --- | --- | --- |
| CLIENT-WB-REQ-013 | 项目启动 | PJ2026-01040113 项目启动 | [PJ2026-010404 项目管理](PJ2026-010404-project-management.md)、[PJ2026-010403 API契约](PJ2026-010403-api-contract.md)、[Agent编排](PJ2026-0102-agent-orchestration.md) |

Web 工作台应提供公共 launch context 消费能力，使项目管理等登录后页面可以通过 `POST /v1/workbench/launches` 创建或选择 Workbench session，并把脱敏 `projectId`、`taskRef`、`sourceKind`、title 摘要和 prompt template 标识保存为 session metadata。

Workbench 对 launch context 的使用必须保持只读和脱敏。它可以在 session header、message detail 或诊断入口展示项目来源摘要，也可以把 metadata 传给 Agent turn admission；但不得反解 `taskRef`、读取 Markdown、调用 Project Management 私有 adapter、访问 PM DB、import MDTODO 页面组件或把项目管理状态写入 Workbench reducer。

项目管理页面跳转到 `/workbench/sessions/{sessionId}` 后，Workbench 必须按既有 session detail、message page、turn snapshot 和 trace event page authority hydrate。`projectId/taskRef` 只作为 metadata 和后续查询 link 的 ID，不得替代 sessionId、turnId、traceId 或 messageId 成为 Workbench authority。

Workbench 模块不得为了项目管理联动新增 iframe、嵌套 Workbench 容器、localStorage 协议、私有 service URL、跨模块 store import 或 Markdown parser 依赖。需要回到项目任务时，只能使用公共 project link URL 或公共 Project Management API 暴露的 link 摘要。

### 6.14 CLIENT-WB-REQ-014 Workbench 调试台

| 编号 | 短名 | 主责模块 | 关联模块 |
| --- | --- | --- | --- |
| CLIENT-WB-REQ-014 | Workbench调试台 | PJ2026-01040114 Workbench调试台 | [PJ2026-010401080313 Workbench实时权威](PJ2026-010401080313-workbench-realtime-authority.md)、[PJ2026-010403 API契约](PJ2026-010403-api-contract.md) |

Cloud Web 应提供独立 Workbench 实时调试台，用于单步验证高纯度 SSE、Kafka retention replay、detail-only 隔离和状态投影收敛。推荐入口是根侧边栏中的独立导航项和独立路由，例如 `/workbench/debug`，而不是继续扩展现有 Workbench topbar 诊断弹窗。原因是单步调试需要深链、fixture 选择、事件播放控制、请求 ledger、cross-page 对照和 Playwright 直达，长期嵌在真实 Workbench 会污染用户任务流和真实 store。

调试台必须默认使用隔离 store/reducer harness。纯 SSE 与 Kafka replay 模式只消费 fake typed event 数组或 fake EventSource adapter；任何自动 `/v1/workbench/sync`、`/v1/workbench/turns/:id`、`/v1/workbench/sessions/:id/messages`、`/v1/workbench/traces/:id/events` 或旧 `/v1/agent/*` 请求都必须进入 request ledger 红灯。

调试台至少应提供这些子标签页：纯 SSE 单步、Authority Gate、Terminal Seal、Reconnect/Cursor、Cross Page、Detail Only、Snapshot Merge、Fake Provider 和 Request Ledger。每个子标签页应输出 event header、authority decision、state diff、DOM-like projection、expected verdict 和可复制的 bounded 证据。Fake Provider 页可使用 fake-echo/fake model provider 的脱敏 fixture 或合成事件序列，但不得依赖真实 provider 成败作为通过条件。

调试 fixture 必须可版本化。每个 fixture 至少记录 `fixtureId`、`schemaVersion`、`capturedFrom` 或 `derivedFrom`、`syntheticReason`、redaction 状态、输入事件列表和 expected verdict。真实采集 fixture 优先；合成 fixture 只覆盖字段缺失、version 回退、duplicate cursor、late running、detail-only、跨页面到达顺序差异和 provider stream disconnect 等边界条件。

调试台不拥有业务修复权。它不得创建真实 session、发送真实 prompt、改写 localStorage truth、持久化用户 Secret、访问未授权 debug API 或在生产 Workbench 页中安装 repair helper。调试台发现的红灯应沉淀为单元测试、fake-server Playwright 用例、web-probe analyzer 规则或 GitHub issue 证据，再回到 projection/read model/reducer 修复。

### 6.15 CLIENT-WB-REQ-015 Native Temporal

| 编号 | 短名 | 主责模块 | 关联模块 |
| --- | --- | --- | --- |
| CLIENT-WB-REQ-015 | Native Temporal | PJ2026-01040115 Native Temporal | [Agent编排](PJ2026-0102-agent-orchestration.md)、[API契约](PJ2026-010403-api-contract.md)、[平台运维](PJ2026-0106-platform-ops.md) |

Workbench 后端必须共享 contracts、repository port 和 application dispatcher。Cloud API adapter 只处理 HTTP envelope、鉴权、状态码和 correlation；默认 local CLI 直接调用 dispatcher，显式 `--over-api` 只切换 transport，两种模式必须保持相同 command DTO、typed error、identity 和 submit-and-poll 合同。不得保留 `--overapi` 别名、CLI 私有业务实现或只在 HTTP 路径成立的隐藏默认值。

Workbench mutating orchestration 必须进入 deterministic Temporal workflow，文件系统、网络、AgentRun adapter、repository 和时间相关副作用必须进入幂等 activity。API 与 worker 必须是独立进程和独立部署对象，可分别启动、停止、重启、观察和健康检查；worker 不建立公网业务入口。API 或 worker 重启不得丢失已被 Temporal 接纳的 operation，也不得依赖 API 进程内 Promise、Map 或 Pod 本地文件恢复 workflow。

Temporal 只负责 durable orchestration、activity retry、cancel 和 worker restart recovery。AgentRun 继续拥有 agent run/command/runner 执行事实；Workbench实时权威专项定义的 `hwlab.event.v1` live/replay Kafka 链继续拥有用户可见 message、running、terminal、Final Response 和 Trace 主状态。dispatcher、workflow、activity、CLI、API 和 native fixture 都不得从 Temporal status 或 activity 返回值合成这些产品事实。

Workbench 必须提供 repo-native L1 开发形态。owning YAML 声明 Temporal serviceRef、logical namespace、task queue、timeout/retry、native API/worker/Web entrypoint、端口、PID、日志和 state 目录，以及 API/worker 独立部署对象。开发者能够在 Kubernetes 外分别启动 native worker、native API 和 Vite HMR；前端连接 repo-owned native API/test service，并继续使用生产 DTO 与相对 path。native fixture 必须显式返回 `mode=native-test`，不得进入 production 配置、selected origin 或线上 fallback。

交付顺序必须先完成 L0/L1 smoke，再由 `v0.3` PR merge 触发现有 GitHub webhook、Gitea snapshot、PaC、Tekton、GitOps/Argo 自动链。native smoke 至少验证真实 workflow/activity、CLI local/`--over-api` 等价、cancel、API restart、worker restart recovery，以及 Vite HMR 下 create/send/running/final/trace/refresh；L2 回归必须验证 API/worker 独立 Ready、部署态 CLI、Kafka live/replay 和公网 Workbench fresh turn。禁止人工 PipelineRun、mirror sync、Argo sync、Compose、direct Kubernetes apply 或 fake production fallback。

## 7. 过程控制

本规格不单独索引过程 issue；跨 L1 的内测、灰度和阶段活动索引统一保留在 [PJ2026-01 HWLAB 总规格](PJ2026-01-HWLAB.md) 的 `7. 过程控制`。
