docs: add D518 workbench timeline acceptance spec
This commit is contained in:
+15
-1
@@ -19,7 +19,7 @@
|
||||
| 短名 | 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-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-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) |
|
||||
@@ -60,6 +60,7 @@ D601 v0.3 可以在 `hwlab-v03` namespace 内为 `hwlab-workbench-runtime` 使
|
||||
- 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 范围外
|
||||
|
||||
@@ -114,6 +115,7 @@ D601 v0.3 可以在 `hwlab-v03` namespace 内为 `hwlab-workbench-runtime` 使
|
||||
| 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。 |
|
||||
@@ -460,6 +462,8 @@ MessagePage 是 Workbench timeline 事实,不是 facts 表写入批次的直
|
||||
|
||||
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 hydration diagnostic、transport diagnostic、result sync diagnostic 和 session health 只能作为独立字段或详情区数据输出。读取链路不得因为后续 turn snapshot 失败、trace event page 失败、SSE gap、realtime timeout 或 compat wrapper 失败而替换 sealed 主正文。
|
||||
@@ -474,6 +478,8 @@ Trace event page 的可见性必须以 durable turn/message/session 关系和 ow
|
||||
|
||||
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
|
||||
@@ -506,6 +512,8 @@ Web reducer 必须提供 sealed guard:对已经有 `sealedAt` 或等价 sealed
|
||||
|
||||
运行中相对时间显示必须保持单一权威:Web server-state 只保存 WorkbenchReadModel 返回的 `startedAt`、`lastEventAt`、`finishedAt`、`durationMs` 和 sealed 标记;浏览器 ticker 只在组件渲染时计算 `now - startedAt` 与 `now - lastEventAt` 文案。`Date.now()`、页面本地 `updatedAt`、`lastEventAgeMs` 快照、轮询间隔和 trace hydration 时间不得写入 reducer/store,也不得影响 lifecycle、terminal、session ordering 或 projection diagnostic。终态消息的耗时只使用 sealed projection 值,不能随浏览器 ticker 继续增长。
|
||||
|
||||
刷新和 session switch 恢复必须保持 active session bucket 不变量。Web 在重新 hydrate、切出再切回、双页面同时观察、SSE 断开后 REST 补洞或 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
|
||||
|
||||
| 编号 | 短名 | 主责模块 | 关联模块 |
|
||||
@@ -536,6 +544,8 @@ Sealed final response 回归必须构造 completed assistant 主正文已经展
|
||||
|
||||
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
|
||||
|
||||
| 编号 | 短名 | 主责模块 | 关联模块 |
|
||||
@@ -598,6 +608,8 @@ Trace-frame 行顺序必须来自 Workbench projectedSeq、aggregateSeq、part o
|
||||
|
||||
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
|
||||
|
||||
| 编号 | 短名 | 主责模块 | 关联模块 |
|
||||
@@ -631,3 +643,5 @@ Workbench turn/message/trace 投影 authority 与 CLI trace 视图收敛的架
|
||||
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。
|
||||
|
||||
Reference in New Issue
Block a user