## Why 各 checker 在执行过程中收集了丰富的结构化数据(HTTP 状态码/headers/body、ICMP 延迟/丢包率、LLM token 用量/首 token 延迟等),但 `CheckResult` 仅有一个 `statusDetail: string | null` 字段,所有观测数据被压缩为人可读字符串后丢弃。这导致:排障时无法获取失败上下文(HTTP 502 返回了什么 body?CMD 的 stderr 输出了什么?)、无法对历史观测数据做结构化查询和趋势分析(ICMP 丢包率变化、LLM token 消耗趋势)。 ## What Changes - **BREAKING**: `CheckResult` 移除 `statusDetail` 字段,新增 `detail: string | null` 和 `observation: Record | null` - **BREAKING**: 存储层 `check_results` 表移除 `status_detail` 列,新增 `observation TEXT` 列(JSON 格式) - 每个 checker 在 execute 返回时组装结构化 observation 对象,包含该类型特有的观测数据(含截断策略);可收集的负向结果保留 observation,仅无法形成领域观测时返回 null - `CheckerDefinition` 接口新增 `buildDetail(observation)` 方法,从 observation 动态构造人可读摘要 - API 序列化层根据 target type 调用对应 checker 的 `buildDetail`,动态生成 `detail` 字段返回给前端 - 前端展示层将 `statusDetail` 引用改为 `detail`,逻辑不变 ## Capabilities ### New Capabilities - `checker-observation`: 定义 observation 数据模型、各 checker 的 observation schema、截断策略、序列化/反序列化规则 ### Modified Capabilities - `checker-runner-abstraction`: CheckerDefinition 接口新增 `buildDetail` 方法;CheckResult 类型变更(statusDetail → detail + observation) - `probe-engine`: checker 执行结果写入字段从 status_detail 改为 observation,detail 不进入存储层 - `probe-data-store`: check_results 表 schema 变更(status_detail → observation);insert/query 方法适配新字段;同步修正现有 spec 中已过时的 target_id 类型为当前代码实际使用的 TEXT - `probe-api`: CheckResult API 合约变更(statusDetail → detail + observation);序列化层需根据 target type 动态构造 detail - `cmd-checker`: CMD 执行结果改为返回 observation,detail 由 buildDetail 构造 - `tcp-checker`: TCP 执行和 banner 摘要改为通过 observation/detail 表达 - `udp-checker`: UDP 执行和响应摘要改为通过 observation/detail 表达 - `icmp-checker`: Ping/ICMP 摘要改为通过 observation/detail 表达,API registry type 仍为 `ping` - `llm-checker`: LLM 执行期 observation 与持久化 preview 分层,状态摘要改为 detail - `target-detail-drawer`: 记录面板详情列从 statusDetail 改为 detail ## Impact - **后端**: 7 个 checker 的 execute/buildDetail 需改造返回 observation;LLM 还涉及 types.ts、observation.ts、expect.ts 的执行期/持久化结构分层;engine.ts/store.ts/helpers.ts/routes 适配新字段 - **前端**: 2 处源码 statusDetail 引用改为 detail(history-table-columns.tsx、OverviewTab.tsx),相关测试 fixture 同步更新 - **存储**: SQLite DDL 变更,不做数据迁移(项目未上线);target_id 继续使用当前代码实际的 TEXT 类型 - **依赖**: 无新增依赖,observation 使用 JSON.stringify/JSON.parse 序列化 - **测试**: 所有涉及 CheckResult、StoredCheckResult、CheckerDefinition mock、API dashboard/history、各 checker execute/buildDetail、前端展示的测试需适配新字段