diff --git a/project-management/PJ2026-01/specs/PJ2026-010205-hwlab-dispatch.md b/project-management/PJ2026-01/specs/PJ2026-010205-hwlab-dispatch.md index c21b04a9..95bfa365 100644 --- a/project-management/PJ2026-01/specs/PJ2026-010205-hwlab-dispatch.md +++ b/project-management/PJ2026-01/specs/PJ2026-010205-hwlab-dispatch.md @@ -19,6 +19,7 @@ | 短名 | HWLAB接入 | | 层级 | L2 课题 | | 状态 | 已生效 | +| 实现引用版本 | draft-2026-06-17-r0 | | 需求规格模板 | [ISO/IEC/IEEE 29148 需求规格模板](../../templates/iso-iec-ieee-29148-requirements-spec-template.md) | | 上级规格 | [PJ2026-0102 Agent编排](PJ2026-0102-agent-orchestration.md) | | 规格治理索引 | [规格治理](spec-governance.md) | @@ -115,6 +116,10 @@ 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。 + +同一次用户提交、steer 或 retry 应在 admission 时生成稳定 turnId、traceId、userMessageId 和 assistantMessageId。初发 UI 可以基于这些标识做 optimistic 展示;AgentRun events/result 到达后必须用同 ID 确认或更新对应 message/part/turn/trace,而不是创建另一条会话消息。页面刷新、session 切换、SSE 重连和 CLI inspect/result 都必须恢复同一组标识和同一语义结果。 + ### 6.4 AR-HWLAB-REQ-004 HWPOD Runtime Context | 编号 | 短名 | 主责模块 | 关联模块 | @@ -135,6 +140,8 @@ HWLAB接入应使用 AgentRun durable cancel、SessionRef、thread continuation 取消必须幂等并写入 command/run 状态与 event;pending command 被取消后不得再创建 runner Job。会话续跑只认标准 SessionRef/threadId;无法续接时必须返回明确失败事实,不能拼接历史 prompt 或伪造继续会话。 +取消、Steer、retry 和 follow-up 必须绑定明确 conversation/session/turn,不得通过“最新 session”、workspace selected、runner latest 或 trace polling 推断目标。命令输入区的发送、取消和 Steer 状态应来自 TurnSnapshot 与 message projection,而不是来自浏览器本地 pending 状态。 + ### 6.6 AR-HWLAB-REQ-006 自然语言单一路由 | 编号 | 短名 | 主责模块 | 关联模块 | 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 844cb7fc..6c3ccf16 100644 --- a/project-management/PJ2026-01/specs/PJ2026-010401-web-workbench.md +++ b/project-management/PJ2026-01/specs/PJ2026-010401-web-workbench.md @@ -19,6 +19,7 @@ | 短名 | Web工作台 | | 层级 | L2 课题 | | 状态 | 已生效 | +| 实现引用版本 | draft-2026-06-17-r0 | | 需求规格模板 | [ISO/IEC/IEEE 29148 需求规格模板](../../templates/iso-iec-ieee-29148-requirements-spec-template.md) | | 上级规格 | [PJ2026-0104 客户端](PJ2026-0104-client.md) | | 规格治理索引 | [规格治理](spec-governance.md) | @@ -70,6 +71,9 @@ Web工作台负责 HWLAB 登录后的浏览器主入口,使用户能够在同 | Trace生命周期展开/折叠 | Code Agent turn 进入运行态时,Web 自动展开对应 Trace阅读视图;turn 进入终态时,Web 自动折叠该 Trace阅读视图,但仍允许用户手动重新打开。 | | 工作态高密度 | 面向持续排障、比较和重复操作的工业化界面密度要求:低圆角、低内边距、正文优先、辅助元信息折叠,避免装饰性卡片和大块留白抢占工作内容。 | | 正式公开入口 | 目标 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 的渲染投影,不发请求也不写事实状态。 | +| 初发刷新一致性 | 同一 prompt 在初次发送、切换 session 后回到该 session、刷新页面和 SSE 重连后,都以同一 userMessageId、assistantMessageId、turnId 和 traceId 还原同一语义结果。 | ## 4. 系统边界和接口 @@ -95,6 +99,73 @@ Web工作台负责 HWLAB 登录后的浏览器主入口,使用户能够在同 | PJ2026-01040105 | 同源体验 | 本规格 6.5 | Web 与 CLI 共享 composer policy、trace renderer 和同源 REST/JSON API 行为 | HWLAB CLI、API契约、Agent编排 | Web/CLI 排障和内测复现 | | PJ2026-01040106 | Trace阅读 | 本规格 6.6 | Code Agent trace 去噪、详情收纳、耗时、正文优先和单一主按钮状态 | Agent编排、API契约、用户管理 | 用户排障和任务继续操作 | | PJ2026-01040107 | 公开入口 | 本规格 6.7 | 正式 Cloud Web public URL、history fallback 和旧入口降级边界 | 平台运维、API契约、用户管理 | 用户访问、Playwright 验收、内测说明 | +| PJ2026-01040108 | 状态投影 | 本规格 6.8 | server-state、reducer、selectors、timeline projection 和初发刷新一致性 | API契约、Agent编排 | Web timeline、session rail、trace detail | +| PJ2026-01040109 | 前端模块 | 本规格 6.9 | API client、event client、server-state、UI state 和组件职责拆分 | API契约、公开入口 | 可维护前端实现 | + +### 5.1 目标数据流程图 + +```mermaid +flowchart TD + U[用户 prompt/steer/retry/cancel] --> C[Composer UI] + C --> A[POST Turn Admission] + A --> O[Optimistic user/assistant message IDs] + A --> T[TurnSnapshot] + A --> E[SSE /workbench/events] + E --> R[Workbench Reducer] + M[GET session messages] --> R + TS[GET turn snapshot] --> R + TE[GET trace events page] --> R + O --> R + R --> S[Workbench Server State] + S --> P[Timeline Projection] + S --> SR[Session Rail Projection] + S --> TD[Trace Detail Projection] + P --> UI[主 timeline] + SR --> UI + TD --> UI +``` + +目标数据流必须保证:提交请求只负责 admission 和稳定标识;实时事件、REST snapshot、trace pagination、页面刷新 hydrate 和 session 切换补洞全部进入同一个 reducer;晚到响应只能更新其所属 session、turn 或 trace cache,不能改变当前 active conversation。 + +### 5.2 目标架构图 + +```mermaid +flowchart LR + subgraph Browser[Cloud Web] + API[WorkbenchApiClient] + EVT[WorkbenchEventClient] + STATE[WorkbenchServerState] + RED[WorkbenchReducer] + SEL[Selectors/Projection] + UI[Session Rail / Timeline / Composer / Trace Detail] + API --> RED + EVT --> RED + RED --> STATE + STATE --> SEL + SEL --> UI + end + subgraph CloudAPI[HWLAB Cloud API] + ROUTE[REST/SSE Routes] + RM[Workbench Read Model] + PROJ[Turn/Message/Trace Projection] + ADAPT[AgentRun Adapter] + end + subgraph AgentRun[AgentRun] + RUN[run/command/runner] + EV[events/result] + end + UI --> API + EVT --> ROUTE + API --> ROUTE + ROUTE --> RM + ROUTE --> PROJ + PROJ --> RM + ADAPT --> PROJ + RUN --> EV + EV --> ADAPT +``` + +Cloud Web 只拥有浏览器交互和投影;Cloud API 拥有 REST/SSE 合同和 read model;Agent编排和 HWLAB接入拥有执行事实映射;公开入口只负责将 Web/API/health 投递到目标 node/lane。 ## 6. 原子需求 @@ -192,6 +263,30 @@ Web工作台的正式浏览器入口必须来自目标 node/lane YAML 声明的 平台运维负责把 YAML 声明的 public URL、FRP、Caddy、TLS 和 health 投递到运行面;Web工作台负责在该入口上完成登录、工作台、导航和错误展示。实现端口可以作为诊断入口暴露给维护者,但不得出现在用户主入口、内测验收入口或客户端默认配置中。 +### 6.8 CLIENT-WB-REQ-008 状态投影 + +| 编号 | 短名 | 主责模块 | 关联模块 | +| --- | --- | --- | --- | +| CLIENT-WB-REQ-008 | 状态投影 | PJ2026-01040108 状态投影 | [PJ2026-010403 API契约](PJ2026-010403-api-contract.md)、[Agent编排](PJ2026-0102-agent-orchestration.md) | + +Web工作台应把 REST snapshot、SSE event、submit optimistic、trace pagination 和 page refresh hydrate 统一归入 Workbench Server State。Server State 应按 sessionId、conversationId、messageId、partId、turnId 和 traceId 归一化保存服务端事实;UI transient state 只保存 route、显式选择、composer draft、scroll、展开状态和临时交互状态。 + +Timeline Projection 只能从 messages、parts、turn status 和 trace events 派生用户可见 rows。Trace detail 只消费 TraceEventPage;session rail 只消费 session list 和 turn summary;composer 只消费当前 route/selected conversation 与明确 running turn。组件、trace polling、submit/cancel 回调不得直接写 messages、final response 或 trace authority。 + +初发刷新一致性是 Web 工作台的硬约束:同一 prompt 从 admission 开始生成稳定 userMessageId、assistantMessageId、turnId 和 traceId;初发 UI 可以 optimistic 展示这些 ID,但刷新、切换 session、SSE 重连和 REST 补洞必须用同 ID 的 durable message、part、turn 和 trace projection 确认。若 trace 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 共同竞争当前消息面板。 + +### 6.9 CLIENT-WB-REQ-009 前端模块 + +| 编号 | 短名 | 主责模块 | 关联模块 | +| --- | --- | --- | --- | +| CLIENT-WB-REQ-009 | 前端模块 | PJ2026-01040109 前端模块 | [PJ2026-010403 API契约](PJ2026-010403-api-contract.md)、[PJ2026-010604 公开入口](PJ2026-010604-public-entry.md) | + +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-010401 Web工作台 draft-2026-06-17-r0; PJ2026-010403 API契约 draft-2026-06-17-r0`,并简述文件职责。实现文件不得只写 issue 编号、`latest` 或 `current` 作为规格引用。 + ## 7. 过程控制 本规格不单独索引过程 issue;跨 L1 的内测、灰度和阶段活动索引统一保留在 [PJ2026-01 HWLAB 总规格](PJ2026-01-HWLAB.md) 的 `7. 过程控制`。 diff --git a/project-management/PJ2026-01/specs/PJ2026-010403-api-contract.md b/project-management/PJ2026-01/specs/PJ2026-010403-api-contract.md index a23924cc..22509073 100644 --- a/project-management/PJ2026-01/specs/PJ2026-010403-api-contract.md +++ b/project-management/PJ2026-01/specs/PJ2026-010403-api-contract.md @@ -19,6 +19,7 @@ | 短名 | API契约 | | 层级 | L2 课题 | | 状态 | 已生效 | +| 实现引用版本 | draft-2026-06-17-r0 | | 需求规格模板 | [ISO/IEC/IEEE 29148 需求规格模板](../../templates/iso-iec-ieee-29148-requirements-spec-template.md) | | 上级规格 | [PJ2026-0104 客户端](PJ2026-0104-client.md) | | 规格治理索引 | [规格治理](spec-governance.md) | @@ -59,6 +60,10 @@ API契约负责定义 Cloud Web、HWLAB CLI 和自动化脚本共同使用的 RE | 业务标识 | sessionId、traceId、runId、commandId、workspaceId、caseId 等用户可继续查询的稳定标识。 | | 错误语义 | HTTP status、错误码、blocker、failureKind、route 和下一步提示组成的可定位失败表达。 | | Conversation detail | `GET /v1/agent/conversations/{conversationId}` 这类按稳定 conversationId 查询当前会话消息和绑定事实的 RESTful detail resource。 | +| TurnSnapshot | 按 turnId 或 traceId 查询一次用户提交/steer/retry/cancel 生命周期、终态、message 指针和执行引用的 RESTful snapshot。 | +| TraceEventPage | 按 traceId 和 cursor/seq 分页查询 trace events 的 RESTful page;只表达 trace 明细,不决定主 timeline 的 final response。 | +| Message/Part | Web 和 CLI 共同渲染会话 timeline 的持久消息事实;message 表达角色、父子关系和终态摘要,part 表达文本、工具、文件、错误、trace 摘要等可组合内容。 | +| EventStream | Cloud Web origin 下的 SSE 实时入口,用于推送 server.connected、session、turn、message、part、trace 和 workspace lifecycle 事件。 | ## 4. 系统边界和接口 @@ -83,6 +88,8 @@ API契约负责定义 Cloud Web、HWLAB CLI 和自动化脚本共同使用的 RE | PJ2026-01040304 | 资源接口 | 本规格 6.4 | workspace、access、provider、HWPOD node-ops、gateway 和性能摘要入口 | 全部业务 L1 | Web、CLI、admin | | PJ2026-01040305 | 错误输出 | 本规格 6.5 | JSON 成功/失败响应、错误码、route/status、脱敏和渐进披露 | 全部业务 L1 | 用户、脚本、排障 | +目标后端模块应至少拆分为 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 到新资源的兼容映射,不拥有第二套业务事实。 + ## 6. 原子需求 ### 6.1 CLIENT-API-REQ-001 同源路由 @@ -127,6 +134,29 @@ Trace resource 必须支持按事件位置继续读取,例如 `sinceSeq` / `cu `POST /v1/agent/chat`、`GET /v1/agent/turns/{traceId}` 和 result 入口可以返回 `traceUrl` 指针,但该指针必须指向 RESTful trace resource。trace resource 可以为了短返回默认裁剪事件,但完整事件补齐、终态 final response、AgentRun run/command identity、错误和脱敏边界仍由同一 trace resource 表达;客户端不得要求用户手动“回放 Trace”才能获得完成态 trace。 +目标 Workbench RESTful API 资源设计如下。旧 `/v1/agent/*` 路径可以作为兼容 wrapper 暂存,但 Web 主路径应逐步收敛到这些资源语义。 + +| 资源 | Method / path | 请求字段 | 响应主体 | 状态码 | 权威边界 | +| --- | --- | --- | --- | --- | --- | +| WorkspaceSelection | `GET /v1/workbench/workspace` | `projectId`, `workspaceId` 可选 | selected ids、workspace revision、composer 配置、public origin 摘要 | 200/401/403 | 只读 selection/config,不返回或修补 message 事实 | +| WorkspaceSelection | `PATCH /v1/workbench/workspace` | 显式 selected project/workspace/conversation ids | 更新后的 selection/config | 200/400/401/403 | 只有显式 mutation 可改变 selection | +| Session list | `GET /v1/workbench/sessions` | `projectId`, `workspaceId`, `cursor`, `limit`, `includeSessionId` | session/conversation rail 摘要 page | 200/401/403 | 列表和排序,不替代 detail | +| Session detail | `GET /v1/workbench/sessions/{sessionId}` | path sessionId | session metadata、当前 conversation 指针 | 200/401/403/404 | session metadata,不拥有 trace events | +| Message page | `GET /v1/workbench/sessions/{sessionId}/messages` | `cursor`, `limit`, `before/after` | message + parts page、next cursor | 200/401/403/404 | 会话 timeline 的 message/part 事实 | +| Conversation detail | `GET /v1/agent/conversations/{conversationId}` | path conversationId | conversation metadata、message page seed、sessionId、threadId、lastTraceId、turn summary | 200/401/403/404 | 当前消息面板权威 detail | +| Turn admission | `POST /v1/workbench/sessions/{sessionId}/turns` | prompt/parts、delivery、workspace/project、client message ids | `202 Accepted` + turnId、traceId、userMessageId、assistantMessageId、status URLs | 202/400/401/403/409/422 | 只表示输入已接收,不表示执行完成 | +| Turn snapshot | `GET /v1/workbench/turns/{turnId}` | path turnId | status、terminal、message ids、traceId、AgentRun refs、failureKind | 200/401/403/404 | turn 状态补洞,不承载 trace events | +| Trace event page | `GET /v1/workbench/traces/{traceId}/events` | `afterSeq/cursor`, `limit` | ordered events、range、hasMore、next cursor | 200/401/403/404/410 | trace 明细分页,不决定主 timeline final response | +| EventStream | `GET /v1/workbench/events` | `projectId`, `workspaceId`, optional session/turn filters | SSE events + heartbeat | 200/401/403 | 实时加速和通知,不替代 REST snapshot | +| Cancel turn | `POST /v1/workbench/turns/{turnId}/cancel` | reason 可选 | updated TurnSnapshot | 200/202/401/403/404/409 | 精确取消目标 turn | +| Steer turn | `POST /v1/workbench/turns/{turnId}/steer` | text/parts、delivery | accepted steer TurnSnapshot 或 continuation id | 202/400/401/403/404/409 | 绑定明确 running turn | +| ProviderProfile | `GET /v1/workbench/provider-profiles` | project/workspace 可选 | profile summary list | 200/401/403 | 配置摘要,不输出 Secret | +| Diagnostic resource | `GET /v1/workbench/diagnostics/{resource}` | resource id/query | redacted health/status summary | 200/401/403/404 | 诊断可见性,不改变业务事实 | + +所有 GET path 必须无业务副作用。需要 repair、finalize、sync 或 migration 时,应由后台 finalizer、显式 mutation 或持久化投影入口执行,不能隐藏在 workspace、conversation、turn 或 trace GET 中。所有分页响应必须包含稳定 cursor 或 seq 边界;所有错误响应必须包含 route、status、code/blocker、redacted actor、target resource 和下一步建议。 + +新增或重构的核心后端文件头部必须标注遵循的 SPEC 编号、短名和实现引用版本,例如 `SPEC: PJ2026-010403 API契约 draft-2026-06-17-r0; PJ2026-010205 HWLAB接入 draft-2026-06-17-r0`,并简述文件职责。实现文件不得只写 issue 编号、`latest` 或 `current` 作为规格引用。 + ### 6.4 CLIENT-API-REQ-004 资源与管理接口 | 编号 | 短名 | 主责模块 | 关联模块 |