docs: define workbench redis derived cache spec

This commit is contained in:
Codex
2026-06-22 04:17:28 +00:00
parent 2733c2d355
commit 24bdb7194a
3 changed files with 133 additions and 13 deletions
@@ -19,10 +19,10 @@
| 短名 | 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-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 |
| 需求规格模板 | [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-010205 HWLAB接入](PJ2026-010205-hwlab-dispatch.md)、[PJ2026-0102 Agent编排](PJ2026-0102-agent-orchestration.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 唯一投影的稳定使命、范围、术语、系统边界、内部分工和原子需求。
@@ -39,6 +39,8 @@ AgentRun terminal outbox 和 command result 是 Code Agent turn terminal 的上
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 hydration、SSE gap、realtime timeout、transport close、read model lag 或 compat wrapper 失败只能写入 trace detail、transport diagnostic、projection diagnostic 或 session health,不能覆盖 sealed 主正文。
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 语义。
@@ -48,6 +50,7 @@ Terminal final response 是 Workbench 投影的 sealed 用户结果。Projection
- 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、fake-server fixture 和 Playwright 回归对同一 durable projection 的消费规则。
- 本专项范围内新增或重构源码文件的 SPEC 头部引用规则。
@@ -59,6 +62,7 @@ Terminal final response 是 Workbench 投影的 sealed 用户结果。Projection
- 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. 术语表
@@ -92,6 +96,9 @@ Terminal final response 是 Workbench 投影的 sealed 用户结果。Projection
| 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 写权。 |
## 4. 系统边界和接口
@@ -118,6 +125,7 @@ Terminal final response 是 Workbench 投影的 sealed 用户结果。Projection
| 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契约 | 高频读降尾延迟 |
### 5.1 目标架构图
@@ -136,12 +144,14 @@ flowchart LR
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
@@ -181,6 +191,9 @@ flowchart TD
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]
@@ -396,6 +409,8 @@ Finalizer 对 sealed turn 的后续重试只能推进 trace detail completeness
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。
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 修复源头;不得在读取时临时合成“看起来正确”的状态。
@@ -480,8 +495,22 @@ SPEC: PJ2026-0104010803 Workbench唯一投影 draft-2026-06-20-p1-zero-split-dur
同一文件同时承载 API契约、HWLAB接入、Web工作台或 Agent编排职责时,应在同一头部追加对应 SPEC 编号与实现引用版本。实现文件不得只写 issue 编号、`latest``current`。自动生成文件、第三方 vendored 文件、纯配置、锁文件和无法承载注释头的二进制产物可例外,但对应生成器、渲染器或配置入口必须能追溯到本 SPEC。
### 6.9 WB-PROJ-REQ-009 derived read cache boundary
| 编号 | 短名 | 主责模块 | 关联模块 |
| --- | --- | --- | --- |
| WB-PROJ-REQ-009 | 派生读缓存 | PJ2026-010401080309 DerivedReadCache | [Workbench性能](PJ2026-01060505-workbench-performance.md)、[API契约](PJ2026-010403-api-contract.md) |
WorkbenchReadModel 可以使用 Redis 派生读缓存降低高频读路径的 Postgres 尾延迟,但缓存只保存可丢弃、可过期、可重建的 read model DTO 或内部 read snapshot。优先允许缓存 `/v1/workbench/sessions` actor-scoped session summary page、terminal turn snapshot 和 terminal trace event pagerunning turn、active session、projectionStatus 非 terminal 或正在变化的页面应使用更短 TTL 或不缓存。
缓存 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 lifecyclecanonical 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。
## 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编排规格是否仍与实现一致。
本专项关闭前,执行 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`
@@ -19,9 +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; 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; 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-20-p1-view-local-timing-ticker; draft-2026-06-22-p1-workbench-redis-derived-cache; 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; 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) |
| 规格治理索引 | [规格治理](spec-governance.md) |
本文采用 ISO/IEC/IEEE 29148 需求规格模板的项目裁剪版:正文只保留 API 契约的稳定使命、范围、术语、系统边界、内部分工和原子需求。
@@ -41,6 +42,7 @@ API契约负责定义 Cloud Web、HWLAB CLI 和自动化脚本共同使用的 RE
- Agent session、chat、steer、cancel、result、trace 和 inspect 的用户可见 API 形态。
- Workbench workspace、Admin Access、provider profile、HWPOD node-ops、gateway 和性能摘要等入口的字段稳定性。
- JSON 成功/失败响应、HTTP 状态、错误分类、脱敏、默认摘要和完整展开边界。
- Workbench pure-read API 的缓存诊断字段,包括 `cacheStatus``cacheAgeMs`、projection revision/seq、dbQueryAvoided 和 Redis unavailable/stale 的低基数表达。
### 2.3 范围外
@@ -49,6 +51,7 @@ API契约负责定义 Cloud Web、HWLAB CLI 和自动化脚本共同使用的 RE
- HWPOD 资源身份、硬件操作、node 路由和原始硬件事实归 [硬件池](PJ2026-0101-hardware-pool.md)。
- CaseRun、评价、aggregate、回放和训练反馈归 [HarnessRL](PJ2026-0103-harness-rl.md)。
- 运行端点、FRP/Caddy、Secret、rollout 和 Prometheus 监控归 [平台运维](PJ2026-0106-platform-ops.md)。
- Redis workload、镜像、资源、NetworkPolicy、TTL 数值、metrics scrape 和运行面发布归 [平台运维](PJ2026-0106-platform-ops.md) 与 [Workbench性能](PJ2026-01060505-workbench-performance.md);API契约只定义客户端可见字段和诊断边界。
## 3. 术语表
@@ -73,6 +76,9 @@ API契约负责定义 Cloud Web、HWLAB CLI 和自动化脚本共同使用的 RE
| 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。 |
| Derived read cache | WorkbenchReadModel 内部可选的 Redis 派生读缓存;它只缓存 durable projection 派生快照,不改变 API 资源、权限、lifecycle 或 final response 语义。 |
| CacheDiagnostic | Workbench pure-read 响应或 OTel span 中用于解释缓存行为的诊断字段集合,至少包含 `cacheStatus``cacheAgeMs`、cacheKeyClass、projectionSeq 或等价字段;它不参与业务状态判断。 |
| cacheStatus | 缓存行为枚举,至少包含 `hit``miss``stale``unavailable`;该字段只能用于性能诊断和 `/performance` 展示,不得用于推断 session/turn/trace lifecycle。 |
| projection commit | projection writer/finalizer 对 message、part、turn、trace 和 session summary 的一次幂等持久化提交;终态 commit 必须保持这些事实语义一致。 |
| projectedSeq | HWLAB durable trace event 的单调分页游标;与 AgentRun `sourceSeq` / `sourceEventId` 分离,用于 Workbench trace page、SSE replay 和 fake-server fixture。 |
| 读侧推理 | API route、read model、SSE consumer、compat wrapper、CLI renderer、Web reducer/selectors、fake-server 或测试断言根据 trace tail、message text、tool event、result cache、session summary、list row、workspace snapshot、localStorage 或 elapsed timeout 推断 lifecycle、terminal、running 或 final response 的行为;API契约禁止该模式。 |
@@ -86,7 +92,7 @@ API契约负责定义 Cloud Web、HWLAB CLI 和自动化脚本共同使用的 RE
| 外部使用者 | Cloud Web、HWLAB CLI、自动化脚本、平台管理员和需要同源 API 的浏览器客户端。 |
| 外部输入 | HTTP method、相对 path、JSON body、query、Web session cookie、Authorization header、`traceparent`、sessionId、turnId、traceId 和业务参数;projectId、workspaceId、conversationId 只允许作为显式筛选或兼容 metadata 输入。 |
| 受控资源 | API path、schema、route policy、AuthPrincipal 摘要、错误码、响应摘要和兼容性契约。 |
| 外部输出 | JSON 响应、HTTP status、`traceparent``x-hwlab-otel-trace-id``x-request-id`、route、actor、业务标识、错误分类、脱敏状态、trace/result 指针和下一步查询提示。 |
| 外部输出 | JSON 响应、HTTP status、`traceparent``x-hwlab-otel-trace-id``x-request-id`、route、actor、业务标识、错误分类、脱敏状态、trace/result 指针、cache diagnostic 和下一步查询提示。 |
| 用户接口 | Cloud Web 同源 API、HWLAB CLI 同源 REST request/client 命令、HTTP API。 |
| 系统边界 | API契约负责接口形态和错误表达;不拥有用户、Agent、硬件、CaseRun、账本或发布事实。 |
@@ -99,6 +105,7 @@ 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 页 |
目标后端模块应至少拆分为 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 factscompat wrapper 只提供旧 path 到新资源的兼容映射,不拥有第二套业务事实。
@@ -110,6 +117,8 @@ API契约负责定义 Cloud Web、HWLAB CLI 和自动化脚本共同使用的 RE
API 契约严禁读侧推理。`GET /v1/workbench/*``/v1/agent/*` compat wrapper、SSE event envelope 和 CLI render 只能返回唯一 Workbench durable projection 中已经存在的 lifecycle/final/status 字段;不得从 `result?.status ?? trace?.status`、最后一条 trace event `completed`、message text 是否为空、part/tool row 状态、session list summary、workspace selected state、轮询耗时或 elapsed timeout 合成 terminal、running、finalResponse 或 `caught-up`。投影缺失或矛盾时返回结构化 unknown/projecting/degraded/blocker,而不是在读侧选择一个优先级最高的事实源。
Derived read cache 只能作为 WorkbenchReadModel 内部性能优化。`GET /v1/workbench/*` 可以返回 `cacheStatus``cacheAgeMs`、cacheKeyClass、projectionSeq、dbQueryAvoided 或等价 CacheDiagnostic 字段,用于解释 hit/miss/stale/unavailable 和读路径耗时;这些字段不得影响 HTTP resource identity、AuthPrincipal、owner visibility、lifecycle、terminal、finalResponse、projectionStatus、404/410 判断或 compat wrapper 映射。Redis unavailable 时,API 只能返回 `cacheStatus=unavailable` 加受控 DB read 或明确 degraded,不能让 liveness 失败,也不能切换到 Cloud API/Web 前端 Redis 直连。
### 5.2 Workbench pure-read DTO 字段矩阵
`GET /v1/workbench/*` 的响应 DTO 只表达已经提交的 durable Workbench projection 和独立诊断。API 可以为渐进披露裁剪长字段,但必须保留 authority 边界和可继续查询的稳定标识。
@@ -126,8 +135,49 @@ API 契约严禁读侧推理。`GET /v1/workbench/*`、`/v1/agent/*` compat wrap
Workbench message/turn DTO 可以输出 timing metadata,但字段权威必须保持单一:`startedAt``lastEventAt``finishedAt` 和 sealed `durationMs` 来自 Workbench durable projectionrunning 消息的“最近/耗时”由浏览器以这些时间戳和本地 now 计算;terminal 消息使用 sealed `durationMs` 或等价 sealed `finishedAt - startedAt`,不得继续增长。`lastEventAgeMs` 若在迁移期保留,只能作为服务端观测时刻的快照或诊断字段,不能作为 Cloud Web 用户可见相对时间的显示权威,也不能参与 lifecycle、terminal、projectionStatus、session sorting 或 final response 选择。
Workbench pure-read DTO 可以携带 CacheDiagnostic,但字段必须与业务事实分仓表达。`cacheStatus``cacheAgeMs``cacheKeyClass``projectionSeq``dbQueryAvoided``dbQueryDuration``payloadBytes` 只能放在 `diagnostic``performance``meta` 或等价非 authority 字段下;默认响应不得输出完整 cache key、actor id、session id 以外的派生 key、trace id 组合 key、prompt、assistant 正文、tool 参数、stdout/stderr、Secret、token、cookie、Authorization header 或 DB DSN。客户端可以显示或上报这些诊断用于性能分析,但不得把 `hit` 视为新鲜、把 `stale` 视为 terminal、把 `unavailable` 视为业务失败,或根据 cache miss 触发 read-through repair。
API 禁止路径清单如下:GET read-through repair、session JSON lifecycle 推理、result cache lifecycle 推理、trace tail lifecycle 推理、workspace/conversation authority、billing finalizer side effect、Code Agent manager shortcut、frontend status priority 和 compat wrapper second authority。需要推进 projection 时必须由 writer/finalizer、后台 scheduler、显式 mutation 或受控 replay/reprojection 入口执行;GET、SSE、CLI render 和 fake-server 只能观察结果。
### 5.3 Workbench cache diagnostic 数据流
```mermaid
flowchart LR
Client[Web / CLI] --> Route[GET /v1/workbench/*]
Route --> Auth[AuthPrincipal + owner visibility]
Auth --> Read[WorkbenchReadModel]
Read --> Cache[(Derived Redis cache)]
Cache -->|hit with matching authority input| Dto[Pure-read DTO]
Cache -->|miss / stale / unavailable| Facts[(Durable Workbench facts)]
Facts --> Read
Read --> Dto
Dto --> Diag[CacheDiagnostic meta]
Diag --> Client
```
缓存诊断数据流要求 route 先完成鉴权和 owner visibility,再由 WorkbenchReadModel 使用 durable facts authority input 访问 Redis 派生缓存。cache hit 只能返回等价 pure-read DTOcache miss、stale 或 unavailable 必须回到 durable facts read 或明确 degraded,不得触发 AgentRun、result polling、workspace repair、projection finalizer 或前端 Redis 直连。
```mermaid
sequenceDiagram
participant C as Web/CLI
participant A as Cloud API route
participant R as WorkbenchReadModel
participant K as Redis derived cache
participant F as Durable facts
C->>A: GET /v1/workbench/sessions
A->>R: principal + query + route
R->>K: get cache key with authority input
alt hit and revision matches
K-->>R: derived DTO + cacheAgeMs
else miss/stale/unavailable
R->>F: read durable projection
F-->>R: authoritative DTO or degraded/blocker
R->>K: set derived snapshot when allowed
end
R-->>A: DTO + CacheDiagnostic
A-->>C: JSON response, lifecycle from durable projection only
```
## 6. 原子需求
### 6.1 CLIENT-API-REQ-001 同源路由
@@ -274,6 +324,18 @@ interface HwlabErrorEnvelope {
Workbench 投影 blocker、proxy timeout、鉴权失败、provider profile、web-performance、全局 route exception 和 dev-entrypoint proxy 错误都应映射到同一 envelope。历史 `{ error: string }` 字段可在迁移期作为 `userMessage` 展示兼容,但不得成为唯一错误事实;新增用户可见错误路径禁止只返回裸字符串、`reason` 或未脱敏 raw exception。
### 6.6 CLIENT-API-REQ-006 Workbench cache diagnostic 字段
| 编号 | 短名 | 主责模块 | 关联模块 |
| --- | --- | --- | --- |
| CLIENT-API-REQ-006 | 缓存诊断 | PJ2026-01040306 缓存诊断 | [Workbench唯一投影](PJ2026-0104010803-workbench-unique-projection.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 分仓。
CacheDiagnostic 不得成为业务状态仲裁字段。Web、CLI、compat wrapper、fake-server 和 web-probe 不得根据 `cacheStatus``cacheAgeMs`、Redis key presence 或 dbQueryAvoided 推断 session running/completed、turn terminal、trace caught-up、final response、deleted/archived/not-found 或权限可见性。缓存 unavailable 不应触发 `/health/live` 失败;route 可以返回受控 DB read 结果或明确 degraded/blocker,但不能静默切换到 Cloud API/Web 前端 Redis 直连或旧 fallback path。
CacheDiagnostic 必须脱敏并保持低基数。响应、日志、OTel span 和 `/performance` 默认展示不得包含完整 cache key、actor id 聚合维度、trace id 组合 key、prompt、assistant 正文、tool 参数、stdout/stderr、Secret、token、cookie、Authorization header、DB DSN 或 raw upstream payload。需要排查单次请求时,只允许通过 OTel trace id、request id、route、cacheKeyClass、projectionSeq 和 valuesRedacted 摘要关联。
## 7. 过程控制
本规格不单独索引过程 issue;跨 L1 的内测、灰度和阶段活动索引统一保留在 [PJ2026-01 HWLAB 总规格](PJ2026-01-HWLAB.md) 的 `7. 过程控制`
本规格不单独索引一般过程 issue;跨 L1 的内测、灰度和阶段活动索引统一保留在 [PJ2026-01 HWLAB 总规格](PJ2026-01-HWLAB.md) 的 `7. 过程控制`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`
@@ -19,10 +19,10 @@
| 短名 | Workbench性能 |
| 层级 | L3 子课题 |
| 状态 | 已生效 |
| 实现引用版本 | draft-2026-06-19-p0; draft-2026-06-20-p0-error-diagnostics |
| 实现引用版本 | draft-2026-06-19-p0; draft-2026-06-20-p0-error-diagnostics; draft-2026-06-22-p1-workbench-redis-derived-cache |
| 需求规格模板 | [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-010403 API契约](PJ2026-010403-api-contract.md)、[PJ2026-010205 HWLAB接入](PJ2026-010205-hwlab-dispatch.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) |
| 规格治理索引 | [规格治理](spec-governance.md) |
本文采用 ISO/IEC/IEEE 29148 需求规格模板的项目裁剪版:正文只保留 D601 v0.3 Workbench 用户可感知性能监控的稳定使命、范围、术语、系统边界、内部分工、目标图和原子需求。
@@ -35,6 +35,8 @@ Workbench性能负责把 HWLAB Cloud Web 工作台中用户直接感知的等待
本规格的目标状态是:用户从 Web 发起动作后,浏览器、Cloud API、Workbench SSE、trace/read model、AgentRun adapter 和性能观测存储之间拥有同一套低基数性能事件口径;平台运维可以按时间窗口判断 D601 v0.3 Workbench 是否变慢,客户端和 Agent编排可以用同一脱敏 correlation 继续定位,但监控本身不替代业务功能闭环。直接探针、synthetic check、Prometheus histogram、RUM field data 和服务端 request metric 分属不同 metric family;它们可以在同一 dashboard 中并列展示,不能用一个 family 的结果裁判或覆盖另一个 family 的结果。
为降低 D601 v0.3 Workbench 高频读路径对远端 durable Postgres 的重复访问压力,`hwlab-v03` namespace 内可以部署 Workbench 专用的 Redis 派生读缓存。该缓存只服务 `hwlab-workbench-runtime` 的 session summary、terminal turn snapshot 和 terminal trace page 等可重建快照;Postgres durable projection 仍是唯一事实源,Redis 命中只影响读路径耗时、`cacheStatus` 诊断和 DB query avoided 指标,不改变 lifecycle、final response、权限或 projection authority。
相关运维必须按 UniDesk YAML-first ops 设计:scrape target、recording rule、alert rule、dashboard summary、Prometheus 查询 endpoint、采样/保留/阈值和 D601 node/lane 归属都进入 UniDesk owning YAML;受控 UniDesk CLI 只负责读取 YAML、校验结构、渲染计划、apply/status/summary,并通过共享 ops helper 执行。运行面 Kubernetes 对象、Prometheus target 状态和 Grafana/Prometheus 查询结果只能作为观测对象,不得反向成为配置 source of truth。
### 2.2 范围内
@@ -44,6 +46,7 @@ Workbench性能负责把 HWLAB Cloud Web 工作台中用户直接感知的等待
- 切换 session 标签时,第一个用户可见消息或工具出现的时间,以及该 session 所需主数据、trace、turn 状态全部加载完成的时间。
- 用户首屏打开 Workbench 时,第一个可操作/可读内容出现时间,以及工作台关键数据全部加载完成时间。
- Workbench REST、SSE、trace pagination、turn snapshot、API proxy、AgentRun adapter 操作的常规 RED 指标。
- `hwlab-v03` namespace-local Workbench Redis 派生读缓存的命中、miss、stale、unavailable、operation duration、payload bytes 和 DB query avoided 指标。
- 运行中 Code Agent turn 的无响应空闲时间、最近活动时间和投影刷新活性口径;该口径只衡量“多久没有新事实或可见进展”,不把 turn 总运行时长作为前端超时。
- 前端 RUM 与后端 Prometheus 指标的关联键、脱敏边界、低基数 label、histogram bucket、recording rule 和低样本告警边界。
- 用户可见错误诊断中的 OTel `trace_id` 与性能观测的关联边界:trace id 可以进入错误诊断、日志、span 和受控 debug payload,不进入 Prometheus label、RUM 默认维度或 `/performance` 默认表格。
@@ -60,6 +63,7 @@ Workbench性能负责把 HWLAB Cloud Web 工作台中用户直接感知的等待
- 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。
## 3. 术语表
@@ -86,6 +90,9 @@ Workbench性能负责把 HWLAB Cloud Web 工作台中用户直接感知的等待
| SLO | 面向运维治理的服务目标口径,由 metric family、统计窗口、最低样本、持续时间、阈值、严重级别和处置入口组成;具体数值以 UniDesk owning YAML 为准。 |
| 告警准入 | 指一个指标进入内部告警前必须满足的可信度条件,包括样本数量、freshness、窗口持续性、sourceFamily 和采集健康;低样本或暂无数据默认不能触发性能慢路径告警。 |
| 性能监控工作台 | Cloud Web `/performance` 中面向管理员和值守人员的 dashboard 视图,用概览卡、趋势、分布、排行和表格 drill-down 展示 Workbench/RUM/API/Long Task 性能健康。 |
| Workbench Redis派生读缓存 | `hwlab-v03` namespace 内服务 `hwlab-workbench-runtime` 的可丢弃 Redis 缓存,只保存从 durable Workbench projection 派生出的短 TTL 读快照;它不是状态源、权限源或 lifecycle authority。 |
| cacheStatus | Workbench read API 和性能观测中的缓存诊断状态,至少区分 `hit``miss``stale``unavailable`;它只解释读路径性能,不参与业务状态判断。 |
| dbQueryAvoided | 因派生读缓存命中而避免的一次 durable read model DB 查询计数;它是性能指标,不表示业务事实变化。 |
| 低基数 label | Prometheus label 只能取有限稳定集合,例如 route template、journey、phase、eventKind、status,不包含 traceId、sessionId、runId 或用户输入。 |
| 诊断 trace_id | 用户可见错误诊断中的 OTel trace id,用于跳转 trace backend 和关联日志/span;它是高基数排障标识,只能进入 diagnostic、日志、span attribute、exemplar 或受控 debug payload,不得作为 Prometheus/RUM 默认聚合维度。 |
| YAML-first UniDesk ops | UniDesk 自有运维事实先进入 YAML,再由受控 CLI 渲染、校验和下发;运行面对象只作为观测面,不反推配置真相。 |
@@ -127,11 +134,14 @@ flowchart LR
SUM["/v1/web-performance/summary"]
TRACE[Trace Store]
READ[Workbench Read Model]
CACHE[(hwlab-v03 Redis derived cache)]
MET[Prometheus Metrics 9100]
ROUTE --> READ
ROUTE --> TRACE
ROUTE --> OBS
ROUTE --> MET
READ <--> CACHE
CACHE --> MET
PERF --> OBS
OBS --> AGG
AGG --> SUM
@@ -171,8 +181,10 @@ flowchart TD
A[用户动作或页面生命周期起点] --> B[clientJourneyId]
B --> C[REST request / SSE cursor / route activation]
C --> D[Cloud API phase timing]
C --> R[cache hit/miss/stale/unavailable]
C --> E[AgentRun event source metadata]
D --> F[Trace/read model projection]
R --> M[server request observation]
E --> F
F --> G[SSE event or REST page received]
G --> H[Workbench reducer applies authoritative state]
@@ -182,11 +194,11 @@ flowchart TD
K --> L[RUM event batch]
D --> M[server request observation]
L --> N[/v1/web-performance ingest]
M --> H[Authority observation history]
N --> H
H --> W[Windowed summary/read model]
M --> OH[Authority observation history]
N --> OH
OH --> W[Windowed summary/read model]
W --> DASH[/performance dashboard]
H --> P[Prometheus metrics export]
OH --> P[Prometheus metrics export]
P --> O[PromQL / recording rules / alerts]
```
@@ -286,6 +298,7 @@ session 切换必须分别记录 `first_visible` 和 `full_load`。first visible
| PJ2026-0106050510 | 窗口质量 | 本规格 6.10 | 时间窗口、样本数、freshness、aggregationKind、approximation 和 lowSample 语义 | 运维监控、API契约 | dashboard、TopN、drill-down |
| 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 高频读降尾延迟 |
## 6. 原子需求
@@ -327,6 +340,8 @@ HWLAB AgentRun adapter、trace store、Workbench SSE 和 Cloud Web 应保留足
Workbench性能应至少提供以下 Prometheus 指标族:`hwlab_workbench_journey_duration_seconds``hwlab_workbench_backend_event_visible_latency_seconds``hwlab_workbench_event_phase_duration_seconds``hwlab_workbench_realtime_events_total``hwlab_workbench_sse_connections``hwlab_http_request_duration_seconds``hwlab_http_requests_total`
Workbench Redis 派生读缓存接入后,还应提供低基数缓存指标,至少包括 `workbench_cache_requests_total``workbench_cache_hit_ratio``workbench_cache_operation_duration_seconds``workbench_cache_payload_bytes``workbench_cache_stale_total``workbench_cache_unavailable_total``workbench_db_query_avoided_total`。这些指标只按 `node``lane``service``cache_key_class``route``status` 等低基数字段聚合,不包含完整 cache key、actor id、session id、trace id、prompt、stdout/stderr 或敏感值。
指标命名、单位和 label 必须符合 Prometheus 常规实践:duration 使用秒,counter 使用 `_total` 后缀,label 只允许 `node``lane``service``route``journey``phase``event_kind``status``method``status_class``source` 等有限枚举。禁止把 traceId、sessionId、conversationId、runId、commandId、prompt、assistant 正文、tool 参数、stdout/stderr、Secret、token、DSN 或用户个人信息放入 label。
API 响应可使用 `Server-Timing` 暴露后端 phase 摘要,但该 header 只能包含阶段名和 duration,不包含敏感值或高基数 ID。
@@ -439,8 +454,22 @@ Workbench 性能 SLO 只能基于稳定 metric family、明确窗口、足够样
每次关闭 Workbench 性能实现或维护 issue 时,closeout 必须说明是否影响 SLO 或告警准入:若影响,回写对应 YAML/source branch、SPEC 引用版本、D601 v0.3 public `/performance` 验收、负向分叉扫描和 rollout 证据;若不影响,说明 `SLO impact=none` 或等价结论。历史数据和当前窗口必须分开判断,不能用全量历史混合近期修复效果,也不能用短窗口低样本替代稳定窗口结论。
### 6.13 OPS-WBPERF-REQ-013 Workbench Redis 派生读缓存
| 编号 | 短名 | 主责模块 | 关联模块 |
| --- | --- | --- | --- |
| 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) |
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。
缓存配置必须 YAML-first。owning YAML 至少声明 enabled、namespace、serviceName、image、resource request/limit、memory policy、TTL、max key size、max payload bytes、connection timeout、operation timeout、metrics labels 和 disable switch;具体数值以 YAML 为准,SPEC 不硬编码阈值。Redis 不可用时不得让 `/health/live` 失败,也不得让 Cloud API、Web、web-probe 或前端直接连接 Redis`hwlab-workbench-runtime` 应暴露 `cacheStatus=unavailable` 或等价诊断,并走受控 DB read 或明确 degraded。
缓存响应和观测必须可解释。命中响应应能暴露 `cacheStatus``cacheAgeMs`、projection revision/seq 或等价低基数字段;OTel span 可以记录 cacheStatus、cacheAgeMs、cacheKeyClass、projectionSeq、dbQueryAvoided、dbQueryDuration 和 payloadBytes,但不得记录完整 cache key、actor id、session id、trace id、prompt、assistant 正文、tool 参数、stdout/stderr、Secret、token 或 DSN。`/performance` 可以展示缓存命中率、DB avoided、缓存不可用和 sessions API P95 变化,但这些指标不得成为 lifecycle、final response、权限或业务状态的判断条件。
缓存验收必须包含负向边界。实现不得用 Redis stale 值做 read-side lifecycle 推理、final response 推断、session repair、GET read-through repair 或多来源仲裁;不得用缓存掩盖 SQL/schema/nullability bug、`row_scan_failed` 或 durable projection blocker。若不能精确失效,TTL 与 user-visible freshness SLO 必须匹配,并通过 `cacheAgeMs` 和 projection revision 让用户可见新鲜度可诊断。
## 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)。该类 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-0104010803 Workbench唯一投影](PJ2026-0104010803-workbench-unique-projection.md) 和 [PJ2026-010403 API契约](PJ2026-010403-api-contract.md) 的引用关系,再进入后续实现。
后续实现 issue 或 PR 收口时必须回写:使用的 SPEC 编号和实现引用版本、触达的源码文件头部标注情况、Prometheus 指标/label 审查结果、D601 v0.3 public origin 的原入口验证结果,以及是否需要继续修订本规格。