# 评估活动分期：v1 静态地基，v2 自适应回路

在现有单次 Run 之上引入「评估活动（Campaign）」——单对象、跨服务周期窗口、聚合多个 Run 的周期评估。核心争议不在聚合本身，而在**由谁、以何种耦合度驱动窗口内的编排**。决定分两期，并把 OpenClaw 的自适应重规划推迟到 v2。

- **v1（静态地基）**：平台新建耐久调度器（活动状态入库、按计划派生 Run、重启从 DB 恢复）+ 活动聚合 + 静态活动计划（手工定义或 OpenClaw 启动时一次性生成）+ 时间趋势/能力汇总双主轴报告。计划一旦确定，窗口执行期间不依赖 OpenClaw 存活。
- **v2（自适应）**：OpenClaw 作为活动层「虚拟用户大脑」，在窗口内的决策点依据已完成时段结果自适应重规划后续编排——AI 进入调度热回路。

## Considered Options

- **v1 直接做完整自适应回路** — 被否：把数天窗口的可靠性与 AI 决策热回路一次性耦合，风险集中且难以定位问题；地基未稳先上活参与者，故障归因困难。
- **完全不用 OpenClaw，平台自建人设生成器** — 被否：放弃平台已嵌入的 AI 助手能力，"模拟真实用户行为"的智能重复造轮子。
- **OpenClaw 全程自主驱动整个活动** — 被否：把 24–72h 的耐久性押在交互式助手会话上，容器重启或会话断开即停摆；耐久调度应归平台。

## Consequences

- 调度器是 Run 之上的独立耐久子系统（活动状态与 child Run 均入库），不是进程内一次性任务——这是 v1 就要建重的原因，勿按"临时脚本"理解。
- v1 的活动计划是静态的：OpenClaw 至多在启动时生成一次，执行期不参与；因此 v1 报告反映的是"预设编排下的周期表现"，尚不含 AI 依结果调整的闭环。
- v2 把 OpenClaw 放进调度热回路，其可靠性边界是"决策点可用"（非全程存活）；决策点不可用时该时段应可跳过/重试而不拖垮整个活动。
- 活动是**单对象**聚合；多对象对比通过并行活动 + 跨活动对比实现，不在活动内部横向编排（与 ADR-0001「同场景同版本才可比」一致）。

---

## v2 修订（2026-08-03）：从"重规划"到"虚拟用户"，双轨结构

原 v2 设想是 OpenClaw 在决策点重排计划条目。经 grilling 重新定位：OpenClaw 的价值不是给固定场景排课表，而是**当虚拟用户本身**——模拟复杂拟真用户行为去打被评对象，产出问题与建议。据此修订为双轨结构：

1. **周期活动内嵌探索（先行）**：现有活动骨架不变（静态计划照常执行），OpenClaw 常驻代理按巡检结果在窗口内派发探索会话；OpenClaw 停摆只暂停探索，固定计划照常完成。
2. **探索活动（后续里程碑）**：独立活动类型，无预设计划，OpenClaw 全权接管评测任务。

两轨共用底座：探索会话对象、种子配置、体验记录、judge 复核、平台护栏。

**关键决策**（完整清单见 grilling 记录）：

