# R2.3 任务报告

完整只读审计见 [UniDesk #1870](https://github.com/pikasTech/unidesk/issues/1870#issuecomment-4952485516)，执行任务为 qt_1e8f647f10ce4030ace2ba8e6ac16fe3。

## 关键发现

- 当前 2998 行 sentinel service 同时负责 runner 私有 SQLite、scheduler metadata、CronJob 触发、终态写入、latest/runs/findings/report 查询、artifact 解析和 monitor-web 资产。
- 仓库没有 /api/root 或 /api/aggregate；monitor root 实际是 runner-served-bridge，前端只读当前 runner 同源 API，切换 sentinel 只是跳转。
- 当前不存在真正全局 latest；入口 runner/PVC/SQLite 不可用时，该实例历史和页面一起不可读。把前端改成 HTTP fan-out 只会放大故障。
- plan、实际 CronJob 执行和 record 终态不是清晰的中心事务链，scheduler heartbeat 不能证明新 run 已完成或 latest 已更新。

## 冻结边界

- runner 只执行既有 observe/analyze、生成不可变 artifact，并提交一次终态与 locator。
- owning YAML/CronJob 保持每 sentinel 唯一调度权威，不新建第二 scheduler。
- 中心 Monitor 持久化与查询服务通过 NC01 Host PG 提供唯一结构化写入/读取权威。
- monitor-web 只消费中心 bounded API，不聚合 runner、不读取私有 SQLite/PVC。
- artifact 实体可暂留 runner PVC；中心只保存不可变 locator、hash、摘要和可达性。
- 禁止 runner fan-out、永久双写、SQLite fallback 和扫描 PVC/SQLite 补洞。

## 后续

结合 R2.1、R2.2 决定最小 ingest 方式、schema、切换窗口与回滚；先更新 P0 SPEC，再进入实现。
