Files
llm-intelligence/docs/plans/2026-05-14-runtime-trust-gap-remediation-plan.md
phamnazage-jpg 42e75e733d docs(runtime): sync execution and backlog status
Update README, execution notes, runtime remediation plan, and OpenClaw backlog to reflect the current pipeline split, CI/Phase 5 status, and latest review findings.

Keep this separate from collector code so operational documentation history remains reviewable.
2026-05-15 22:43:21 +08:00

198 lines
7.7 KiB
Markdown
Raw 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.
# Runtime Trust Gap Remediation Plan
> **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.
> **状态更新2026-05-14 16:23 CST**:三阶段已按顺序完成并落到仓库;对应提交为 `a8999ab`。
> **最新验证**`go test ./...`、`npm run build``frontend/`)、`bash scripts/verify_phase3.sh`、`bash scripts/verify_phase5.sh` 均已通过。
**Goal:** 系统性修复日报与采集链路中影响真实性和长期可信度的 3 个缺口,确保“每日定时产出”的结果来自真实采集、可审计运行、并覆盖多源数据链路。
**Architecture:** 不推翻现有 Phase 1/Phase 2 设计,只在运行语义和审计层补强。将“采集是否真实成功”“这次运行是否为正式日常产出/历史重建”“多源数据是否进入定时链路”拆成独立状态,并让 `run_daily.sh`、日报生成器、验证脚本、数据库记录统一使用同一套运行语义。优先修复最容易掩盖真实失败的宽松成功判定,再修复审计分流,最后把多源采集纳入自动调度。
**Tech Stack:** Bash、Go 1.22、PostgreSQL、cron、html/template
## 实施结果摘要
- 阶段 1`fetch_openrouter.go` 已支持严格真实模式,正式调度不再把 mock、仅写 JSON 或旧数据误判为成功。
- 阶段 2日报写入已统一携带 `run_kind``trigger_source``is_official_daily`,正式日报与历史重建已分流。
- 阶段 3`fetch_multi_source.go` 已纳入每日调度链,并把 `selected_source_keys` / `failed_source_keys` 写入运行审计摘要。
- Phase 5 基线文档已补齐 `.github/workflows/ci.yml`Phase 5 门禁不再卡在 CI 文件缺失。
---
### Task 1: 收紧“采集成功”判定,避免 mock / 写库失败被伪装成成功
**Files:**
- Modify: `scripts/fetch_openrouter.go`
- Modify: `scripts/run_daily.sh`
- Modify: `scripts/run_real_pipeline.sh`
- Modify: `scripts/verify_phase3.sh`
- Test: `scripts/fetch_openrouter_test.go`
- Test: `scripts/run_daily` 对应 shell 验证(可先用现有 verify 脚本)
**Step 1: 写失败测试**
补 3 个失败场景:
- 没有 `OPENROUTER_API_KEY` 时,调度链不应被当作真实采集成功
- `summarizeDB` 写库失败时,`fetch_openrouter` 在“真实模式”下应返回非 0
- `run_daily.sh` 不能仅凭“数据库里已有旧数据”就通过质量检查
**Step 2: 跑测试确认当前行为过宽**
Run:
- `go test -tags llm_script scripts/fetch_openrouter.go scripts/fetch_openrouter_test.go`
- `bash scripts/verify_phase3.sh`
Expected:
- 能看到 mock / 降级 / 旧数据掩盖真实失败的风险暴露出来
**Step 3: 最小实现**
建议分两层收紧:
- `fetch_openrouter.go` 增加严格模式或显式运行模式,真实调度默认要求数据库写入成功,否则退出非 0
- `run_daily.sh` 在质量检查中引入“本次运行必须产生当天的写入痕迹”而不是只看历史总量
- `run_real_pipeline.sh` 明确只把“真实采集 + 真实写库 + 真实日报生成”视为成功
**Step 4: 重新运行验证**
Run:
- `bash scripts/run_daily.sh`
- `bash scripts/run_real_pipeline.sh`
- `bash scripts/verify_phase3.sh`
Expected:
- 真实失败会真正失败
- mock / 仅写 JSON / 旧数据不会再伪装成已完成
**Step 5: Commit**
```bash
git add scripts/fetch_openrouter.go scripts/run_daily.sh scripts/run_real_pipeline.sh scripts/verify_phase3.sh scripts/fetch_openrouter_test.go
git commit -m "fix(runtime): harden daily ingestion success checks"
```
### Task 2: 将正式日报与历史重建分流到不同运行语义,修复审计混写
**Files:**
- Modify: `scripts/generate_daily_report.go`
- Modify: `scripts/rebuild_historical_report.sh`
- Modify: `scripts/report_utils.sh`
- Modify: `scripts/run_daily.sh`
- Modify: `scripts/run_real_pipeline.sh`
- Modify: `scripts/verify_phase3.sh`
- Test: `scripts/generate_daily_report_test.go`
**Step 1: 写失败测试**
补测试验证:
- 正式日常产出与历史重建会写入不同的运行类型
- 历史重建不应冒充“每日定时产出”
- `fetchLatestReport` 与前端最新日报读取仍然只面向正式产出口径
**Step 2: 跑测试确认当前混写**
Run:
- `go test -tags llm_script scripts/generate_daily_report.go scripts/generate_daily_report_test.go`
Expected:
- 当前 `daily_report` / `report_runs` 的运行语义仍不区分正式与重建
**Step 3: 最小实现**
建议新增并统一以下语义字段:
- `run_kind`: `scheduled` / `historical_rebuild` / `manual`
- `trigger_source`: `cron` / `cli` / `rebuild_script`
- `is_official_daily`: 是否属于当天定时正式产出
落点建议:
- `generate_daily_report.go` 的数据库写入携带运行类型
- `rebuild_historical_report.sh` 强制标记历史重建语义
- 前端和 API 默认只读取正式产出作为“最新日报”
**Step 4: 重新运行验证**
Run:
- `go test ./...`
- `bash scripts/rebuild_historical_report.sh 2025-08-07`
- `bash scripts/run_daily.sh`
Expected:
- 历史重建和日常产出可以共存,但不会再在审计层混为一类
**Step 5: Commit**
```bash
git add scripts/generate_daily_report.go scripts/rebuild_historical_report.sh scripts/report_utils.sh scripts/run_daily.sh scripts/run_real_pipeline.sh scripts/verify_phase3.sh scripts/generate_daily_report_test.go
git commit -m "feat(audit): separate scheduled and rebuild report runs"
```
### Task 3: 把多源数据纳入同一条每日自动调度链
**Files:**
- Modify: `scripts/run_daily.sh`
- Modify: `scripts/run_real_pipeline.sh`
- Modify: `scripts/fetch_multi_source.go`
- Create or Modify: `scripts/fetch_multi_source_test.go`
- Modify: `scripts/verify_phase3.sh`
- Modify: `scripts/verify_phase5.sh`
- 视需要修改:`scripts/import_phase2_data.go``scripts/import_zhipu_data.go``scripts/import_bytedance_data.go`
**Step 1: 写失败测试**
补测试验证:
- 调度链能明确知道哪些来源参与了当日同步
- 至少 OpenRouter、国内厂商、聚合平台的每日同步在验证层可被看见
**Step 2: 设计最小调度编排**
建议把每日调度拆成可枚举阶段:
- `openrouter`
- `multi_source`
- `official_imports`
- `daily_report`
并定义每个阶段的失败策略:
- 任一必需来源失败时,日报应标记为降级/失败,不应伪装成完全成功
- 允许某些官方导入在单源失败时继续,但必须在运行记录中留下来源级失败痕迹
**Step 3: 最小实现**
优先级建议:
- 先把 `fetch_multi_source.go` 接入每日调度
- 再把已有官方导入脚本接入可选的日常补充同步阶段
- 最后统一审计输出,让 `report_runs` 能显示本次触发的来源集合和失败来源集合
**Step 4: 重新运行验证**
Run:
- `go test -tags llm_script scripts/fetch_multi_source.go scripts/fetch_multi_source_test.go`
- `bash scripts/run_daily.sh`
- `bash scripts/verify_phase3.sh`
- `bash scripts/verify_phase5.sh`
Expected:
- 每日调度不再只证明 OpenRouter 独立刷新
- 多源同步在调度和验收层都能被识别
**Step 5: Commit**
```bash
git add scripts/run_daily.sh scripts/run_real_pipeline.sh scripts/fetch_multi_source.go scripts/fetch_multi_source_test.go scripts/verify_phase3.sh scripts/verify_phase5.sh
git commit -m "feat(runtime): fold multi-source sync into daily pipeline"
```
---
### 执行顺序建议
1. 先做 **Task 1**,因为这是最容易把“假成功”伪装成“真成功”的问题,风险最高。
2. 再做 **Task 2**,把正式日报与历史重建的审计边界切开。
3. 最后做 **Task 3**,把多源同步真正纳入每日调度链。
### 验收顺序建议
1. `bash scripts/run_daily.sh`
2. `bash scripts/rebuild_historical_report.sh <date>`
3. `bash scripts/verify_phase3.sh`
4. `bash scripts/verify_phase5.sh`
5. `go test ./...`