- **平台耐久底座 + OpenClaw 常驻代理循环**（原"OpenClaw 全程自主驱动"仍被否，但修正为：常驻的是代理进程/循环而非会话；耐久性归平台，自主性归代理）。可靠性边界沿用原文："决策点可用"，不可用时跳过不拖垮活动。
- **探索会话是独立实体**，不并入 Run——Run 绑定场景与规则判定，探索会话两者皆无，合并会污染 ADR-0001/0002 的可比性与通过率口径。
- **判定 = 体验判定为主 + judge 抽样复核**：意图-结果闭环只有行动者自己能给；judge 补客观质量维度，两条证据链在分析层汇合。
- **种子集（种子人设 × 种子目标）是探索式评测的可比性单位**，活动级配置、与 `plan` 同构；代理可在预算内有限衍生。
- **巡检载体**：全局一个 OpenClaw heartbeat/cron 常驻作业 + 平台巡检 API（OpenClaw 调度持久化在 SQLite、重启不丢、连续失败自动禁用）。
- **护栏平台硬执行**：超预算 API 直接拒绝（默认 ≤8 会话/窗口、≤12 轮/会话、≥30min 间隔）。
- **档位**：正式线（time_scale == 1）自动，加速线仅手动——时间压缩与拟真本质冲突。
- **产出接入**：报告新增"探索发现"维度 + 喂 v0.7 分析 + Markdown 导出；周期对比暂不扩展，待口径稳定。

词汇表更新见 `CONTEXT.md`「探索式评测」章节。

## v1 持久化与恢复修订（2026-08-06）

为使静态活动真正可跨进程恢复，v1 的耐久边界进一步明确：

- **数据库是唯一权威**：`TaskRegistry` 只保存进程内任务句柄，不决定活动或 Run 的持久状态。
- **子 Run 身份持久化**：新建 child Run 保存 `campaign_id`、计划条目索引和 occurrence 索引；三者由 Campaign 范围内唯一索引约束。历史 Run 保持空值，不回填。
- **Claim 先于执行**：调度器对每个 occurrence 先执行条件 claim，再进入 `EvalEngine`。重复 tick、并发调度或重启不会创建第二个 Run；取消后的 Campaign 不允许新 claim，已启动 Run 可继续完成。
- **恢复边界**：持久化为 `pending` 且仍属于 running Campaign 的子 Run 可以恢复；进程中断遗留的 `running` 子 Run 统一标记为 `failed/interrupted`，禁止重放可能已经发送的外部消息。
- **生命周期 CAS**：创建、启动、取消和完成均通过生命周期模块与条件更新完成。取消竞态优先于完成；Campaign 终态与 running 探索会话结算在同一事务提交，任一步失败均保持活动与探索会话为 `running`，由后续调度 tick 重试。
- **活动智能作业耐久化**：智能分析与周期对比统一由活动智能作业 module 管理。两类作业都先写入 `queued` 再启动进程内 worker，并以 `queued → generating` 条件认领防止同一作业被重复执行。
- **作业恢复边界**：重启恢复 queued 智能分析与周期对比；遗留 `generating` 作业标记为中断失败，不自动重放可能已经产生费用的模型调用。失败或重复执行不改变 Campaign 完成状态。
- **进程句柄收口**：智能分析与周期对比共享一个进程内 TaskRegistry owner；Web 生命周期只恢复和关闭该 owner，不分别了解两条作业链的 registry。
- **Campaign runtime seam**：Campaign 耐久执行统一由 `CampaignRuntime` module 提供 `start`、`cancel`、`recover`、`shutdown` 四个生命周期级操作。HTTP 与 Web 生命周期不再调用 tick、advance、reconcile、loop 或 TaskRegistry 阶段函数。
- **内部 adapter**：真实 UTC 时钟与 `EvalEngine` child-Run 执行器是 runtime implementation 的默认 adapter；测试可注入可控时钟和本地执行器，但这些 internal seam 不进入生产调用方的 interface。
- **恢复与取消**：`recover` 自行清理中断 Run、枚举 running Campaign 并重建循环；每个循环内部先 reconcile child Run，再 tick。`cancel` 只处理进程句柄，Campaign 终态仍先由生命周期 CAS 持久化。

启动恢复顺序固定为：结算遗留 generating 智能作业并重启 queued 智能作业 → `CampaignRuntime.recover` 清理中断 Run 并重建 running Campaign 调度循环（每个循环先完成 child Run reconciliation）。该顺序保证恢复动作只依据已提交的数据库事实，不依赖上一次进程的内存状态。
