docs: 废弃 Workbench 事务投影旧规格
This commit is contained in:
@@ -145,7 +145,7 @@ Agent编排应原样消费 AgentRun 的 run、command、runner job、event、ter
|
||||
|
||||
HWLAB 不应在客户端、adapter 或 prompt 中推断或补造 AgentRun 没有发出的事实。AgentRun 已正确输出时,HWLAB 负责消费和业务映射;AgentRun 合同缺失或行为错误时,应回到 AgentRun 实现与对应 OA 规格修复。
|
||||
|
||||
[PJ2026-0104010803 Workbench唯一投影](PJ2026-0104010803-workbench-unique-projection.md) 要求 Agent编排只把 AgentRun run、command、event、terminal status、failureKind 和 result envelope 交给 HWLAB接入的 projection writer/finalizer。Agent编排不得让 Web、CLI、Workbench GET、trace polling 或 legacy conversation path 分别读取 AgentRun 并各自推断 session running、assistant final response、turn terminal 或 trace terminal;同一 AgentRun 事实只能形成一份 HWLAB Workbench durable projection。
|
||||
[PJ2026-010401080313 Workbench实时权威](PJ2026-010401080313-workbench-realtime-authority.md) 要求 Agent编排只把 AgentRun run、command、event、terminal status、failureKind 和 result envelope 发布到 `agentrun.event.v1`,再由 HWLAB mapper direct publish 到 `hwlab.event.v1`。Agent编排不得让 Web、CLI、Workbench GET、trace polling、legacy conversation path 或 PostgreSQL outbox 建立第二事实权威。
|
||||
|
||||
Serve/session aggregate authority 要求职责进一步分离:AgentRun 拥有 run、command、runner job、cancel delivery、terminal report 和 execution diagnostic;HWLAB Workbench 拥有用户态 session aggregate、input/command fact、message/part、trace/timing、sealed final response 和 projection diagnostic。AgentRun 应暴露稳定 runId、commandId、event/result id、terminal status、failureKind、cancel/no-op 和 stale/blocked diagnostic,使 Workbench input/command fact 能回绑执行事实;AgentRun 不拥有 Workbench message/final/timing 显示权,也不通过旧 conversation/session 路径覆盖 Workbench read model。
|
||||
|
||||
|
||||
@@ -256,7 +256,7 @@ stale lease 不能单独推断 runner lost。runner lost、still running、compl
|
||||
|
||||
| 编号 | 短名 | 主责模块 | 关联模块 |
|
||||
| --- | --- | --- | --- |
|
||||
| AR-CORE-REQ-007 | 终态Outbox | PJ2026-01020106 终态Outbox | [后端Profile](PJ2026-010204-backend-profile.md)、[HWLAB接入](PJ2026-010205-hwlab-dispatch.md)、[Workbench唯一投影](PJ2026-0104010803-workbench-unique-projection.md) |
|
||||
| AR-CORE-REQ-007 | 终态Outbox | PJ2026-01020106 终态Outbox | [后端Profile](PJ2026-010204-backend-profile.md)、[HWLAB接入](PJ2026-010205-hwlab-dispatch.md)、[Workbench实时权威](PJ2026-010401080313-workbench-realtime-authority.md) |
|
||||
|
||||
runner 对 command terminal、run terminal、final assistant response、failureKind、threadId/turnId 和 terminal artifact 摘要必须使用 durable outbox、retry-until-ack 或等价可恢复提交协议。manager HTTP 短暂不可用时,runner 可以延迟上报,但不能把 terminal fact 只保留在进程内内存或易丢 stdout 中。
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
| 短名 | HWLAB接入 |
|
||||
| 层级 | L2 课题 |
|
||||
| 状态 | 已生效 |
|
||||
| 实现引用版本 | draft-2026-06-17-r0; PJ2026-0104010803 唯一投影 draft-2026-06-19-p1-agentrun-incremental-cursor; draft-2026-06-25-p0-session-warm-runner-contract |
|
||||
| 实现引用版本 | draft-2026-06-17-r0; draft-2026-06-25-p0-session-warm-runner-contract; 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-0102 Agent编排](PJ2026-0102-agent-orchestration.md) |
|
||||
| 规格治理索引 | [规格治理](spec-governance.md) |
|
||||
@@ -61,7 +61,7 @@ Workbench 多 turn 接入还必须保持 session execution lane。HWLAB adapter
|
||||
| 手动调度 API | AgentRun 为已存在 run/command 显式创建 runner Job 的短返回 API。 |
|
||||
| HWLAB canary | HWLAB v0.2 通过 AgentRun 执行真实 Code Agent turn 的最小接入闭环。 |
|
||||
| result envelope | AgentRun command result 的结构化输出,包含 status、terminalStatus、reply、failureKind、events 和 artifact 摘要。 |
|
||||
| Workbench projection writer | [PJ2026-0104010803 Workbench唯一投影](PJ2026-0104010803-workbench-unique-projection.md) 定义的唯一写入组件,在 HWLAB接入中把 AgentRun result envelope 和 events 写成 Workbench session、message、part、turn 和 trace facts。 |
|
||||
| Workbench事件映射器 | [PJ2026-010401080313 Workbench实时权威](PJ2026-010401080313-workbench-realtime-authority.md) 定义的 direct publish 组件,把 `agentrun.event.v1` 归一化为 `hwlab.event.v1`,不以内联 PostgreSQL 投影或 outbox 作为前置。 |
|
||||
| HWPOD runtime context | HWLAB dispatcher 为单次 runner job 提供的 owner-scoped 硬件运行上下文。 |
|
||||
| transientEnv | 单次 runner job 的短期 env 上下文,由 AgentRun 转为短期 Secret 投影并脱敏输出。 |
|
||||
| 自然语言单一路由 | `/v1/agent/chat` 中自然语言请求统一进入 AgentRun Code Agent turn,不由 Cloud API 做关键词分流或文本 fallback。 |
|
||||
@@ -127,11 +127,11 @@ HWLAB接入应消费 AgentRun events、command result、terminal status、failur
|
||||
|
||||
HWLAB 不得用 partial assistant、stdout、transport close、idle timeout 或日志尾部推断 completed。`eventsCapped=true`、final assistant 截断或 command 未终态时,HWLAB 应继续读取 AgentRun events/trace,而不是把当前摘要当作完整归档。
|
||||
|
||||
HWLAB接入应把 AgentRun result 和 events 投影为 HWLAB 自己的 Turn、Message、Part 和 TraceEvent 事实。AgentRun 是 execution backend,Web Workbench 的会话事实由 HWLAB 的 session/turn/message/trace model 承担;Web、CLI 和 REST snapshot 只能重放该投影,不能分别从 runnerTrace、terminalEvidence、workspace snapshot 或 result polling 生成多套 final response。
|
||||
HWLAB接入应把 AgentRun events 映射并 direct publish 为 `hwlab.event.v1` 的 Turn、Message、Part 和 TraceEvent typed events。AgentRun 是 execution backend,Kafka 是 Workbench 实时与回放的单一事件权威;Web、CLI 和 REST snapshot 不能分别从 runnerTrace、terminalEvidence、workspace snapshot、result polling 或数据库 outbox 生成多套 final response。
|
||||
|
||||
[PJ2026-0104010803 Workbench唯一投影](PJ2026-0104010803-workbench-unique-projection.md) 是 HWLAB接入中 AgentRun -> Workbench facts 的唯一专项规格。dispatcher、adapter、compat wrapper、Workbench GET、result polling 和 trace polling 都不能直接写 session summary、assistant message、turn terminal、trace terminal 或 final response;它们只能把 normalized facts 交给 projection writer/finalizer,或通过 read model 重放 durable projection。AgentRun terminal result 到达时,终态提交、checkpoint、diagnostic 和重启恢复语义以专项 SPEC 为准。
|
||||
[PJ2026-010401080313 Workbench实时权威](PJ2026-010401080313-workbench-realtime-authority.md) 是 HWLAB接入中 AgentRun -> Workbench 的唯一专项规格。mapper 只负责 `agentrun.event.v1 -> hwlab.event.v1`;live SSE 与 refresh replay 都消费 `hwlab.event.v1`,并使用同一 reducer。dispatcher、compat wrapper、Workbench GET、result polling 和 trace polling 不得建立第二写权或替代 Kafka replay。
|
||||
|
||||
HWLAB 接入消费 AgentRun events 时必须按 Workbench 唯一投影的 durable cursor 执行增量拉取。运行中进度以 `events?afterSeq=<lastSourceSeq>` 和 command/window 过滤后的 normalized facts 为主读源;AgentRun `/result` 只用于终态补全或后台归档,不得作为 running turn 的主读源,也不得因为 `/result` 慢或超时阻断 events projection、Workbench trace 进度或 projection state 推进。
|
||||
HWLAB 接入必须按 AgentRun Kafka event cursor 幂等消费并 direct publish。AgentRun `/result` 只用于终态补全或后台归档,不得作为 running turn 的主读源,也不得因为 `/result` 慢或超时阻断 Kafka event mapping、Workbench trace 进度或 terminal typed event 发布。
|
||||
|
||||
AgentRun manager rolling 或 runner terminal report delayed 时,HWLAB接入只能消费 AgentRun durable diagnosis、observation facts 和 terminalReportState,并把它们交给 Workbench projection diagnostic。若 AgentRun ledger 暂时 stale、runnerJob observation 尚未恢复或 terminal outbox 尚未提交,HWLAB 应输出 projecting/degraded/stalled/blocker 等可解释状态;不得在 dispatcher、compat wrapper、GET handler、CLI renderer、trace polling 或 Web reducer 中根据 Kubernetes Job phase、stdout、最后一条 event、elapsed timeout 或用户切换 session 推断 completed。
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
| 短名 | 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-20-p1-view-local-timing-ticker; draft-2026-06-24-p0-no-ui-timing-fabrication; draft-2026-06-25-p0-web-caserun-e2e; draft-2026-06-25-p0-project-management-mdtodo; PJ2026-0104010803 唯一投影 draft-2026-06-20-p0-durable-facts-model; draft-2026-06-20-p1-zero-split-durable-realtime; draft-2026-06-20-p2-terminal-outbox-recovery; draft-2026-06-24-p0-aggregate-event-stream; draft-2026-06-25-p0-serve-session-aggregate-authority; draft-2026-06-25-p0-session-warm-runner-contract; draft-2026-06-27-p0-workbench-read-model-contract; PJ2026-010401080313 Workbench实时权威 draft-2026-07-08-p0-workbench-realtime-authority-v2; draft-2026-07-09-p1-single-step-debug |
|
||||
| 实现引用版本 | 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; 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) |
|
||||
@@ -70,7 +70,7 @@ Web工作台负责 HWLAB 登录后的浏览器主入口,使用户能够在同
|
||||
| 主任务区 | 用户完成主要工作流的区域,包括会话消息和命令输入区。 |
|
||||
| 命令输入区 | 用户输入新任务、引导运行中任务、取消或重试任务的 Web 控件集合。 |
|
||||
| 诊断入口 | 用户主动打开的工作台状态详情入口,通常以 topbar 内的小型按钮或状态图标呈现。 |
|
||||
| Workbench实时调试台 | 独立于真实 Workbench 业务页的调试路由,用 fake fixture 单步驱动 reducer 和 UI 投影,验证高纯度 SSE、统一 sync replay、detail-only 隔离和禁止补洞规则。 |
|
||||
| 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 能力的入口。 |
|
||||
@@ -92,11 +92,11 @@ Web工作台负责 HWLAB 登录后的浏览器主入口,使用户能够在同
|
||||
| 正式公开入口 | 目标 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 的渲染投影,不发请求也不写事实状态。 |
|
||||
| Aggregate event stream revision | [PJ2026-0104010803 Workbench唯一投影](PJ2026-0104010803-workbench-unique-projection.md) 定义的 `eventSeq`、`aggregateSeq` 或等价 projection revision;Web reducer 只能用它判断新旧和补洞,不得用网络到达顺序或本地时间重排 terminal/final/timing。 |
|
||||
| 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-0104010803 Workbench唯一投影](PJ2026-0104010803-workbench-unique-projection.md) 定义的状态链路:AgentRun 执行事实只经 HWLAB projection writer/finalizer 写入 durable Workbench facts,REST、SSE、CLI、fake-server 和 Web 前端只消费该投影。 |
|
||||
| Serve Session Aggregate Authority | [PJ2026-0104010803 Workbench唯一投影](PJ2026-0104010803-workbench-unique-projection.md) 定义的会话级权威链路;Web 的 prompt、steer、cancel、retry、run-state、message/part、trace/timing 和 final response 只能消费该 aggregate read model。 |
|
||||
| session execution lane | [PJ2026-0104010803 Workbench唯一投影](PJ2026-0104010803-workbench-unique-projection.md) 定义的会话执行通道;Web 只能展示其 read model 和 diagnostic,不从 DOM active card 或本地 pending 状态推断是否复用了 runner。 |
|
||||
| 实时权威 | [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工作台禁止该模式。 |
|
||||
@@ -151,7 +151,7 @@ flowchart TD
|
||||
C --> A[POST Turn Admission]
|
||||
A --> O[Optimistic user/assistant message IDs]
|
||||
A --> E[SSE /workbench/events typed events]
|
||||
A --> SY[/workbench/sync replay when needed]
|
||||
A --> SY[/workbench/Kafka replay when needed]
|
||||
E --> R[Workbench Reducer]
|
||||
SY --> R
|
||||
SNAP[Initial snapshot] --> R
|
||||
@@ -166,7 +166,7 @@ flowchart TD
|
||||
TD --> UI
|
||||
```
|
||||
|
||||
目标数据流必须保证:提交请求只负责 admission 和稳定标识;主状态只接受 initial snapshot、SSE typed event、统一 `/workbench/sync` replay/delta 和可对账的 optimistic echo。显式 detail/history 只进入 detail 或 diagnostic bucket。晚到响应只能更新其声明的 session、turn、message 或 trace bucket,不能改变当前 active session、active route、当前消息区或 composer。
|
||||
目标数据流必须保证:提交请求只负责 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 目标架构图
|
||||
|
||||
@@ -268,15 +268,15 @@ flowchart LR
|
||||
|
||||
长程 observer 的数据流必须保证:`trans` 只写命令文件和读取产物,不打开入站控制端口;observer 是目标 host 上的客户端进程,不是 Web 服务、daemon API、数据库消费者或平台状态源。控制命令、采样器和后处理分析共享同一份时间戳化 artifact;控制命令改变页面时必须记录为用户意图来源,采样器本身不得通过主动 API 请求、reload、自动点击、session repair 或网络拦截制造新业务事件。
|
||||
|
||||
### 5.5 PJ2026-0104010803 Workbench唯一投影专项
|
||||
### 5.5 PJ2026-010401080313 Workbench实时权威专项
|
||||
|
||||
[PJ2026-0104010803 Workbench唯一投影](PJ2026-0104010803-workbench-unique-projection.md) 是 Workbench 状态投影的唯一专项规格,集中定义 durable facts schema、`WorkbenchProjectionWriter`、`WorkbenchProjectionFinalizer`、`WorkbenchFactsStore`、`WorkbenchReadModel`、terminal commit、sealed final response、cloud-api 重启恢复、GET 纯读和代码引用规则。
|
||||
[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 只能消费该专项定义的 durable projection;SSE 只是 projection commit 后的通知和加速;fake-server fixture 只重放同一 REST/SSE 合同。Web reducer/selectors、Trace renderer、CLI renderer、fake-server 和测试断言不得从 trace tail、message text、tool event、result cache、session summary、list row、workspace snapshot、localStorage 或 elapsed timeout 推断 lifecycle、terminal、running 或 final response。运行中相对时间展示是唯一允许的显示层本地 now 使用场景:`startedAt`、`lastEventAt`、`finishedAt` 和 sealed `durationMs` 仍来自 durable projection,浏览器只用本地 now 对这些权威字段做直接格式化,不产生新事实。前端严禁为了掩盖跳变、归零、非单调、投影滞后或后台 tab 抖动而加入平滑、滤波、单调 floor、跳变 cap、二次缓存、最近更新时间重算或“看起来连续”的时间造假;发现此类异常必须暴露 diagnostic 并修 durable projection、read model、SSE/outbox 或上游时间源。详细架构图、数据流图、关键时序图、0repair 和严禁读侧推理约束以专项规格为准,本文不再维护第二份投影架构正文。
|
||||
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、统一 sync replay、detail-only 隔离、禁止前端多源补洞和单步调试台的专项规格。Web 工作台新增或修改 EventSource、sync replay、detail/history、Colada key、server-state reducer 或 debug fixture 时,必须先遵守该专项的 authority gate、sealed guard、legacy fan-out 禁止路径和 fake SSE 单步验收。
|
||||
[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、sync 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 降级上;这些探针只能提供证据和红灯。
|
||||
[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 或局部截图替代。
|
||||
|
||||
@@ -411,13 +411,13 @@ Web工作台的正式浏览器入口必须来自目标 node/lane YAML 声明的
|
||||
| --- | --- | --- | --- |
|
||||
| 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、统一 `/v1/workbench/sync` replay/delta 和 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、展开状态和临时交互状态。
|
||||
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-0104010803 Workbench唯一投影](PJ2026-0104010803-workbench-unique-projection.md) 和 [PJ2026-010401080313 Workbench实时权威](PJ2026-010401080313-workbench-realtime-authority.md) 要求 Web 工作台把 `sessionId`、`messageId`、`partId`、`turnId` 和 `traceId` 作为 reducer 合并键,并同时检查 `realtimeAuthority`、entity family/id/version、cursor 和 `projectionRevision`。initial snapshot、SSE typed event、sync replay、submit optimistic 和 explicit detail/history 的任何 late response 都只能更新其自身 key 与授权 bucket 对应的事实,不得清空当前 selected session、覆盖已存在 sealed message、或用 list summary/localStorage/workspace snapshot 重建当前 timeline。running trace 在 terminal 前 detail page 收到 `hasMore=false` 只表示 detail page 暂时追平,不表示主 turn 已 terminal;后续 SSE typed event 或 sync replay 仍必须能追加 terminal seal 和 final response。
|
||||
[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 重连和 sync replay 后必须保持同一 turn timeline 顺序:同一轮用户输入应先于对应 assistant/agent terminal,跨轮次按 turn timeline/aggregate seq/事件时间排序,不得按 role、source table、投影写入批次或 `updatedAt desc` 形成 `UUAA`、`UUUAAA` 等用户消息聚簇。前端不得通过 DOM 后处理或本地排序掩盖 read model 聚簇;若 API 已经聚簇,修复点必须回到 WorkbenchReadModel 或 projection writer。
|
||||
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 当作正常标题。
|
||||
|
||||
@@ -431,11 +431,11 @@ Web 工作台必须把主消息投影、trace detail、session status 和 transp
|
||||
|
||||
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 重连和 sync replay 必须用同 ID 的 durable message、part、turn 和 trace projection 确认。若 trace detail events 缺失,只影响 trace detail;主 timeline 的用户消息、assistant final response 和 turn terminal 状态不得因此退化为“思考中”。
|
||||
初发刷新一致性是 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 断线重连、sync replay 和 trace detail 分页后保持同一组 sessionId、turnId、traceId、messageId 与终态语义;conversationId/projectId/workspaceId 只可作为 metadata 被展示或调试,不得改变通过条件。测试不得依赖 live AgentRun、Cloud API、HWPOD、数据库或 Kubernetes 状态作为通过条件。
|
||||
状态投影正确性必须能被独立浏览器回归验证覆盖。测试应在同一 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 判定通过。
|
||||
|
||||
@@ -449,7 +449,7 @@ OpenCode 的参照边界是职责结构,不是技术栈照搬。可借鉴的
|
||||
|
||||
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-0104010803 唯一投影 draft-2026-06-20-p0-durable-facts-model; 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` 作为规格引用。
|
||||
新增或重构的核心前端文件头部必须标注遵循的 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 浏览器回归
|
||||
|
||||
@@ -463,13 +463,13 @@ mock 数据应优先来自目标 node/lane 的真实受控样本,而不是从
|
||||
|
||||
合成 fixture 只能补足真实样本难以稳定覆盖的边界条件,例如延迟响应、SSE 断线、分页缺口、列表缺少当前选中项、可选字段格式异常、空集合和特定 HTTP 错误。每个合成 fixture 必须标明 `derivedFrom` 和 `syntheticReason`,不得替代可从真实运行面采集的常规会话、完成态、失败态或 Trace 数据。
|
||||
|
||||
浏览器回归验证至少覆盖以下用户可见路径:切换 session 后主工作区显示 loading 并恢复目标 session;fresh browser context 深链进入 session 后以同一 message、turn 和 trace 标识还原 timeline;SSE 事件重复、乱序、丢失或重连后通过 SSE replay 或统一 `/v1/workbench/sync` replay 收敛,不触发旧 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 后主工作区显示 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、sync replay、projection lag、terminal sealed、diagnostic 分仓和截图 artifact。两类回归都必须记录 fixture schema/redaction 版本、capturedFrom、capturedAt、derivedFrom、截图 SHA 或等价 artifact 校验值。
|
||||
黄金链路回归必须覆盖完整用户流程:新建 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、sync 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 修正页面后判通过。
|
||||
状态投影回归必须覆盖新建 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、sync replay 或 realtime diagnostic 失败。主 timeline 的 sealed final response 不变,诊断只显示在详情/感叹号/transport health 区域;Trace detail 延迟返回或分页缺口不得 remount 主消息卡片,也不得重置用户展开/折叠控制。
|
||||
状态投影回归还必须覆盖 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 或测试专用后门读取诊断字段。
|
||||
|
||||
@@ -529,11 +529,11 @@ Workbench 模块不得为了项目管理联动新增 iframe、嵌套 Workbench
|
||||
|
||||
| 编号 | 短名 | 主责模块 | 关联模块 |
|
||||
| --- | --- | --- | --- |
|
||||
| CLIENT-WB-REQ-014 | Workbench调试台 | PJ2026-01040114 Workbench调试台 | [PJ2026-010401080313 Workbench实时权威](PJ2026-010401080313-workbench-realtime-authority.md)、[PJ2026-0104010803 Workbench唯一投影](PJ2026-0104010803-workbench-unique-projection.md)、[PJ2026-010403 API契约](PJ2026-010403-api-contract.md) |
|
||||
| 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、统一 sync replay、detail-only 隔离和状态投影收敛。推荐入口是根侧边栏中的独立导航项和独立路由,例如 `/workbench/debug`,而不是继续扩展现有 Workbench topbar 诊断弹窗。原因是单步调试需要深链、fixture 选择、事件播放控制、请求 ledger、cross-page 对照和 Playwright 直达,长期嵌在真实 Workbench 会污染用户任务流和真实 store。
|
||||
Cloud Web 应提供独立 Workbench 实时调试台,用于单步验证高纯度 SSE、Kafka retention replay、detail-only 隔离和状态投影收敛。推荐入口是根侧边栏中的独立导航项和独立路由,例如 `/workbench/debug`,而不是继续扩展现有 Workbench topbar 诊断弹窗。原因是单步调试需要深链、fixture 选择、事件播放控制、请求 ledger、cross-page 对照和 Playwright 直达,长期嵌在真实 Workbench 会污染用户任务流和真实 store。
|
||||
|
||||
调试台必须默认使用隔离 store/reducer harness。纯 SSE 模式下,页面只消费 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 红灯。显式打开 sync replay 模式时,也只能使用 `/v1/workbench/sync` 等价 fixture,不得恢复 trace/session/turn 多端点补洞。
|
||||
调试台必须默认使用隔离 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 成败作为通过条件。
|
||||
|
||||
|
||||
+21
-619
@@ -1,4 +1,4 @@
|
||||
# PJ2026-0104010803 Workbench唯一投影
|
||||
# PJ2026-0104010803 Workbench唯一投影(已废弃)
|
||||
|
||||
## 修改历史
|
||||
|
||||
@@ -7,12 +7,8 @@
|
||||
|
||||
当前正文仍在规格治理草稿中;未定稿前不新增版本号,不为单次编辑追加 `待提交` 版本。
|
||||
|
||||
> 裁决优先级:本规格中以 PostgreSQL aggregate event stream、transactional projector、durable outbox 或 `/v1/workbench/sync` 作为实时/回放 authority 的条款,已被 2026-07-14 的 [PJ2026-010401080313 Workbench实时权威](PJ2026-010401080313-workbench-realtime-authority.md) `draft-2026-07-14-p0-pure-kafka-authority` 取代。当前权威链固定为 `agentrun.event.v1 -> mapper -> hwlab.event.v1 -> 实时 SSE / Kafka retention 回放 SSE`;PostgreSQL 只可作为非阻塞派生读模型,不能成为 Cloud API 启动、Kafka 实时或回放的前置。未完成正文重整前,冲突条款一律以最新专项裁决为准。
|
||||
|
||||
## 正文
|
||||
|
||||
## PJ2026-0104010803 Workbench唯一投影需求规格
|
||||
|
||||
## 1. 文档控制
|
||||
|
||||
| 字段 | 内容 |
|
||||
@@ -20,630 +16,36 @@
|
||||
| 编号 | PJ2026-0104010803 |
|
||||
| 短名 | Workbench唯一投影 |
|
||||
| 层级 | L4 专项规格切片 |
|
||||
| 状态 | 已生效 |
|
||||
| 实现引用版本 | draft-2026-06-20-p0-durable-facts-model; draft-2026-06-20-p1-view-local-timing-ticker; draft-2026-06-20-p1-zero-split-durable-realtime; draft-2026-06-20-p2-terminal-outbox-recovery; draft-2026-06-22-p1-workbench-redis-derived-cache; draft-2026-06-24-p0-no-ui-timing-fabrication; draft-2026-06-24-p0-aggregate-event-stream; draft-2026-06-24-p1-opencode-message-part-authority; draft-2026-06-25-p0-serve-session-aggregate-authority; draft-2026-06-25-p0-session-warm-runner-contract; draft-2026-06-27-p0-read-model-timeline-contract; draft-2026-06-28-p0-d518-session-timeline-consistency |
|
||||
| 需求规格模板 | [ISO/IEC/IEEE 29148 需求规格模板](../../templates/iso-iec-ieee-29148-requirements-spec-template.md) |
|
||||
| 状态 | 已废弃 |
|
||||
| 替代规格 | [PJ2026-010401080313 Workbench实时权威](PJ2026-010401080313-workbench-realtime-authority.md) |
|
||||
| 上级规格 | [PJ2026-010401 Web工作台](PJ2026-010401-web-workbench.md) |
|
||||
| 关联规格 | [PJ2026-010403 API契约](PJ2026-010403-api-contract.md)、[PJ2026-01060505 Workbench性能](PJ2026-01060505-workbench-performance.md)、[PJ2026-010205 HWLAB接入](PJ2026-010205-hwlab-dispatch.md)、[PJ2026-0102 Agent编排](PJ2026-0102-agent-orchestration.md) |
|
||||
| 规格治理索引 | [规格治理](spec-governance.md) |
|
||||
|
||||
本文采用 ISO/IEC/IEEE 29148 需求规格模板的项目裁剪版:正文只保留 Workbench 唯一投影的稳定使命、范围、术语、系统边界、内部分工和原子需求。
|
||||
## 2. 废弃裁决
|
||||
|
||||
## 2. 目的和范围
|
||||
本规格曾把 PostgreSQL aggregate event stream、transactional projector、durable projection outbox 和数据库 replay 定义为 Workbench 的唯一提交序与实时前置。该架构已废弃,不再是实现、测试、发布门禁或源码引用的有效依据。
|
||||
|
||||
### 2.1 目的
|
||||
|
||||
Workbench唯一投影负责把 AgentRun 执行事实收敛成 HWLAB 自有的 durable Workbench facts,使 Web、CLI、REST、SSE、fake-server 和浏览器回归都消费同一份可恢复、可分页、可诊断的用户态会话事实。
|
||||
|
||||
本专项的目标状态是:AgentRun run、command、event 和 result 只作为执行事实输入;HWLAB 只有 `WorkbenchProjectionWriter`、`WorkbenchProjectionFinalizer` 写入 Workbench facts;cloud-api boot/background scheduler 是 startup/resume 的 authority,负责扫描 durable open checkpoint 和 running/projecting turn 并恢复追平;投影推进只能由上游 source event/result、projection writer/finalizer、background scheduler/reconciler 或显式受控 checkpoint replay/reprojection 触发。所有 `GET /v1/workbench/*` 和兼容读路径都只通过 `WorkbenchReadModel` 读取,不在读取时调用 AgentRun、Code Agent manager、trace polling、result polling、`hydrateRealtimeGap` 或 workspace repair 推进事实。Workbench 必须满足 0repair:页面、GET、SSE、fake-server 和 web-probe 都不得通过 reload、切换 session、`sessionRepair`、`realignFreshSession`、localStorage truth、SSE gap repair、visibility gap refresh 或 read-through repair 把已经分裂的 route/session/message/trace 状态补成看起来正确。
|
||||
|
||||
Workbench aggregate event stream 是上述唯一投影的提交脊柱。所有 admission、AgentRun event/result、cancel、replay/reprojection 和 diagnostic transition 先归一化为带 `eventSeq`、`aggregateId`、`aggregateSeq`、`turnId`、`traceId`、`sourceRunId`、`sourceCommandId` 和来源幂等键的 append-only 事件,再由同一 projector 写入 message、part、turn、trace、checkpoint、outbox 和 read model。Web、SSE、CLI、fake-server 和 probe 只能消费该 event stream 的投影结果或 cursor replay,不能分别从 trace tail、result envelope、message cache、session list 和浏览器本地状态重新排序。
|
||||
|
||||
Workbench message/part authority 必须采用类似 OpenCode serve 的职责分离:prompt admission、session status、message page、message part、event stream 和 abort/cancel 分别有清晰 authority,最终由同一投影提交序收敛。用户消息、assistant 文本、tool/command 行、diagnostic、steer/cancel 控制事件和 final response 必须是稳定 `messageId/partId/order/status/sealedAt` 的 part 事实;禁止把同一 trace 的全部 assistant 输出压成单个 trace-level assistant message,再由 read model、前端 store、CLI renderer 或 analyzer 根据文本内容重新选择“最终回答”。
|
||||
|
||||
AgentRun terminal outbox 和 command result 是 Code Agent turn terminal 的上游权威输入之一。Projection finalizer 必须以 at-least-once、幂等方式消费对应 run/command 的 terminal outbox/result;即使 events page 没有出现 terminal event、cloud-api 曾重启、进程内 poller 丢失或 result sync 曾超时,后台 resume 也必须重新读取 command result authority 并把真实 terminal 通过同一 writer 写入 Workbench facts。用户 cancel、GET trace/detail、Web reload 或 CLI renderer 都不能代替这个写侧恢复。
|
||||
|
||||
Terminal final response 是 Workbench 投影的 sealed 用户结果。Projection writer/finalizer 一旦把 assistant final text、terminal status 和 `sealedAt` 或等价 sealed 标记写入同一 durable terminal commit,主消息区的正文、finalResponse 和 terminal status 就只能由后续同一写侧投影的受控 replay/reprojection 修正;旧 turn polling、trace detail、SSE gap、realtime timeout、transport close、read model lag 或 compat wrapper 失败只能写入 trace detail、transport diagnostic、projection diagnostic 或 session health,不能覆盖 sealed 主正文。
|
||||
|
||||
CLI trace 视图是 web-probe 工测和自动判别器的人工可读基准。`web-probe collect/observe` 只负责按固定频率保存采样事实;`analyze turn-summary` 和 `analyze trace-frame` 从既有采样事实或同源 read model 渲染文字版 trace 截图,不新增第二套保存来源。自动判别器的 finding 必须能被 CLI trace 视图复核;当二者冲突时,以 CLI trace 视图暴露的有序 turn/message/part/final response 事实作为需要修复的可见症状。
|
||||
|
||||
D601 v0.3 可以在 `hwlab-v03` namespace 内为 `hwlab-workbench-runtime` 使用 Redis 派生读缓存,但该缓存只能保存 WorkbenchReadModel 从 durable facts 组装出的短 TTL 快照。Redis 不写入 Workbench facts,不推进 checkpoint,不生成 lifecycle、terminal、final response 或 projectionStatus;缓存 miss、stale 或 unavailable 只能改变读路径性能诊断,不能改变唯一投影事实。
|
||||
|
||||
### 2.2 范围内
|
||||
|
||||
- AgentRun facts 到 Workbench facts 的标准映射、幂等写入和 terminal commit 语义。
|
||||
- `session`、`message`、`part`、`turn`、`trace event`、`projection checkpoint` 和 `projection diagnostic` 的 durable facts schema。
|
||||
- `WorkbenchFactsStore`、`WorkbenchProjectionWriter`、`WorkbenchProjectionFinalizer` 和 `WorkbenchReadModel` 的组件边界。
|
||||
- AgentRun events 增量拉取 cursor、projection state、result sync state 和 cloud-api 重启后按 durable cursor 继续投影的语义。
|
||||
- Workbench aggregate event stream 的 append-only 事件 schema、全局 cursor、aggregate cursor、来源幂等键、projector 边界和投影 revision。
|
||||
- cloud-api 进程重启、进程内后台任务丢失、慢任务超过短轮询预算后的 durable finalizer 追平语义。
|
||||
- Terminal final response 的 sealed 字段、diagnostic 分仓和 sealed 后不可被读侧失败覆盖的显示语义。
|
||||
- `GET /v1/workbench/*` 纯读、`/v1/agent/*` compat wrapper 降级和 projection diagnostics 输出要求。
|
||||
- WorkbenchReadModel 内部的 Redis 派生读缓存 key、payload、失效、TTL 和降级边界。
|
||||
- Web reducer、CLI renderer、web-probe analyze/collect、fake-server fixture 和 Playwright 回归对同一 durable projection 的消费规则。
|
||||
- 本专项范围内新增或重构源码文件的 SPEC 头部引用规则。
|
||||
- D518 HWLAB v0.3 Workbench fake-echo 与 dsflash-go 原入口哨兵对 timeline、refresh、session switch、timing 与 OTel 可见性的关闭验收合同。
|
||||
|
||||
### 2.3 范围外
|
||||
|
||||
- AgentRun run/command/runner job 的执行生命周期事实归 [PJ2026-0102 Agent编排](PJ2026-0102-agent-orchestration.md)。
|
||||
- HWLAB 到 AgentRun 的 dispatcher、runtime assembly、manual dispatch 和 provider profile 归 [PJ2026-010205 HWLAB接入](PJ2026-010205-hwlab-dispatch.md) 及 Agent编排下级规格。
|
||||
- API path、HTTP schema、错误 envelope 和 route policy 归 [PJ2026-010403 API契约](PJ2026-010403-api-contract.md)。
|
||||
- Web 布局、组件、浏览器交互和可见 UX 归 [PJ2026-010401 Web工作台](PJ2026-010401-web-workbench.md)。
|
||||
- 用户身份、权限、额度、账本和 owner visibility 归 [PJ2026-0105 用户管理](PJ2026-0105-user-management.md)。
|
||||
- CI/CD、GitOps、公开入口、Prometheus 和运行面运维归 [PJ2026-0106 平台运维](PJ2026-0106-platform-ops.md)。
|
||||
- Redis 部署、镜像、资源、NetworkPolicy、TTL 数值和指标接入归 [PJ2026-01060505 Workbench性能](PJ2026-01060505-workbench-performance.md) 与 YAML-first 运维;本专项只定义其不能改变唯一投影 authority。
|
||||
|
||||
## 3. 术语表
|
||||
|
||||
| 术语 | 定义 |
|
||||
| --- | --- |
|
||||
| AgentRun facts | AgentRun 产生的 run、command、runner job、event、result、terminalStatus、failureKind、sourceSeq 和 sourceEventId 等执行事实。 |
|
||||
| Workbench facts | HWLAB 自有的 session、message、part、turn、trace event、checkpoint 和 diagnostic 持久事实,用于用户态 Workbench 展示。 |
|
||||
| WorkbenchProjectionWriter | 唯一把 normalized AgentRun facts 写成 Workbench facts 的组件;它不处理 HTTP route、鉴权、UI transient state 或兼容 API 输出。 |
|
||||
| WorkbenchProjectionFinalizer | 以 checkpoint 为驱动的幂等追平组件;可由 submit 后、event 到达、后台恢复或显式 checkpoint replay/reprojection 触发,但所有入口调用同一 finalization 逻辑。 |
|
||||
| WorkbenchFactsStore | durable facts 存储接口,负责幂等 upsert、terminal commit、checkpoint、diagnostic、分页查询和 owner visibility 过滤所需的持久化读写。 |
|
||||
| Workbench aggregate event stream | Workbench 投影自己的 append-only 事件流,承载 admission、source event/result、terminal、diagnostic、replay/reprojection 和 cancel transition;它是 trace/timeline 顺序、SSE replay cursor 和 projector revision 的唯一提交序。 |
|
||||
| message/part authority | Workbench timeline 的消息和片段权威。每个 user/assistant/tool/diagnostic/final response 片段都有稳定 `messageId`、`partId`、`order`、`status` 和 sealed 状态;trace-level 文本、DOM 行、result envelope 或 analyzer 不能替代它选择最终内容。 |
|
||||
| WorkbenchReadModel | 唯一读取 Workbench facts 并组装 session rail、session detail、message page、turn snapshot、trace event page 和 projection diagnostics 的读模型。 |
|
||||
| 上游投影推进 | Workbench facts 只能由 projection writer/finalizer、background scheduler/reconciler、AgentRun source event/result outbox 或显式受控 checkpoint replay/reprojection 推进;REST GET、Web 页面、SSE consumer、SSE open/error/visibility handler、web-probe、fake-server 和 CLI renderer 只能观察或展示投影与诊断,不能以 gap hydration、trace/result polling、reload 或 read-through sync 触发写侧投影。 |
|
||||
| checkpoint replay/reprojection | 受控管理入口按已持久化 sourceRun/sourceCommand/checkpoint 重放投影逻辑,用于恢复投影 lag 或阻塞;它只能调用同一 finalizer/writer,不由 GET、Web 页面、SSE 订阅或测试 helper 触发,也不得改变 active session 或 route。 |
|
||||
| projection commit | writer/finalizer 对一组 message、part、turn、trace、session summary 和 checkpoint 的一次幂等持久化提交;terminal commit 必须保持用户可见事实一致。 |
|
||||
| terminal commit | 标记同一 turn 结束的 projection commit,必须原子更新 assistant final text、message/part status、turn terminal、trace terminal event、session running=false、summary 和 SSE cursor。 |
|
||||
| sealed final response | terminal commit 写入的 assistant 主正文、finalResponse、message/turn terminal status 和 `sealedAt` 或等价 sealed 标记;它是主消息区用户结果的唯一权威,不参与后续读侧 diagnostic 竞争。 |
|
||||
| eventSeq | Workbench aggregate event stream 的全局单调提交序,用于 SSE replay、审计和 projector recovery;它不等同于 AgentRun sourceSeq,也不由浏览器生成。 |
|
||||
| aggregateId/aggregateSeq | session、turn、trace 或 message 这类 Workbench aggregate 内部的稳定身份和单调序列,用于同一 aggregate 内的 ordering、去重和 revision 判断。 |
|
||||
| projection revision | projector 成功应用到 read model/facts 后产生的 revision,可由 `eventSeq`、`aggregateSeq` 或等价版本字段表达;API/SSE/Redis cache 只能用它判断新鲜度,不能用本地到达顺序替代。 |
|
||||
| projectedSeq | HWLAB trace event 和 projection commit 的单调序列,用于 REST 分页、SSE replay、fake-server fixture 和审计;不得与 AgentRun `sourceSeq` 混用。 |
|
||||
| sourceSeq/sourceEventId | AgentRun event/result 的来源序列或来源事件标识,只作为映射审计字段和幂等输入,不作为 Workbench trace page cursor。 |
|
||||
| checkpoint | finalizer 已成功投影到某个 sourceRunId/sourceCommandId/sourceSeq 的 durable 位置记录,用于 cloud-api 重启或后台任务丢失后继续追平。 |
|
||||
| projection state | checkpoint 的运行态扩展,至少记录 traceId/sessionId/sourceRunId/sourceCommandId、lastSourceSeq、lastProjectedSeq、sourceLatestSeq、projectionStatus、projectionHealth、resultSyncState、lastError/blocker、failureCount 和 nextRetryAt。 |
|
||||
| result sync state | AgentRun `/result` 归档或终态补全的低优先级状态;它不得阻塞运行中 events projection。 |
|
||||
| sourceLatestSeq | finalizer 在本次或最近一次拉取中观察到的 AgentRun command 最新 sourceSeq,用于诊断投影 lag;它不得替代 lastSourceSeq 成为已提交事实。 |
|
||||
| projection diagnostic | 暴露 projection lag、blocker、lastProjectedSeq、sourceRunId、sourceCommandId、updatedAt 和恢复状态的可诊断字段。 |
|
||||
| terminal outbox | AgentRun runner 在 command 结束时写出的 durable terminal envelope,包含 runId、commandId、terminalStatus、failureKind、final response 或 terminal error 等终态输入;它必须被 Workbench finalizer 幂等消费。 |
|
||||
| already terminal cancel | 用户发起 cancel 前,HWLAB 发现 AgentRun command 或本地 sealed projection 已经 terminal 的状态;此时 cancel mutation 不得覆盖 terminal facts,应返回 already-terminal/no-op 或触发 terminal projection。 |
|
||||
| control command boundary | prompt、steer、retry 和 cancel 的受控 mutation 边界。每个控制命令必须有独立 action、target turn/run/command、HTTP route、commandId 或 no-op reason;采集器、analyzer 和 Web 不能把后续 steer/cancel 误归入前一个 prompt 提交。 |
|
||||
| AgentRun execution diagnostic | AgentRun durable ledger 对 runner job observation、stale lease、terminalReportState、reconciler backlog 和不可恢复 blocker 的诊断输出;Workbench 只能把它作为 projection diagnostic 输入,不拥有执行状态写权。 |
|
||||
| transport diagnostic | SSE、旧 turn polling、trace detail、result sync、realtime timeout 或浏览器网络层观察到的可见性诊断;它只能描述传输或读侧健康,不拥有 message text、finalResponse 或 terminal status 写权。 |
|
||||
| projection health | 对 projection diagnostic 的只读解释,状态至少区分 `projecting`、`caught-up`、`degraded` 和 `stalled`;它不推进 facts,也不得把 stale projecting 标为 caught-up。 |
|
||||
| timing display input | Workbench ReadModel 输出的 `startedAt`、`lastEventAt`、`finishedAt` 和 sealed `durationMs` 等投影时间字段;它们是浏览器相对时间文案的唯一事实输入。浏览器本地 now 只能参与直接渲染计算,不成为 Workbench facts,也不得通过 UI 侧平滑、滤波、单调 floor、跳变 cap、二次缓存或本地推断伪造更连续的 `elapsed/recent` 事实。 |
|
||||
| TraceEventPage | 由 WorkbenchReadModel 返回的 trace 分页事实,必须按 `projectedSeq` 单调排序,并保持 `range.fromSeq <= range.toSeq`;空页用显式 empty range 表达,不生成非法区间。 |
|
||||
| compat wrapper | 旧 `/v1/agent/*` 或 conversation path 的兼容包装层;只能调用 `WorkbenchReadModel` 或正式 mutation,不拥有第二套事实写入或 read-through repair。 |
|
||||
| read-through repair | GET 路径为了让页面“看起来正确”而同步调用 AgentRun、Code Agent manager、workspace repair、trace/result polling 或 billing finalizer 推进事实;本专项禁止该模式。 |
|
||||
| 读侧推理 | REST GET、SSE consumer、compat wrapper、CLI renderer、Web reducer/selectors、Trace renderer、fake-server 或测试断言根据 trace tail、message text、tool event、result cache、session summary、list row、workspace snapshot、localStorage 或 elapsed timeout 推断 turn/session/message lifecycle、terminal、running 或 final response 的行为;本专项禁止该模式。 |
|
||||
| 事后 repair | 页面或测试发现 active route/session/message/trace 已经分裂后,再通过 reload、切换 session、`sessionRepair`、`realignFreshSession`、workspace selection repair、active tab repair、localStorage truth、GET read-through 或 SSE gap repair 把 UI 补成看起来正确;本专项禁止该模式。 |
|
||||
| Redis派生读缓存 | WorkbenchReadModel 内部可选的 Redis 缓存层,只保存从 durable Workbench facts 组装出的 session summary、terminal turn snapshot 或 terminal trace page 快照;它可丢弃、可过期、可重建,不是 Workbench facts、checkpoint 或 lifecycle authority。 |
|
||||
| cache authority input | 构成缓存 key 与有效性判断的权威输入,至少包含 schema version、actor visibility input、session/turn/trace/cursor、projection revision/seq 或等价字段;这些输入必须来自 durable facts/read model。 |
|
||||
| cache diagnostic | `cacheStatus`、`cacheAgeMs`、cache key class、projection revision/seq、dbQueryAvoided 和 Redis unavailable/stale 等读路径诊断;它只能解释性能和新鲜度,不拥有主 timeline 写权。 |
|
||||
| CLI trace 视图 | `web-probe analyze` 从采样事实渲染的文字版 trace 视图,包含多 turn 的 `turn-summary` 和单 turn/单 frame 的 `trace-frame` 两层;它用于人工复核自动 finding,不保存新事实,不从 DOM 重新推断。 |
|
||||
| canonical timeline digest | ReadModel、OTel 和 web-probe 用于比较同一 session/timeline 快照是否一致的脱敏摘要。摘要至少覆盖 sessionId、messageId、role、turnId、traceId、message/part order、status、sealed/timing 字段和文本哈希,不包含完整 prompt、完整 final response、Secret、cookie、Authorization 或 provider payload。 |
|
||||
| Serve Session Aggregate Authority | Workbench 会话级聚合根,统一接收 prompt admission、steer、cancel、retry、run-state、message/part、trace/timing 和 terminal/final response 的写入序列;它是 Web、REST、SSE、CLI 和 web-probe 可见状态的上游 authority。 |
|
||||
| durable input/command fact | 用户输入或控制命令进入执行前写入的持久事实,至少绑定 `sessionId`、`turnId`、`messageId`、`commandId`、action、target、admittedSeq、status 和 no-op/blocker;它先于 AgentRun dispatch 或 Kubernetes job 创建。 |
|
||||
| session execution lane | 同一 Workbench session 的受控执行 lane,把连续 prompt、steer、cancel 和 retry 串到同一 AgentRun session/run command channel、warm runner lease 或等价机制;它不能只是 metadata。 |
|
||||
| warm runner contract | AgentRun/HWLAB 对连续 turn 的低延迟执行合同:已创建的 runner 在同一 session/run lane 内继续 poll 后续 command,或由明确 runner lease/session channel 承接后续 command;每 turn 新建独立 run-scoped runner Job 不能标称为 runner reuse。 |
|
||||
|
||||
## 4. 系统边界和接口
|
||||
|
||||
本规格把 Workbench唯一投影作为客户端、API契约、HWLAB接入和Agent编排之间的状态边界看待;本章只描述输入、输出和责任边界。
|
||||
|
||||
| 边界项 | 内容 |
|
||||
| --- | --- |
|
||||
| 外部使用者 | Cloud Web、HWLAB CLI、Cloud API route、AgentRun adapter、fake-server 回归和运维诊断。 |
|
||||
| 外部输入 | AgentRun run/command/event/result facts、turn admission metadata、owner/session visibility、显式 checkpoint replay/reprojection 请求、REST/SSE 查询参数。 |
|
||||
| 受控资源 | Workbench facts、projection checkpoint、diagnostic、projectedSeq、session/message/part/turn/trace 查询模型和 SSE projection commit notification。 |
|
||||
| 外部输出 | session rail、session detail、message/part page、turn snapshot、trace event page、sealed final response、projection/transport diagnostics、SSE events 和 compat wrapper envelope。 |
|
||||
| 用户接口 | Cloud Web `/workbench`、同源 `/v1/workbench/*` REST/SSE、HWLAB CLI 的同源 Workbench/API 入口。 |
|
||||
| 系统边界 | 本专项只定义 Workbench 用户态事实的唯一写入和读取链路;它不定义 AgentRun 执行合同、用户权限策略、Web UI 布局或平台发布机制。 |
|
||||
|
||||
## 5. 内部分工与规格索引
|
||||
|
||||
| 编号 | 内部模块 | 规格文档 | 主责边界 | 上游依赖 | 下游支撑 |
|
||||
| --- | --- | --- | --- | --- | --- |
|
||||
| PJ2026-010401080301 | FactsStore | 本规格 6.1 | durable facts schema、幂等 upsert、terminal commit、checkpoint 和分页读取 | 数据库/runtimeStore、用户管理 visibility | Writer、Finalizer、ReadModel |
|
||||
| PJ2026-010401080302 | ProjectionWriter | 本规格 6.2 | normalized AgentRun facts 到 Workbench facts 的唯一写入 | HWLAB接入、Agent编排 | ReadModel、SSE、CLI/Web |
|
||||
| PJ2026-010401080303 | ProjectionFinalizer | 本规格 6.3 | checkpoint 驱动追平、重启恢复和显式 checkpoint replay/reprojection 的同一幂等入口 | FactsStore、AgentRun facts source | Writer、diagnostics |
|
||||
| PJ2026-010401080304 | ReadModel | 本规格 6.4 | session/message/turn/trace/projection diagnostics 的唯一读模型 | FactsStore、用户管理 visibility | REST GET、compat wrapper、CLI、fake-server |
|
||||
| PJ2026-010401080305 | CompatWrapper | 本规格 6.5 | 旧 `/v1/agent/*` 和 conversation path 到 ReadModel 或正式 mutation 的兼容映射 | API契约、ReadModel | Web/CLI 迁移期兼容 |
|
||||
| PJ2026-010401080306 | WebServerState | 本规格 6.6 | Web reducer/selectors 只消费 REST/SSE projection,分仓保存 sealed message projection、trace detail、session status 和 transport diagnostics | Web工作台、API契约 | session rail、timeline、composer、trace detail |
|
||||
| PJ2026-010401080307 | Regression | 本规格 6.7 | 后端红灯、fake-server Playwright、D601 web-probe 和分叉清零验收 | 平台运维、Web工作台 | issue 收口和防回归 |
|
||||
| PJ2026-010401080308 | CodeReference | 本规格 6.8 | 源码文件头部 SPEC 引用和实现版本追溯 | 规格治理 | 后续实现审计 |
|
||||
| PJ2026-010401080309 | DerivedReadCache | 本规格 6.9 | ReadModel 内部 Redis 派生缓存的 authority input、payload、失效和降级边界 | Workbench性能、API契约 | 高频读降尾延迟 |
|
||||
| PJ2026-010401080310 | AggregateEventStream | 本规格 6.10 | Workbench append-only aggregate event stream、cursor replay、projector revision 和顺序权威 | ProjectionWriter、ProjectionFinalizer、FactsStore | ReadModel、SSE、Web、CLI、fake-server、web-probe |
|
||||
| PJ2026-010401080311 | CliTraceView | 本规格 6.11 | web-probe 采样事实的 turn-summary/trace-frame 渲染、final response 展示和 analyzer 判据 | ReadModel、AggregateEventStream | 工测复核、自动 finding、issue 证据 |
|
||||
| PJ2026-010401080312 | ServeSessionAggregate | 本规格 6.12 | prompt admission、steer/cancel、run-state、message/part、trace/timing 的 session aggregate authority | API契约、Agent编排、HWLAB接入 | Web、CLI、web-probe、fake-server |
|
||||
|
||||
### 5.1 OpenCode serve 对照原则
|
||||
|
||||
本专项采用 OpenCode serve 的架构边界作为对照,但不复制其实现。`/root/opencode/packages/server/src/groups/session.ts` 将 prompt admission 与等待/上下文读取分离;`groups/message.ts` 和 `handlers/message.ts` 通过 message page、cursor 和稳定顺序提供投影读取;`groups/event.ts`、`event-v2-bridge.ts` 和 `bus/global.ts` 把 location-scoped event 与单调 event id 作为同步基础;`session/status.ts` 与 `session/run-state.ts` 集中表达 idle/busy/retry/cancel;`session/message-v2.ts` 与 `session/processor.ts` 以 message/part 追加、delta 和 cleanup 形成最终 assistant message;instance HTTP API 将 prompt、async prompt 和 abort 作为不同 route。
|
||||
|
||||
HWLAB 的实现必须吸收这些边界:admission 只创建 stable turn/message/part/control ids;status/cancel 不由 trace tail 推断;message page 和 trace page 只读 read model;event stream/outbox 负责 replay 和 ordering;assistant 最终内容来自 sealed assistant part,而不是从 trace 行、result envelope、DOM、`message.text` 或 analyzer fallback 重新挑选。凡是需要保留旧 compat route 的地方,都只能包装正式 mutation 或 WorkbenchReadModel,不能保留第二套 prompt/result/trace 仲裁。
|
||||
|
||||
### 5.2 目标架构图
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
subgraph AgentRun[AgentRun execution backend]
|
||||
RUN[run]
|
||||
CMD[command]
|
||||
SRC[events / result / sourceSeq]
|
||||
RUN --> CMD
|
||||
CMD --> SRC
|
||||
end
|
||||
subgraph CloudAPI[HWLAB Cloud API]
|
||||
AD[AgentRun Adapter: normalize facts]
|
||||
WR[WorkbenchProjectionWriter]
|
||||
FIN[WorkbenchProjectionFinalizer]
|
||||
FS[(WorkbenchFactsStore)]
|
||||
RM[WorkbenchReadModel]
|
||||
CACHE[(Redis derived read cache)]
|
||||
SSE[SSE publisher]
|
||||
COMP[Compat wrappers]
|
||||
AD --> WR
|
||||
FIN --> WR
|
||||
WR --> FS
|
||||
FS --> RM
|
||||
RM <--> CACHE
|
||||
FS --> SSE
|
||||
RM --> COMP
|
||||
end
|
||||
subgraph Consumers[Projection consumers]
|
||||
REST[GET /v1/workbench/*]
|
||||
WEB[Cloud Web reducer/selectors]
|
||||
CLI[HWLAB CLI renderer]
|
||||
FAKE[fake-server fixture]
|
||||
SSEOUT[/v1/workbench/events]
|
||||
RM --> REST
|
||||
REST --> WEB
|
||||
REST --> CLI
|
||||
REST --> FAKE
|
||||
SSE --> SSEOUT
|
||||
SSEOUT --> WEB
|
||||
end
|
||||
SRC --> AD
|
||||
```
|
||||
|
||||
目标架构要求 route/auth、adapter、projection writer/finalizer、facts store、read model、SSE publisher 和 compat wrapper 分工清晰。任何 route、GET handler、trace polling、result polling、workspace snapshot 或 front-end reducer 都不能绕过 writer/finalizer 直接改变 Workbench facts。
|
||||
|
||||
目标架构还要求投影推进只发生在上游写侧。SSE publisher/handler 只发布和 replay durable outbox commit;Web/CLI/fake-server/SSE consumer 只消费 REST/SSE projection。SSE open/error、visibility change、route hydrate、Trace detail hydration、web-probe 观察、GET refresh 和 observer reload 不能触发 `hydrateRealtimeGap`、read-through sync、result sync 或 trace polling 来推动 projection;缺口只能表现为 projection diagnostic/blocker,并由 scheduler/reconciler/finalizer 或 source event/outbox 追平。
|
||||
|
||||
目标架构还要求彻底禁止读侧推理。`turn.status`、`message.status`、`session.running`、`trace terminal`、`finalResponse` 和 `projectionStatus` 必须是 projection writer/finalizer 已经写入 durable facts 的字段;read model、REST route、SSE consumer、compat wrapper、Web reducer、CLI renderer、fake-server 和测试只能读取和重放这些字段。AgentRun facts、trace events、message parts、result envelope、session summary、list row 和 workspace snapshot 只能作为 writer/finalizer 输入或诊断字段,不得在读取链路中通过优先级、fallback、最后事件、空文本、超时或 UI heuristic 生成生命周期事实。
|
||||
|
||||
### 5.3 目标数据流图
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
USER[用户 prompt/steer/retry/cancel] --> ADMISSION[Turn admission]
|
||||
ADMISSION --> IDS[stable turnId traceId userMessageId assistantMessageId]
|
||||
ADMISSION --> AR[AgentRun run/command]
|
||||
IDS --> WR0[ProjectionWriter: admission facts]
|
||||
AR --> EV[AgentRun events/result]
|
||||
EV --> NORM[normalize AgentRun facts]
|
||||
NORM --> FIN[ProjectionFinalizer]
|
||||
FIN --> WR[ProjectionWriter]
|
||||
WR0 --> TX[projection commit]
|
||||
WR --> TX
|
||||
TX --> FACTS[(Workbench facts + checkpoint + diagnostics)]
|
||||
FACTS --> RM[WorkbenchReadModel]
|
||||
RM --> CACHE{derived cache?}
|
||||
CACHE -->|hit| SNAP[REST snapshot / pages]
|
||||
CACHE -->|miss/stale| FACTS
|
||||
FACTS --> BUS[SSE projection commit]
|
||||
RM --> SNAP[REST snapshot / pages]
|
||||
BUS --> STREAM[SSE events]
|
||||
SNAP --> RED[Web reducer / CLI / fake-server]
|
||||
STREAM --> RED
|
||||
```
|
||||
|
||||
数据流必须保证:admission 只生成稳定标识和初始 facts;AgentRun facts 必须先归一化,再由 writer/finalizer 进入 projection commit;REST snapshot 和 SSE event 只能重放 durable facts;diagnostic 明确表达 lag/blocker,不能让读取路径、页面路径或测试路径隐式修复事实。
|
||||
|
||||
### 5.4 terminal commit 关键时序图
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant AR as AgentRun
|
||||
participant Adapter as AgentRun Adapter
|
||||
participant Finalizer as ProjectionFinalizer
|
||||
participant Writer as ProjectionWriter
|
||||
participant Store as FactsStore
|
||||
participant SSE as SSE Publisher
|
||||
participant Read as ReadModel
|
||||
participant Web as Web/CLI/fake-server
|
||||
AR-->>Adapter: terminal result + events + sourceSeq
|
||||
Adapter-->>Finalizer: normalized facts
|
||||
Finalizer->>Writer: finalize sourceRunId/sourceCommandId
|
||||
Writer->>Store: atomic terminal commit
|
||||
Store-->>Writer: projectedSeq + checkpoint
|
||||
Writer-->>SSE: projection commit notification
|
||||
Web->>Read: GET session/messages/turn/trace
|
||||
Read->>Store: read only
|
||||
Read-->>Web: same terminal facts + diagnostics
|
||||
```
|
||||
|
||||
terminal commit 必须在同一幂等提交内更新 assistant final text、message/part terminal status、turn terminal、trace terminal event、session running=false、summary updated、projection checkpoint 和 SSE cursor。若提交失败或暂时无法完成,只能暴露 projection lag/blocker;不得让 session rail 显示 completed、message page 显示 running、turn snapshot 显示 failed 或 trace page 缺 terminal 这类互相矛盾状态。
|
||||
|
||||
### 5.5 cloud-api 重启恢复时序图
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant Boot as cloud-api boot/background scheduler
|
||||
participant Store as FactsStore
|
||||
participant AR as AgentRun facts source
|
||||
participant Finalizer as ProjectionFinalizer
|
||||
participant Writer as ProjectionWriter
|
||||
participant Read as ReadModel
|
||||
Boot->>Store: load open checkpoints / running-projecting turns
|
||||
Store-->>Boot: sourceRunId/sourceCommandId/lastSourceSeq/lastProjectedSeq
|
||||
Boot->>Finalizer: resume checkpoint
|
||||
Finalizer->>AR: fetch events/result after source checkpoint
|
||||
AR-->>Finalizer: source facts or still-running status
|
||||
Finalizer->>Writer: idempotent catch-up commit
|
||||
Writer->>Store: update facts/checkpoint/diagnostic
|
||||
Read->>Store: read only snapshots
|
||||
Store-->>Read: caught-up facts or explicit lag/blocker
|
||||
```
|
||||
|
||||
重启恢复要求 finalizer 不依赖进程内 90s 轮询作为唯一推进机制。进程内任务丢失、cloud-api 重启或慢任务超过短轮询预算后,boot/background scheduler 必须能从 durable checkpoint 和 running/projecting turn 找回需要追平的 sourceRun/sourceCommand,并以同一 writer 逻辑提交或记录 blocker。GET、SSE、Web 页面、visibility handler、fake-server、web-probe 和 CLI renderer 只能观察恢复状态,不能触发恢复、gap hydration 或 read-through sync。
|
||||
|
||||
### 5.6 durable Workbench facts 对象模型
|
||||
|
||||
Workbench durable facts 是唯一投影的持久对象模型。后续实现可以选择关系表、文档表或 runtime store 等价结构,但必须保留下列对象、稳定键和职责边界;旧 `agent_sessions.session_json`、result snapshot、trace tail、compact snapshot 和 workspace/conversation metadata 只能作为迁移输入或诊断来源,不得成为读取路径 lifecycle authority。
|
||||
|
||||
| 对象 | 稳定键 | 关键字段 | 生命周期职责 |
|
||||
| --- | --- | --- | --- |
|
||||
| `workbench_session` | `sessionId` | `owner`, `projectId`, `workspaceId`, `status`, `running`, `currentTurnId`, `summary`, `updatedAt` | session rail、detail 和 composer 可继续操作的用户态会话事实。 |
|
||||
| `workbench_message` | `messageId` | `sessionId`, `role`, `turnId`, `status`, `sealedAt`, `createdAt`, `updatedAt` | timeline message 容器;assistant terminal message sealed 后不被 diagnostic 覆盖。 |
|
||||
| `workbench_part` | `partId` | `messageId`, `type`, `status`, `text`, `tool`, `error`, `finalResponse`, `traceRef`, `order`, `sealedAt` | 主正文、工具、错误、final response 和 trace 摘要的组合事实。 |
|
||||
| `workbench_turn` | `turnId` | `sessionId`, `traceId`, `status`, `terminal`, `failureKind`, `sourceRunId`, `sourceCommandId`, `startedAt`, `lastEventAt`, `finishedAt`, `durationMs`, `sealedAt` | 一次 prompt、steer、retry 或 cancel 的生命周期事实;时间字段只由投影写入。 |
|
||||
| `workbench_aggregate_event` | `eventSeq` 或 `eventId` | `aggregateId`, `aggregateSeq`, `sessionId`, `turnId`, `traceId`, `messageId`, `sourceRunId`, `sourceCommandId`, `sourceSeq`, `sourceEventId`, `eventType`, `occurredAt`, `committedAt`, `payloadRef`, `redactedPayload`, `projectionRevision` | append-only event stream;负责排序、幂等、SSE replay 和 projector recovery,不直接作为 Web 主 DTO 绕过 read model。 |
|
||||
| `workbench_trace_event` | `traceId` + `projectedSeq` | `sourceSeq`, `sourceEventId`, `type`, `status`, `timestamp`, `redactedPayload` | Trace event page 的唯一分页事实;`projectedSeq` 是 Workbench cursor。 |
|
||||
| `workbench_projection_checkpoint` | `sourceRunId` + `sourceCommandId` + `turnId` | `lastSourceSeq`, `lastProjectedSeq`, `sourceLatestSeq`, `status`, `attempt`, `nextRetryAt`, `lastError`, `blocker` | finalizer/resume 追平位置、幂等边界和阻塞恢复状态。 |
|
||||
| `workbench_projection_diagnostic` | `sessionId` + `turnId` + `traceId` | `projectionStatus`, `health`, `lag`, `blocker`, `sourceRunId`, `sourceCommandId`, `lastProjectedSeq`, `updatedAt` | GET、CLI、Web 和运维可见的投影健康诊断;不推进主事实。 |
|
||||
|
||||
对象模型必须支持下列 DTO 投影:session rail summary、session detail、message/part page、turn snapshot、trace event page、projection diagnostic 和 transport diagnostic。DTO 可以裁剪字段,但不得合并 authority;例如 trace detail 可展示 `sourceSeq/sourceEventId` 审计信息,主 timeline 的 finalResponse 只能来自 sealed message/part/turn facts。`workbench_aggregate_event` 是 projector 和 replay 的提交输入,不允许 Web/API/CLI 直接把事件 payload 拼成另一套 timeline。
|
||||
|
||||
Assistant 输出必须按 message/part authority 建模。一个 turn 内可以有多个 assistant text/tool/diagnostic/final response part,每个 part 有稳定 order 和 status;final response 是 terminal commit sealed 的 final part,不是“最后一个非空文本”。同一 trace 只生成 `msg_<trace>_agent` 这类单一 assistant 容器而缺少 part 身份、order 和 sealed 状态的实现,不能作为本规格的完成形态。
|
||||
|
||||
运行中和终态 timing DTO 必须保持可审计:`elapsed`、`recent update`、轮次完成耗时和 trace 首尾耗时的用户可见差异只能来自 durable projection 或上游事件时间戳,不能由 Web reducer、组件、ticker、fake-server、web-probe 或 CLI renderer 在读侧修正。前端只允许把 `now - startedAt`、`now - lastEventAt` 或 sealed `durationMs` 格式化成中文文案;不得保存 per-message timing floor、recent age cache、sealed duration cache、monotonic repair state 或后台 tab resume 补偿状态。若这些值在采样中出现归零、非单调、跳秒或和 terminal commit 不一致,系统必须暴露 projection/timing diagnostic 并修 writer/finalizer/read model、SSE/outbox 或 AgentRun source event,而不是在 UI 层滤波。
|
||||
|
||||
|
||||
### 5.7 durable projection outbox 与 reconciler
|
||||
|
||||
Projection outbox 是 durable commit notification log,与 projection facts 和 aggregate event stream commit 在同一数据库事务提交。outbox 的作用是让 SSE、CLI 和其他消费者从 durable cursor 恢复实时通知,不依赖进程内内存 listener。aggregate event stream 表达“发生了什么”和顺序权威;outbox 表达“某次投影 commit 可以通知消费者”,二者不得分叉成两套 lifecycle truth。
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
AR[AgentRun events/result] --> AD[Adapter normalize]
|
||||
AD --> WR[ProjectionWriter]
|
||||
WR --> TX[(DB transaction: aggregate events + facts + outbox + checkpoint)]
|
||||
TX --> AEV[aggregate event stream]
|
||||
TX --> FACTS[durable facts]
|
||||
TX --> OUTBOX[durable outbox rows]
|
||||
TX --> CP[checkpoint]
|
||||
OUTBOX --> SSE[SSE cursor replay]
|
||||
OUTBOX --> REC[reconciler worker]
|
||||
FACTS --> RM[ReadModel]
|
||||
RM --> REST[GET /v1/workbench/*]
|
||||
SSE --> STREAM[SSE events]
|
||||
CP --> BOOT[boot/resume scheduler]
|
||||
BOOT --> FIN[Finalizer]
|
||||
FIN --> WR
|
||||
```
|
||||
|
||||
Outbox 每行至少包含 `outboxSeq`(全局单调)、`eventSeq`、`aggregateId`、`aggregateSeq`、`traceId`、`sessionId`、`turnId`、`projectedSeq`、`projectionRevision`、`commitType`(event/terminal/checkpoint/diagnostic)、`createdAt` 和可序列化 payload 摘要。SSE 连接建立时先从 durable outbox 按 `afterSeq` 查询历史 commit notification 进行 replay,再切换到 live tail;cloud-api 重启后不需要内存 listener 即可恢复 SSE 输出。
|
||||
|
||||
Reconciler 是后台 worker,消费 outbox 和 checkpoint 驱动 finalizer 追平。它取代旧的请求/轮询式 `syncAgentRunChatResult` 推进模式:AgentRun result sync 只负责拉取/写入 projection source state,事件推进由 outbox/reconciler 管道统一处理。
|
||||
|
||||
### 5.8 SSE cursor replay 架构
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant Client as Web/CLI
|
||||
participant SSE as SSE handler
|
||||
participant DB as durable outbox
|
||||
participant WR as ProjectionWriter
|
||||
Client->>SSE: GET /v1/workbench/events?afterSeq=N
|
||||
SSE->>DB: SELECT outbox WHERE outboxSeq > N
|
||||
DB-->>SSE: replay rows (terminal, events, diagnostics)
|
||||
SSE-->>Client: replay events
|
||||
Note over WR,DB: new projection commit
|
||||
WR->>DB: INSERT outbox row
|
||||
DB-->>SSE: live tail notification
|
||||
SSE-->>Client: live event
|
||||
```
|
||||
|
||||
SSE handler 不再直接订阅内存 `traceStore.subscribe`。它只从 durable outbox 读取:连接建立时执行 replay(按 `afterSeq` 查询历史 commit notification),replay 完成后切换到 live tail(poll 或 LISTEN/NOTIFY 等价机制)。cloud-api 滚动、多副本和多用户同看同 trace 时,SSE 从同一 durable outbox 恢复,不丢 terminal/sealed 状态。
|
||||
|
||||
### 5.9 DB 唯一约束与幂等保障
|
||||
|
||||
`workbench_trace_events` 表必须有 `(trace_id, source_event_id)` 唯一约束,防止并发或历史数据写入重复 source event。allocator 查询 sourceEventId 复用 projectedSeq 时,数据库层必须硬约束阻断重复写入。
|
||||
|
||||
`(trace_id, projected_seq)` 也应有唯一约束,确保同一 trace 内 projectedSeq 单调不重复。历史 collision 数据在 migration 时通过 collision blocker 策略处理:检测到重复时暴露 `projectionStatus=blocked`、`projectionHealth=degraded` 和稳定 blocker code,不把损坏序列交给 renderer 继续展示。
|
||||
|
||||
Projection outbox 的 `outboxSeq` 必须全局单调递增,可通过数据库 sequence 或等价机制生成。outbox 行与 projection facts 在同一事务提交,保证 commit notification 与 durable facts 一致。
|
||||
|
||||
Aggregate event stream 必须同时具备 `(eventSeq)` 全局单调约束、`(aggregateId, aggregateSeq)` aggregate 内单调唯一约束和来源幂等唯一约束。来源幂等键至少覆盖 `sourceRunId`、`sourceCommandId`、`sourceEventId` 或等价 source result id;admission、cancel 和 replay/reprojection 这类本地事件必须有稳定 deterministic eventId。任何需要重排、补 terminal 或修 timing 的逻辑都必须追加受控事件并重新投影,不得直接改 read model 或前端 store。
|
||||
|
||||
### 5.10 0读侧推理验收矩阵
|
||||
|
||||
| 层 | 禁止模式 | 验收方式 |
|
||||
| --- | --- | --- |
|
||||
| 后端 turn projection | `result?.status ?? trace?.status ?? session?.status` | 源码扫描 + 单元测试构造多来源矛盾样本 |
|
||||
| 后端 SSE handler | `traceStore.subscribe` / 内存 trace snapshot | 源码扫描 + cloud-api 重启后 SSE cursor 恢复验证 |
|
||||
| 后端 trace snapshot | `events.at(-1)` 推导 status/lastEvent | 源码扫描 + 矛盾 events 样本测试 |
|
||||
| 后端 compact result | result/traceSummary/agentRun/memoryTrace 混合 | 源码扫描 + GET 路径不访问旧 compact path 验证 |
|
||||
| 后端 message projection | trace-level assistant id 或 firstNonEmpty/fallback 选择 final response | 源码扫描 + 多 assistant part / running final 空值样本 |
|
||||
| 前端 store | `events.at(-1)` 推导 activity/label/status | 源码扫描 + fake-server Playwright |
|
||||
| 前端 subscription | turn poll + trace poll + event tail 合并 lifecycle | 源码扫描 + SSE gap/timeout Playwright |
|
||||
| 前端 timing | `lastEventAgeMs` 作为相对时间权威 | 源码扫描 + fake clock Playwright |
|
||||
| CLI renderer | `lastEvent.status` 推 trace lifecycle 或 DOM 行顺序选择 final response | 源码扫描 + CLI 同源语义验证 |
|
||||
|
||||
每层验收必须先用负向 fixture 形成红灯,再用修复后代码证明通过。负向源码扫描是辅助证据,不能替代 fake-server Playwright 与 D601 v0.3 web-probe。
|
||||
|
||||
## 6. 原子需求
|
||||
|
||||
### 6.1 WB-PROJ-REQ-001 durable facts store
|
||||
|
||||
| 编号 | 短名 | 主责模块 | 关联模块 |
|
||||
| --- | --- | --- | --- |
|
||||
| WB-PROJ-REQ-001 | FactsStore | PJ2026-010401080301 FactsStore | [用户管理](PJ2026-0105-user-management.md)、[API契约](PJ2026-010403-api-contract.md) |
|
||||
|
||||
Workbench facts store 应持久化 session、message、part、turn、trace event、projection checkpoint 和 projection diagnostic,使 Workbench 用户态事实可在 cloud-api 重启、进程内任务丢失或后台 finalizer 重跑后恢复。
|
||||
|
||||
Facts schema 至少包含以下事实:
|
||||
|
||||
| fact | 必需字段 | 职责边界 |
|
||||
| --- | --- | --- |
|
||||
| session | sessionId/conversationId/threadId/projectId/workspaceId/owner/status/running/currentTurnId/summary/updatedAt | 会话可见性、rail 摘要和当前 turn 指针;不保存 provider Secret 或完整 prompt 原文之外的敏感负载。 |
|
||||
| message | messageId/sessionId/role/status/turnId/sealedAt/createdAt/updatedAt | timeline message 事实;assistant final text 通过 part 表达,sealedAt 或等价字段表示主消息结果已封存。 |
|
||||
| part | partId/messageId/type/status/text/tool/error/finalResponse/sealedAt/traceRef/order | 文本、工具、错误、final response 和 trace 摘要的可组合展示事实;final response part sealed 后不得被读侧 diagnostic 覆盖。 |
|
||||
| turn | turnId/sessionId/traceId/status/terminal/sealedAt/failureKind/sourceRunId/sourceCommandId/messageIds/startedAt/lastEventAt/finishedAt/durationMs | 一次用户提交、steer、retry 或 cancel 的生命周期事实;运行中相对时间显示只消费这些投影时间戳。 |
|
||||
| trace event | traceId/projectedSeq/sourceSeq/sourceEventId/type/status/timestamp/redactedPayload | Workbench trace page 的分页事实;projectedSeq 是唯一 cursor。 |
|
||||
| checkpoint | turnId/traceId/sourceRunId/sourceCommandId/lastSourceSeq/lastProjectedSeq/sourceLatestSeq/status/attempt/lastAttemptAt/lastError/blocker/updatedAt | finalizer 追平位置、幂等边界、恢复状态和退避诊断。 |
|
||||
| diagnostic | sessionId/turnId/traceId/projectionStatus/health/lag/blocker/sourceRunId/sourceCommandId/lastSourceSeq/lastProjectedSeq/sourceLatestSeq/updatedAt | GET 和运维可见的 projection 状态,不推进事实。 |
|
||||
|
||||
Checkpoint/projection state 唯一键必须包含 `sourceRunId`、`sourceCommandId` 和对应 `turnId`/`traceId`,或等价的 command-scoped 唯一键。同一 AgentRun run 的不同 command 不得共享 cursor;旧 command 的历史事件不得误投到新 turn。`lastSourceSeq` 表示已经成功投影的来源位置,`sourceLatestSeq` 只表示最近观察到的来源最新位置;二者差值可用于 lag/health 诊断,但不得让读侧推断 terminal。
|
||||
|
||||
AgentRun events 进入 Workbench trace facts 时,FactsStore 必须把 filtered trace event 写入和 projection cursor 推进放在同一 durable commit 中,或采用等价的幂等事务语义。cursor 只能在对应 source event 已成功持久化或被确认幂等去重后推进;不得先更新 `lastSourceSeq` 再异步 best-effort 写 trace event。cloud-api 重启后必须直接从 projection state 的 `lastSourceSeq` 继续请求上游 events,不能通过扫描 `agent_trace_events`、trace tail、session JSON、result payload 或长 trace 全量重放来反推出下一次 `afterSeq`。
|
||||
|
||||
Facts store 必须支持幂等 upsert、terminal commit、projection checkpoint、diagnostic update、open checkpoint 扫描、running/projecting turn 扫描和按 owner visibility 过滤的分页查询。`agent_sessions.session_json` 可作为迁移期 metadata 来源,但不得继续承载业务 projection 真相。
|
||||
|
||||
Facts store 必须把 assistant 文本、tool/command 行、diagnostic 和 final response 持久化为 message/part facts。对同一 turn/trace 的 assistant 输出,必须能按 part order 恢复 running 中间态、steer 后续输出和 terminal final part;不得只持久化 trace-level assistant message id,再让读取端从 `text/content/message/finalResponse` 的 first-non-empty/fallback 链条重建主消息。
|
||||
|
||||
### 6.2 WB-PROJ-REQ-002 projection writer
|
||||
|
||||
| 编号 | 短名 | 主责模块 | 关联模块 |
|
||||
| --- | --- | --- | --- |
|
||||
| WB-PROJ-REQ-002 | Writer | PJ2026-010401080302 ProjectionWriter | [HWLAB接入](PJ2026-010205-hwlab-dispatch.md)、[Agent编排](PJ2026-0102-agent-orchestration.md) |
|
||||
|
||||
WorkbenchProjectionWriter 应作为唯一写入口,把 admission facts 和 normalized AgentRun facts 转换为 durable Workbench facts。Writer 不负责 HTTP route、鉴权、AgentRun fetch、UI transient state、旧 API envelope 或测试 fixture。
|
||||
|
||||
Writer 必须使用稳定幂等键写入 messageId、partId、turnId、traceId、sourceRunId、sourceCommandId、sourceSeq/sourceEventId 和 projectedSeq。重复 event、重放 result、重启恢复或 checkpoint replay/reprojection 不得创建重复 assistant message、重复 terminal event 或冲突 session summary。
|
||||
|
||||
Writer 必须在 admission 阶段为 user message、assistant message 和初始 part 分配稳定身份,并在后续 event/result/steer/cancel projection 中追加或封存对应 part。assistant 文本增量、工具输出、backend diagnostic、steer 确认、cancel 结果和 final response 不得写入同一个无 order 的文本字段;terminal final response 必须是明确 partKind/status/sealedAt 的 sealed part。
|
||||
|
||||
Writer 的 terminal commit 必须同时写入 assistant final text、finalResponse part、message/turn terminal status、trace terminal fact、session running=false、checkpoint 和 `sealedAt` 或等价 sealed 标记。Completed、failed、canceled、blocked 都是 terminal result;若 AgentRun 或 projection 给出可读 final error/blocker,它必须作为 sealed final response 的一种结果写入,而不是作为后续 transport diagnostic 写入主正文。
|
||||
|
||||
### 6.3 WB-PROJ-REQ-003 projection finalizer
|
||||
|
||||
| 编号 | 短名 | 主责模块 | 关联模块 |
|
||||
| --- | --- | --- | --- |
|
||||
| WB-PROJ-REQ-003 | Finalizer | PJ2026-010401080303 ProjectionFinalizer | [HWLAB接入](PJ2026-010205-hwlab-dispatch.md)、[AgentRun核心](PJ2026-010201-agentrun-core.md) |
|
||||
|
||||
WorkbenchProjectionFinalizer 应以 checkpoint 为驱动追平 AgentRun facts。submit 后、event arrival 后、后台恢复和显式 checkpoint replay/reprojection 可以触发 finalizer,但这些入口必须调用同一幂等 finalization 逻辑。显式 replay/reprojection 是受控投影恢复入口,不是前端、GET、SSE 或 probe 的事后 repair;它不得改变 active session、route、当前消息区或用户显式选择。
|
||||
|
||||
Finalizer 不得伪造 terminal、不取消 AgentRun、不用日志尾部推断 completed,也不得让 GET route 临时同步执行 finalization。若 AgentRun 事实暂不可取或映射失败,finalizer 应写入 diagnostic blocker,保留 retry 所需 sourceRun/sourceCommand/checkpoint。
|
||||
|
||||
AgentRun rolling recovery 的缺口必须显式落入 projection diagnostic。若 AgentRun durable ledger 缺 terminal fact、runnerJob observation 尚未恢复、lease stale 但 Kubernetes phase 未确认、terminalReportState 仍 pending/outbox-retrying,或 AgentRun result/diagnosis API 返回 unrecoverable blocker,Finalizer 应把这些上游事实归一化为 Workbench projectionStatus、projectionHealth、blocker、sourceRunId、sourceCommandId 和 nextRetryAt 等诊断字段。Finalizer 不得根据 Kubernetes Job completed、stdout tail、最后一个 AgentRun event、elapsed timeout、session summary 或 Web 当前页面状态补造 Workbench completed。
|
||||
|
||||
Startup/resume authority 只属于 cloud-api boot/background scheduler。该 scheduler 启动后必须扫描 durable open checkpoint、`projectionStatus=projecting` 或等价 running/projecting turn,按 bounded concurrency、attempt、lastAttemptAt 和 backoff 推进;它只能调用同一 `WorkbenchProjectionFinalizer/Writer`,不得新增第二套 result polling、manager shortcut 或 GET repair。恢复任务失败时必须写入 `lastError/blocker` 和下一次 retry 所需 cursor,不能静默丢弃。
|
||||
|
||||
Finalizer 的 cursor 必须以 command 和 checkpoint 为边界追平。对同一 run 的第二个及后续 command,finalizer 必须从该 command 自己的 checkpoint 或 command-scoped event/result window 继续,避免每次从 run head 扫描大量旧事件;当只能获得 run-level event page 时,也必须用 `sourceCommandId`、稳定幂等键和 source checkpoint 过滤旧 command 事件。result 先到、events 后到、terminal event 缺失但 command result terminal、source event 缺口或 sourceSeq 回退都必须进入 diagnostic/blocker 或补洞路径,不得在读侧修正。
|
||||
|
||||
运行中投影必须以 AgentRun events 增量接口为主读源:finalizer/resume loop 使用 durable `lastSourceSeq` 调用上游 `events?afterSeq=<lastSourceSeq>&limit=<boundedPage>`,再按 commandId 和 seq window 过滤并提交 Workbench facts。running loop 不得为了恢复或刷新进度同步等待 `/result`,也不得在每次拉取时从 run seq 0、长 trace、result envelope 或历史 events 数组重新扫描。发现 terminal evidence 后,finalizer 可以把 projection 标记为 terminal/pending-result,并把 `/result` 同步交给后台低优先级归档;`/result` timeout 只能更新 `resultSyncState`、`lastError/blocker` 和 retry/backoff,不得阻止 events cursor 继续推进。
|
||||
|
||||
Projection resume 对 `projectionStatus=projecting/degraded/stalled` 或等价 running turn 超过受控阈值的 trace,必须周期性读取 AgentRun command result authority,不能只等待 events page 中出现 terminal event。Command result 已 terminal 时,finalizer 必须写入同一 terminal commit;若 result 拉取失败或超时,`resultSyncState=timed_out/failed/pending` 必须进入 projection state 并按 backoff 重试。长期 `terminal=0 failed=0` 的 resume pass 不能被记录成无问题完成;它必须暴露候选数、result sync 状态和下一次 retry 信息。
|
||||
|
||||
Cancel 是受控 mutation,不是终态仲裁。`/v1/agent/chat/cancel` 或 Workbench cancel mutation 在转发 AgentRun cancel 前,必须先检查本地 sealed terminal projection,并在可能时读取当前 run/command result 或 command state。若上游 command 已 `completed`、`failed`、`blocked`、`canceled` 或等价 terminal,cancel 不得把 Workbench turn 改写为 canceled;应返回 already-terminal/no-op 或触发 terminal projection,使 Workbench 保持真实 terminal final response。
|
||||
|
||||
Finalizer 对 sealed turn 的后续重试只能推进 trace detail completeness、result archive、diagnostic health 或受控 replay/reprojection;不得把 `/result` timeout、events gap、provider transport error、poll idle timeout 或 hydration failure 映射成新的 assistant 主正文、finalResponse、message status 或 turn terminal status。
|
||||
|
||||
### 6.4 WB-PROJ-REQ-004 read model and pure GET
|
||||
|
||||
| 编号 | 短名 | 主责模块 | 关联模块 |
|
||||
| --- | --- | --- | --- |
|
||||
| WB-PROJ-REQ-004 | ReadModel | PJ2026-010401080304 ReadModel | [API契约](PJ2026-010403-api-contract.md)、[Web工作台](PJ2026-010401-web-workbench.md) |
|
||||
|
||||
WorkbenchReadModel 应作为唯一读模型,从 durable facts 组装 session list、session detail、message page、turn snapshot、trace event page 和 projection diagnostics。Read model 只读 facts store,不调用 AgentRun、Code Agent manager、legacy conversation manager、billing finalizer、workspace repair 或 trace/result polling。
|
||||
|
||||
Read model 可以在组装完成后读取或写入 Redis 派生读缓存,但缓存 payload 必须等价于同一 durable facts/read model DTO 的可重建快照。缓存 key 必须包含 cache authority input;命中缓存不得绕过 owner visibility、不得补造缺失 facts、不得把 stale payload 升级成 terminal truth。Redis unavailable、timeout、decode failed 或 revision mismatch 必须退化为 cache diagnostic,并继续走 durable facts read 或明确 degraded。
|
||||
|
||||
`GET /v1/workbench/*` 必须纯读。若 projection 滞后,响应应输出 `projectionStatus`、`lastProjectedSeq`、`sourceRunId`、`sourceCommandId`、`blocker` 或等价 diagnostic 字段,不能在 GET 内做 read-through repair。
|
||||
|
||||
MessagePage 是 Workbench timeline 事实,不是 facts 表写入批次的直接 dump。WorkbenchReadModel 必须按 turn timeline、aggregate seq 或等价事件时间组装用户可见顺序;同一 turn 的 user message 必须位于对应 assistant/agent terminal message 之前,跨 turn 不得因为 user message 的 `projectedSeq/sourceSeq` 先整体写入、assistant terminal 后整体写入而输出 `UUAA`、`UUUAAA` 等 role cluster。`projectedSeq/sourceSeq/sourceEventId` 必须保留用于审计和幂等,但不得让 role/source bucket 或投影批次覆盖用户可见 timeline。
|
||||
|
||||
Session summary 的 title/preview 必须由 durable message/part projection 生成脱敏摘要,并随 session list/detail 作为显式字段返回。fallback `Session ses_*` 只表示 read model 缺摘要,是需要通过 OTel/session_list_read、web-probe finding 或 reprojection 暴露的问题,不是正常 UI 文案来源。
|
||||
|
||||
MessagePage、session detail 和 session list 必须输出足够的脱敏诊断来证明同一 session 的 canonical timeline 一致性。推荐字段为 `timelineDigest`、`roleSequencePrefix`、`adjacentSameRoleCount`、`traceIds`、`messageCount`、`projectionRevision` 或等价组合;这些字段可以作为 API DTO、OTel attribute 或 web-probe summary 出现,但必须同源于 ReadModel。刷新、session 切换、双观察者、deep link 与 SSE 重连后,同一 projection revision 的 digest 不得变化;若变化,系统必须把差异暴露为 projection/read-model/transport diagnostic,而不是在 Web reducer 或 analyzer 中重排掩盖。
|
||||
|
||||
Read model 严禁读侧推理。它不得从 `result?.status ?? trace?.status`、最后一条 trace event `status=completed`、message text 是否为空、part/tool row 状态、session list summary、workspace selected state、localStorage mirror、轮询耗时或 elapsed timeout 推断 turn terminal、message terminal、trace terminal、session running、final response 或 projection caught-up。若 durable facts 中唯一投影对象缺少这些字段,Read model 必须返回未知、投影中、degraded 或 blocker 等显式 diagnostic,由 projection writer/finalizer 修复源头;不得在读取时临时合成“看起来正确”的状态。
|
||||
|
||||
Read model 读取到 sealed final response 时,必须把主消息正文、finalResponse、message status 和 turn terminal 从 sealed projection 输出;projection diagnostic、trace detail diagnostic、transport diagnostic、result sync diagnostic 和 session health 只能作为独立字段或详情区数据输出。读取链路不得因为后续 turn snapshot 失败、trace detail page 失败、SSE gap、realtime timeout 或 compat wrapper 失败而替换 sealed 主正文。
|
||||
|
||||
Read model 输出 running turn 时,finalResponse 必须为空值或等价 `(空内容)` 展示输入;诊断、后台状态解释、steer accepted 文案或用户 prompt 不能填入 finalResponse。Read model 输出 terminal turn 时,finalResponse 只能来自 sealed final part;若 sealed final part 缺失,应输出 projection blocker,而不是回退到 user message、assistant 中间文本、trace 最后一行或 result summary。
|
||||
|
||||
Projection health 必须只解释 durable diagnostic。`projectionStatus=projecting` 且 `lastProjectedSeq < sourceLatestSeq`、checkpoint stale 超过受控阈值、存在 `lastError/blocker` 或 attempt 正在退避时,不得返回 `caught-up`;应返回 `projecting`、`degraded` 或 `stalled`,并暴露 `blocker`、`lastProjectedSeq`、`sourceRunId`、`sourceCommandId` 和更新时间。`caught-up` 只能表示对应 command checkpoint 已追平可见 source facts,或 source 明确仍 running 且无新可投影 facts。
|
||||
|
||||
Trace event page 必须按 `projectedSeq` 单调返回,响应范围必须合法。非空页满足 `range.fromSeq <= range.toSeq`;空页必须用明确空集合和空 range/null range 表达,禁止出现 `fromSeq=5/toSeq=4` 这类非法区间。`projectedSeq` 是 Workbench 读取 cursor,`sourceSeq` 只作为来源审计字段;二者不得混用。
|
||||
|
||||
Trace event page 的可见性必须以 durable turn/message/session 关系和 owner visibility 判断,不能只依赖 session 当前 `lastTraceId`。同一 session 后续产生新 trace 后,旧 trace 只要对应 turn、message 或 projection facts 对当前 actor 可见,`GET /v1/workbench/traces/{traceId}/events` 仍应返回 200 和 trace page;若 trace facts 缺页或 projection 未追平,应返回 projection blocker/degraded,而不是 actor 不可见 404。真正 archived/deleted/not-found 的生命周期必须来自 canonical lifecycle projection。
|
||||
|
||||
Trace event page continuation 的空窗口不得升级成 404。若 page 没有新 event、但 trace checkpoint 或 projection diagnostic 显示 read model 尚未追到 `traceLastSeq/lastProjectedSeq`,响应应为 `200` 空页并标记 `projectionStatus/projectionHealth=projecting` 或等价 degraded/stalled,暴露 `latestProjectedSeq` 或 `lastProjectedSeq`、`traceLastSeq`、`fullTraceLoaded=false` 和 `diagnostic.code=workbench_trace_events_missing`。`fullTraceLoaded=true` 只能表示本次 page 实际 `toProjectedSeq` 已追到 `traceLastSeq` 且没有更多 page,不能仅由 `hasMore=false` 或 `range.total` 推断。
|
||||
|
||||
Trace event page 的 OTel/read-model 诊断必须能解释 web-probe 的 trace-row-order 与 completion/timing finding。每次读取至少应能关联 traceId、sessionId、range.fromProjectedSeq、range.toProjectedSeq、returnedEvents、totalEvents、hasMore、fullTraceLoaded、traceLastSeq、projectionStatus、projectionHealth、sourceRunId 和 sourceCommandId;这些字段应来自同一 ReadModel 响应或同源 OTel span,不能由 analyzer 在事后猜测。
|
||||
|
||||
Workbench facts/read model 的 PostgreSQL pool connect/query timeout 必须被转换为结构化 degraded/readiness/blocker 响应和日志,不能逃逸为 cloud-api 进程未捕获异常。Liveness 不应因单次 Workbench read query timeout 变为 EOF;readiness 或 route 响应应暴露 route、store method、timeout kind、runtime readiness、projection candidate count、相关 trace/run/command 摘要和 `valuesRedacted=true`。
|
||||
|
||||
### 6.5 WB-PROJ-REQ-005 compat wrapper
|
||||
|
||||
| 编号 | 短名 | 主责模块 | 关联模块 |
|
||||
| --- | --- | --- | --- |
|
||||
| WB-PROJ-REQ-005 | CompatWrapper | PJ2026-010401080305 CompatWrapper | [API契约](PJ2026-010403-api-contract.md)、[HWLAB接入](PJ2026-010205-hwlab-dispatch.md) |
|
||||
|
||||
迁移期 `/v1/agent/turns/*`、`/v1/agent/traces/*`、conversation detail、result polling 和 legacy conversation path 可以作为 compat wrapper 暂存,但只能调用 WorkbenchReadModel 或正式 mutation。Compat wrapper 不得拥有第二套 session/message/turn/trace 写入逻辑,不得在读取时同步 finalizer,也不得用 result cache 或 trace tail 组装另一份 final response。
|
||||
|
||||
旧路径返回的 envelope 可以保留 legacy 字段名,但字段值必须来自同一 Workbench facts。若无法映射,应返回结构化 incompatibility/blocker,而不是回退到旧 manager 或空 stub。
|
||||
|
||||
### 6.6 WB-PROJ-REQ-006 Web server-state single path
|
||||
|
||||
| 编号 | 短名 | 主责模块 | 关联模块 |
|
||||
| --- | --- | --- | --- |
|
||||
| WB-PROJ-REQ-006 | Web单路径 | PJ2026-010401080306 WebServerState | [Web工作台](PJ2026-010401-web-workbench.md)、[API契约](PJ2026-010403-api-contract.md) |
|
||||
|
||||
Cloud Web 应把 REST snapshot、SSE projection commit、trace event page 和 submit optimistic ids 归一化到同一 server-state/reducer/selectors。UI 组件只消费 selectors;组件、trace polling、result polling、localStorage、workspace snapshot 或 session list summary 不得直接写 final response、message terminal、turn terminal 或 trace authority。
|
||||
|
||||
Web server-state 必须分仓表达 `messageProjection`、`traceDetail`、`sessionStatus` 和 `transportDiagnostics`,或采用等价结构保证主消息投影与读侧诊断不会竞争同一字段。`messageProjection` 承载 role、status、text、finalResponse、turnId、traceId 和 sealedAt;`traceDetail` 承载 events、pagination、hydration 状态和 trace diagnostics;`sessionStatus` 承载 rail/card 运行摘要;`transportDiagnostics` 承载 SSE、poll、hydration timeout 或 realtime gap。Selectors 可以在消息详情入口汇总诊断,但主 timeline 的 sealed final response 不得被 diagnostic 文案替换。
|
||||
|
||||
active session 只能由 route sessionId 或用户显式选择产生。REST detail、session list、workspace summary、SSE event、trace page 或 turn snapshot 晚到时,只能更新其声明 sessionId 对应的 server-state bucket;不得重新选择 session、替换 URL、覆盖当前消息区、改变 composer 或把另一个 session 的 running/terminal 状态投射到当前页面。缺少 sessionId 或 session/trace 不匹配的 event 必须进入 authority mismatch diagnostic,不得猜测、fallback 或应用到当前 active session。
|
||||
|
||||
active turn/trace 只能来自 read model 声明的 current turn、用户显式选择或提交 mutation 返回的 stable ids。Web store 不得通过倒序扫描 messages、查找 running trace、`messageHasCompletedFinalResponse()`、最新 traceId 或 composer mode 推断 active trace;这类推断只能作为迁移期负向扫描对象。prompt、steer 和 cancel 的按钮 action 必须与当前 active command boundary 一致;没有 active turn 时,steer/cancel 应返回 no-op/blocker,不得 fallback 成普通 prompt。
|
||||
|
||||
SSE typed event 是 projection commit 的 live delivery 主路径,但事实来源仍是 durable aggregate event stream 和 Workbench read model。SSE 断线、丢事件或重连后,Web 只能通过同一 durable cursor 的 SSE replay 或统一 `/v1/workbench/sync` replay 追平;不得回退到 session/messages/turns/trace detail 多端点补洞。running trace 在 terminal 前 detail page `hasMore=false` 只表示当前 detail 页追平,不得设置永久 `fullTraceLoaded=true`,也不得影响主 turn terminal 判定。
|
||||
|
||||
Web reducer 必须提供 sealed guard:对已经有 `sealedAt` 或等价 sealed 标记的 assistant message/turn,旧 turn polling、trace detail、SSE gap、late realtime diagnostic、compat wrapper error 或 elapsed timeout 只能更新所属 trace/session 的 diagnostic bucket,不得写回 message text、finalResponse、message status 或 turn terminal。需要主动修改 sealed 主正文时,必须来自同一 durable projection 的新 revision、受控 replay/reprojection 或明确用户 mutation,而不是读侧失败。
|
||||
|
||||
运行中相对时间显示必须保持单一权威:Web server-state 只保存 WorkbenchReadModel 返回的 `startedAt`、`lastEventAt`、`finishedAt`、`durationMs` 和 sealed 标记;浏览器 ticker 只在组件渲染时计算 `now - startedAt` 与 `now - lastEventAt` 文案。`Date.now()`、页面本地 `updatedAt`、`lastEventAgeMs` 快照、轮询间隔和 trace detail 读取时间不得写入 reducer/store,也不得影响 lifecycle、terminal、session ordering 或 projection diagnostic。终态消息的耗时只使用 sealed projection 值,不能随浏览器 ticker 继续增长。
|
||||
|
||||
刷新和 session switch 恢复必须保持 active session bucket 不变量。Web 在重新 hydrate、切出再切回、双页面同时观察、SSE replay、`/v1/workbench/sync` replay 或 optimistic submit reconcile 时,只能用 ReadModel 声明的 sessionId/turnId/messageId/traceId 更新对应 bucket;pending optimistic message 必须按 stable ids 与服务器 message 对账,不能按数组位置、最近 traceId、session rail 行或 DOM 到达顺序合并。web-probe 在第 1、5、10 轮刷新或切换后看到的主 timeline digest、role sequence、session rail title/preview 和 traceId 归属必须与同一 ReadModel 快照一致。
|
||||
|
||||
### 6.7 WB-PROJ-REQ-007 regression and validation
|
||||
|
||||
| 编号 | 短名 | 主责模块 | 关联模块 |
|
||||
| --- | --- | --- | --- |
|
||||
| WB-PROJ-REQ-007 | 回归验收 | PJ2026-010401080307 Regression | [Web工作台](PJ2026-010401-web-workbench.md)、[平台运维](PJ2026-0106-platform-ops.md) |
|
||||
|
||||
Workbench唯一投影必须有后端和浏览器两层回归:后端用 Workbench-only HTTP 用例证明 submit 后不访问旧 `/v1/agent/turns` 或 result polling 也能自然 completed;durable recovery 用例证明进程内 sync 丢失或 cloud-api 重启后 finalizer 能从 checkpoint 追平;terminal atomicity 用例证明 session rail、session detail、messages、turn snapshot 和 trace event page 不出现 running/completed 组合矛盾。
|
||||
|
||||
Durable recovery 红灯必须覆盖长 run、多 command 和大量旧事件场景。fixture 应优先从 D601 v0.3 真实样本脱敏派生,至少覆盖同一 run 中后续 command 已 completed、eventCount 大于 2000、Workbench 只投影早期 seq、GET 保持纯读、随后后台 resume 从 command-scoped checkpoint 追平并展示 final response 的路径。用例还必须断言 GET 没有调用 AgentRun 或 result polling。
|
||||
|
||||
后端回归还必须包含不依赖 Web、CLI、数据库外部服务或其他模块的最小单元测试,直接覆盖 AgentRun events 拉取计划和 projection cursor 推进逻辑。该测试必须构造长 trace 或大量旧 source events 的反例,并断言下一次 `afterSeq` 来自 durable projection state/checkpoint 而不是遍历历史 trace event;测试应通过受控计数器、throwing iterable 或等价方式证明 cursor 计算复杂度不随历史 trace/event 数量线性增长。任何恢复到从 trace tail、result payload 或 events 数组扫描最大 sourceSeq 的实现都应让该单元测试红灯。
|
||||
|
||||
回归还必须覆盖读侧推理清零。后端和前端测试应构造最后一条 trace event 为非终态 `completed`、message text 为空、result/trace/session summary 字段互相矛盾或投影暂时滞后的样本,断言 API 与 DOM 不从这些原始字段推断 terminal/final/running。收口证据应包含负向源码扫描,至少覆盖 `result?.status ?? trace?.status`、`trace.status` 终结 turn、last event `completed` 终结 turn、message/session/list 状态覆盖 turn、elapsed timeout 改写 terminal 和 no-final-response 占位 final text 等读侧推理路径。
|
||||
|
||||
fake-server Playwright 应使用目标 node/lane 的真实采集脱敏 fixture,覆盖 session 切换、刷新、SSE 断线重连、sync replay、trace detail 分页和 terminal final response。纯 SSE 单步 fixture 应能禁用所有补洞请求,只用 typed event 验证 terminal seal、late stale rejection、detail-only rejection 和 cross-page convergence。D601 v0.3 public origin web-probe 应验证不切 session、不刷新页面、fresh deep link 和多观察者场景都通过同一 read model 收敛。
|
||||
|
||||
fake-server Playwright 还必须覆盖 timing display 红灯:在固定 projection timestamp、禁止 SSE/API 后续更新、使用浏览器 fake clock 推进的条件下,running 消息头部的“最近”和“耗时”应随 fake clock 前进;completed/failed/canceled/blocked 等终态消息的 sealed 耗时不得随 fake clock 前进。该测试不得读取内部 store,也不得通过更新 fixture、重新请求 API 或触发 projection repair 判定通过。
|
||||
|
||||
AgentRun rolling recovery 回归必须覆盖上游 stale ledger 与不可恢复 blocker 样本:manager rolling 后 AgentRun diagnosis 仍处于 pending observation 时,Workbench list/detail/messages/turn/trace 应一致展示 projecting/degraded/stalled diagnostic;terminal facts 后续提交后,同一 durable projection writer/finalizer 应自然推进 sealed final response。测试不得通过 GET read-through、Web reload、切换 session、result fallback 或 fake-server 后门把 pending 状态改成 completed。
|
||||
|
||||
Terminal outbox recovery 回归必须覆盖 events page 缺 terminal、command result 已 completed 且含 final response 的样本。测试应断言 projection resume 会强制读取 command result authority、写入 completed terminal commit,并让 session/detail/messages/turn/trace events 全部从 durable facts 看到同一 terminal;随后用户 cancel 应返回 already-terminal/no-op,不得把 completed 改成 canceled。历史 trace 可见性回归必须覆盖同一 session 后续新 trace 成为 `lastTraceId` 后,旧 trace events 仍以 turn/message 关系返回 200 或明确 projection blocker。
|
||||
|
||||
Read model degradation 回归必须覆盖 PostgreSQL pool connect/query timeout:Workbench facts query 应返回结构化 503/degraded 或 readiness/blocker,并记录脱敏诊断;测试不得通过未捕获异常、进程退出、liveness EOF 或 GET read-through repair 判定通过。
|
||||
|
||||
Sealed final response 回归必须构造 completed assistant 主正文已经展示后,`/v1/workbench/turns/{traceId}`、`/v1/workbench/traces/{traceId}/events`、SSE 或 realtime diagnostic 发生 timeout/500/gap/close 的样本,断言主消息正文、finalResponse、message status 和 turn terminal 保持 sealed 不变,诊断只出现在 trace detail、transport diagnostic、session health 或消息详情入口。回归还必须覆盖 trace detail 延迟返回、分页缺口和用户手动展开/折叠状态,确保 late update 不 remount 主消息卡片、不重置用户控制状态。
|
||||
|
||||
多 turn / running steer 回归必须覆盖连续 prompt、运行中 steer、terminal 后再次 prompt 和 cancel no-op 的组合。用例应断言 `turn-summary` 的每个用户消息绑定正确 traceId/runId/commandId;`trace-frame --turn N` 与 `trace-frame --trace-id <id>` 读取同一 turn;running frame 的 `Final Response` 为空;terminal frame 的 final response 是 sealed assistant final part;后续 steer/cancel 不会让 analyzer 把普通 prompt 标成 `prompt-routed-to-steer`,也不会让 trace-frame 误选用户 prompt、backend diagnostic 或 steer accepted 中间文案作为最终回答。
|
||||
|
||||
0repair 验收必须先在 fake-server + Playwright 中形成红灯:fresh context 直达 session A、普通点击切到 session B、A 的 delayed detail/turn/trace/SSE 晚到、用户没有提交 B 的新消息时,B 的 URL、active tab、message card、composer 和 trace detail 不得出现 A 的 user/agent 文本、running 状态或 terminal trace。web-probe 必须连续截图观察提交前、running、中间态、terminal 和晚到事件;不得用 reload、切换 session、`sessionRepair`、`realignFreshSession`、localStorage 修改或 helper 自动点击修正页面后再判通过。
|
||||
|
||||
D518 HWLAB v0.3 的 issue #1217 closeout 必须在真实 public origin 上完成 fake-echo 与 dsflash-go 两类 Workbench 哨兵。fake-echo 验收要求同一 session 多轮 prompt 后,刷新、切换 away/back、deep link 和双观察者场景的 message role sequence 保持 `UAUA...`,不得出现 user cluster、session rail title fallback、cross-page projection divergence 或 activeSession/routeSession 漂移。dsflash-go 验收要求 trace rows 按 Workbench projectedSeq/aggregateSeq 单调,completion row 与 sealed final response 属于同一 trace/turn,终态 duration 不继续增长,Code Agent 卡片耗时、完成行耗时与 ReadModel timing 字段一致。关闭 issue 前,两个哨兵都必须连续 3 次通过或给出明确未通过 blocker;不得通过减少轮数、跳过刷新/切换步骤、提高 120s 预算、忽略 WBC-011/WBC-046/trace-row-order-nonmonotonic/timing mismatch,或在 probe/analyzer 侧补偿来判绿。
|
||||
|
||||
### 6.8 WB-PROJ-REQ-008 code reference rule
|
||||
|
||||
| 编号 | 短名 | 主责模块 | 关联模块 |
|
||||
| --- | --- | --- | --- |
|
||||
| WB-PROJ-REQ-008 | 代码引用 | PJ2026-010401080308 CodeReference | [规格治理](spec-governance.md) |
|
||||
|
||||
本专项范围内新增或重构的核心源码文件,文件头部必须标注遵循的 SPEC 编号、短名和实现引用版本,例如:
|
||||
Workbench 的唯一终态由替代规格定义,固定数据链为:
|
||||
|
||||
```text
|
||||
SPEC: PJ2026-0104010803 Workbench唯一投影 draft-2026-06-20-p1-zero-split-durable-realtime
|
||||
agentrun.event.v1
|
||||
-> HWLAB mapper/direct publish
|
||||
-> hwlab.event.v1
|
||||
-> live SSE / Kafka retention replay SSE
|
||||
-> 同一浏览器 reducer
|
||||
```
|
||||
|
||||
同一文件同时承载 API契约、HWLAB接入、Web工作台或 Agent编排职责时,应在同一头部追加对应 SPEC 编号与实现引用版本。实现文件不得只写 issue 编号、`latest` 或 `current`。自动生成文件、第三方 vendored 文件、纯配置、锁文件和无法承载注释头的二进制产物可例外,但对应生成器、渲染器或配置入口必须能追溯到本 SPEC。
|
||||
PostgreSQL 只可承载非阻塞派生读模型。数据库 schema、migration、transactional projector 和 projection outbox 均不得成为 prompt admission、Cloud API 启动、direct publish、live SSE、Kafka replay 或滚动上线的前置条件。
|
||||
|
||||
### 6.9 WB-PROJ-REQ-009 derived read cache boundary
|
||||
## 3. 禁止继续采用的旧思想
|
||||
|
||||
| 编号 | 短名 | 主责模块 | 关联模块 |
|
||||
| --- | --- | --- | --- |
|
||||
| WB-PROJ-REQ-009 | 派生读缓存 | PJ2026-010401080309 DerivedReadCache | [Workbench性能](PJ2026-01060505-workbench-performance.md)、[API契约](PJ2026-010403-api-contract.md) |
|
||||
- 禁止把 Workbench PostgreSQL aggregate event stream、facts、checkpoint 或 outbox 恢复为 Kafka 事件之前的 inline authority。
|
||||
- 禁止要求 prompt admission 与本地 projection outbox 在同一事务提交。
|
||||
- 禁止用数据库 outbox replay、`/v1/workbench/sync`、业务 REST 补链、页面轮询或读侧 repair 替代 Kafka retention replay。
|
||||
- 禁止保留 direct/live 与 transactional projector 两套可切换 authority。
|
||||
- 禁止因派生读模型 schema 缺失、迁移未执行或 projector 退化而返回 admission failure、关闭 Kafka 实时能力或阻塞服务启动。
|
||||
- 禁止新增源码、测试、issue 或发布门禁继续引用本规格作为有效实现合同。
|
||||
|
||||
WorkbenchReadModel 可以使用 Redis 派生读缓存降低高频读路径的 Postgres 尾延迟,但缓存只保存可丢弃、可过期、可重建的 read model DTO 或内部 read snapshot。优先允许缓存 `/v1/workbench/sessions` actor-scoped session summary page、terminal turn snapshot 和 terminal trace event page;running turn、active session、projectionStatus 非 terminal 或正在变化的页面应使用更短 TTL 或不缓存。
|
||||
## 4. 迁移规则
|
||||
|
||||
缓存 key 必须包含 schema version、cache key class、actor visibility input、sessionId/turnId/traceId/cursor、projection revision/seq 或等价 authority input。payload 不得包含 raw secret、Authorization header、cookie、DB DSN、完整 prompt、完整 provider payload、完整 stdout/stderr 或未脱敏身份信息。命中缓存前必须能确认 authority input 匹配;revision mismatch、decode failed、actor mismatch、stale 或 Redis unavailable 时,ReadModel 必须走 durable facts read 或返回结构化 degraded,不得把缓存内容作为 lifecycle、terminal、final response、not-found、deleted 或 archived 的判断依据。
|
||||
|
||||
失效策略必须跟随 projection commit。Projection writer/finalizer 成功提交 session、turn 或 trace revision 后,应精确失效相关 key;若阶段上只能依赖短 TTL,自然过期策略必须与 user-visible freshness SLO 匹配,并通过 API/diagnostic 暴露 `cacheAgeMs` 和 projection revision/seq。Redis 中是否存在 key 不得用于推断 session lifecycle;canonical deleted、archived、not-found、running、completed、failed、blocked 和 final response 仍只能来自 durable Workbench facts。
|
||||
|
||||
派生缓存不能成为 GET repair 或多来源仲裁路径。缓存 miss 不得触发 AgentRun、result polling、workspace repair、trace polling 或 projection finalizer;缓存 hit 不得掩盖 SQL/schema/nullability bug、projection blocker、`row_scan_failed` 或 facts corruption。测试和负向扫描必须覆盖 cache hit、miss、stale、unavailable、revision mismatch、actor 隔离和 running turn 不长 TTL。
|
||||
|
||||
### 6.10 WB-PROJ-REQ-010 aggregate event stream
|
||||
|
||||
| 编号 | 短名 | 主责模块 | 关联模块 |
|
||||
| --- | --- | --- | --- |
|
||||
| WB-PROJ-REQ-010 | AggregateEventStream | PJ2026-010401080310 AggregateEventStream | [API契约](PJ2026-010403-api-contract.md)、[Web工作台](PJ2026-010401-web-workbench.md)、[Workbench性能](PJ2026-01060505-workbench-performance.md)、[Agent编排](PJ2026-0102-agent-orchestration.md) |
|
||||
|
||||
Workbench aggregate event stream 必须成为 Workbench 投影的唯一提交序。所有 admission、normalized AgentRun event、command result、terminal outbox、cancel mutation、diagnostic transition、checkpoint replay 和受控 reprojection 都必须先形成 durable event,再由同一 projector 生成 message、part、turn、trace event、session summary、projection checkpoint、diagnostic、read model cache invalidation 和 SSE outbox。任何直接写 message/status/trace/read cache 而不追加 aggregate event 的路径都属于第二写权。
|
||||
|
||||
每个事件必须携带稳定身份与排序字段:全局 `eventSeq`、`eventId`、`aggregateId`、`aggregateSeq`、`aggregateType`、`sessionId`、`turnId`、`traceId`、可选 `messageId/partId`、`sourceRunId`、`sourceCommandId`、`sourceSeq/sourceEventId`、`eventType`、`occurredAt`、`committedAt`、`projectionRevision` 和脱敏 payload 摘要。`eventSeq` 用于跨 aggregate SSE replay 和审计;`aggregateSeq` 用于同一 session/turn/trace/message 内的顺序;`sourceSeq` 只用于来源审计和幂等,不得作为 Workbench API cursor。
|
||||
|
||||
Projector 必须按 event stream 的提交序更新 read model。terminal event 必须在同一 projector revision 内原子写入 sealed final response、message/part terminal status、turn terminal、trace terminal marker、session running=false、checkpoint 和 outbox notification。terminal revision 之后的 late event、transport diagnostic、trace detail result、result archive 或 performance diagnostic 只能追加新的 diagnostic/detail revision;不得重新打开 sealed 主消息、把完成行挪到非最后位置、让完成耗时继续增长,或让 trace/timeline 因到达顺序不同而重新排序。
|
||||
|
||||
SSE replay 必须以 event stream/outbox durable cursor 为权威。`/v1/workbench/events?afterSeq=N` 或等价入口只能返回 `eventSeq/outboxSeq > N` 的投影 commit notification,并在 replay 完成后切到同一 durable tail;不得订阅进程内 `traceStore`、浏览器本地 pending queue、result polling 或 session list diff 作为 live truth。客户端收到重复、乱序或缺口时,应按 cursor 触发 SSE replay、统一 `/v1/workbench/sync` replay 或 transport diagnostic;不能在浏览器 reducer 内通过 arrival order 合成最终顺序,也不能调用 trace/session/turn 多端点补洞写主状态。
|
||||
|
||||
Timing 字段必须由 aggregate event stream 和 projector 统一产生。`startedAt` 来自 admission/source start event,`lastEventAt` 来自最新已投影活动事件,`finishedAt` 和 `durationMs` 来自 terminal event 或等价 terminal result;browser local now 只参与渲染运行中相对文案。web-probe 若发现 trace 乱序、完成行不是最后、完成耗时和 trace 首尾耗时不一致、终态耗时继续增长或红色 timing finding,根因修复必须回到 event stream/projector/read model/SSE cursor,不得再通过 Web reducer、probe analyzer、fake-server fixture 或 CSS/DOM 文案做补偿。
|
||||
|
||||
迁移实现必须删除旧的多来源仲裁路径。`traceStore.subscribe`、result envelope fallback、session JSON lifecycle、last trace event heuristic、turn polling status priority、localStorage truth、session repair、fake-server 专用重排和 probe 侧完成行修正只能作为负向扫描对象或迁移输入;保留兼容 wrapper 时也必须调用 WorkbenchReadModel 或正式 mutation。负向回归必须构造 source event 乱序、terminal result 先到、trace detail 晚到、SSE replay gap、cloud-api rolling restart 和浏览器 session 切换样本,证明完成行、final response、duration、trace page 和 session rail 均按 aggregate event stream revision 收敛。
|
||||
|
||||
### 6.11 WB-PROJ-REQ-011 CLI trace view and analyzer contract
|
||||
|
||||
| 编号 | 短名 | 主责模块 | 关联模块 |
|
||||
| --- | --- | --- | --- |
|
||||
| WB-PROJ-REQ-011 | CLI视图 | PJ2026-010401080311 CliTraceView | [Web工作台](PJ2026-010401-web-workbench.md)、[Workbench性能](PJ2026-01060505-workbench-performance.md)、[API契约](PJ2026-010403-api-contract.md) |
|
||||
|
||||
`web-probe collect/observe` 是唯一采样保存入口,负责按 5 到 10 秒级别采集 DOM/API/console/network 等事实,并把 frame、sample、request、traceId、runId、commandId 和时间戳写入采样目录。`web-probe analyze` 的 trace 截图是从这些采样事实或同源 read model 渲染出来的文字视图,不得另存一份“截图事实”,也不得在 analyze 阶段重新访问页面来补采样。
|
||||
|
||||
CLI 视图必须提供两层:第一层 `turn-summary` 展示多 turn 摘要,至少包含用户消息摘要、turn index、traceId、runId、commandId、status、elapsed、recent、warning 和最终内容摘要;第二层 `trace-frame` 按 turn、traceId、sample seq 或时间点渲染单 turn 的有序事件行。`trace-frame` 必须固定包含 `Final Response` 分区;running 或未 sealed 时显示 `(空内容)`,terminal sealed 后显示 sealed final part 的实际内容。该分区不得从用户 prompt、backend diagnostic、中间 assistant text、steer accepted 文案或 DOM 最后一行回退。
|
||||
|
||||
Trace-frame 行顺序必须来自 Workbench projectedSeq、aggregateSeq、part order 或采样事实中的同源顺序字段;完成行、assistant part 和 diagnostic 行不得按 DOM 到达顺序、文本时间戳排序或 analyzer 私有排序重排。若同一 frame 中存在乱序、completion row 非最后、duration 不一致或缺少 order 字段,CLI 应直接标红或 warning,保留原始矛盾供人工判断,而不是把视图修正成看起来正确。
|
||||
|
||||
自动判别器必须以 CLI trace 视图为判据。finding 生成、降级和消除都要能在 `turn-summary` 或 `trace-frame` 中复核;不能只依赖机器规则把长期存在的问题误判为通过。任何单次 Workbench 操作、turn 投影、命令执行、finalizer catch-up、trace detail/history hydration 或 analyze 阶段超过 120 秒,都必须输出 severe timeout warning,并要求进一步调查;该 warning 不得被普通 poll retry、fallback route、自动刷新或 analyzer 补偿吞掉。
|
||||
|
||||
prompt、steer、cancel 和 retry 必须在 CLI 视图中保留 control command boundary。普通 prompt 的 POST `/v1/agent/chat`、运行中 steer 的 `/v1/agent/chat/steer`、cancel 的 `/v1/agent/chat/cancel`、以及 terminal/no-active no-op 必须分别显示 action、target turn/run/command、HTTP status、accepted/no-op/blocker 和相关 ids;analyzer 不得因为同一时间窗内出现 steer 请求就把此前 prompt 判定成 `prompt-routed-to-steer`。
|
||||
|
||||
D518/v0.3 business trace closeout 必须能从 node/lane YAML 解析 AgentRun namespace、control-plane route 和 public origin,而不是硬编码 namespace 或依赖当前 kubectl context。`diagnose-code-agent --target D518` 或等价受控入口应输出 traceId、sessionId、runId、commandId、runner identity、projection/read span、OTel span 状态和 redacted namespace/endpoint 摘要;缺少 namespace、OTel span、trace frame 或 ReadModel digest 时,issue 不能仅凭 PR 合并或构建通过关闭。
|
||||
|
||||
### 6.12 WB-PROJ-REQ-012 serve/session aggregate authority
|
||||
|
||||
| 编号 | 短名 | 主责模块 | 关联模块 |
|
||||
| --- | --- | --- | --- |
|
||||
| WB-PROJ-REQ-012 | 会话聚合权威 | PJ2026-010401080312 ServeSessionAggregate | [API契约](PJ2026-010403-api-contract.md)、[Agent编排](PJ2026-0102-agent-orchestration.md)、[Web工作台](PJ2026-010401-web-workbench.md)、[HWLAB接入](PJ2026-010205-hwlab-dispatch.md) |
|
||||
|
||||
Workbench session 必须是用户可见执行状态的 aggregate root。prompt、steer、cancel 和 retry 先写成 durable input/command fact,再进入 AgentRun run/command、runner job 创建、steer delivery 或 cancel delivery;admission route 只能返回 durable accepted、structured conflict、structured no-op 或 blocker,不得让浏览器请求等待 Kubernetes Job 创建、runner 启动、result polling 或 trace detail hydration。
|
||||
|
||||
每个 input/command fact 必须至少绑定 `sessionId`、`turnId`、`traceId`、`userMessageId`、`assistantMessageId`、`commandId`、action、target run/command、`admittedSeq`、`promotedSeq`、status、no-op reason 或 blocker。`turnId/traceId/messageId/partId` 必须在 dispatch 前或首次 projection commit 前稳定分配;后续 AgentRun event/result、steer accepted、cancel requested、terminal result 和 diagnostic 都必须回绑这些身份。提交 HTTP 500、AgentRun dispatch failure 或 delivery timeout 也必须绑定到本次 input fact,不得回落到旧 trace、旧 final response 或旧 active card。
|
||||
|
||||
同一 session 必须有一条受控 execution lane。wake、interrupt、steer、cancel、retry 和 runner terminal 之间必须按 session aggregate seq 判定新旧;stale wake、late runner event、旧 turn polling、DOM active card、session list summary、last trace row 或浏览器 local state 都不能覆盖更新 turn 的状态。没有 active turn 的 cancel/steer 必须返回结构化 no-op 或 error;已 terminal 的 cancel 必须返回 already-terminal/no-op 或触发 terminal projection catch-up,不能重新打开 sealed turn 或覆盖 terminal facts。
|
||||
|
||||
同一 session execution lane 必须有可审计的 AgentRun 承载机制。优先形态是同一个 AgentRun run 接收连续 command,并让已 claim 的 runner 在 idle timeout 内继续 poll 后续 command;若后续实现选择 session runner lease 或跨 run warm runner channel,也必须暴露稳定 session/channel/lease identity、command handoff、cancel/interrupt fencing 和 terminal diagnostic。仅在 `sessionPolicy`、metadata、thread id 或 PVC 上标记“reuse”,但每个 Workbench turn 都新建独立 run-scoped runner Job,不满足本要求,也不能作为 10x canary 或 120s 性能验收通过证据。
|
||||
|
||||
Message/part 是用户结果的显示权威。assistant final response 只能来自 sealed assistant final/text part,diagnostic、stdout/stderr、transport error、steer/cancel accepted 文案和 analyzer summary 必须分仓展示。trace rows、turn timing、session running、completion row 和 duration 必须从同一 session aggregate/event stream/read model 派生;`trace-frame --trace-id newTrace` 不得显示旧 trace 行。若缺少 order、缺少 terminal 或存在 projection 矛盾,CLI/API/Web 必须暴露 projection blocker 或 warning,而不是读侧补齐。
|
||||
|
||||
兼容 `/v1/agent/*`、conversation path、旧 Web route、CLI renderer、SSE 和 fake-server 都只能调用同一个 mutation/read model。保留 wrapper 时,它只能做鉴权、schema 映射和旧字段降级,不拥有第二套 prompt admission、status、final response、timing 或 trace authority。
|
||||
|
||||
本要求参考 OpenCode serve 的职责边界,但不复制其技术栈。HWLAB 应学习其 `SessionInput` admitted/promoted、session run coordinator、run-state、message/part event 和 abort route 分工:输入先成为可审计事件,run-state 集中仲裁 busy/idle/cancel/retry,message/part 按顺序追加并 sealed,读取路径只消费 page/cursor/read model。后续实现不得继续沿用 trace tail、result envelope、DOM、session list 或 analyzer fallback 作为架构补丁。
|
||||
|
||||
## 7. 过程控制
|
||||
|
||||
本规格的执行证据保留在对应 GitHub 执行 issue、PR、web-probe 报告和 Playwright artifact 中;规格正文不承载长证据、运行日志或一次性排障流水。
|
||||
|
||||
本专项关闭前,执行 issue 必须回写以下证据:专项 SPEC commit、后端写点/读点清单、旧路径最终状态、PR、D601 v0.3 发布证据、fake-server Playwright 结果、public origin web-probe 的 script SHA/runDir/report SHA/截图 SHA,以及父级 Web/API/HWLAB接入/Agent编排规格是否仍与实现一致。Workbench Redis 派生读缓存执行 issue 为 [#1870](https://github.com/pikasTech/HWLAB/issues/1870),P0 SPEC-first 子 issue 为 [#1871](https://github.com/pikasTech/HWLAB/issues/1871),后续实现必须引用 `draft-2026-06-22-p1-workbench-redis-derived-cache`。
|
||||
|
||||
web-probe 历史窗口 trace 乱序、完成行非最后、耗时不一致和红色 finding 的架构修复执行 issue 为 [#2055](https://github.com/pikasTech/HWLAB/issues/2055)。阶段跟踪必须以子 issue 为准:P0 SPEC-first [#2057](https://github.com/pikasTech/HWLAB/issues/2057)、P1 event schema/projector [#2058](https://github.com/pikasTech/HWLAB/issues/2058)、P2 read/SSE seq replay [#2059](https://github.com/pikasTech/HWLAB/issues/2059)、P3 Cloud Web trace/timing 补偿清理 [#2060](https://github.com/pikasTech/HWLAB/issues/2060)、P4 web-probe/OTel 验收固化 [#2061](https://github.com/pikasTech/HWLAB/issues/2061)、P5 D601/v03 长程验收与旧路径删除 [#2062](https://github.com/pikasTech/HWLAB/issues/2062)。后续实现必须引用 `draft-2026-06-24-p0-aggregate-event-stream`,并在关闭各阶段 issue 时说明是否仍存在读侧 repair、到达顺序排序、UI timing fabrication 或 probe 侧补偿。
|
||||
|
||||
Workbench turn/message/trace 投影 authority 与 CLI trace 视图收敛的架构修复执行 issue 为 [#2079](https://github.com/pikasTech/HWLAB/issues/2079),正式 20 轮长程采样父 issue 为 [#2072](https://github.com/pikasTech/HWLAB/issues/2072),运行中 steer 与前 1-5 轮采样子 issue 为 [#2078](https://github.com/pikasTech/HWLAB/issues/2078)。后续实现必须引用 `draft-2026-06-24-p1-opencode-message-part-authority`,并在各阶段子 issue 中说明是否已经消除 final response 误选、turn-summary/trace-frame traceId 误归因、completion row 非最后、duration 不一致、prompt/steer/cancel 边界误判和 analyzer-only 误判。
|
||||
|
||||
Workbench serve/session aggregate authority 架构修复执行 issue 为 [#2125](https://github.com/pikasTech/HWLAB/issues/2125)。阶段跟踪必须以子 issue 为准:P0 SPEC-first [#2128](https://github.com/pikasTech/HWLAB/issues/2128)、P1 durable input/command 与 session aggregate seq [#2127](https://github.com/pikasTech/HWLAB/issues/2127)、P2 message/part/turn/trace read model 与 terminal atomic commit [#2126](https://github.com/pikasTech/HWLAB/issues/2126)、P3 prompt/steer/cancel run-state authority [#2129](https://github.com/pikasTech/HWLAB/issues/2129)、P4 REST/SSE/CLI/Web 单源消费与 legacy wrapper 降级 [#2131](https://github.com/pikasTech/HWLAB/issues/2131)、P5 删除 fallback/repair/renderer 补丁路径 [#2130](https://github.com/pikasTech/HWLAB/issues/2130)、P6 fake-server 与 D601/v03 20轮原入口验收 [#2132](https://github.com/pikasTech/HWLAB/issues/2132)。后续实现必须引用 `draft-2026-06-25-p0-serve-session-aggregate-authority`,并在关闭各阶段 issue 时说明 prompt admission、steer/cancel、run-state、message/part、trace/timing、final response 是否已经共享同一 session aggregate authority。
|
||||
|
||||
dsflash-go 10x canary 超过 120s、同一 Workbench session 连续 turn 创建多个独立 AgentRun runner/job、DOM trace rows 与后端 trace API 不一致的证据 issue 为 [#2171](https://github.com/pikasTech/HWLAB/issues/2171)。后续实现必须同时引用 `draft-2026-06-25-p0-session-warm-runner-contract`,并在 P1/P3/P6 closeout 中证明同一 session 的连续 turn 已进入同一 execution lane 或等价 warm runner/session command channel;若仍出现每 turn 新建 run-scoped runner Job,必须保持验收 red,而不是提高 120s 预算、减少轮数或用 renderer/probe fallback 掩盖。
|
||||
|
||||
D518 Workbench 会话 timeline 与刷新一致性执行 issue 为 [pikasTech/unidesk#1217](https://github.com/pikasTech/unidesk/issues/1217)。后续实现必须引用 `draft-2026-06-28-p0-d518-session-timeline-consistency`,并在 closeout 中回写 UniDesk SPEC PR、HWLAB v0.3 PR、D518 control-plane rollout commit/PipelineRun/Argo revision、fake-echo 与 dsflash-go 三连哨兵报告、OTel business trace 诊断、ReadModel role sequence/digest 证据,以及是否仍存在 session title fallback、cross-page divergence、trace row nonmonotonic 或 timing mismatch。
|
||||
仍引用 `PJ2026-0104010803` 的实现与测试必须迁移到 `PJ2026-010401080313`。旧链接可以保留用于历史追溯,但任何与替代规格冲突的断言、schema 门禁、migration 依赖和 outbox 原子提交要求都必须删除,不做兼容保留。
|
||||
|
||||
+4
-3
@@ -18,11 +18,12 @@
|
||||
| 编号 | PJ2026-010401080313 |
|
||||
| 短名 | Workbench实时权威 |
|
||||
| 层级 | L4 专项规格切片 |
|
||||
| 状态 | 草稿 |
|
||||
| 状态 | 已生效 |
|
||||
| 实现引用版本 | draft-2026-07-08-p0-workbench-realtime-authority-v2; draft-2026-07-09-p1-single-step-debug; draft-2026-07-14-p0-pure-kafka-authority |
|
||||
| 需求规格模板 | [ISO/IEC/IEEE 29148 需求规格模板](../../templates/iso-iec-ieee-29148-requirements-spec-template.md) |
|
||||
| 上级规格 | [PJ2026-010401 Web工作台](PJ2026-010401-web-workbench.md) |
|
||||
| 关联规格 | [PJ2026-0104010803 Workbench唯一投影](PJ2026-0104010803-workbench-unique-projection.md)、[PJ2026-0106050514 Workbench实时运行面](PJ2026-0106050514-workbench-realtime-runtime.md)、[PJ2026-010403 API契约](PJ2026-010403-api-contract.md)、[PJ2026-01060508 Web哨兵](PJ2026-01060508-web-probe-sentinel.md) |
|
||||
| 废弃规格 | [PJ2026-0104010803 Workbench唯一投影](PJ2026-0104010803-workbench-unique-projection.md) |
|
||||
| 关联规格 | [PJ2026-0106050514 Workbench实时运行面](PJ2026-0106050514-workbench-realtime-runtime.md)、[PJ2026-010403 API契约](PJ2026-010403-api-contract.md)、[PJ2026-01060508 Web哨兵](PJ2026-01060508-web-probe-sentinel.md) |
|
||||
| 规格治理索引 | [规格治理](spec-governance.md) |
|
||||
|
||||
本文承载 Workbench Realtime Authority v2 的长期裁决。GitHub issue 记录阶段执行和证据;本文定义长期稳定的实时权威、禁止路径、回归和调试工作台边界。
|
||||
@@ -55,7 +56,7 @@ PostgreSQL 可以保存查询优化所需的派生读模型,但不是 `agentru
|
||||
### 2.3 范围外
|
||||
|
||||
- AgentRun run/command/runner job、provider stream 和 Code Agent 执行事实仍由 Agent编排定义。
|
||||
- Durable event stream、projection writer/finalizer、facts store、read model 的写侧事务细节由 [PJ2026-0104010803 Workbench唯一投影](PJ2026-0104010803-workbench-unique-projection.md) 定义。
|
||||
- PostgreSQL 派生读模型的内部存储细节不改变本规格的数据权威,也不得成为 admission、实时或回放链路的前置。
|
||||
- 浏览器内存、freeze blocker、RUM 和 web-probe 运行策略由 [PJ2026-0106050514 Workbench实时运行面](PJ2026-0106050514-workbench-realtime-runtime.md) 和 Web哨兵规格定义。
|
||||
- 调试工作台不是用户业务入口,不拥有 session lifecycle、权限、Secret、真实 mutation 或运行面修复权。
|
||||
|
||||
|
||||
@@ -19,10 +19,10 @@
|
||||
| 短名 | API契约 |
|
||||
| 层级 | L2 课题 |
|
||||
| 状态 | 已生效 |
|
||||
| 实现引用版本 | draft-2026-06-20-p0-workbench-pure-read-api; draft-2026-06-20-p0-error-diagnostics; draft-2026-06-20-p1-view-local-timing-ticker; draft-2026-06-22-p1-workbench-redis-derived-cache; draft-2026-06-25-p0-web-caserun-e2e; draft-2026-06-25-p0-project-management-mdtodo; draft-2026-06-25-p0-mdtodo-web-active-editing-hwpod-source; draft-2026-06-27-p0-workbench-read-api-contract; PJ2026-0104010803 唯一投影 draft-2026-06-20-p0-durable-facts-model; draft-2026-06-20-p1-zero-split-durable-realtime; draft-2026-06-20-p2-terminal-outbox-recovery; draft-2026-06-24-p0-aggregate-event-stream; draft-2026-06-25-p0-serve-session-aggregate-authority; PJ2026-01050105 Web鉴权 draft-2026-06-18-p0-auth |
|
||||
| 实现引用版本 | draft-2026-06-20-p0-workbench-pure-read-api; draft-2026-06-20-p0-error-diagnostics; draft-2026-06-22-p1-workbench-redis-derived-cache; draft-2026-06-27-p0-workbench-read-api-contract; PJ2026-010401080313 Workbench实时权威 draft-2026-07-14-p0-pure-kafka-authority; PJ2026-01050105 Web鉴权 draft-2026-06-18-p0-auth |
|
||||
| 需求规格模板 | [ISO/IEC/IEEE 29148 需求规格模板](../../templates/iso-iec-ieee-29148-requirements-spec-template.md) |
|
||||
| 上级规格 | [PJ2026-0104 客户端](PJ2026-0104-client.md) |
|
||||
| 关联规格 | [PJ2026-0104010803 Workbench唯一投影](PJ2026-0104010803-workbench-unique-projection.md)、[PJ2026-01060505 Workbench性能](PJ2026-01060505-workbench-performance.md) |
|
||||
| 关联规格 | [PJ2026-010401080313 Workbench实时权威](PJ2026-010401080313-workbench-realtime-authority.md)、[PJ2026-01060505 Workbench性能](PJ2026-01060505-workbench-performance.md) |
|
||||
| 规格治理索引 | [规格治理](spec-governance.md) |
|
||||
|
||||
本文采用 ISO/IEC/IEEE 29148 需求规格模板的项目裁剪版:正文只保留 API 契约的稳定使命、范围、术语、系统边界、内部分工和原子需求。
|
||||
@@ -87,10 +87,10 @@ API契约负责定义 Cloud Web、HWLAB CLI 和自动化脚本共同使用的 RE
|
||||
| Message/Part | Web 和 CLI 共同渲染会话 timeline 的持久消息事实;message 表达角色、父子关系和终态摘要,part 表达文本、工具、文件、错误、trace 摘要等可组合内容。 |
|
||||
| Timing metadata | Workbench DTO 中用于显示消息最近事件和轮次耗时的投影时间字段,至少包括 `startedAt`、`lastEventAt`、`finishedAt` 和 sealed `durationMs`;相对 age 只能由浏览器显示层用本地 now 临时计算。 |
|
||||
| EventStream | Cloud Web origin 下的 SSE 实时入口,用于推送 server.connected、session、turn、message、part、trace 和 workspace lifecycle 事件。 |
|
||||
| WorkbenchProjectionWriter | [PJ2026-0104010803 Workbench唯一投影](PJ2026-0104010803-workbench-unique-projection.md) 定义的唯一写入组件,把 AgentRun run、command、event 和 result 转换为 HWLAB durable Workbench facts。 |
|
||||
| WorkbenchReadModel | [PJ2026-0104010803 Workbench唯一投影](PJ2026-0104010803-workbench-unique-projection.md) 定义的唯一读模型,从 durable Workbench facts 组装 session detail、message page、turn snapshot、trace event page 和 session rail summary。 |
|
||||
| Aggregate event stream | [PJ2026-0104010803 Workbench唯一投影](PJ2026-0104010803-workbench-unique-projection.md) 定义的 Workbench append-only event stream;API 只能暴露其 projection revision、cursor 和 replay envelope,不得把 source event array 或 result envelope 作为第二 API 事实源。 |
|
||||
| Serve Session Aggregate Authority | [PJ2026-0104010803 Workbench唯一投影](PJ2026-0104010803-workbench-unique-projection.md) 定义的会话聚合权威;API mutation 先写 durable input/command fact,GET/SSE/compat wrapper 只读同一 aggregate projection。 |
|
||||
| WorkbenchEventMapper | [PJ2026-010401080313 Workbench实时权威](PJ2026-010401080313-workbench-realtime-authority.md) 定义的 direct publish 组件,把 `agentrun.event.v1` 转换为 `hwlab.event.v1`,不要求内联数据库事务。 |
|
||||
| WorkbenchReadModel | [PJ2026-010401080313 Workbench实时权威](PJ2026-010401080313-workbench-realtime-authority.md) 定义的唯一读模型,从 durable Workbench facts 组装 session detail、message page、turn snapshot、trace event page 和 session rail summary。 |
|
||||
| Workbench event stream | `hwlab.event.v1` append-only Kafka event stream;API 只暴露其 revision、cursor 和 replay envelope,不得建立第二 API 事实源。 |
|
||||
| Serve Session Authority | 会话级 typed event 权威;API mutation 提交执行命令,GET/SSE/compat wrapper 不得建立数据库 outbox authority。 |
|
||||
| eventSeq/aggregateSeq | Workbench event stream 的全局 cursor 与 aggregate 内 cursor,用于 SSE replay、projection revision、新鲜度和乱序检测;它们与 AgentRun `sourceSeq` 分离。 |
|
||||
| Derived read cache | WorkbenchReadModel 内部可选的 Redis 派生读缓存;它只缓存 durable projection 派生快照,不改变 API 资源、权限、lifecycle 或 final response 语义。 |
|
||||
| CacheDiagnostic | Workbench pure-read 响应或 OTel span 中用于解释缓存行为的诊断字段集合,至少包含 `cacheStatus`、`cacheAgeMs`、cacheKeyClass、projectionSeq 或等价字段;它不参与业务状态判断。 |
|
||||
@@ -121,19 +121,19 @@ API契约负责定义 Cloud Web、HWLAB CLI 和自动化脚本共同使用的 RE
|
||||
| PJ2026-01040303 | Agent接口 | 本规格 6.3 | conversation、session、chat、steer、cancel、result、trace 和 inspect API 形态 | Agent编排、用户管理 | Web工作台、HWLAB CLI |
|
||||
| PJ2026-01040304 | 资源接口 | 本规格 6.4 | workspace、access、provider、HWPOD node-ops、gateway 和性能摘要入口 | 全部业务 L1 | Web、CLI、admin |
|
||||
| PJ2026-01040305 | 错误输出 | 本规格 6.5 | JSON 成功/失败响应、错误码、route/status、脱敏和渐进披露 | 全部业务 L1 | 用户、脚本、排障 |
|
||||
| PJ2026-01040306 | 缓存诊断 | 本规格 6.6 | Workbench pure-read cache diagnostic 字段、脱敏边界和禁止状态仲裁 | Workbench唯一投影、Workbench性能 | Web、CLI、Performance 页 |
|
||||
| PJ2026-01040306 | 缓存诊断 | 本规格 6.6 | Workbench pure-read cache diagnostic 字段、脱敏边界和禁止状态仲裁 | Workbench实时权威、Workbench性能 | Web、CLI、Performance 页 |
|
||||
| PJ2026-01040307 | CaseRun接口 | 本规格 6.7 | CaseRun case/run/status/events/aggregate/cancel REST 资源、短返回和错误语义 | HarnessRL、硬件池、Agent编排 | Web CaseRun、CLI、web-probe |
|
||||
| PJ2026-01040308 | 项目管理接口 | 本规格 6.8 | 项目管理 REST 资源、MDTODO DTO、Workbench launch intent、link 查询和独立微服务代理边界 | 项目管理、Web工作台、用户管理 | `/projects`、`/projects/mdtodo`、CLI、web-probe |
|
||||
|
||||
目标后端模块应至少拆分为 route/handler、schema/contract、read model、persistence/projection、AgentRun adapter、trace event pager、SSE/event publisher 和 compat wrapper。route 文件只负责 HTTP 入口、鉴权桥接和错误映射;schema/contract 只负责类型和字段;read model 只组装查询模型;adapter 只转换外部执行事实;projection 只写 durable facts;compat wrapper 只提供旧 path 到新资源的兼容映射,不拥有第二套业务事实。
|
||||
|
||||
### 5.1 Workbench唯一投影 API 边界
|
||||
### 5.1 Workbench实时权威 API 边界
|
||||
|
||||
[PJ2026-0104010803 Workbench唯一投影](PJ2026-0104010803-workbench-unique-projection.md) 集中定义 AgentRun facts 到 Workbench durable facts 的目标架构、aggregate event stream、数据流、terminal commit 时序和 cloud-api 重启恢复时序。API契约在本文只保留接口边界:`GET /v1/workbench/*` 只读取 `WorkbenchReadModel`;SSE 只发布 projection commit notification;compat wrapper 只能调用同一 read model 或正式 mutation。
|
||||
[PJ2026-010401080313 Workbench实时权威](PJ2026-010401080313-workbench-realtime-authority.md) 集中定义 `agentrun.event.v1 -> hwlab.event.v1 -> live/replay SSE` 的目标架构。API 契约只保留接口边界:SSE 从 Kafka cursor 回放并切到同一 live tail;`GET /v1/workbench/*` 只读非阻塞派生模型;compat wrapper 只能调用正式 mutation 或只读接口。
|
||||
|
||||
Workbench mutation API 必须接入 serve/session aggregate authority。`POST /v1/agent/chat`、steer、cancel、retry 或未来 `/v1/workbench/sessions/{sessionId}/turns` 等入口,应先写入 durable input/command fact 并短返回 `202 Accepted`、structured conflict、structured no-op 或 blocker;响应中必须包含可继续查询的 `sessionId`、`turnId`、`traceId`、`commandId` 或 no-op reason。API 不得把浏览器请求阻塞到 Kubernetes Job 创建、runner 启动、result polling、trace hydration 或 finalizer catch-up,也不得在失败时把新提交回落到旧 session/trace/final。旧 `/v1/agent/*` wrapper 只能调用同一 mutation/read model 并做字段降级。
|
||||
Workbench mutation API 必须在 AgentRun durable admission 成功后短返回 `202 Accepted`,并包含可继续关联的 `sessionId`、`turnId`、`traceId`、`commandId` 或 no-op reason。`POST /v1/agent/chat`、steer、cancel 和 retry 不得等待 PostgreSQL projection、outbox、migration、runner 启动、result polling 或 trace hydration;派生读模型失败只能形成 warning/diagnostic,不能把已接纳命令改写为 admission failure。
|
||||
|
||||
Workbench SSE/event API 必须按 aggregate event stream/outbox cursor replay。`GET /v1/workbench/events?afterSeq=N` 或等价入口返回的每条 envelope 至少应携带 `eventSeq` 或 `outboxSeq`、`aggregateId`、`aggregateSeq`、`sessionId`、`turnId`、`traceId`、`projectionRevision`、`commitType` 和脱敏 payload 摘要。API 不承诺按网络到达顺序、trace hydration 完成顺序、result polling 返回顺序或 session list 更新时间排序;客户端必须按 cursor/revision 应用,缺口进入 transport diagnostic 和 REST 补洞。
|
||||
Workbench SSE/event API 必须按 `hwlab.event.v1` Kafka cursor replay。`GET /v1/workbench/events?afterSeq=N` 或等价入口返回的每条 envelope 至少应携带 Kafka cursor、`sessionId`、`turnId`、`traceId`、entity family/id/version、`projectionRevision` 和脱敏 payload 摘要。回放追上水位后必须在同一连接切到 live tail;缺口进入 transport diagnostic 和 Kafka retention replay,禁止 REST 补洞或数据库 outbox replay。
|
||||
|
||||
若 AgentRun 事实已经 terminal 但 Workbench projection 尚未追平,GET 响应应暴露 `projectionStatus`、`lastProjectedSeq`、`sourceRunId`、`sourceCommandId`、`blocker` 或等价诊断字段;不得在 GET 中同步调用 AgentRun、Code Agent manager、legacy conversation manager、billing finalizer、workspace repair、trace polling 或 result polling 来推进事实。读模型、SSE publisher、compat wrapper 和 CLI render 都不能各自解释 terminal、running、final response 或 trace pagination;它们只能重放 durable projection。
|
||||
|
||||
@@ -292,7 +292,7 @@ Cancel mutation 在转发 AgentRun cancel 前必须核验本地 sealed terminal
|
||||
|
||||
Workbench read-model dependency timeout 必须返回结构化 degraded/readiness/blocker 响应;PostgreSQL pool connect/query timeout 不得作为未捕获异常杀死 cloud-api 进程,也不得让 liveness 因单次 Workbench read query 变成 EOF。
|
||||
|
||||
新增或重构的核心后端文件头部必须标注遵循的 SPEC 编号、短名和实现引用版本,例如 `SPEC: PJ2026-0104010803 唯一投影 draft-2026-06-20-p0-durable-facts-model; draft-2026-06-20-p1-zero-split-durable-realtime; PJ2026-010403 API契约 draft-2026-06-20-p0-workbench-pure-read-api; PJ2026-010205 HWLAB接入 draft-2026-06-17-r0`,并简述文件职责。实现文件不得只写 issue 编号、`latest` 或 `current` 作为规格引用。
|
||||
新增或重构的核心后端文件头部必须标注遵循的 SPEC 编号、短名和实现引用版本,例如 `SPEC: PJ2026-010401080313 Workbench实时权威 draft-2026-07-14-p0-pure-kafka-authority; PJ2026-010403 API契约 draft-2026-06-20-p0-workbench-pure-read-api; PJ2026-010205 HWLAB接入 draft-2026-06-17-r0`,并简述文件职责。实现文件不得只写 issue 编号、`latest` 或 `current` 作为规格引用。
|
||||
|
||||
### 6.4 CLIENT-API-REQ-004 资源与管理接口
|
||||
|
||||
@@ -355,7 +355,7 @@ Workbench 投影 blocker、proxy timeout、鉴权失败、provider profile、web
|
||||
|
||||
| 编号 | 短名 | 主责模块 | 关联模块 |
|
||||
| --- | --- | --- | --- |
|
||||
| CLIENT-API-REQ-006 | 缓存诊断 | PJ2026-01040306 缓存诊断 | [Workbench唯一投影](PJ2026-0104010803-workbench-unique-projection.md)、[Workbench性能](PJ2026-01060505-workbench-performance.md) |
|
||||
| CLIENT-API-REQ-006 | 缓存诊断 | PJ2026-01040306 缓存诊断 | [Workbench实时权威](PJ2026-010401080313-workbench-realtime-authority.md)、[Workbench性能](PJ2026-01060505-workbench-performance.md) |
|
||||
|
||||
Workbench pure-read API 可以在成功或 degraded 响应中输出 CacheDiagnostic,用于说明 Redis 派生读缓存是否命中、是否 stale、是否 unavailable、快照年龄和是否避免 durable DB 查询。该诊断至少应能表达 `cacheStatus=hit|miss|stale|unavailable`、`cacheAgeMs`、cacheKeyClass、projectionSeq 或等价 revision、dbQueryAvoided、dbQueryDuration 和 payloadBytes;字段位置必须与 lifecycle/final/status 分仓。
|
||||
|
||||
|
||||
@@ -77,7 +77,7 @@ AgentRun发布Lane负责定义 AgentRun `v0.1` 在 G14 上的专用发布 lane
|
||||
| PJ2026-0106010502 | EnvImage | 本规格 6.2 | env image identity、digest-pinned image、work-ready 工具和 promotion | Source commit、registry、Containerfile | Runtime装配、runner job |
|
||||
| PJ2026-0106010503 | CLI验收 | 本规格 6.3 | AgentRun CLI JSON、短返回、redaction 和正式命令入口 | AgentRun REST API | HWLAB 接入、队列会话 |
|
||||
| PJ2026-0106010504 | 真实联调 | 本规格 6.4 | real provider turn、Postgres durable facts、SecretRef 和 terminal status | AgentRun核心、后端Profile | 发布判定 |
|
||||
| PJ2026-0106010505 | Rolling验收 | 本规格 6.5 | manager/cloud-api rolling、runner 不中断、reconciler re-attach 和 Workbench projection recovery | AgentRun核心、HWLAB接入、Workbench唯一投影 | 发布判定、运维监控 |
|
||||
| PJ2026-0106010505 | Rolling验收 | 本规格 6.5 | manager/cloud-api rolling、runner 不中断、reconciler re-attach 和 Workbench projection recovery | AgentRun核心、HWLAB接入、Workbench实时权威 | 发布判定、运维监控 |
|
||||
|
||||
## 6. 原子需求
|
||||
|
||||
@@ -125,7 +125,7 @@ mock backend、fake provider、source-only、dry-run、缺 provider credential
|
||||
|
||||
| 编号 | 短名 | 主责模块 | 关联模块 |
|
||||
| --- | --- | --- | --- |
|
||||
| AR-RELEASE-REQ-005 | Rolling验收 | PJ2026-0106010505 Rolling验收 | [AgentRun核心](PJ2026-010201-agentrun-core.md)、[HWLAB接入](PJ2026-010205-hwlab-dispatch.md)、[Workbench唯一投影](PJ2026-0104010803-workbench-unique-projection.md)、[运维监控](PJ2026-010605-observability-monitoring.md) |
|
||||
| AR-RELEASE-REQ-005 | Rolling验收 | PJ2026-0106010505 Rolling验收 | [AgentRun核心](PJ2026-010201-agentrun-core.md)、[HWLAB接入](PJ2026-010205-hwlab-dispatch.md)、[Workbench实时权威](PJ2026-010401080313-workbench-realtime-authority.md)、[运维监控](PJ2026-010605-observability-monitoring.md) |
|
||||
|
||||
AgentRun `v0.1` 发布验收应包含 rolling recovery canary。验收在 D601 v0.3 HWLAB 用户入口或等价受控 CLI 发起长程 Code Agent session,记录 `sessionId`、`traceId`、`runId`、`commandId`、`runnerJobId` 和 Kubernetes `jobName`;runner 正在执行时滚动 HWLAB cloud-api,runner 继续执行时滚动 AgentRun manager。滚动结束后,同一 run/command/runnerJob 必须被 manager reconciler 恢复控制并进入 Workbench projection,不重建 run、不人工 resubmit、不切 session repair。
|
||||
|
||||
|
||||
@@ -96,8 +96,8 @@
|
||||
| PJ2026-01060504 | 边界约束 | 本规格 6.4 | 监控与业务通过、长证据、敏感输出的边界 | 全部 L1 | 用户反馈和排障 |
|
||||
| PJ2026-01060505 | Workbench性能 | [PJ2026-01060505 Workbench性能](PJ2026-01060505-workbench-performance.md) | Web 工作台用户可感知性能、RUM、AgentRun event visible latency 和 Prometheus 指标口径 | Web工作台、Agent编排、API契约 | 平台运维、客户端和性能回归调查 |
|
||||
| PJ2026-01060506 | Metrics接入 | 本规格 6.6 | metrics endpoint、scrape target 和 label 口径 | 各 L1 服务健康指标 | Prometheus 查询 |
|
||||
| PJ2026-01060507 | Rolling恢复观测 | 本规格 6.7 | active runner、reconciler backlog、terminal retry、projection lag 和不可恢复 blocker 的查询口径 | AgentRun核心、HWLAB接入、Workbench唯一投影、发布Lane | rolling 发布判定、故障收口 |
|
||||
| PJ2026-01060508 | Web哨兵 | [PJ2026-01060508 Web哨兵](PJ2026-01060508-web-probe-sentinel.md) | `web-probe observe` 的 YAML-first 生产哨兵、独立 runner、中心 Monitor/Host PG、报告视图、dashboard 分析工作台和发布恢复验证 | Web工作台、Workbench唯一投影、YAML运维、公开入口、发布流水 | 平台值守、CI/CD targetValidation、用户入口恢复判定 |
|
||||
| PJ2026-01060507 | Rolling恢复观测 | 本规格 6.7 | active runner、reconciler backlog、terminal retry、projection lag 和不可恢复 blocker 的查询口径 | AgentRun核心、HWLAB接入、Workbench实时权威、发布Lane | rolling 发布判定、故障收口 |
|
||||
| PJ2026-01060508 | Web哨兵 | [PJ2026-01060508 Web哨兵](PJ2026-01060508-web-probe-sentinel.md) | `web-probe observe` 的 YAML-first 生产哨兵、独立 runner、中心 Monitor/Host PG、报告视图、dashboard 分析工作台和发布恢复验证 | Web工作台、Workbench实时权威、YAML运维、公开入口、发布流水 | 平台值守、CI/CD targetValidation、用户入口恢复判定 |
|
||||
| PJ2026-01060509 | 出站诊断 | 本规格 6.9 | provider egress TCP tunnel、受控 relay、async job/server lifecycle 的阶段化日志、低噪声摘要和诊断入口 | provider-gateway、backend-core、YAML运维、发布流水 | D601/G14 runtime 出站排障、OpenFGA/Postgres/OA Event Flow 链路验收 |
|
||||
|
||||
## 6. 原子需求
|
||||
@@ -255,7 +255,7 @@ Workbench 性能监控只记录低基数指标、阶段耗时、状态分类和
|
||||
|
||||
| 编号 | 短名 | 主责模块 | 关联模块 |
|
||||
| --- | --- | --- | --- |
|
||||
| OPS-MON-REQ-007 | Rolling恢复 | PJ2026-01060507 Rolling恢复观测 | [AgentRun核心](PJ2026-010201-agentrun-core.md)、[HWLAB接入](PJ2026-010205-hwlab-dispatch.md)、[Workbench唯一投影](PJ2026-0104010803-workbench-unique-projection.md)、[AgentRun发布Lane](PJ2026-01060105-agentrun-v01-release-lane.md) |
|
||||
| OPS-MON-REQ-007 | Rolling恢复 | PJ2026-01060507 Rolling恢复观测 | [AgentRun核心](PJ2026-010201-agentrun-core.md)、[HWLAB接入](PJ2026-010205-hwlab-dispatch.md)、[Workbench实时权威](PJ2026-010401080313-workbench-realtime-authority.md)、[AgentRun发布Lane](PJ2026-01060105-agentrun-v01-release-lane.md) |
|
||||
|
||||
运维监控应为 AgentRun/HWLAB rolling recovery 和 cancel lifecycle 提供可查询的低基数 metrics、trace span 和受控 CLI 摘要。最小观测对象包括 active runner 数、runner job observation phase、stale lease 数、cancel request accepted 数、cancel delivered 数、cancel terminalized 数、late-write-fenced 数、terminal report retry/outbox backlog、manager reconciler backlog、reconciler last success/error、projection lag、projection blocker 数、Job TTL cleanup 数和不可恢复 blocker 数。
|
||||
|
||||
@@ -267,7 +267,7 @@ rolling recovery 相关 span 应能用 OTel trace id/request id 关联 `sessionI
|
||||
|
||||
| 编号 | 短名 | 主责模块 | 关联模块 |
|
||||
| --- | --- | --- | --- |
|
||||
| OPS-MON-REQ-008 | Web哨兵 | [PJ2026-01060508 Web哨兵](PJ2026-01060508-web-probe-sentinel.md) | [Web工作台](PJ2026-010401-web-workbench.md)、[Workbench唯一投影](PJ2026-0104010803-workbench-unique-projection.md)、[YAML运维](PJ2026-010603-yaml-first-ops.md)、[公开入口](PJ2026-010604-public-entry.md)、[发布流水](PJ2026-010601-controlled-release.md) |
|
||||
| OPS-MON-REQ-008 | Web哨兵 | [PJ2026-01060508 Web哨兵](PJ2026-01060508-web-probe-sentinel.md) | [Web工作台](PJ2026-010401-web-workbench.md)、[Workbench实时权威](PJ2026-010401080313-workbench-realtime-authority.md)、[YAML运维](PJ2026-010603-yaml-first-ops.md)、[公开入口](PJ2026-010604-public-entry.md)、[发布流水](PJ2026-010601-controlled-release.md) |
|
||||
|
||||
运维监控应提供 YAML-first Web 哨兵能力,把现有 `web-probe observe start/status/command/collect/analyze` 服务化为生产可用的持续 canary、报告视图和发布恢复验证入口。该能力只 wrap 现有 observe runner、control queue、artifact JSONL、`collect` 渲染和 `observe analyze` 报告,不新增第二套 Playwright runner、offline analyzer、finding classifier、dashboard 事实源或 Workbench 状态机。
|
||||
|
||||
|
||||
@@ -19,10 +19,10 @@
|
||||
| 短名 | Workbench性能 |
|
||||
| 层级 | L3 子课题 |
|
||||
| 状态 | 已生效 |
|
||||
| 实现引用版本 | draft-2026-06-19-p0; draft-2026-06-20-p0-error-diagnostics; draft-2026-06-22-p1-workbench-redis-derived-cache; PJ2026-0104010803 唯一投影 draft-2026-06-24-p0-aggregate-event-stream |
|
||||
| 实现引用版本 | draft-2026-06-19-p0; draft-2026-06-20-p0-error-diagnostics; draft-2026-06-22-p1-workbench-redis-derived-cache; 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-010605 运维监控](PJ2026-010605-observability-monitoring.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-010205 HWLAB接入](PJ2026-010205-hwlab-dispatch.md) |
|
||||
| 关联规格 | [PJ2026-010401 Web工作台](PJ2026-010401-web-workbench.md)、[PJ2026-010401080313 Workbench实时权威](PJ2026-010401080313-workbench-realtime-authority.md)、[PJ2026-010403 API契约](PJ2026-010403-api-contract.md)、[PJ2026-010205 HWLAB接入](PJ2026-010205-hwlab-dispatch.md) |
|
||||
| 规格治理索引 | [规格治理](spec-governance.md) |
|
||||
|
||||
本文采用 ISO/IEC/IEEE 29148 需求规格模板的项目裁剪版:正文只保留 D601 v0.3 Workbench 用户可感知性能监控的稳定使命、范围、术语、系统边界、内部分工、目标图和原子需求。
|
||||
@@ -65,7 +65,7 @@ Workbench timing 观测必须以唯一投影的 aggregate event stream revision
|
||||
- Prometheus 具体采样间隔、保留周期、阈值、Grafana 面板 URL 和告警路由以 YAML/config 为准,不在本规格硬编码。
|
||||
- 浏览器即时 probe、管理员手工 curl、后端日志 grep、Prometheus raw dump 或 synthetic check 不得作为 `/performance` 同一展示字段的替代权威;这些只能作为独立 metric family、定位证据或运维检查。
|
||||
- 长 trace、完整 prompt、assistant 正文、tool 参数、命令输出、Secret、token、DSN 和原始 provider payload 不进入性能指标 label 或默认日志。
|
||||
- Redis 不承载登录态、权限、OpenFGA、账本、AgentRun command/lease、runner 状态、session lifecycle 或 final response;这些事实分别归用户管理、Agent编排、Workbench唯一投影和对应 durable store。
|
||||
- Redis 不承载登录态、权限、OpenFGA、账本、AgentRun command/lease、runner 状态、session lifecycle 或 final response;这些事实分别归用户管理、Agent编排、Workbench实时权威和对应 durable store。
|
||||
|
||||
## 3. 术语表
|
||||
|
||||
@@ -77,7 +77,7 @@ Workbench timing 观测必须以唯一投影的 aggregate event stream revision
|
||||
| First visible | 某个 journey 中第一条用户可读消息、工具调用、错误或加载完成主体在 Web 中可见。 |
|
||||
| Full load | 当前 view 所需权威 REST snapshot、必要 trace page、turn status 和 session rail 数据都已到达并完成可见投影。 |
|
||||
| Backend event visible latency | AgentRun backend 事件的 `createdAt` 或源 seq 时间到 Cloud Web visible ack 的耗时。 |
|
||||
| Aggregate event stream revision | Workbench唯一投影写侧提交序,至少由 `eventSeq`、`aggregateSeq`、`projectionRevision` 或等价字段表达;性能观测只能用它关联业务顺序和可见耗时,不得用本地采样到达顺序重排业务事实。 |
|
||||
| Aggregate event stream revision | Workbench实时权威写侧提交序,至少由 `eventSeq`、`aggregateSeq`、`projectionRevision` 或等价字段表达;性能观测只能用它关联业务顺序和可见耗时,不得用本地采样到达顺序重排业务事实。 |
|
||||
| 无响应空闲时间 | 从最近一次可证明的 turn 活动到当前观察点的间隔;活动包括 accepted、run/command/runner job 创建、AgentRun event/result 更新、trace/sourceSeq 前进、SSE/REST snapshot 更新、visible ack 或 liveness heartbeat。 |
|
||||
| RUM | 浏览器端 Real User Monitoring,通过 Web Performance API、Navigation Timing、Long Task、SSE 接收和 DOM paint ack 采集真实用户性能。 |
|
||||
| Server-Timing | HTTP 响应头中的阶段耗时摘要,用于把 API 总耗时拆成 read model、DB、AgentRun adapter、projection 等后端阶段。 |
|
||||
@@ -271,7 +271,7 @@ sequenceDiagram
|
||||
|
||||
U->>W: open workbench or select session tab
|
||||
W->>W: start journey open/session_switch
|
||||
W->>A: GET initial snapshot or /workbench/sync replay
|
||||
W->>A: GET initial snapshot or Kafka replay SSE
|
||||
A->>S: query session/message/turn projection
|
||||
A->>T: query trace detail only when explicitly opened
|
||||
A-->>W: first authoritative payload
|
||||
@@ -299,10 +299,10 @@ session 切换必须分别记录 `first_visible` 和 `full_load`。first visible
|
||||
| PJ2026-0106050508 | Dashboard可视化 | 本规格 6.8 | `/performance` 中文化图表、chart-ready summary、低基数维度、空态/错误态和表格 drill-down | Web工作台、API契约、运维监控 | D601 v0.3 Performance 原入口验收 |
|
||||
| PJ2026-0106050509 | 权威观测 | 本规格 6.9 | observation history、metric family、windowed summary 和跨族不可覆盖边界 | 运维监控、Web工作台、API契约 | `/performance`、告警、审计 |
|
||||
| PJ2026-0106050510 | 窗口质量 | 本规格 6.10 | 时间窗口、样本数、freshness、aggregationKind、approximation 和 lowSample 语义 | 运维监控、API契约 | dashboard、TopN、drill-down |
|
||||
| PJ2026-0106050511 | 分叉禁令 | 本规格 6.11 | 禁止 collectorStatus 旁路、读侧 repair、fallback、bucket 上界冒充精确值和跨族仲裁 | Workbench唯一投影、Web工作台 | 后续迁移和回归 |
|
||||
| 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 多轮卡死和请求风暴治理 |
|
||||
| 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. 原子需求
|
||||
|
||||
@@ -370,7 +370,7 @@ UniDesk CLI 应提供薄 domain 入口,例如 `hwlab nodes observability plan|
|
||||
| --- | --- | --- | --- |
|
||||
| OPS-WBPERF-REQ-006 | 代码引用 | PJ2026-0106050506 代码引用 | [规格治理](spec-governance.md)、[Web工作台](PJ2026-010401-web-workbench.md)、[API契约](PJ2026-010403-api-contract.md) |
|
||||
|
||||
本性能监控能力的实现必须先引用本规格,再进入代码变更。新增或修改的前端、后端、CLI/helper、metrics、RUM、trace adapter、web-probe 和 dashboard 源码文件头部必须标注遵循的 SPEC 编号、短名和实现引用版本,例如 `SPEC: PJ2026-01060505 Workbench性能 draft-2026-06-19-p0; PJ2026-0104010803 Workbench唯一投影 draft-2026-06-24-p0-aggregate-event-stream`,并用一句话说明文件职责。
|
||||
本性能监控能力的实现必须先引用本规格,再进入代码变更。新增或修改的前端、后端、CLI/helper、metrics、RUM、trace adapter、web-probe 和 dashboard 源码文件头部必须标注遵循的 SPEC 编号、短名和实现引用版本,例如 `SPEC: PJ2026-01060505 Workbench性能 draft-2026-06-19-p0; PJ2026-010401080313 Workbench实时权威 draft-2026-06-24-p0-aggregate-event-stream`,并用一句话说明文件职责。
|
||||
|
||||
实现文件不得只写 issue 编号、`latest`、`current` 或“按最新方案”作为规格引用。自动生成文件、第三方 vendored 文件、纯 YAML/config、锁文件和无法承载注释头的二进制产物不要求加源码头部,但对应生成器、渲染器或配置入口必须能追溯到本 SPEC。
|
||||
|
||||
@@ -380,7 +380,7 @@ UniDesk CLI 应提供薄 domain 入口,例如 `hwlab nodes observability plan|
|
||||
| --- | --- | --- | --- |
|
||||
| OPS-WBPERF-REQ-007 | TurnStatus预算 | PJ2026-0106050507 TurnStatus预算 | [API契约](PJ2026-010403-api-contract.md)、[HWLAB接入](PJ2026-010205-hwlab-dispatch.md)、[Agent编排](PJ2026-0102-agent-orchestration.md)、[Web工作台](PJ2026-010401-web-workbench.md) |
|
||||
|
||||
`/v1/agent/turns/:traceId` 属于旧 compat/diagnostic 读取面,不再是 Workbench 主消息运行态的 poll 权威入口。Workbench 主状态的 live/恢复权威来自 initial snapshot、`/v1/workbench/events` typed event 和统一 `/v1/workbench/sync` replay;trace/detail 读取只能解释过程或诊断,不能覆盖 message finalResponse、turn terminal 或 session running。
|
||||
`/v1/agent/turns/:traceId` 属于旧 compat/diagnostic 读取面,不再是 Workbench 主消息运行态的 poll 权威入口。Workbench 主状态的 live/恢复权威来自 initial snapshot 与 `hwlab.event.v1` live/replay SSE;trace/detail 读取只能解释过程或诊断,不能覆盖 message finalResponse、turn terminal 或 session running。
|
||||
|
||||
Cloud API 如保留旧 turn status 或 trace detail 请求内的上游刷新尝试,刷新必须有独立的短预算;预算、开关和后续调整必须来自 YAML/env 配置,不得把具体数值写成第二真相。预算耗尽时,API 应返回已有快照并标记 `turn_status_degraded`、`agentrun_result_poll_failed`、`trace_refresh_timeout` 或等价低基数错误,后续 SSE、sync replay 或后台 projector 仍可继续补齐最新事件。除非权限不匹配、trace 不存在或请求参数非法,旧 diagnostic/detail 请求不应因为上游刷新慢而让 Web 客户端超时,也不得被前端用作 automatic repair authority。
|
||||
|
||||
@@ -438,7 +438,7 @@ Metric family 可以在同一页面中并列展示和关联 drill-down,但不
|
||||
|
||||
| 编号 | 短名 | 主责模块 | 关联模块 |
|
||||
| --- | --- | --- | --- |
|
||||
| OPS-WBPERF-REQ-011 | 分叉禁令 | PJ2026-0106050511 分叉禁令 | [Workbench唯一投影](PJ2026-0104010803-workbench-unique-projection.md)、[Web工作台](PJ2026-010401-web-workbench.md)、[API契约](PJ2026-010403-api-contract.md) |
|
||||
| OPS-WBPERF-REQ-011 | 分叉禁令 | PJ2026-0106050511 分叉禁令 | [Workbench实时权威](PJ2026-010401080313-workbench-realtime-authority.md)、[Web工作台](PJ2026-010401-web-workbench.md)、[API契约](PJ2026-010403-api-contract.md) |
|
||||
|
||||
Performance 页必须吸收 Workbench 唯一投影的失败教训:不得在 Web reducer、summary API、fake-server、probe 脚本或 dashboard 组件中保留多个事实源,再通过“优先级、覆盖、fallback、字段缺失时改走另一端点、刷新后 repair、测试专用后门”等方式决定展示状态。字段缺失、投影滞后、采集失败或样本不足时,必须暴露数据质量或 blocker,并修 observation writer、aggregator、read model 或正式 API 契约。
|
||||
|
||||
@@ -464,7 +464,7 @@ Workbench 性能 SLO 只能基于稳定 metric family、明确窗口、足够样
|
||||
|
||||
| 编号 | 短名 | 主责模块 | 关联模块 |
|
||||
| --- | --- | --- | --- |
|
||||
| OPS-WBPERF-REQ-013 | Redis读缓存 | PJ2026-0106050513 Redis读缓存 | [Workbench唯一投影](PJ2026-0104010803-workbench-unique-projection.md)、[API契约](PJ2026-010403-api-contract.md)、[YAML运维](PJ2026-010603-yaml-first-ops.md) |
|
||||
| OPS-WBPERF-REQ-013 | Redis读缓存 | PJ2026-0106050513 Redis读缓存 | [Workbench实时权威](PJ2026-010401080313-workbench-realtime-authority.md)、[API契约](PJ2026-010403-api-contract.md)、[YAML运维](PJ2026-010603-yaml-first-ops.md) |
|
||||
|
||||
D601 v0.3 Workbench 可以在 `hwlab-v03` namespace 内使用 Workbench 专用 Redis 作为派生读缓存,用于降低 `/v1/workbench/sessions`、terminal turn snapshot 和 terminal trace page 等高频读路径的远端 Postgres 重复查询和尾延迟。Redis 只缓存从 durable Workbench projection 派生出的短 TTL 快照;cache key 必须包含 schema version、cache key class、actor visibility input、session/turn/trace/cursor 和 projection revision/seq 或等价 authority input。
|
||||
|
||||
@@ -476,6 +476,6 @@ D601 v0.3 Workbench 可以在 `hwlab-v03` namespace 内使用 Workbench 专用 R
|
||||
|
||||
## 7. 过程控制
|
||||
|
||||
本规格的执行 issue 为 [#1392](https://github.com/pikasTech/HWLAB/issues/1392),性能问题修复执行 issue 为 [#1422](https://github.com/pikasTech/HWLAB/issues/1422),Performance dashboard 中文化可视化执行 issue 为 [#1609](https://github.com/pikasTech/HWLAB/issues/1609)。单一权威观测模型架构治理 issue 为 [#1638](https://github.com/pikasTech/HWLAB/issues/1638),阶段执行 issue 为 P0 [#1639](https://github.com/pikasTech/HWLAB/issues/1639)、P1 [#1641](https://github.com/pikasTech/HWLAB/issues/1641)、P2 [#1640](https://github.com/pikasTech/HWLAB/issues/1640)、P3 [#1642](https://github.com/pikasTech/HWLAB/issues/1642)、P4 [#1643](https://github.com/pikasTech/HWLAB/issues/1643) 和 P5 [#1644](https://github.com/pikasTech/HWLAB/issues/1644)。Workbench Redis 派生读缓存架构执行 issue 为 [#1870](https://github.com/pikasTech/HWLAB/issues/1870),P0 SPEC-first 子 issue 为 [#1871](https://github.com/pikasTech/HWLAB/issues/1871)。该类 issue 的 P0 阶段必须以本 SPEC 为前置:先确认本规格、父级 [PJ2026-010605 运维监控](PJ2026-010605-observability-monitoring.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) 的引用关系,再进入后续实现。
|
||||
本规格的执行 issue 为 [#1392](https://github.com/pikasTech/HWLAB/issues/1392),性能问题修复执行 issue 为 [#1422](https://github.com/pikasTech/HWLAB/issues/1422),Performance dashboard 中文化可视化执行 issue 为 [#1609](https://github.com/pikasTech/HWLAB/issues/1609)。单一权威观测模型架构治理 issue 为 [#1638](https://github.com/pikasTech/HWLAB/issues/1638),阶段执行 issue 为 P0 [#1639](https://github.com/pikasTech/HWLAB/issues/1639)、P1 [#1641](https://github.com/pikasTech/HWLAB/issues/1641)、P2 [#1640](https://github.com/pikasTech/HWLAB/issues/1640)、P3 [#1642](https://github.com/pikasTech/HWLAB/issues/1642)、P4 [#1643](https://github.com/pikasTech/HWLAB/issues/1643) 和 P5 [#1644](https://github.com/pikasTech/HWLAB/issues/1644)。Workbench Redis 派生读缓存架构执行 issue 为 [#1870](https://github.com/pikasTech/HWLAB/issues/1870),P0 SPEC-first 子 issue 为 [#1871](https://github.com/pikasTech/HWLAB/issues/1871)。该类 issue 的 P0 阶段必须以本 SPEC 为前置:先确认本规格、父级 [PJ2026-010605 运维监控](PJ2026-010605-observability-monitoring.md)、[PJ2026-010401 Web工作台](PJ2026-010401-web-workbench.md)、[PJ2026-010401080313 Workbench实时权威](PJ2026-010401080313-workbench-realtime-authority.md) 和 [PJ2026-010403 API契约](PJ2026-010403-api-contract.md) 的引用关系,再进入后续实现。
|
||||
|
||||
后续实现 issue 或 PR 收口时必须回写:使用的 SPEC 编号和实现引用版本、触达的源码文件头部标注情况、Prometheus 指标/label 审查结果、D601 v0.3 public origin 的原入口验证结果,以及是否需要继续修订本规格。
|
||||
|
||||
+20
-20
@@ -22,25 +22,25 @@
|
||||
| 实现引用版本 | draft-2026-06-30-p0-1297-spec-first; PJ2026-010401080313 Workbench实时权威 draft-2026-07-08-p0-workbench-realtime-authority-v2 |
|
||||
| 需求规格模板 | [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-010401080313 Workbench实时权威](PJ2026-010401080313-workbench-realtime-authority.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) |
|
||||
| 关联规格 | [PJ2026-010401 Web工作台](PJ2026-010401-web-workbench.md)、[PJ2026-010401080313 Workbench实时权威](PJ2026-010401080313-workbench-realtime-authority.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、统一 sync replay、错误处理、限流/队列、缓存、timeline、storage、scroll、health、OTel 与 Web 哨兵冻结探测必须用同一组受控语义协作。实时事实权威、禁止前端多源补洞和单步调试工作台以 [PJ2026-010401080313 Workbench实时权威](PJ2026-010401080313-workbench-realtime-authority.md) 为准;本文只定义浏览器运行面、队列、性能和 no-probe-masking 规则。
|
||||
本文定义 Workbench 浏览器实时运行面的迁移边界:SSE、Kafka retention replay、错误处理、限流/队列、缓存、timeline、storage、scroll、health、OTel 与 Web 哨兵冻结探测必须用同一组受控语义协作。实时事实权威、禁止前端多源补洞和单步调试工作台以 [PJ2026-010401080313 Workbench实时权威](PJ2026-010401080313-workbench-realtime-authority.md) 为准;本文只定义浏览器运行面、队列、性能和 no-probe-masking 规则。
|
||||
|
||||
## 2. 目的和范围
|
||||
|
||||
### 2.1 目的
|
||||
|
||||
Workbench实时运行面负责把浏览器侧多轮 Workbench 的实时输入、SSE typed event、统一 `/v1/workbench/sync` replay、initial snapshot、trace/detail 只读投影、可见性诊断和 Web 哨兵采样收敛为可控、可观测、可回归的运行链路。目标是解除第二轮消息后页面卡死、浏览器内存无界上涨、SSE error 引发请求风暴、刷新后消息堆叠、跨 session/trace 串线和 monitor 只能看到症状看不到根因的问题。
|
||||
Workbench实时运行面负责把浏览器侧多轮 Workbench 的实时输入、SSE typed event、Kafka retention replay SSE、initial snapshot、trace/detail 只读投影、可见性诊断和 Web 哨兵采样收敛为可控、可观测、可回归的运行链路。目标是解除第二轮消息后页面卡死、浏览器内存无界上涨、SSE error 引发请求风暴、刷新后消息堆叠、跨 session/trace 串线和 monitor 只能看到症状看不到根因的问题。
|
||||
|
||||
本专项采用 OpenCode serve 的边界作为对照:事件流负责 replay 和 ordering,统一 sync replay 负责按 durable cursor 追平,REST detail/history 只负责显式详情和历史分页,错误 envelope 统一诊断,队列/single-flight 限制重复工作,timeline row model 保持稳定 identity。可整模块迁移的 TypeScript 策略模块必须先按 OpenCode 原文件或原核心函数机械拷贝,再在拷贝件上做 Vue/HWLAB 适配;禁止只阅读 OpenCode 后重写一个薄 wrapper 或只覆盖 happy path。Solid/Effect/TanStack 等框架专属层不直接搬运,但其状态机、分支语义、错误处理和 row/queue/transport 边界必须在 HWLAB runtime 中逐项保真。
|
||||
本专项采用 OpenCode serve 的边界作为对照:事件流负责 replay 和 ordering,Kafka retention replay 负责按 durable cursor 追平,REST detail/history 只负责显式详情和历史分页,错误 envelope 统一诊断,队列/single-flight 限制重复工作,timeline row model 保持稳定 identity。可整模块迁移的 TypeScript 策略模块必须先按 OpenCode 原文件或原核心函数机械拷贝,再在拷贝件上做 Vue/HWLAB 适配;禁止只阅读 OpenCode 后重写一个薄 wrapper 或只覆盖 happy path。Solid/Effect/TanStack 等框架专属层不直接搬运,但其状态机、分支语义、错误处理和 row/queue/transport 边界必须在 HWLAB runtime 中逐项保真。
|
||||
|
||||
所有可调参数必须来自 YAML/source-of-truth 或其前端 runtime projection。本文和源码只定义字段族、状态机、责任边界和验收读取方式;不得写入硬编码阈值、采样周期、重试次数、并发数、缓存容量、退避窗口、超时窗口或浏览器内存 kill 数值。
|
||||
|
||||
### 2.2 范围内
|
||||
|
||||
- Workbench 浏览器 typed error、diagnostic envelope 和用户可见错误归一化。
|
||||
- SSE runtime、cursor replay、sync replay、gap 分类、transport state 和 recovery action。
|
||||
- SSE runtime、cursor replay、Kafka 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。
|
||||
@@ -53,7 +53,7 @@ Workbench实时运行面负责把浏览器侧多轮 Workbench 的实时输入、
|
||||
|
||||
### 2.3 范围外
|
||||
|
||||
- Workbench durable facts、message/part authority、terminal final response 和 read model 写侧仍由 [PJ2026-0104010803 Workbench唯一投影](PJ2026-0104010803-workbench-unique-projection.md) 定义。
|
||||
- Workbench durable facts、message/part authority、terminal final response 和 read model 写侧仍由 [PJ2026-010401080313 Workbench实时权威](PJ2026-010401080313-workbench-realtime-authority.md) 定义。
|
||||
- AgentRun run/command/runner job、provider profile 和 backend execution lifecycle 不由本专项重新定义。
|
||||
- 具体 YAML 路径下的参数数值、Secret、runtime image、node/lane、namespace、public origin 和 rollout 策略不在本文硬编码。
|
||||
- Web 哨兵不负责修复业务投影;它只负责采样、分类、保存证据、报红和暴露根因入口。
|
||||
@@ -64,8 +64,8 @@ Workbench实时运行面负责把浏览器侧多轮 Workbench 的实时输入、
|
||||
| --- | --- |
|
||||
| 实时运行面 | Workbench 浏览器侧从用户动作到 REST/SSE/read model/timeline/DOM 可见性/诊断的运行链路。 |
|
||||
| typed error | 带 code、layer、category、route、traceId、requestId、retryable 和 diagnostic 的标准错误对象。 |
|
||||
| transport state | SSE/EventSource 与统一 sync replay 的连接、打开、错误、关闭、replay、degraded 和 blocked 状态。 |
|
||||
| recovery action | transport state 变化后允许触发的受控动作,例如继续 SSE replay、请求 `/v1/workbench/sync`、标记 degraded 或直接 blocked;动作不得绕过 queue/single-flight,也不得回退到 trace/session/turn 多端点补洞。 |
|
||||
| transport state | SSE/EventSource 与Kafka retention replay 的连接、打开、错误、关闭、replay、degraded 和 blocked 状态。 |
|
||||
| recovery action | transport state 变化后允许触发的受控动作,例如继续 Kafka retention replay SSE、标记 degraded 或直接 blocked;动作不得触发 `/v1/workbench/sync` 或 trace/session/turn 多端点补洞。 |
|
||||
| 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。 |
|
||||
@@ -73,7 +73,7 @@ Workbench实时运行面负责把浏览器侧多轮 Workbench 的实时输入、
|
||||
| browser memory policy | YAML/source-of-truth 下发给 web-probe 或 runtime 的浏览器内存观测与 kill 策略;本文只定义字段语义,不定义数值。 |
|
||||
| REST 风暴 | 同一用户动作或 transport 错误导致 `/sessions`、`/messages`、`/turns`、`/traceEvents`、`/health` 等请求族无界重复或互相触发的状态。 |
|
||||
| 架构退化修复 | 为了让 smoke、dashboard 或哨兵变绿而改变探针、刷新策略、fallback、采样强度或错误等级,却没有修复 Workbench runtime/projection/read model 根因的行为;本专项禁止该模式。 |
|
||||
| 单步调试工作台 | [PJ2026-010401080313 Workbench实时权威](PJ2026-010401080313-workbench-realtime-authority.md) 定义的独立 debug route,用 fake SSE/sync/detail fixture 单步驱动 reducer,不触发真实 Workbench mutation 或 automatic recovery。 |
|
||||
| 单步调试工作台 | [PJ2026-010401080313 Workbench实时权威](PJ2026-010401080313-workbench-realtime-authority.md) 定义的独立 debug route,用 fake live/replay SSE 与 detail fixture 单步驱动 reducer,不触发真实 Workbench mutation 或 automatic recovery。 |
|
||||
|
||||
## 4. 系统边界和接口
|
||||
|
||||
@@ -90,8 +90,8 @@ Workbench实时运行面负责把浏览器侧多轮 Workbench 的实时输入、
|
||||
|
||||
| 编号 | 内部模块 | 规格文档 | 主责边界 | 上游依赖 | 下游支撑 |
|
||||
| --- | --- | --- | --- | --- | --- |
|
||||
| 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、sync replay queue 和 prefetch/cache trimming | YAML运维、Workbench性能、Workbench实时权威 | SSE、sync replay、请求风暴治理 |
|
||||
| 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、Kafka replay queue 和 prefetch/cache trimming | YAML运维、Workbench性能、Workbench实时权威 | SSE、Kafka replay、请求风暴治理 |
|
||||
| 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 复现 |
|
||||
@@ -162,7 +162,7 @@ flowchart LR
|
||||
flowchart TD
|
||||
U[用户消息或 session 切换] --> K[scoped key]
|
||||
K --> Q[refresh queue / single-flight]
|
||||
Q --> R[initial snapshot or /workbench/sync replay]
|
||||
Q --> R[initial snapshot or /workbench/Kafka replay]
|
||||
Q --> E[SSE subscribe with cursor]
|
||||
E --> C[event coalescing]
|
||||
C --> S[server-state reducer]
|
||||
@@ -177,7 +177,7 @@ flowchart TD
|
||||
O --> P[web-probe / monitor evidence]
|
||||
```
|
||||
|
||||
同一用户动作只能通过 scoped key 进入受控 queue;SSE error、visibility change、health probe 或 storage failure 只能产生 diagnostic 和受控 recovery action。允许的 live recovery 是 SSE replay 或 `/v1/workbench/sync`,不能绕过 queue 直接触发 session/message/turn/trace 多端点 fan-out。
|
||||
同一用户动作只能通过 scoped key 进入受控 queue;SSE error、visibility change、health probe 或 storage failure 只能产生 diagnostic 和受控 recovery action。允许的 live recovery 只有 Kafka retention replay SSE;禁止调用 `/v1/workbench/sync` 或 session/message/turn/trace 多端点 fan-out。
|
||||
|
||||
### 5.3 SSE gap 与阻塞时序图
|
||||
|
||||
@@ -198,7 +198,7 @@ sequenceDiagram
|
||||
S-->>S: transport error or seq gap
|
||||
S->>O: transport diagnostic
|
||||
S->>Q: allowed recovery action
|
||||
Q->>A: bounded /workbench/sync replay when policy allows
|
||||
Q->>A: bounded /workbench/Kafka replay 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
|
||||
@@ -210,8 +210,8 @@ sequenceDiagram
|
||||
| --- | --- | --- |
|
||||
| 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、sync replay、explicit snapshot/detail/history、prefetch 和 health probe 必须通过 key 去重、single-flight 或 coalesced queue;同一错误路径不得产生无界 REST fan-out。 |
|
||||
| OPS-WBRT-REQ-004 | SseRuntime | SSE runtime 必须以 server cursor/replay 为同步 authority;live recovery 只允许 SSE replay、统一 `/v1/workbench/sync` replay 或 diagnostic,不得在 SSE error 中全量刷新多个请求族来“补洞”。 |
|
||||
| OPS-WBRT-REQ-003 | QueueRuntime | SSE event、Kafka replay、explicit snapshot/detail/history、prefetch 和 health probe 必须通过 key 去重、single-flight 或 coalesced queue;同一错误路径不得产生无界 REST fan-out。 |
|
||||
| OPS-WBRT-REQ-004 | SseRuntime | SSE runtime 必须以 server cursor/replay 为同步 authority;live recovery 只允许 SSE replay、Kafka retention replay SSE 或 diagnostic,不得在 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。 |
|
||||
@@ -221,7 +221,7 @@ sequenceDiagram
|
||||
| OPS-WBRT-REQ-011 | MechanicalCopy | 可迁移的 OpenCode 通用模块必须先机械拷贝再适配;closeout 必须记录 OpenCode 来源行号、HWLAB 拷贝后行号、适配 diff 范围、被保留/删除/改名的能力清单,以及不存在“参考后重写”的复查结论。 |
|
||||
| OPS-WBRT-REQ-012 | ShrinkageReview | 缩水是独立 P0 缺口;如果迁移后模块缺少 OpenCode 原有状态机、错误处理、限流/防抖、SSE/reducer、scroll persistence、timeline row parity 或 root cause 输出,即使生产路径已经 import,也不得判定完成。 |
|
||||
| OPS-WBRT-REQ-013 | AppFixBoundary | 请求风暴、浏览器卡死、内存上涨、final response 投影缺失和刷新堆叠的修复必须落在 Workbench runtime、projection writer/finalizer、read model、SSE/REST contract、Vue store/reducer 或本专项迁移的共享模块;web-probe/Playwright 只能增强证据、baseline、blocker red 和 report 可见性,不能作为业务修复点。 |
|
||||
| OPS-WBRT-REQ-014 | RequestStormRegression | 所有 SSE error、visibility change、health probe、explicit snapshot/detail/history 读取和 sync replay 都必须携带 scoped key、原因、in-flight/dedup 诊断和 recovery action;同一 scoped key 的重复恢复必须被 queue/single-flight 合并或阻塞,不能跨请求族递归触发。 |
|
||||
| OPS-WBRT-REQ-014 | RequestStormRegression | 所有 SSE error、visibility change、health probe、explicit snapshot/detail/history 读取和 Kafka replay 都必须携带 scoped key、原因、in-flight/dedup 诊断和 recovery action;同一 scoped key 的重复恢复必须被 queue/single-flight 合并或阻塞,不能跨请求族递归触发。 |
|
||||
| OPS-WBRT-REQ-015 | EvidenceSplit | closeout 必须区分 provider/AgentRun 执行完成、Workbench projection 完成和浏览器可见完成。OTel 显示 completed 但 UI trace rows/final response 为空时,应归入 read model/projection/runtime 可见性问题继续调查;不得把 completed trace 的空 UI 重新归因成 provider 失败,也不得用 analyzer fallback 生成假的 final response。 |
|
||||
| OPS-WBRT-REQ-016 | NoProbeMasking | web-probe smoke 的目标是用户指定业务入口。为通过 smoke 而减少轮次、禁用内存/freeze 检测、自动 reload、重建页面、关闭 network 采样、吞掉 submit/command 失败或把 blocker red 降级为 warning,都属于架构退化。 |
|
||||
| OPS-WBRT-REQ-017 | SingleStepDebug | Workbench 必须支持隔离的 fake SSE/sync/detail 单步调试工作台,用于验证 authority gate、sealed guard、detail-only rejection、cursor/reconnect 和 cross-page convergence;纯 SSE 模式下任何 automatic `/sync` 或旧 detail fan-out 都必须红灯。 |
|
||||
@@ -231,7 +231,7 @@ sequenceDiagram
|
||||
新增或修改的 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唯一投影 <实现引用版本>.
|
||||
SPEC: PJ2026-0106050514 Workbench实时运行面 draft-2026-06-30-p0-1297-spec-first; PJ2026-010401080313 Workbench实时权威 <实现引用版本>.
|
||||
```
|
||||
|
||||
自动生成文件、锁文件、第三方 vendored 文件和不能承载注释头的二进制产物不要求源码头部,但生成器、渲染器或配置入口必须能追溯到本规格。
|
||||
@@ -267,8 +267,8 @@ Workbench 请求风暴或浏览器 freeze 类 issue 的关闭证据必须同时
|
||||
| 编号 | 迁移模块 | OpenCode 对照能力 | HWLAB 目标接入点 | 完成口径 |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| M01 | ErrorRuntime | typed error、diagnostic envelope、用户可见错误 | `web/hwlab-cloud-web/src/utils/workbench-error-runtime.ts`、Workbench store、消息面板 | REST/SSE/storage/health/projection 错误统一归一化并暴露 root cause/recovery action |
|
||||
| M02 | RefreshQueueRuntime | queue、single-flight、cooldown、请求风暴抑制 | `workbench-refresh-runtime.ts`、`src/stores/workbench.ts` | sync replay、explicit snapshot/detail/history、health probe 进入同一 keyed queue |
|
||||
| M03 | SseTransportRuntime | EventSource lifecycle、cursor、gap 分类 | `workbench-stream-transport.ts`、Workbench store | SSE reconnect 只触发 SSE replay、`/workbench/sync` 或 diagnostic,不触发旧 REST fan-out |
|
||||
| M02 | RefreshQueueRuntime | queue、single-flight、cooldown、请求风暴抑制 | `workbench-refresh-runtime.ts`、`src/stores/workbench.ts` | Kafka replay、explicit snapshot/detail/history、health probe 进入同一 keyed queue |
|
||||
| M03 | SseTransportRuntime | EventSource lifecycle、cursor、gap 分类 | `workbench-stream-transport.ts`、Workbench store | SSE reconnect 只触发 Kafka retention replay SSE 或 diagnostic,不触发 `/workbench/sync` 与旧 REST fan-out |
|
||||
| M04 | ScopedKeyRuntime | scope key、cache key、trace key | `workbench-key.ts`、store/runtime modules | session/trace/message/part 的 key 生成规则生产路径共用 |
|
||||
| M05 | TimelineRuntime | 稳定 row identity、增量替换、跨 session 隔离 | server-state reducer、timeline composables、Vue message rendering | 刷新和第二轮消息不产生堆叠、重复或串线 |
|
||||
| M06 | StorageRuntime | safe storage、namespace、quota/security 降级 | `workbench-storage-runtime.ts`、store、session rail | localStorage/sessionStorage 访问不再直接散落在组件和 store |
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
| 浏览器资源治理实现引用版本 | draft-2026-07-13-p18-browser-resource-guard |
|
||||
| 需求规格模板 | [ISO/IEC/IEEE 29148 需求规格模板](../../templates/iso-iec-ieee-29148-requirements-spec-template.md) |
|
||||
| 上级规格 | [PJ2026-010605 运维监控](PJ2026-010605-observability-monitoring.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-010601 发布流水](PJ2026-010601-controlled-release.md)、[PJ2026-010602 源码同步](PJ2026-010602-source-sync.md)、[PJ2026-010603 YAML运维](PJ2026-010603-yaml-first-ops.md)、[PJ2026-010604 公开入口](PJ2026-010604-public-entry.md)、[PJ2026-01060505 Workbench性能](PJ2026-01060505-workbench-performance.md) |
|
||||
| 关联规格 | [PJ2026-010401 Web工作台](PJ2026-010401-web-workbench.md)、[PJ2026-010401080313 Workbench实时权威](PJ2026-010401080313-workbench-realtime-authority.md)、[PJ2026-010403 API契约](PJ2026-010403-api-contract.md)、[PJ2026-010601 发布流水](PJ2026-010601-controlled-release.md)、[PJ2026-010602 源码同步](PJ2026-010602-source-sync.md)、[PJ2026-010603 YAML运维](PJ2026-010603-yaml-first-ops.md)、[PJ2026-010604 公开入口](PJ2026-010604-public-entry.md)、[PJ2026-01060505 Workbench性能](PJ2026-01060505-workbench-performance.md) |
|
||||
| 规格治理索引 | [规格治理](spec-governance.md) |
|
||||
|
||||
本文采用 ISO/IEC/IEEE 29148 需求规格模板的项目裁剪版:正文只保留 Web 哨兵的稳定使命、范围、术语、系统边界、内部分工、目标图和原子需求。Web 哨兵是现有 `web-probe observe` 能力的生产化运行形态,不是新的探针实现。
|
||||
@@ -61,7 +61,7 @@ Web哨兵必须遵循 UniDesk YAML-first ops。目标 node/lane、public origin
|
||||
|
||||
### 2.3 范围外
|
||||
|
||||
- Workbench 会话、message/part、Trace 顺序、final response、steer/cancel 和 timing authority 的业务正确性仍由 [PJ2026-0104010803 Workbench唯一投影](PJ2026-0104010803-workbench-unique-projection.md) 定义。
|
||||
- Workbench 会话、message/part、Trace 顺序、final response、steer/cancel 和 timing authority 的业务正确性仍由 [PJ2026-010401080313 Workbench实时权威](PJ2026-010401080313-workbench-realtime-authority.md) 定义。
|
||||
- AgentRun run/command/provider profile 的执行生命周期归 [PJ2026-0102 Agent编排](PJ2026-0102-agent-orchestration.md) 和 [PJ2026-010205 HWLAB接入](PJ2026-010205-hwlab-dispatch.md)。
|
||||
- API path、错误 envelope、route policy 和用户身份语义归 [PJ2026-010403 API契约](PJ2026-010403-api-contract.md)。
|
||||
- 第一阶段不交付分布式压测;loadtest 只保留同镜像、同 wrapper 的配置和命令扩展点。
|
||||
@@ -120,10 +120,10 @@ Web哨兵必须遵循 UniDesk YAML-first ops。目标 node/lane、public origin
|
||||
|
||||
| 编号 | 内部模块 | 规格文档 | 主责边界 | 上游依赖 | 下游支撑 |
|
||||
| --- | --- | --- | --- | --- | --- |
|
||||
| PJ2026-0106050801 | Wrapper边界 | 本规格 6.1 | 只 wrap 现有 observe CLI,禁止第二 runner/analyzer | web-probe observe、Workbench唯一投影 | 服务化入口、人工排障 |
|
||||
| PJ2026-0106050801 | Wrapper边界 | 本规格 6.1 | 只 wrap 现有 observe CLI,禁止第二 runner/analyzer | web-probe observe、Workbench实时权威 | 服务化入口、人工排障 |
|
||||
| PJ2026-0106050802 | YAML配置 | 本规格 6.2 | configRefs、owning YAML、parser 校验和 redacted plan | YAML运维、公开入口、Secret分发 | plan/status、部署渲染 |
|
||||
| PJ2026-0106050803 | 常驻服务 | 本规格 6.3 | scheduler、scenario runner、artifact PVC、中心 ingest/query、Host PG、health、metrics、maintenance API | Wrapper边界、YAML配置 | dashboard、CI/CD |
|
||||
| PJ2026-0106050804 | 报告视图 | 本规格 6.4 | CLI/report API 渐进读取、分页、redaction、trace-frame | observe collect/analyze、Workbench唯一投影 | issue evidence、dashboard |
|
||||
| PJ2026-0106050804 | 报告视图 | 本规格 6.4 | CLI/report API 渐进读取、分页、redaction、trace-frame | observe collect/analyze、Workbench实时权威 | issue evidence、dashboard |
|
||||
| PJ2026-0106050805 | 发布集成 | 本规格 6.5 | CI/CD、GitOps、Argo、maintenance、targetValidation、publicExposure | 发布流水、源码同步、公开入口 | 发布恢复判定 |
|
||||
| PJ2026-0106050806 | Canary验收 | 本规格 6.6 | dsflash-go 十轮工具调用、24 小时 dry-run 和 profile 结构化失败边界 | Agent编排、Workbench、web-probe | 生产巡检收口 |
|
||||
| PJ2026-0106050807 | 安全隔离 | 本规格 6.7 | Secret/prompt/provider redaction、NetworkPolicy、public dashboard auth | 用户管理、平台运维 | 安全 closeout |
|
||||
@@ -475,7 +475,7 @@ sequenceDiagram
|
||||
|
||||
| 编号 | 短名 | 主责模块 | 关联模块 |
|
||||
| --- | --- | --- | --- |
|
||||
| OPS-SENTINEL-REQ-001 | Wrapper边界 | PJ2026-0106050801 Wrapper边界 | [Workbench唯一投影](PJ2026-0104010803-workbench-unique-projection.md)、[Web工作台](PJ2026-010401-web-workbench.md) |
|
||||
| OPS-SENTINEL-REQ-001 | Wrapper边界 | PJ2026-0106050801 Wrapper边界 | [Workbench实时权威](PJ2026-010401080313-workbench-realtime-authority.md)、[Web工作台](PJ2026-010401-web-workbench.md) |
|
||||
|
||||
Web哨兵必须只编排现有顶层 `web-probe observe start/status/command/collect/analyze` 命令语义。常驻服务可以把这些 verb 包成稳定 adapter,但底层采样器、control queue、artifact schema、collect 渲染和 offline analyzer 必须与人工 CLI 共享同一实现或同一生成物。
|
||||
|
||||
@@ -485,7 +485,7 @@ Web哨兵必须只编排现有顶层 `web-probe observe start/status/command/col
|
||||
|
||||
人工 CLI 是排障和原入口验收的一等入口;哨兵是调度入口。两者对同一 stateDir、同一 report 和同一 trace-frame 的解释必须一致。
|
||||
|
||||
当 `web-probe` 被用于 Workbench smoke 或巡检时,smoke 目标是 Workbench 用户入口,不是 web-probe 自身。若观察到请求风暴、浏览器 freeze、内存上涨、submit/command 失败、trace rows 缺失或 final response 缺失,哨兵只能记录 blocker、root cause、artifact 和 drill-down;修复责任必须回到 [Workbench实时运行面](PJ2026-0106050514-workbench-realtime-runtime.md)、[Workbench唯一投影](PJ2026-0104010803-workbench-unique-projection.md) 或对应业务规格。不得为了让哨兵变绿而减少采样、自动刷新页面、重建 page、关闭 freeze/memory 检测、降低 finding 等级、修改 Playwright 启动参数或把业务 smoke 改成 web-probe 工具自检。
|
||||
当 `web-probe` 被用于 Workbench smoke 或巡检时,smoke 目标是 Workbench 用户入口,不是 web-probe 自身。若观察到请求风暴、浏览器 freeze、内存上涨、submit/command 失败、trace rows 缺失或 final response 缺失,哨兵只能记录 blocker、root cause、artifact 和 drill-down;修复责任必须回到 [Workbench实时运行面](PJ2026-0106050514-workbench-realtime-runtime.md)、[Workbench实时权威](PJ2026-010401080313-workbench-realtime-authority.md) 或对应业务规格。不得为了让哨兵变绿而减少采样、自动刷新页面、重建 page、关闭 freeze/memory 检测、降低 finding 等级、修改 Playwright 启动参数或把业务 smoke 改成 web-probe 工具自检。
|
||||
|
||||
### 6.2 OPS-SENTINEL-REQ-002 YAML-first 配置引用
|
||||
|
||||
@@ -517,7 +517,7 @@ runner `/health` 必须覆盖配置装载、scheduler/CronJob 观察、artifact
|
||||
|
||||
| 编号 | 短名 | 主责模块 | 关联模块 |
|
||||
| --- | --- | --- | --- |
|
||||
| OPS-SENTINEL-REQ-004 | 报告视图 | PJ2026-0106050804 报告视图 | [Workbench唯一投影](PJ2026-0104010803-workbench-unique-projection.md)、[Workbench性能](PJ2026-01060505-workbench-performance.md) |
|
||||
| OPS-SENTINEL-REQ-004 | 报告视图 | PJ2026-0106050804 报告视图 | [Workbench实时权威](PJ2026-010401080313-workbench-realtime-authority.md)、[Workbench性能](PJ2026-01060505-workbench-performance.md) |
|
||||
|
||||
Web哨兵的 `sentinel report` 和 dashboard 必须按 YAML report views 渐进展示同一 observe/analyze artifact:run overview、turn-summary、findings、trace-frame/sample drill-down 和显式 raw artifact 下载。默认视图不得 dump JSONL,也不得展示 prompt 原文、完整 assistant 正文、cookie、token、API key、provider payload 或完整 stdout/stderr。
|
||||
|
||||
|
||||
Reference in New Issue
Block a user