# v0.6 Spec — 评估活动（Campaign）v1 静态地基

**状态**: ready-for-agent
**领域词汇**: 见 CONTEXT.md「周期评估」章节（评估活动 / 服务周期窗口 / 活动计划）
**关键决策**: ADR-0003（分期：v1 静态地基、v2 自适应回路；OpenClaw 进调度热回路的取舍）

## Problem Statement

被评智能体（AI 数字员工 / AI 助手）提供的是 7×24 的持续服务，但现有平台只能做「一个对象 × 一个场景」的单次评测（Run）。用户拿不到「这个智能体在一个完整服务周期内，服务质量如何随时间波动」的画像——夜间是否降级、高峰是否变慢、凌晨无人值守时表现如何，这些只有跨时段持续采样才能暴露。用户需要一种能在一个可配置长度的服务周期窗口内、按计划持续对同一对象施加多场景评测、并汇总成周期报告的能力。

## Solution

引入**评估活动（Campaign）**：针对单个评测对象、跨一个服务周期窗口（可配 6/12/24/48/72 小时）的评估聚合。用户定义一份**静态活动计划**（在窗口的哪些时间点、对哪个场景、跑几次），平台的**耐久调度器**在窗口内按计划持续派生普通 Run，最后聚合成**双主轴周期报告**（时间趋势 + 能力汇总）。活动状态入库、抗重启：服务重启后调度器从数据库恢复，继续未完成的窗口。多对象通过并行多个活动 + 跨活动对比实现（跨活动对比可后续迭代）。

v1 计划是静态的（手工定义，或后续由 OpenClaw 在启动时一次性生成）；OpenClaw 在窗口内依结果自适应重规划的能力是 v2（ADR-0003）。

活动支持**可配时间倍速**：正式线用真实墙钟（24h 活动真的持续 24h，采到真实的凌晨/高峰表现）；开发线可设压缩倍速（如把 24h 压成几分钟）快速验证调度与聚合，不改变任何判定语义。

## User Stories

1. 作为质量负责人，我想对一个数字员工发起一个 24 小时评估活动，以便看到它一整天的服务质量画像。
2. 作为质量负责人，我想自定义活动窗口长度（6/12/24/48/72h），以便匹配不同的服务周期考察需求。
3. 作为质量负责人，我想在活动计划里指定"哪些时段跑哪个场景、各跑几次"，以便模拟真实用户在一天里不同时间的不同诉求。
4. 作为质量负责人，我想让活动只针对单个评测对象，以便活动身份清晰、报告维度单纯。
5. 作为质量负责人，我想在活动进行中查看它的实时进度（已派生多少 Run、当前窗口位置、已完成时段的通过率），以便掌握活动健康度。
6. 作为质量负责人，我想在活动结束后得到一份周期报告，主轴一是**时间趋势**（通过率/可用性/时延随时段的曲线），以便发现质量随时间的波动。
7. 作为质量负责人，我想周期报告的主轴二是**能力汇总**（按场景/能力维度聚合的整窗表现），以便看到这一周期里哪些能力强、哪些弱。
8. 作为质量负责人，我想活动派生的每个 Run 仍是标准 Run（可单独打开看逐轮对话与判定），以便下钻排查具体失败。
9. 作为运维，我想活动在服务重启后能自动恢复继续跑，以便长窗口活动不因一次部署而中断作废。
10. 作为运维，我想中途取消一个进行中的活动，以便及时止损；已完成的子 Run 结果保留。
11. 作为开发者，我想在开发线用时间压缩倍速把 24h 活动压成几分钟跑完，以便快速验证调度与报告聚合。
12. 作为质量负责人，我想活动列表能看到每个活动的对象、窗口、状态（计划中/进行中/已完成/已取消/失败）、整窗通过率，以便一览管理。
13. 作为质量负责人，我想活动的通过率口径与单 Run 一致（用例级、含执行失败，ADR-0002），以便跨层数字可比。
14. 作为质量负责人，当某个时段的 Run 因通道故障失败时，我想它照常计入周期报告（失败也是质量信号），以便报告反映真实可用性。
15. 作为质量负责人，我想活动报告能导出（复用现有导出能力），以便存档与分享。

## Implementation Decisions

### 领域与聚合
- **评估活动是 Run 之上的新聚合**，不是巨型长命 Run。活动按计划派生多个普通 Run（每个仍是"一个对象 × 一个场景 × 一个时段"），完整复用现有引擎、规则、判定（judgement）、单 Run 报告。
- **单对象**：一个活动绑定一个 `target_id` + 一份计划（计划条目引用若干 `scenario_id`）。多对象=并行多个活动。
- 子 Run 通过一个新的可空外键 `campaign_id` 归属到活动；非活动派生的手动 Run 该字段为空。子 Run 复用现有 `EvalEngine.run(existing_run=...)` 派生路径。

