## 现状问题 `internal/engine/runner_dispatch.go` 中的 `Engine.awaitRunnerTask`(约 70 行)把三件事揉在一起: 1. 一个 22 行的 `reportStatus` 闭包,内联构造 `runner.claimed` / `runner.started` 两条遥测事件; 2. 「读取任务 → 桥接事件 → 上报状态 → 判断是否终态」这一组步骤在订阅前、订阅后**原样写了两遍**(含两处相同的 `task disappeared` 报错和两处相同的终态 `switch`); 3. 订阅 + 1s 兜底轮询的等待循环。 重复块后续改动时容易只改一处,状态→事件的映射也无法单独测试。 ## 重构方案 - 拆出纯函数 `runnerTaskStatusEvent(task) (domain.TelemetryEvent, bool)`:只负责把 Leased/Running 状态映射为对应遥测事件,其他状态返回 false。 - 拆出 `runnerTaskFinished(status) bool`:统一 Success/Failed/Canceled 三个终态判断。 - `awaitRunnerTask` 内用一个 `observe` 闭包合并两处重复的「读取/桥接/上报/终态判断」,主循环只保留订阅、兜底计时器和取消处理。 事件字段、文案、报错文字、去重逻辑(同一状态只上报一次)、取消时 `CancelRunnerTask`、终态时 `flushAllObservations` 的调用时机全部保持不变。 ## 影响范围 仅 `internal/engine/runner_dispatch.go` 中 `awaitRunnerTask` 及新增的两个包内私有函数;函数签名与所有调用方(dispatch/push/align/integrate)不变,无对外接口或行为变化。 ## 验证方式 - 新增单测覆盖 `runnerTaskStatusEvent` 各状态映射与 `runnerTaskFinished` 终态判断; - 现有 `awaitRunnerTask` 相关测试(runner_cases_test / misc_helpers_cases_test / runner_observability_test)保持通过; - `go vet ./internal/engine/...`、`go test ./internal/engine/...`。
Activity