docs: add workbench realtime runtime spec

This commit is contained in:
Codex
2026-06-30 10:17:40 +00:00
parent 73ea3c750b
commit 5c05edcb9e
2 changed files with 240 additions and 0 deletions
@@ -302,6 +302,7 @@ session 切换必须分别记录 `first_visible` 和 `full_load`。first visible
| PJ2026-0106050511 | 分叉禁令 | 本规格 6.11 | 禁止 collectorStatus 旁路、读侧 repair、fallback、bucket 上界冒充精确值和跨族仲裁 | Workbench唯一投影、Web工作台 | 后续迁移和回归 |
| PJ2026-0106050512 | SLO治理 | 本规格 6.12 | SLO、阈值、告警准入、用户可见页面和内部告警职责分离 | 运维监控、YAML运维 | 持续治理和维护 issue |
| PJ2026-0106050513 | Redis读缓存 | 本规格 6.13 | Workbench Redis 派生读缓存的指标、SLO、YAML-first 参数和降级可见性 | Workbench唯一投影、API契约、YAML运维 | D601 v0.3 sessions/turn/trace 高频读降尾延迟 |
| PJ2026-0106050514 | Workbench实时运行面 | [PJ2026-0106050514 Workbench实时运行面](PJ2026-0106050514-workbench-realtime-runtime.md) | SSE、错误处理、队列、缓存、timeline、storage、scroll、health、OTel 和 Web 哨兵冻结探测的迁移边界 | Web工作台、Workbench唯一投影、API契约、Web哨兵、YAML运维 | JD01 Workbench 多轮卡死和请求风暴治理 |
## 6. 原子需求
@@ -0,0 +1,239 @@
# PJ2026-0106050514 Workbench实时运行面
## 修改历史
| 版本 | 对应 commit id | 更新日期 | 变更说明 |
| --- | --- | --- | --- |
当前正文仍在规格治理草稿中;未定稿前不新增版本号,不为单次编辑追加 `待提交` 版本。
## 正文
## PJ2026-0106050514 Workbench实时运行面需求规格
## 1. 文档控制
| 字段 | 内容 |
| --- | --- |
| 编号 | PJ2026-0106050514 |
| 短名 | Workbench实时运行面 |
| 层级 | L4 专项规格切片 |
| 状态 | 草稿 |
| 实现引用版本 | draft-2026-06-30-p0-1297-spec-first |
| 需求规格模板 | [ISO/IEC/IEEE 29148 需求规格模板](../../templates/iso-iec-ieee-29148-requirements-spec-template.md) |
| 上级规格 | [PJ2026-01060505 Workbench性能](PJ2026-01060505-workbench-performance.md) |
| 关联规格 | [PJ2026-010401 Web工作台](PJ2026-010401-web-workbench.md)、[PJ2026-0104010803 Workbench唯一投影](PJ2026-0104010803-workbench-unique-projection.md)、[PJ2026-010403 API契约](PJ2026-010403-api-contract.md)、[PJ2026-01060508 Web哨兵](PJ2026-01060508-web-probe-sentinel.md)、[PJ2026-010603 YAML运维](PJ2026-010603-yaml-first-ops.md) |
| 规格治理索引 | [规格治理](spec-governance.md) |
本文定义 Workbench 浏览器实时运行面的迁移边界:SSE、错误处理、限流/队列、缓存、timeline、storage、scroll、health、OTel 与 Web 哨兵冻结探测必须用同一组受控语义协作。Issue 只承载阶段状态和证据索引,稳定语义、字段族、状态机和验收口径以本文为准。
## 2. 目的和范围
### 2.1 目的
Workbench实时运行面负责把浏览器侧多轮 Workbench 的实时输入、SSE 事件、REST snapshot、trace/message 投影、可见性诊断和 Web 哨兵采样收敛为可控、可观测、可回归的运行链路。目标是解除第二轮消息后页面卡死、浏览器内存无界上涨、SSE error 引发 REST 请求风暴、刷新后消息堆叠、跨 session/trace 串线和 monitor 只能看到症状看不到根因的问题。
本专项采用 OpenCode serve 的边界作为对照:事件流负责 replay 和 orderingREST 负责初始加载、分页和受控 gap-fill,错误 envelope 统一诊断,队列/single-flight 限制重复工作,timeline row model 保持稳定 identity。HWLAB Vue 侧不物理复制 Solid/Effect/TanStack 代码;纯 TypeScript 策略模块按语义迁移,Vue lifecycle、浏览器 EventSource、Pinia store 和 web-probe 观察层按本文一一对应重写。
所有可调参数必须来自 YAML/source-of-truth 或其前端 runtime projection。本文和源码只定义字段族、状态机、责任边界和验收读取方式;不得写入硬编码阈值、采样周期、重试次数、并发数、缓存容量、退避窗口、超时窗口或浏览器内存 kill 数值。
### 2.2 范围内
- Workbench 浏览器 typed error、diagnostic envelope 和用户可见错误归一化。
- SSE runtime、cursor replay、gap 分类、transport state 和 recovery action。
- event coalescing、keyed single-flight、bounded refresh queue、prefetch/cache trimming 和 scoped key。
- message/part/timeline row model、刷新恢复、增量归一化和 DOM row identity。
- localStorage/sessionStorage 容错、namespace 迁移、quota/security exception 降级和可观测 storage failure。
- scroll/follow/anchor 稳定、pane 内部滚动和布局不无限拉长。
- server health/availability 探测、诊断投影和避免健康探测放大请求风暴。
- OTel/RUM/web-probe 对同一 Workbench 运行链路的 trace id、span、browser memory、request family 和 freeze/blocker 观测。
- Web 哨兵在浏览器无响应或浏览器内存超过受控 YAML 参数时直接杀死浏览器并报阻塞红错误;不得 fallback、自动刷新或把阻塞降为普通警告。
- 多阶段执行 issue、PR、rollout 和 web-probe smoke 的收口要求。
### 2.3 范围外
- Workbench durable facts、message/part authority、terminal final response 和 read model 写侧仍由 [PJ2026-0104010803 Workbench唯一投影](PJ2026-0104010803-workbench-unique-projection.md) 定义。
- AgentRun run/command/runner job、provider profile 和 backend execution lifecycle 不由本专项重新定义。
- 具体 YAML 路径下的参数数值、Secret、runtime image、node/lane、namespace、public origin 和 rollout 策略不在本文硬编码。
- Web 哨兵不负责修复业务投影;它只负责采样、分类、保存证据、报红和暴露根因入口。
## 3. 术语表
| 术语 | 定义 |
| --- | --- |
| 实时运行面 | Workbench 浏览器侧从用户动作到 REST/SSE/read model/timeline/DOM 可见性/诊断的运行链路。 |
| typed error | 带 code、layer、category、route、traceId、requestId、retryable 和 diagnostic 的标准错误对象。 |
| transport state | SSE/EventSource 或 REST gap-fill 的连接、打开、错误、关闭、replay、degraded 和 blocked 状态。 |
| recovery action | transport state 变化后允许触发的受控动作,例如继续 replay、单次 delta gap-fill、标记 degraded 或直接 blocked;动作不得绕过 queue/single-flight。 |
| refresh queue | Workbench 前端聚合 REST refresh 请求的队列,按 scope/key 去重、限流、标记原因并输出诊断。 |
| scoped key | 由 node/lane/user/session/trace/message/part 等 authority id 归一化后的键,用于 cache、queue、storage、row identity 和 OTel 属性。 |
| timeline row model | 面向 Vue 渲染的稳定行模型,把 message、part、diagnostic、trace summary 和 gap placeholder 表达为可增量替换的 row。 |
| freeze blocker | web-probe 或浏览器运行面证明页面无响应、浏览器无法操作或浏览器内存超过受控 policy 后产生的阻塞红错误。 |
| browser memory policy | YAML/source-of-truth 下发给 web-probe 或 runtime 的浏览器内存观测与 kill 策略;本文只定义字段语义,不定义数值。 |
| REST 风暴 | 同一用户动作或 transport 错误导致 `/sessions``/messages``/turns``/traceEvents``/health` 等请求族无界重复或互相触发的状态。 |
## 4. 系统边界和接口
| 边界项 | 内容 |
| --- | --- |
| 外部使用者 | Workbench 用户、平台值守人员、web-probe smoke、Web 哨兵、OTel 调查 agent、发布验收流程。 |
| 外部输入 | 用户消息、session route、REST snapshot、SSE event/cursor、runtime config projection、YAML policy、browser memory sample、Long Task/freeze sample、OTel trace context。 |
| 受控资源 | Vue Workbench store、SSE client、event queue、refresh queue、session/cache/timeline model、storage namespace、scroll controller、web-probe observer、OTel/RUM events。 |
| 外部输出 | 用户可见 timeline、diagnostic panel、OTel span/attribute、RUM event、web-probe analysis report、monitor red finding、PR/issue closeout smoke evidence。 |
| 用户接口 | HWLAB Cloud Web `/workbench`、同源 `/v1/workbench/*` REST/SSE、`web-probe observe`、monitor Web 哨兵报告和受控 GitHub issue/PR。 |
| 系统边界 | 本专项只约束浏览器运行面和哨兵观测面;不拥有 durable Workbench facts、AgentRun execution facts、Secret、用户权限或发布流水 source of truth。 |
## 5. 内部分工与规格索引
| 编号 | 内部模块 | 规格文档 | 主责边界 | 上游依赖 | 下游支撑 |
| --- | --- | --- | --- | --- | --- |
| PJ2026-010605051401 | ErrorRuntime | 本规格 6.1 | typed error、diagnostic envelope、用户可见错误和 OTel 关联 | API契约、Workbench唯一投影 | Workbench store、diagnostic panel |
| PJ2026-010605051402 | QueueRuntime | 本规格 6.2 | coalesced event queue、keyed single-flight、refresh queue 和 prefetch/cache trimming | YAML运维、Workbench性能 | SSE、REST gap-fill、请求风暴治理 |
| PJ2026-010605051403 | SseRuntime | 本规格 6.3 | EventSource lifecycle、cursor replay、transport state、gap 分类和 recovery action | API契约、唯一投影 | timeline、web-probe、OTel |
| PJ2026-010605051404 | TimelineRuntime | 本规格 6.4 | message/part 增量归一化、row identity、刷新恢复和跨 session/trace 隔离 | Web工作台、唯一投影 | Vue timeline、scroll、probe analyzer |
| PJ2026-010605051405 | BrowserRuntime | 本规格 6.5 | storage 容错、scroll 稳定、pane 滚动、health 探测和 local state 诊断 | Web工作台、YAML运维 | 用户体验、freeze 复现 |
| PJ2026-010605051406 | SentinelFreeze | 本规格 6.6 | browser memory/freeze 采样、kill policy、blocked red finding 和 no fallback/no auto refresh | Web哨兵、Workbench性能 | monitor、rollout smoke、issue evidence |
| PJ2026-010605051407 | OTelEvidence | 本规格 6.7 | trace/span 关联、request family、memory/freeze/root cause 可见性和调查入口 | 运维监控、API契约 | 根因调查、回归判定 |
| PJ2026-010605051408 | CodeReference | 本规格 6.8 | 源码文件头部 SPEC 标注、阶段子 issue 和 PR/rollout/web-probe smoke 收口 | 规格治理 | 后续实现审计 |
### 5.1 目标架构图
```mermaid
flowchart LR
subgraph Config[YAML / runtime projection]
Policy[Workbench realtime policy fields]
Memory[web-probe browser memory policy]
Cadence[sentinel scenario/cadence fields]
end
subgraph Browser[Cloud Web Workbench]
Store[Pinia Workbench store]
Errors[typed error runtime]
Queue[coalesced queue / single-flight / refresh queue]
SSE[SSE runtime]
Timeline[timeline row model]
Storage[storage namespace]
Scroll[scroll/anchor controller]
Health[server health probe]
Store --> Timeline
SSE --> Queue
Queue --> Store
Errors --> Store
Storage --> Store
Scroll --> Timeline
Health --> Errors
end
subgraph API[HWLAB Cloud API]
Rest[REST read model]
Events[SSE cursor replay]
OTel[OTel spans]
Rest --> OTel
Events --> OTel
end
subgraph Probe[web-probe / Web哨兵]
Observe[observe runner]
Mem[browser memory/freeze sampler]
Analyze[analyze report]
Monitor[monitor red finding]
Observe --> Mem
Mem --> Analyze
Analyze --> Monitor
end
Policy --> Queue
Policy --> SSE
Policy --> Storage
Memory --> Mem
Cadence --> Observe
Rest --> Store
Events --> SSE
Browser --> OTel
Observe --> Browser
```
### 5.2 运行数据流图
```mermaid
flowchart TD
U[用户消息或 session 切换] --> K[scoped key]
K --> Q[refresh queue / single-flight]
Q --> R[REST initial snapshot or delta gap-fill]
Q --> E[SSE subscribe with cursor]
E --> C[event coalescing]
C --> S[server-state reducer]
R --> S
S --> T[timeline row model]
T --> D[Vue DOM rows]
D --> A[visible ack / scroll anchor]
E --> X[transport diagnostic]
R --> X
A --> O[OTel/RUM event]
X --> O
O --> P[web-probe / monitor evidence]
```
同一用户动作只能通过 scoped key 进入受控 queueSSE error、visibility change、health probe 或 storage failure 只能产生 diagnostic 和受控 recovery action,不能绕过 queue 直接触发 REST fan-out。
### 5.3 SSE gap 与阻塞时序图
```mermaid
sequenceDiagram
participant W as Workbench
participant S as SSE Runtime
participant Q as Refresh Queue
participant A as Cloud API
participant O as OTel/RUM
participant P as web-probe
W->>S: connect with cursor
S-->>W: connected + cursor summary
A-->>S: event / snapshot
S->>Q: coalesced event by scoped key
Q->>W: apply projection
S-->>S: transport error or seq gap
S->>O: transport diagnostic
S->>Q: allowed recovery action
Q->>A: bounded delta read when policy allows
P->>W: sample responsiveness and browser memory
P->>O: freeze/memory evidence
P-->>P: kill browser and mark blocked when policy says blocked
```
## 6. 原子需求
| ID | 模块 | 需求 |
| --- | --- | --- |
| OPS-WBRT-REQ-001 | ConfigSource | Workbench realtime、refresh queue、cache、storage、health、browser memory、freeze、sentinel cadence 和 smoke policy 的所有可调参数必须来自 YAML/source-of-truth 或其前端 runtime projection;源码和 SPEC 不得保存第二份数值真相。 |
| OPS-WBRT-REQ-002 | ErrorRuntime | 浏览器侧所有 REST/SSE/storage/health/projection 错误必须归一化为 typed error,并保留 layer、category、route、retryable、traceId/requestId 和 redaction 状态。 |
| OPS-WBRT-REQ-003 | QueueRuntime | SSE event、REST gap-fill、session refresh、trace refresh、prefetch 和 health probe 必须通过 key 去重、single-flight 或 coalesced queue;同一错误路径不得产生无界 REST fan-out。 |
| OPS-WBRT-REQ-004 | SseRuntime | SSE runtime 必须以 server cursor/replay 为同步 authorityREST 只用于初始加载、分页和受控 delta gap-fill,不得在 SSE error 中全量刷新多个请求族来“补洞”。 |
| OPS-WBRT-REQ-005 | TimelineRuntime | timeline 渲染必须基于稳定 message/part/row identity;刷新、SSE snapshot、trace event 和 REST page 替换不能造成用户消息堆叠、agent message 重复或跨 session/trace 串线。 |
| OPS-WBRT-REQ-006 | BrowserRuntime | storage、scroll、pane layout 和 health probe 的失败只能写入 diagnostic 或受控 recovery action;不得通过 reload、fallback、localStorage truth 或 document 级无限滚动掩盖状态分裂。 |
| OPS-WBRT-REQ-007 | SentinelFreeze | web-probe 必须把浏览器无响应和浏览器内存超过受控 policy 的状态分类为 blocker red,并保存 memory sample、freeze sample、request family、trace/span 和截图/日志证据;触发 blocker 后必须杀死浏览器,不得自动刷新页面或降级为 fallback。 |
| OPS-WBRT-REQ-008 | OTelEvidence | REST/SSE/queue/timeline/web-probe 必须暴露同一 scoped key 摘要、request family、transport state、recovery action 和 root cause 字段,确保 monitor 再次出现 INV/CHECK 类问题时能直接看到根因。 |
| OPS-WBRT-REQ-009 | WebProbeSmoke | 每个实现阶段合入或滚动上线后,必须用 `web-probe observe` 对 JD01/HWLAB v0.3 `/workbench` 做 smoke;smoke 证据至少包含页面可操作性、第二轮消息、memory/freeze 判定、request family 摘要和是否出现 blocker red。 |
| OPS-WBRT-REQ-010 | StageTracking | 本专项每个执行阶段必须有独立 GitHub 子 issue 跟踪,父 issue 只保存总 SPEC、阶段索引、PR/rollout/web-probe evidence 和剩余风险。 |
## 7. 过程控制和源码引用
新增或修改的 HWLAB Cloud Web、Cloud API、web-probe、monitor、OTel 和相关测试源码文件头部必须引用本规格,例如:
```text
SPEC: PJ2026-0106050514 Workbench实时运行面 draft-2026-06-30-p0-1297-spec-first; PJ2026-0104010803 Workbench唯一投影 <实现引用版本>.
```
自动生成文件、锁文件、第三方 vendored 文件和不能承载注释头的二进制产物不要求源码头部,但生成器、渲染器或配置入口必须能追溯到本规格。
阶段子 issue 的最小划分如下:
| 阶段 | 子 issue 职责 | 退出条件 |
| --- | --- | --- |
| P0 SPEC | 更新本 SPEC、父 issue P0 gate、阶段子 issue 索引和 YAML 参数来源约束 | 父 issue 链接 SPEC 和所有子 issue,后续代码阶段不再缺规格入口 |
| P1 纯 TS 模块 | 迁移/重写 typed error、queue/single-flight、scoped key、timeline row、storage、health 等纯 TS 模块和窄测试 | 模块有源码 SPEC 头,测试覆盖 key/coalesce/cache/timeline/storage/health 基本语义 |
| P2 Vue runtime 接入 | 接入 SSE runtime、refresh queue、server-state reducer、timeline/scroll/storage/health 和 OTel/RUM 事件 | 第二轮消息不再请求风暴,刷新后 timeline 不堆叠,scope/key/原因可见 |
| P3 Web 哨兵增强 | 接入 browser memory/freeze blocker red、no fallback/no auto refresh 和 monitor root cause 展示 | 卡死或内存 policy 命中时浏览器被杀死并报阻塞红错误,monitor 能看到根因 |
| P4 rollout smoke | PR 合并、JD01 滚动上线、web-probe smoke 和 issue closeout | smoke 通过或明确记录 blocker;父 issue 回填 PR、版本、截图/报告和 OTel 证据 |
P0 未完成前,不得把 P1-P4 标记为可执行完成;P1-P4 中任何稳定语义、字段族、状态机或验收口径变化,必须先更新本 SPEC,再更新对应子 issue 和代码。