### 活动计划（静态）
- 计划是一组条目，每条描述：目标场景、在窗口内的触发时间点（相对窗口起点的偏移）、重复次数/强度。存为活动记录上的 JSON（仿现有 cases 的 JSON 列存取），不新建计划子表。
- 计划由用户创建活动时提供；v1 不含 OpenClaw 生成/自适应（ADR-0003）。

### 耐久调度器
- 平台新建一个耐久调度子系统，生命周期挂在 Web 应用 lifespan：启动时从数据库加载所有"进行中"的活动并恢复推进，关闭时优雅停止。
- **调度决策是纯函数**：给定活动计划 + 当前活动时钟位置，算出"此刻应派生哪些 Run / 活动是否已达窗口终点"。外层是薄的异步循环 + 派生 Run 的副作用壳。这是主要的新可测接缝，仿 v0.5 的 `combine_case_outcome`。
- **抗重启**：活动状态（窗口起止、已完成/已派生进度）入库；进程内不持有权威状态。重启后调度器据库恢复。沿用 `mark_orphans_failed` 的思路处理重启时正在跑的子 Run。
- **时间倍速**：活动记录带 `time_scale`（默认 1.0=真实墙钟）。活动时钟 = (真实经过时间 × time_scale) 映射到窗口位置。倍速只影响"何时派生 Run"，不影响任何判定/报告口径。开发线可设大倍速加速；正式线用 1.0。

### 报告聚合（双主轴）
- 新增活动报告聚合纯函数：消费该活动全部子 Run 的 summary，产出两轴：
  - **时间趋势轴**：按时段桶聚合通过率/可用性/时延（仿 stats.py 的 trend 按时间分桶取均值）。
  - **能力汇总轴**：按场景/能力维度聚合整窗表现（仿 stats.py 的 dashboard 分组取均值）。
- 通过率口径沿用单 Run 的用例级、含执行失败（ADR-0002），保证跨层可比。
- 报告导出复用现有 report 渲染/导出能力。

### API 与前端
- 新增活动 API：创建 / 列表 / 详情（含进度）/ 报告 / 取消，形状与命名沿用现有 `runsApi` 风格。
- 前端新增「评估活动」页（keep-alive tab，仿现有页面注册方式）：活动列表 + 创建 + 进度 + 双主轴报告视图。`api.ts` 新增 `campaignsApi` 与 `Campaign`/`CampaignReport` 类型。

### 持久化与迁移
- 新增活动表（含窗口、状态、计划 JSON、time_scale、时间戳）；`EvalRunDB` 加可空 `campaign_id`。
- Alembic batch mode 迁移（SQLite），沿用现有迁移链与 `render_as_batch=True` 约定；`init_db` 的 create_all 覆盖全新库。

## Testing Decisions

- **好测试只验外部行为**：断言 API 契约、调度决策的输出、报告聚合的数值，不耦合内部实现细节。
- **三接缝**（已与用户确认）：
  1. **API 集成接缝**：`POST/GET /api/campaigns`、`GET /api/campaigns/{id}/report`、取消——用 `test_runs_api.py` 同款 httpx AsyncClient + MockChannel + monkeypatch get_session 端到端测。
  2. **调度决策纯函数接缝**：`due_entries(plan, clock) -> 待派生条目`，注入任意时钟/倍速，无需真实定时器，仿 `test_orphan_runs.py` 的纯 `db_session` 风格。
  3. **活动聚合纯函数接缝**：`generate_campaign_report`，用 `_seed_run × N` 构造多子 Run 后断言两轴数值，仿 `test_report.py`。
- **时间压缩用于测试**：调度决策纯函数吃注入时钟，测试可瞬间推进整个窗口，无需等待。
- **抗重启测试**：构造"进行中"活动 + 部分子 Run，模拟重启后调度恢复，断言不重复派生、不丢进度。
- 现有 `conftest.py` 的 `db_session`/TestClient 夹具与显式模型 import 列表需加入新活动模型。

## Out of Scope

- **OpenClaw 生成/自适应计划**（v2，ADR-0003）：v1 计划静态、执行期不依赖 OpenClaw。
- **Layer 2 逐轮自由漫游**：时段内对话仍由现有动态用例生成器产出，不做 OpenClaw 逐轮即兴。
- **跨活动对比视图**：多对象对比留待后续迭代；v1 先把单活动闭环。
- **人设（persona）深度建模**：v1 计划条目可带轻量人设标签，但不强制影响生成；深度人设留待 v2。
- **告警/通知**：活动异常主动通知不在 v1。

## Further Notes

- 与既有决策的一致性：单对象聚合 + 通过率用例级含故障，均与 ADR-0001/0002 对齐。
- 风险点：耐久调度器是全新子系统，长窗口 + 重启恢复是主要复杂度来源；建议 to-tickets 时把「调度决策纯函数 + 持久化 + 恢复」作为最早的 tracer-bullet，先立稳地基再叠 API/前端/报告。
- 时间倍速是把双刃剑：务必保证它只影响派生时机，绝不渗入判定/报告口径，否则开发线与正式线数字不可比。
