# Migration: schema_version 1.2 → 1.3

> **Type**: MINOR（兼容；老 state 用 `state.get(field, default)` 兜底不会崩，跑迁移让字段对齐 schema 文档）

---

## WHAT changed

### state file 新增 2 个字段

| 字段 | 类型 | 默认 | 含义 |
|---|---|---|---|
| `last_prediction_self_scored` | bool | `false` | 上次 `/cheat-predict` 是否走了 `--skip-blind` 或 Phase 2.5 选 b（信主 Claude 自估而非 sub-agent 盲打分） |
| `last_self_scored_at` | string / null | `null` | 上一条 `last_prediction_self_scored=true` 触发的 ISO 8601 时间戳；下次走 sub-agent 时一起清回 null |

### 新概念（不在 state，在 prediction 文件 header）

引入 **`BlindScored By`** + **`BlindScore Disagreement`** 两个 header 字段——见 [shared-references/prediction-anatomy.md](../shared-references/prediction-anatomy.md) 组件 1。

老的 prediction 文件没有这两个字段——**不强制回填**，cheat-retro 读取时 graceful default。

---

## WHY

v1.3 引入 [skills/cheat-score-blind](../skills/cheat-score-blind/SKILL.md) sub-agent 作为 channel B——通过 Task tool 隔离打分动作，让 sub-agent 只看 script + rubric_notes.md，避免主对话被实绩/复盘/用户态度污染。

`/cheat-predict` Phase 2 默认走 sub-agent；`--skip-blind` 是 escape hatch。一旦使用 escape hatch，必须留下追踪轨迹——这就是 `last_prediction_self_scored` 存在的理由。

`/cheat-bump` Phase 2 **强制**走 sub-agent，不接受 fallback；所以 bump 不会触发 `last_prediction_self_scored=true`。

---

## HOW (Claude steps for /cheat-migrate)

按顺序：

1. 读 `.cheat-state.json` → 解析 JSON
2. 校验 `schema_version == "1.2"`，否则报错"当前 state 不是 1.2，无需此迁移"
3. 检查 `last_prediction_self_scored` 字段：
   - 不存在 → 默认 `false`
   - 已存在（罕见，用户手改过）→ 保留原值
4. 检查 `last_self_scored_at` 字段：
   - 不存在 → 默认 `null`
   - 已存在 → 保留原值
5. 设 `schema_version = "1.3"`
6. **原子写**：写到 `.cheat-state.json.tmp` → rename
7. 报告："✅ 迁移到 1.3 完成。新增 2 字段，无字段被删除。"

**不需要回填老 prediction 文件**——`BlindScored By` 字段缺失时按 `unknown` 处理（cheat-retro 在 reading 时 graceful default）。如果用户想标记"这些老 predictions 都是 v1.2 时代的 inline 打分"，可手动在文件头加 `BlindScored By: legacy-inline`——但**不在 migration 自动执行**，避免改动现有 prediction 文件触发 immutability hook。

---

## Manual fallback

不想跑 `/cheat-migrate` 的用户可以**完全不动 state**——所有 skills 都用 `state.get(field, default)` 兜底，新字段自动用默认值。但 `schema_version` 字段会一直显示 `"1.2"`，SessionStart hook 会持续提示 mismatch warning。

如果想消除 warning 又不想跑 skill，手改：

```diff
 {
-  "schema_version": "1.2",
+  "schema_version": "1.3",
+  "last_prediction_self_scored": false,
+  "last_self_scored_at": null,
   ...
 }
```

下次 `/cheat-predict` 走 sub-agent 时这两个字段会被自然 touch 到（写为 false / null），手改其实可选。

---

## 验收

迁移完成后：
- `jq '.schema_version' .cheat-state.json` → `"1.3"`
- `jq '.last_prediction_self_scored' .cheat-state.json` → `false`（或保留的旧值）
- `jq '.last_self_scored_at' .cheat-state.json` → `null`（同上）
- 跑 `bash hooks/session-start.sh` → 不再有 schema mismatch warning
