feat: add web probe sentinel service (#896)

Co-authored-by: Codex <codex@noreply.local>
This commit is contained in:
Lyon
2026-06-25 22:19:25 +08:00
committed by GitHub
parent 9309efabb8
commit 46205321bf
5 changed files with 655 additions and 1 deletions
+2
View File
@@ -98,6 +98,7 @@ bun scripts/cli.ts hwlab nodes web-probe observe stop webobs-xxxx
bun scripts/cli.ts hwlab nodes web-probe observe analyze webobs-xxxx
bun scripts/cli.ts hwlab nodes web-probe sentinel plan --node D601 --lane v03 --dry-run
bun scripts/cli.ts hwlab nodes web-probe sentinel status --node D601 --lane v03
bun scripts/web-probe-sentinel-service.ts --node D601 --lane v03 --state-root .state/web-probe-sentinel-smoke --scheduler-disabled --once
```
`observe analyze` 的 duplicate final response 判定必须以 trace-frame 可见行事实为准。`observe collect --view trace-frame` 固定渲染的 `Final Response` 区块是 summary,不是第二条业务 assistant message;只有同一 trace-frame 中出现两个可见 assistant final rows 且内容重复时,才应报告 duplicate finding,并在证据中写明 `finalResponseSummaryBlockCounted=false`
@@ -125,6 +126,7 @@ bun scripts/cli.ts hwlab nodes web-probe observe analyze webobs-xxxx
- `observe collect --view turn-summary` 是第一层 CLI 阅读视图:只从 `samples.jsonl``control.jsonl` 和已有 `analysis/report.json` 按需渲染同一 session 的多 turn 摘要,包含用户消息 preview/hash、traceId、状态、耗时/最近更新时间、steer/cancel 标记和 Final Response 摘要。`observe collect --view trace-frame --trace-id <id> --sample-seq <n>` 是第二层 CLI 阅读视图:从同一采样帧渲染单帧 trace 文字截图,并固定输出 `Final Response` 区块。`observe collect --view project-summary` 从同一 artifact 渲染项目管理 / mdtodo DOM 采样、Workbench launch command、捕获到的 `x-hwlab-otel-trace-id` 和 Tempo drill-down 命令。collect 视图不是采样器新增保存物,不构成第二事实源。
- `observe start/status/command/collect/analyze` 默认输出包含 `Wrapper contract` 区块;该区块证明 Web 哨兵只能 wrap 现有 observe CLI verb、现有 runner/analyzer 和既有 artifact contract,不新增第二套 Playwright runner、analyzer、状态机或私有 web-probe API。
- `web-probe sentinel plan|status` 只读取 `observability.webProbe.sentinel.enabled/configRefs` 和 owning YAML,渲染 redacted 配置引用图、文件 hash、缺失字段和跨 ref 冲突;它不启动浏览器、不读取 Secret 值、不保存采样结果,也不是第二套 runner/analyzer。真正的采样和判定仍以 `observe start|command|collect|analyze` artifacts 为准。
- `scripts/web-probe-sentinel-service.ts` 是 Web 哨兵 Pod entrypoint`--once` 只做 config/PVC/SQLite/scheduler/analyzer-command health 快照,`--scheduler-disabled` 仅用于本地服务健康冒烟,不能作为生产运行参数。HTTP 服务只提供 `/api/health``/api/status``/api/runs``/api/maintenance``/metrics` 和 redacted dashboard 外壳,底层采样仍只能经 observe CLI adapter。
- `trace-frame` 出现 `(无 trace rows;这是 blocker...)` 时,必须先看同一输出中的 `TRACE DIAGNOSTIC`:记录 pageRole/pageId、traceRows/turns/messages 数量、sampleTraceIds、尾部 traceRow/turn/message 归属。若目标 trace 的 turn/message/final 存在但 traceRows 全部属于旧 trace,应按 Workbench read model authority 分裂登记到架构/业务 issue(例:HWLAB #2124),不得把旧 traceRows 当作新 turn 通过证据,也不得让 analyzer 的聚合计数压过 CLI trace 视图。
- analyzer finding 不得压过 CLI `trace-frame` 人工视图。尤其 `trace-assistant-message-duplicates-final-response` 只有在 `trace-frame` 中同一 completed turn 可见多条相同 assistant final rows 时才按业务 bug 处理;如果 `trace-frame` 只有一条 assistant final row、后面固定 `Final Response` 区块正确且 API messages/turns 对齐,该 amber 归类为 analyzer 精度问题,应登记/修工具,不得阻止业务 closeout。
-`observe status` 显示 PID still alive 但 heartbeat/sample 不推进、`commands/pending/*.json` 不被消费,或 `observe stop --force` 只是继续排队 stop command,应先按 web-probe runner 工具缺陷处理(例:UniDesk #874),用 route 只读确认 PID/heartbeat 后清理进程;不要把 pending command、未触发的 cancel 或 runner stale 混入 Workbench 业务结论。