Files
2026-07-19 19:06:56 +02:00

184 lines
10 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
name: unidesk-kafka
description: UniDesk Kafka 调试与事件链校对技能,覆盖 platform-infra Kafka 状态、topic/offset/group、codex stdio、AgentRun/HWLAB 事件映射、debug topic、离线 regenerate、隔离 replay、SSE/reducer 对账和事件丢失分层定位。用户提到 Kafka、topic、offset、consumer lag、Kafka replay/重放、离线重放、stdio event、agentrun.event、hwlab.event、事件丢失或要求用 CLI 校对事件链时使用。
---
# UniDesk Kafka 调试与重放
## 核心边界
- Kafka 运行事实由 `config/platform-infra/kafka.yaml` 与目标运行面共同拥有。
- 产品链路 topic 固定只读调查:
- `codex-stdio.raw.v1`
- `agentrun.event.v1`
- `hwlab.event.v1`
- 调试重建只能写隔离 topic
- `agentrun.event.debug.v1`
- `hwlab.event.debug.v1`
- replay/regenerate 不得向产品 topic 追加事件,不得重置产品 consumer group,不得把 debug group 冒充产品消费证据。
- 同一个全局输入 topic 到同一个全局输出 topic 的 direct projector
- 跨 lane 实例必须使用同一个 consumer group
- 各 lane 面向自身客户端的 SSE fanout 必须使用彼此独立的 consumer group
- 禁止用 lane 专属 direct-projector group 重复消费全局输入并向全局输出写入同一事件。
- 优先使用应用生产 reducer/mapper 的 regenerate CLI;平台 `kafka tail` 只返回 hash/bytes,不能证明 payload 语义。
- 调查结论必须区分:
- 源 stdio 未产生;
- stdio→AgentRun reducer 丢失或降维;
- AgentRun durable event→Kafka producer 丢失;
- AgentRun→HWLAB mapper 丢失;
- Kafka→SSE/reducer/read model 丢失或滞后。
- 版本、commit、schema/provenance 漂移只能作为 `warning`,不得阻塞用户业务或覆盖 durable terminal authority。
## Kafka-only 第二权威审计
- 声明产品链路为 Kafka-only 前,必须同时审计事件入口、终态来源和配置来源;SSE 已连接或收到一个 topic event 不能单独证明通过。
- 使用一次有界源码检索覆盖应用、renderer 和 owning YAML,再对命中做语义分类:
```bash
rg -n -S \
'(/events|/result|waitForTerminal|projectTerminal|runnerTrace|snapshot|terminalAuthority|POLL_INTERVAL|TERMINAL_TIMEOUT)' \
<workbench-source-path> <renderer-source-path> <owning-yaml-path>
```
- 允许的路径:
- 提交接纳与 cancel 使用有界 `POST`,只返回 session/trace/run/command identity 和接纳状态;
- 非 UI 诊断读取 result/snapshot 时,必须与产品 reducer 隔离,不能写回消息、Trace 或 terminal 状态。
- 禁止的第二权威:
- 轮询 AgentRun `/events` 或 `/result` 后补 UI event
- 从 `runnerTrace.events`、session/turn snapshot、read model 或 terminal result 合成 assistant、tool、terminal、final
- 把 `agentrun-command-result`、HTTP result、snapshot 或 projection read 声明为 Kafka-only UI terminal authority
- 在 owning YAML、renderer 或进程环境保留仅服务于 result/events polling 的 timeout、interval 或开关。
- 通过判定必须同时满足:
- UI assistant、tool、terminal、final 只由产品 Kafka envelope 经 SSE 和同一 reducer 产生;
- 正式 CLI 只从产品 SSE 路由观察业务 event;
- 运行配置不存在 polling 参数,进程环境不存在对应 polling 变量;
- AgentRun 或 CI/CD 不可用时明确报告 source blocker,不得启用 REST、snapshot、read-model 或 terminal-result fallback。
## 调查顺序
1. 固定 identity:记录 node/lane、business trace、OTel trace、session、run、command 和时间窗口。
2. 查 OTel stdio:统计 `codex_stdio.notification`、`tool_call.started|completed`、assistant delta 和 diff notification。
3. 查 AgentRun durable events:按 seq 分页,精确下钻 tool/diff/terminal event;不得只看默认前 20 条。
4. 查 Kafka control plane:确认 broker、topic ready、end offset 和相关 fixed group lag。
5. 怀疑重复投影时,先按同一 `sourceEventId` 聚合 `hwlab.event.v1`
- 一条 AgentRun durable event 对应多个 HWLAB envelope,且 `source`/producer 不同,直接判为多 projector 重复消费;
- 同一 producer 重复出现时,再调查 offset commit、重试和幂等;
- 上游 `agentrun.event.v1` 的 event id 唯一时,不再重复调查 provider、runner 或前端 reducer。
6. 先执行 `--no-publish`/`--dry-run` regenerate,对照源 frame 数、解析数、产出 event 数、拒绝原因和 lineage。
7. 需要跨 mapper 校对时,才把结果写入 debug topic,再由下一层从 debug topic regenerate;每层保存 count/hash/seq/type/tool identity。
8. 需要浏览器产品 reducer 校对时,使用 Workbench 隔离 debug replay;不得直接操作产品 SSE group。
9. 输出首个发生差异的层级和缺失 identity,不用后层缺失反推前层未产生。
## 受控 CLI
本技能遵循 `Skill(cli-spec)`。
平台状态与只读元数据:
```bash
bun scripts/cli.ts platform-infra kafka status --node NC01
bun scripts/cli.ts platform-infra kafka offsets --node NC01 --topic codex-stdio.raw.v1
bun scripts/cli.ts platform-infra kafka offsets --node NC01 --topic agentrun.event.v1 --group <group>
bun scripts/cli.ts platform-infra kafka tail --node NC01 --topic hwlab.event.v1 --limit 20
```
AgentRun 生产 reducer 重建:
```bash
bun scripts/cli.ts platform-infra kafka replay agentrun \
--node NC01 \
--lane nc01-v02 \
--session-id <ses_agentrun_...> \
--trace-id <trc_...> \
--no-publish \
-o json
```
- 该入口自动进入 YAML 选中的 AgentRun manager Pod
- 使用运行中 commit 自带的正式 `./scripts/agentrun kafka regenerate agentrun`
- 复用生产 reducer
- 同时读取源 topic 的 partition earliest/end offset
- 不要求 host 解析 cluster DNS
- 不创建 port-forward。
- 默认输出紧凑文本;机器读取使用 `-o json|yaml`。
- scan limit、应用读取 timeout 和短连接 grace 由 `config/platform-infra/kafka.yaml#management.replay` 控制。
- 当前只接受 `--no-publish` 或同义 `--dry-run`
- `mutation=false`
- `topicAppended=false`
- `valuesPrinted=false`。
HWLAB 生产 mapper 重建:
```bash
hwlab-cli kafka regenerate hwlab \
--from kafka \
--session-id <session> \
--trace-id <trc_...>
```
Workbench 隔离 replay
```bash
bun scripts/cli.ts web-probe observe command <observerId> \
--type validateWorkbenchKafkaDebugReplay
bun scripts/cli.ts web-probe observe status <observerId> \
--command-id <commandId>
```
## 网络平面
- Kafka cluster DNS 只在目标 k3s 网络内解析;host workspace 报 `getaddrinfo ENOTFOUND` 只说明网络平面错误,不是 topic 或事件缺失。
- 优先使用 `platform-infra kafka replay agentrun`
- CLI 从 `config/platform-infra/kafka.yaml` 选择 Kafka target
- CLI 从 `config/agentrun.yaml` 选择同 node 的 AgentRun lane
- CLI 在 manager 应用 Pod 内运行正式 replay。
- 运行镜像未携带应用 CLI 时,允许 operator 侧通过 `trans <node>:k3s kubectl ... port-forward` 建立有界临时诊断通道,再从同一 node 的 source workspace 使用显式 `--brokers 127.0.0.1:<port>` 调用正式 CLI
- 先确认端口只监听 loopback
- 只用于当前只读或 debug-topic 调试;
- 完成或失败后立即关闭;
- 不把 port-forward 作为长期入口或验收 authority。
- 禁止因 host 无法解析 cluster DNS 而改写 `/etc/hosts`、暴露 broker 公网端口或添加第二套 Kafka endpoint。
## Replay 校对字段
- stdio 层:frame count、method/type、tool name、call id、started/completed、exit、diff notification、source seq。
- AgentRun 层:event id、run seq、type、phase、command/tool identity、output hash/bytes、terminal。
- HWLAB 层:source event id/seq、mapped envelope id/type、trace/session/command lineage、terminal/final response。
- 浏览器层:server scanned/matched/deliveredclient received/decoded/applieddeduplicatedtimeline 与 terminal seal。
- 每层同时给出:
- 输入数;
- 接受数;
- 拒绝数及 typed reason
- 输出数;
- 首个缺失/不一致 identity
- `mutation`、`topicAppended` 和 `valuesPrinted`。
## 判定规则
- `classification` 必须使用 typed reason
- `matched`:生产 reducer 已生成调试事件;
- `producer-not-written`:源 topic 从未有记录;
- `retention-offset-empty-window`partition 有历史 offset,但当前保留窗口为空;
- `filter-mismatch`:读取到记录,但 session/trace/direction/method 不匹配;
- `decode-schema-rejection`:记录存在,但 JSON 或 schema 无法解析;
- `network-or-runtime-error`:集群网络面、broker Pod、应用 workload 或命令执行失败。
- stdio 有完整 tool/diff,但 regenerate 未产出对应 AgentRun event:归因 reducer/mapping。
- regenerate 能产出,但 durable `agentrun.event.v1` 缺失:归因 producer/durable append。
- AgentRun 产品 event 存在,而 HWLAB debug mapper不产出:归因 HWLAB mapper。
- 同一 AgentRun `eventId` 在 `hwlab.event.v1` 对应多个不同 producer 的 envelope
- 归因 direct projector consumer group 所有权错误;
- owning YAML 中共享 projector group 是修复点;
- 前端按 event id 去重只能作为显示层防御,不能作为根因修复。
- `hwlab.event.v1` 存在且 direct publish/fanout 数相等,但 UI/read model 缺失:归因 SSE/reducer/projection。
- `turn/diff/updated` 只保留 phase/correlation、不保留文件或变更摘要时,应报告为源映射降维;不能把它描述成“后续展示偶然漏了一条”。
- 直接答复没有工具调用时,不要求合成 tool event。
## 配合技能
- OTel trace 与跨服务 identity`$unidesk-otel`。
- AgentRun durable resource/events`$unidesk-agentrun`。
- Workbench 隔离 replay`$unidesk-webdev`。
- 跨 host/k3s 临时诊断通道:`$unidesk-trans` 与 `$unidesk-daddev`。
- Kafka/YAML owner 或 Secret 变更:`$unidesk-ymalops`;本技能默认只读,不从运行面反解 Secret。