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 4c6627d9..001c2c77 100644 --- a/project-management/PJ2026-01/specs/PJ2026-010205-hwlab-dispatch.md +++ b/project-management/PJ2026-01/specs/PJ2026-010205-hwlab-dispatch.md @@ -19,7 +19,7 @@ | 短名 | HWLAB接入 | | 层级 | L2 课题 | | 状态 | 已生效 | -| 实现引用版本 | draft-2026-06-17-r0; PJ2026-0104010803 唯一投影 draft-2026-06-18-p0-unique-projection | +| 实现引用版本 | draft-2026-06-17-r0; PJ2026-0104010803 唯一投影 draft-2026-06-19-p1-agentrun-incremental-cursor | | 需求规格模板 | [ISO/IEC/IEEE 29148 需求规格模板](../../templates/iso-iec-ieee-29148-requirements-spec-template.md) | | 上级规格 | [PJ2026-0102 Agent编排](PJ2026-0102-agent-orchestration.md) | | 规格治理索引 | [规格治理](spec-governance.md) | @@ -121,6 +121,8 @@ HWLAB接入应把 AgentRun result 和 events 投影为 HWLAB 自己的 Turn、Me [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 为准。 +HWLAB 接入消费 AgentRun events 时必须按 Workbench 唯一投影的 durable cursor 执行增量拉取。运行中进度以 `events?afterSeq=` 和 command/window 过滤后的 normalized facts 为主读源;AgentRun `/result` 只用于终态补全或后台归档,不得作为 running turn 的主读源,也不得因为 `/result` 慢或超时阻断 events projection、Workbench trace 进度或 projection state 推进。 + 同一次用户提交、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 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 f09e85a9..4ffc00ce 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-19-p0-projector-resume | +| 实现引用版本 | draft-2026-06-19-p1-agentrun-incremental-cursor | | 需求规格模板 | [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) | @@ -40,6 +40,7 @@ Workbench唯一投影负责把 AgentRun 执行事实收敛成 HWLAB 自有的 du - 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 继续投影的语义。 - cloud-api 进程重启、进程内后台任务丢失、慢任务超过短轮询预算后的 durable finalizer 追平语义。 - `GET /v1/workbench/*` 纯读、`/v1/agent/*` compat wrapper 降级和 projection diagnostics 输出要求。 - Web reducer、CLI renderer、fake-server fixture 和 Playwright 回归对同一 durable projection 的消费规则。 @@ -70,6 +71,8 @@ Workbench唯一投影负责把 AgentRun 执行事实收敛成 HWLAB 自有的 du | 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 和恢复状态的可诊断字段。 | | projection health | 对 projection diagnostic 的只读解释,状态至少区分 `projecting`、`caught-up`、`degraded` 和 `stalled`;它不推进 facts,也不得把 stale projecting 标为 caught-up。 | @@ -246,7 +249,9 @@ Facts schema 至少包含以下事实: | 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 唯一键必须包含 `sourceRunId`、`sourceCommandId` 和对应 `turnId`/`traceId`,或等价的 command-scoped 唯一键。同一 AgentRun run 的不同 command 不得共享 cursor;旧 command 的历史事件不得误投到新 turn。`lastSourceSeq` 表示已经成功投影的来源位置,`sourceLatestSeq` 只表示最近观察到的来源最新位置;二者差值可用于 lag/health 诊断,但不得让读侧推断 terminal。 +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 真相。 @@ -274,6 +279,8 @@ Startup/resume authority 只属于 cloud-api boot/background scheduler。该 sch 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=&limit=`,再按 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 继续推进。 + ### 6.4 WB-PROJ-REQ-004 read model and pure GET | 编号 | 短名 | 主责模块 | 关联模块 | @@ -322,6 +329,8 @@ Workbench唯一投影必须有后端和浏览器两层回归:后端用 Workben 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 断线重连、REST 补洞、trace 分页和 terminal final response。D601 v0.3 public origin web-probe 应验证不切 session、不刷新页面、fresh deep link 和多观察者场景都通过同一 read model 收敛。 @@ -337,7 +346,7 @@ fake-server Playwright 应使用目标 node/lane 的真实采集脱敏 fixture 本专项范围内新增或重构的核心源码文件,文件头部必须标注遵循的 SPEC 编号、短名和实现引用版本,例如: ```text -SPEC: PJ2026-0104010803 Workbench唯一投影 draft-2026-06-19-p0-projector-resume +SPEC: PJ2026-0104010803 Workbench唯一投影 draft-2026-06-19-p1-agentrun-incremental-cursor ``` 同一文件同时承载 API契约、HWLAB接入、Web工作台或 Agent编排职责时,应在同一头部追加对应 SPEC 编号与实现引用版本。实现文件不得只写 issue 编号、`latest` 或 `current`。自动生成文件、第三方 vendored 文件、纯配置、锁文件和无法承载注释头的二进制产物可例外,但对应生成器、渲染器或配置入口必须能追溯到本 SPEC。