From 5c05edcb9e0b55986133735a83683245d999bed2 Mon Sep 17 00:00:00 2001 From: Codex Date: Tue, 30 Jun 2026 10:17:40 +0000 Subject: [PATCH] docs: add workbench realtime runtime spec --- .../PJ2026-01060505-workbench-performance.md | 1 + ...6-0106050514-workbench-realtime-runtime.md | 239 ++++++++++++++++++ 2 files changed, 240 insertions(+) create mode 100644 project-management/PJ2026-01/specs/PJ2026-0106050514-workbench-realtime-runtime.md diff --git a/project-management/PJ2026-01/specs/PJ2026-01060505-workbench-performance.md b/project-management/PJ2026-01/specs/PJ2026-01060505-workbench-performance.md index a14a500f..f53ff7cd 100644 --- a/project-management/PJ2026-01/specs/PJ2026-01060505-workbench-performance.md +++ b/project-management/PJ2026-01/specs/PJ2026-01060505-workbench-performance.md @@ -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. 原子需求 diff --git a/project-management/PJ2026-01/specs/PJ2026-0106050514-workbench-realtime-runtime.md b/project-management/PJ2026-01/specs/PJ2026-0106050514-workbench-realtime-runtime.md new file mode 100644 index 00000000..acff3f57 --- /dev/null +++ b/project-management/PJ2026-01/specs/PJ2026-0106050514-workbench-realtime-runtime.md @@ -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 和 ordering,REST 负责初始加载、分页和受控 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 进入受控 queue;SSE 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 为同步 authority;REST 只用于初始加载、分页和受控 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 和代码。