diff --git a/project-management/PJ2026-01/specs/PJ2026-010401-web-workbench.md b/project-management/PJ2026-01/specs/PJ2026-010401-web-workbench.md index 756dceef..d5aa8b86 100644 --- a/project-management/PJ2026-01/specs/PJ2026-010401-web-workbench.md +++ b/project-management/PJ2026-01/specs/PJ2026-010401-web-workbench.md @@ -19,7 +19,7 @@ | 短名 | Web工作台 | | 层级 | L2 课题 | | 状态 | 已生效 | -| 实现引用版本 | draft-2026-06-18-r1; PJ2026-0104010803 唯一投影 draft-2026-06-18-p0-unique-projection | +| 实现引用版本 | draft-2026-06-18-r1; PJ2026-0104010803 唯一投影 draft-2026-06-18-p0-zero-repair | | 需求规格模板 | [ISO/IEC/IEEE 29148 需求规格模板](../../templates/iso-iec-ieee-29148-requirements-spec-template.md) | | 上级规格 | [PJ2026-0104 客户端](PJ2026-0104-client.md) | | 规格治理索引 | [规格治理](spec-governance.md) | @@ -77,6 +77,7 @@ Web工作台负责 HWLAB 登录后的浏览器主入口,使用户能够在同 | Workbench Server State | Web 工作台从 REST snapshot、SSE event、trace page 和 submit optimistic 归一化得到的服务端事实缓存。 | | Timeline Projection | 只从 messages、parts、turn status 和 trace events 派生用户可见 timeline row 的渲染投影,不发请求也不写事实状态。 | | 唯一投影 | [PJ2026-0104010803 Workbench唯一投影](PJ2026-0104010803-workbench-unique-projection.md) 定义的状态链路:AgentRun 执行事实只经 HWLAB projection writer/finalizer 写入 durable Workbench facts,REST、SSE、CLI、fake-server 和 Web 前端只消费该投影。 | +| 0repair | Web 工作台在首次进入、刷新、deep link、session 切换、SSE 重连和 trace 补洞时必须按同一 authority 自然收敛;不得通过 reload、切走再切回、`sessionRepair`、`realignFreshSession`、workspace selection repair、active tab repair、GET read-through、localStorage truth 或测试 helper 自动点击,把已经分裂的 route/session/message/trace 状态补成看起来正确。 | | 初发刷新一致性 | 同一 prompt 在初次发送、切换 session 后回到该 session、刷新页面和 SSE 重连后,都以同一 userMessageId、assistantMessageId、turnId 和 traceId 还原同一语义结果。 | | 浏览器回归验证 | 使用 Playwright 在真实浏览器中验证 Workbench 用户可见行为、状态投影和 Trace 阅读正确性的前端端到端单元测试;测试过程使用本地 mock server,不依赖实时 Cloud API、AgentRun、HWPOD 或其他运行组件。 | | 真实采集 fixture | 从目标 node/lane 的受控样本采集 Workbench REST、SSE、conversation、session、turn 和 trace 响应,经稳定伪 ID 映射与敏感字段脱敏后,用于浏览器回归验证的数据集。 | @@ -132,7 +133,7 @@ flowchart TD TD --> UI ``` -目标数据流必须保证:提交请求只负责 admission 和稳定标识;实时事件、REST snapshot、trace pagination、页面刷新 hydrate 和 session 切换补洞全部进入同一个 reducer;晚到响应只能更新其所属 session、turn 或 trace cache,不能改变当前 active conversation。 +目标数据流必须保证:提交请求只负责 admission 和稳定标识;实时事件、REST snapshot、trace pagination、页面刷新 hydrate 和 session-bound gap-fill 全部进入同一个 reducer;晚到响应只能更新其所属 session、turn 或 trace cache,不能改变当前 active session、active route、当前消息区或 composer。 ### 5.2 目标架构图 @@ -206,7 +207,7 @@ flowchart LR [PJ2026-0104010803 Workbench唯一投影](PJ2026-0104010803-workbench-unique-projection.md) 是 Workbench 状态投影的唯一专项规格,集中定义 durable facts schema、`WorkbenchProjectionWriter`、`WorkbenchProjectionFinalizer`、`WorkbenchFactsStore`、`WorkbenchReadModel`、terminal commit、cloud-api 重启恢复、GET 纯读和代码引用规则。 -Web工作台在本规格中只保留前端消费边界:Cloud Web reducer、selectors、session rail、timeline、composer 和 Trace detail 只能消费该专项定义的 durable projection;SSE 只是 projection commit 后的通知和加速;fake-server fixture 只重放同一 REST/SSE 合同。详细架构图、数据流图和关键时序图以专项规格为准,本文不再维护第二份投影架构正文。 +Web工作台在本规格中只保留前端消费边界:Cloud Web reducer、selectors、session rail、timeline、composer 和 Trace detail 只能消费该专项定义的 durable projection;SSE 只是 projection commit 后的通知和加速;fake-server fixture 只重放同一 REST/SSE 合同。详细架构图、数据流图、关键时序图和 0repair 约束以专项规格为准,本文不再维护第二份投影架构正文。 ## 6. 原子需求 @@ -238,6 +239,8 @@ Web工作台必须使用显式 Agent session:无 session 时先让用户创建 会话列表、当前消息头、composer 主按钮和运行态动效必须先确定唯一权威 API,再由 Web 展示该 API 的结果;不得让 workspace selected conversation、snapshot、stub、localStorage、message 派生状态、trace 快照或浏览器临时缓存与权威 API 并列竞争、互相覆盖或按失败路径 fallback 成另一套数据源。已经定下来的 authority 不变量如下:浏览器登录态只作为请求 transport;资源归属、project 可见性和权限由后端从当前 Web session/AuthPrincipal 判定;session rail 会话集合的主入口是 `/v1/workbench/sessions`,当前 session 消息本体的主入口是 `/v1/workbench/sessions/{sessionId}/messages`,session metadata 的主入口是 `/v1/workbench/sessions/{sessionId}`,turn 状态的主入口是 `TurnSnapshot`,Trace 阅读状态的主入口是 `TraceEventPage`。`projectId`、`workspaceId` 和 `conversationId` 可以作为后端返回的上下文字段、显式筛选字段或迁移期 metadata,但不得成为前端鉴权、资源可见性、active session 或 deep link 的 authority。深链恢复、刷新、从其他 session 切回和 route watcher 应走同一 session detail/message page 加显式 select/update 路径,不得先用 workspace selected snapshot、列表摘要或空 stub 覆盖当前 `messages`,再等待另一路请求补齐。 +active session 只能由路由中的 sessionId 或用户显式选择产生。REST detail、session list、workspace summary、SSE event、trace page 或 turn snapshot 晚到时,只能更新其声明 `sessionId` 对应的 server-state bucket;不得重新选择 session、替换 URL、覆盖当前消息区、改变 composer 或把另一个 session 的 running/terminal 状态投射到当前页面。若 `routeSessionId`、`activeSessionId`、`activeConversationId`、message session 或 trace session 不一致,Web 必须暴露 authority mismatch/blocker 并让测试失败;不得通过 `sessionRepair`、`realignFreshSession`、reload、切走再切回或测试 helper 自动点击修正后判通过。 + 用户切换 session 标签、通过深链进入 session 或从其他 session 切回时,若当前主工作区的 session detail/message page 尚未返回并应用,Web 工作台必须在主任务区显示明确的加载中转圈或等价 loading state。该状态表示已有会话正在加载,不等同于 Code Agent 已经加载完但尚未产生第一条可读消息的“思考中...”。Web 不得在主工作区尚未就绪时显示空对话、空 Code Agent 卡片、空 Trace 面板或静默留白,使用户无法判断切换是否生效。 当前 selected session 若需要出现在列表中,必须由 session list API 在显式 `includeSessionId` 或等价稳定业务 id 参数下返回,不得由后端隐藏读取 Web workspace selected 状态实现。Workspace API 只提供工作台选择、composer 配置和稳定业务 id,不作为 session 消息本体 authority;列表 API 只提供 rail 排序和摘要,不作为当前消息面板 authority。Web 只能把 route、用户显式选择或后端返回的稳定 session/turn/trace id 作为权威 API 的显式参数,不得把前端拼接出的 status、final response、markdown、running 动效或 stub 传回后端变成事实。Web 在权威 API 失败时只能保留上一份成功结果或显示未加载/错误态,不得从 workspace selected snapshot、stub 或本地缓存拼出单条 session tab、running 状态或 final response。运行中的 turn 必须同时反映在主任务区和对应 session tab;已进入终态的 turn 不得继续以 `Code Agent 处理中`、running 动效或旧 snapshot 文案呈现。 @@ -328,6 +331,8 @@ OpenCode 的参照边界是职责结构,不是技术栈照搬。可借鉴的 状态投影正确性必须能被独立浏览器回归验证覆盖。测试应在同一 Web 构建产物上使用 mock server 重放真实采集 fixture,断言 session rail、主 timeline、workspace card、composer、message card 和 trace detail 在 session 切换、刷新页面、SSE 断线重连、REST 补洞和 trace 分页补拉后保持同一组 sessionId、turnId、traceId、messageId 与终态语义;conversationId/projectId/workspaceId 只可作为 metadata 被展示或调试,不得改变通过条件。测试不得依赖 live AgentRun、Cloud API、HWPOD、数据库或 Kubernetes 状态作为通过条件。 +浏览器回归验证必须先覆盖 0repair 红灯:fresh context 直达 session、普通点击切换 session、A session 延迟 detail/turn/trace/SSE 晚到、B session active、无用户新消息时,都不得让 A 的 user/agent 消息、running 状态或 trace 出现在 B。Playwright 和 web-probe 只能观察、连续截图和断言;不得用 reload、切换 session、`sessionRepair`、`realignFreshSession` 或 localStorage 修改把页面修正后再判通过。 + ### 6.9 CLIENT-WB-REQ-009 前端模块 | 编号 | 短名 | 主责模块 | 关联模块 | diff --git a/project-management/PJ2026-01/specs/PJ2026-0104010803-workbench-unique-projection.md b/project-management/PJ2026-01/specs/PJ2026-0104010803-workbench-unique-projection.md index d5dfda75..5f97b418 100644 --- a/project-management/PJ2026-01/specs/PJ2026-0104010803-workbench-unique-projection.md +++ b/project-management/PJ2026-01/specs/PJ2026-0104010803-workbench-unique-projection.md @@ -19,7 +19,7 @@ | 短名 | Workbench唯一投影 | | 层级 | L4 专项规格切片 | | 状态 | 已生效 | -| 实现引用版本 | draft-2026-06-18-p0-unique-projection | +| 实现引用版本 | draft-2026-06-18-p0-zero-repair | | 需求规格模板 | [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) | @@ -33,7 +33,7 @@ Workbench唯一投影负责把 AgentRun 执行事实收敛成 HWLAB 自有的 durable Workbench facts,使 Web、CLI、REST、SSE、fake-server 和浏览器回归都消费同一份可恢复、可分页、可诊断的用户态会话事实。 -本专项的目标状态是:AgentRun run、command、event 和 result 只作为执行事实输入;HWLAB 只有 `WorkbenchProjectionWriter`、`WorkbenchProjectionFinalizer` 写入 Workbench facts;所有 `GET /v1/workbench/*` 和兼容读路径都只通过 `WorkbenchReadModel` 读取,不在读取时调用 AgentRun、Code Agent manager、trace polling、result polling 或 workspace repair 推进事实。 +本专项的目标状态是:AgentRun run、command、event 和 result 只作为执行事实输入;HWLAB 只有 `WorkbenchProjectionWriter`、`WorkbenchProjectionFinalizer` 写入 Workbench facts;所有 `GET /v1/workbench/*` 和兼容读路径都只通过 `WorkbenchReadModel` 读取,不在读取时调用 AgentRun、Code Agent manager、trace polling、result polling 或 workspace repair 推进事实。Workbench 必须满足 0repair:页面、GET、SSE、fake-server 和 web-probe 都不得通过 reload、切换 session、`sessionRepair`、`realignFreshSession`、localStorage truth 或 read-through repair 把已经分裂的 route/session/message/trace 状态补成看起来正确。 ### 2.2 范围内 @@ -61,9 +61,10 @@ Workbench唯一投影负责把 AgentRun 执行事实收敛成 HWLAB 自有的 du | 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 到达、后台恢复或显式 repair mutation 触发,但所有入口调用同一 finalization 逻辑。 | +| WorkbenchProjectionFinalizer | 以 checkpoint 为驱动的幂等追平组件;可由 submit 后、event 到达、后台恢复或显式 checkpoint replay/reprojection 触发,但所有入口调用同一 finalization 逻辑。 | | WorkbenchFactsStore | durable facts 存储接口,负责幂等 upsert、terminal commit、checkpoint、diagnostic、分页查询和 owner visibility 过滤所需的持久化读写。 | | WorkbenchReadModel | 唯一读取 Workbench facts 并组装 session rail、session detail、message page、turn snapshot、trace event page 和 projection diagnostics 的读模型。 | +| 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。 | | projectedSeq | HWLAB trace event 和 projection commit 的单调序列,用于 REST 分页、SSE replay、fake-server fixture 和审计;不得与 AgentRun `sourceSeq` 混用。 | @@ -72,6 +73,7 @@ Workbench唯一投影负责把 AgentRun 执行事实收敛成 HWLAB 自有的 du | projection diagnostic | 暴露 projection lag、blocker、lastProjectedSeq、sourceRunId、sourceCommandId、updatedAt 和恢复状态的可诊断字段。 | | 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 推进事实;本专项禁止该模式。 | +| 事后 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 补成看起来正确;本专项禁止该模式。 | ## 4. 系统边界和接口 @@ -80,7 +82,7 @@ Workbench唯一投影负责把 AgentRun 执行事实收敛成 HWLAB 自有的 du | 边界项 | 内容 | | --- | --- | | 外部使用者 | Cloud Web、HWLAB CLI、Cloud API route、AgentRun adapter、fake-server 回归和运维诊断。 | -| 外部输入 | AgentRun run/command/event/result facts、turn admission metadata、owner/session visibility、显式 repair mutation、REST/SSE 查询参数。 | +| 外部输入 | 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、projection diagnostics、SSE events 和 compat wrapper envelope。 | | 用户接口 | Cloud Web `/workbench`、同源 `/v1/workbench/*` REST/SSE、HWLAB CLI 的同源 Workbench/API 入口。 | @@ -92,7 +94,7 @@ Workbench唯一投影负责把 AgentRun 执行事实收敛成 HWLAB 自有的 du | --- | --- | --- | --- | --- | --- | | 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 驱动追平、重启恢复和显式 repair mutation 的同一幂等入口 | FactsStore、AgentRun facts source | Writer、diagnostics | +| 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,不补写事实 | Web工作台、API契约 | session rail、timeline、composer、trace detail | @@ -166,7 +168,7 @@ flowchart TD STREAM --> RED ``` -数据流必须保证:admission 只生成稳定标识和初始 facts;AgentRun facts 必须先归一化,再由 writer/finalizer 进入 projection commit;REST snapshot 和 SSE event 只能重放 durable facts;diagnostic 明确表达 lag/blocker,不能让读取路径隐式修复事实。 +数据流必须保证:admission 只生成稳定标识和初始 facts;AgentRun facts 必须先归一化,再由 writer/finalizer 进入 projection commit;REST snapshot 和 SSE event 只能重放 durable facts;diagnostic 明确表达 lag/blocker,不能让读取路径、页面路径或测试路径隐式修复事实。 ### 5.3 terminal commit 关键时序图 @@ -248,7 +250,7 @@ Facts store 必须支持幂等 upsert、terminal commit、projection checkpoint 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、重启恢复或 repair mutation 不得创建重复 assistant message、重复 terminal event 或冲突 session summary。 +Writer 必须使用稳定幂等键写入 messageId、partId、turnId、traceId、sourceRunId、sourceCommandId、sourceSeq/sourceEventId 和 projectedSeq。重复 event、重放 result、重启恢复或 checkpoint replay/reprojection 不得创建重复 assistant message、重复 terminal event 或冲突 session summary。 ### 6.3 WB-PROJ-REQ-003 projection finalizer @@ -256,7 +258,7 @@ Writer 必须使用稳定幂等键写入 messageId、partId、turnId、traceId | --- | --- | --- | --- | | 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 后、后台恢复和显式 repair mutation 可以触发 finalizer,但这些入口必须调用同一幂等 finalization 逻辑。 +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。 @@ -288,6 +290,8 @@ WorkbenchReadModel 应作为唯一读模型,从 durable facts 组装 session l 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。 +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。 + SSE 只作为 projection commit 后的通知和加速,不是事实来源。SSE 断线、丢事件或重连后,Web 只能通过同一 REST snapshot 与 trace page 补洞。running trace 在 terminal 前 `hasMore=false` 只表示当前页追平,不得设置永久 `fullTraceLoaded=true`。 ### 6.7 WB-PROJ-REQ-007 regression and validation @@ -300,6 +304,8 @@ Workbench唯一投影必须有后端和浏览器两层回归:后端用 Workben fake-server Playwright 应使用目标 node/lane 的真实采集脱敏 fixture,覆盖 session 切换、刷新、SSE 断线重连、REST 补洞、trace 分页和 terminal final response。D601 v0.3 public origin web-probe 应验证不切 session、不刷新页面、fresh deep link 和多观察者场景都通过同一 read model 收敛。 +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 自动点击修正页面后再判通过。 + ### 6.8 WB-PROJ-REQ-008 code reference rule | 编号 | 短名 | 主责模块 | 关联模块 | @@ -309,7 +315,7 @@ fake-server Playwright 应使用目标 node/lane 的真实采集脱敏 fixture 本专项范围内新增或重构的核心源码文件,文件头部必须标注遵循的 SPEC 编号、短名和实现引用版本,例如: ```text -SPEC: PJ2026-0104010803 Workbench唯一投影 draft-2026-06-18-p0-unique-projection +SPEC: PJ2026-0104010803 Workbench唯一投影 draft-2026-06-18-p0-zero-repair ``` 同一文件同时承载 API契约、HWLAB接入、Web工作台或 Agent编排职责时,应在同一头部追加对应 SPEC 编号与实现引用版本。实现文件不得只写 issue 编号、`latest` 或 `current`。自动生成文件、第三方 vendored 文件、纯配置、锁文件和无法承载注释头的二进制产物可例外,但对应生成器、渲染器或配置入口必须能追溯到本 SPEC。