Merge pull request #1797 from pikasTech/docs/hwlab-kafka-refresh-authority
Pipelines as Code CI / hwlab-web-probe-sentinel-nc01- Success
Pipelines as Code CI / platform-infra-gitea-nc01- Success
Pipelines as Code CI / unidesk-host- Success

docs: 固化 HWLAB 纯 Kafka 刷新实时交接合同
This commit is contained in:
Lyon
2026-07-12 04:12:44 +08:00
committed by GitHub
+24
View File
@@ -226,6 +226,30 @@ HWLAB 与 AgentRun 协同修复必须按 `docs/reference/agentrun.md` 的职责
HWLAB v0.3 订阅 AgentRun Kafka event 的权威输入是 `agentrun.event.v1`,内存 direct mapper 的权威输出是 `hwlab.event.v1`;三 topic 的 ownership 统一见 `docs/reference/platform-infra.md#kafka-event-bus-boundary``directPublish` 使用固定独立 group 消费 AgentRun event、调用生产 mapper 并直接发布完整 HWLAB envelope`liveKafkaSse` 使用另一个固定 group 的进程级 shared consumer,再向当前 SSE subscriber fanout,同一 Kafka record 不为每个浏览器重复消费。两者不读取数据库、projection inbox/checkpoint/outbox 或 snapshot,不得回写 `agentrun.event.v1`,也不得把 `codex-stdio.raw.v1` 混入 HWLAB product schema。transactional projector、projection outbox relay 和 projection realtime 是三个可独立组合的 capability,关闭时必须保持不启动、不就绪门禁、不参与产品链路。
### 纯 Kafka 页面刷新与实时交接合同
- Workbench 的产品权威链固定为:
- `codex-stdio.raw.v1 -> agentrun.event.v1 -> HWLAB direct mapper -> hwlab.event.v1 retention -> bounded refresh bootstrap -> shared live fanout -> SSE -> Web ingress/reducer`
- 用户输入必须先成为 `agentrun.event.v1` 的正式 `user_message`,再一对一映射为 `hwlab.event.v1` 的正式 user event
- 用户消息、assistant、tool、terminal 和 final 不得另建数据库、HTTP history 或浏览器本地事实源。
- 页面刷新只允许从 retained `hwlab.event.v1` 恢复已授权的 session/trace
- 服务端先建立 shared live handoff 保护,再读取目标分区 end offset 作为 barrier
- barrier 内由有界 retention bootstrap 输出,barrier 后由 shared live fanout 输出;
- overlap 只按 Kafka topic/partition/offset 与稳定 event identity 收敛;
- messageId 必须由正式 trace/item identity 派生,禁止按正文、时间戳、数组位置或 DOM 内容去重与重排。
- refresh bootstrap 是短生命周期读取器:
- 到达 barrier 后必须退出,不得把每个浏览器连接变成新的长期 Kafka consumer
- 实时阶段继续复用进程级 shared consumer/fanout
- 同一 Workbench session 只建立一个产品 EventSource,刷新与重连不得复制业务 subscriber。
- `kafkaRefreshReplay``liveKafkaSse` 是可组合、可独立开关的 capability
- topic、group、扫描预算、等待预算、live buffer 上限和失败策略只从选中 node/lane 的 owning YAML/runtime config 读取;
- replay 与 live frame 必须进入同一 decode、queue、reducer、row model 和 card
- barrier 不可获得、扫描或 buffer 超限、授权 scope 不完整时必须 typed fail-closed,不得回退 projector/read model/snapshot/sync/gap-fill/finalizer、polling 或 HTTP history。
- 关闭此类问题时先用 repo-owned CLI 复用生产 bootstrap/codec/reducer,披露 scanned、matched、applied、barrier、buffered、deduplicated、terminal 与 stable identity
- CLI 通过后,使用 semantic internal WebProbe 在同一已有 session 上执行只刷新、不提交新输入的验收;
- 刷新前后 user/agent identity 和可见顺序必须一致,retention 与产品 SSE envelope 多重集必须精确相等;
- OTel 应只出现 direct publish、shared fanout receive 和 product SSE writeprojector/projection write span 必须为 0。
纯 Kafka 调试分成三个可复用入口,不以临时脚本作为长期路径。AgentRun 使用 `./scripts/agentrun kafka regenerate agentrun --session-id <ses_agentrun_...> --trace-id <trc_...>`,从 stdio Kafka/JSONL 调用生产 reducer,只输出 `agentrun.event.debug.v1` 并明示 partial reconstructionHWLAB 使用 `hwlab-cli kafka regenerate hwlab --from kafka|jsonl --session-id <id> --trace-id <id>` 调用生产 mapper,只输出 `hwlab.event.debug.v1`。原 Workbench 页面的管理员 YAML 调试开关只在显式点击后按当前 traceId 建立唯一 debug group,清空隔离面板并复用生产 reducer/card;正式浏览器验收使用 `web-probe observe command <observer> --type validateWorkbenchKafkaDebugReplay`。typed command 继承 observer 的 YAML `internal|public` origin,不接受 URL/IP 来选择内外网。
产品实时链路的最小关闭证据必须来自一个真实 Workbench turn,并同时证明:AgentRun→HWLAB direct publish 数与 HWLAB shared fanout receive 数一致;产品 SSE 收到 terminal/final responseOTel 覆盖 `hwlab-cloud-api``agentrun-manager``agentrun-runner` 且 error=0projection write/projector span 为 0。单步 debug 关闭证据另需证明 stdio frame→AgentRun debug→HWLAB debug→Workbench applied 的逐级 count、顺序、lineage 和 terminal,不得把 debug topic/group 冒充产品 topic/group。KafkaJS 2.2.4 `TimeoutNegativeWarning` 已由 `pikasTech/unidesk#1704` 跟踪空 pending queue 的 1ms 自循环;它不是数据丢失证据,也不得通过 suppress warning、全局 timer patch 或退回产品 polling 路径掩盖。