项目文件夹

文件
2026-07-13 12:29:17 +08:00

6.5 KiB

Migration: schema_version 1.3 → 1.4

Type: MINOR but BREAKING for blind channel integrity——state 字段不变,但 rubric_notes.md 必须拆开。老用户跑 migrate 之前 blind sub-agent 仍泄漏实绩


WHAT changed

文件层(核心

之前 之后
rubric_notes.md 顶部累积所有 bump Memo(含视频名 + 实绩 + 派生证据) rubric_notes.md 只含通用语言(公式 / 维度定义 / bucket 边界 / 指针),绝不含实绩
—— rubric-memo.md)累积所有 bump Memo 全文(含视频名 + 实绩 + 派生证据)

state 字段

无新增 / 删除 / 改名。仅 schema_version bump 标识本次"文件层迁移"必跑。

channel B hard refusal list

cheat-score-blind/SKILL.mdrubric-memo.md 路径 + refusal_code blocked_rubric_memo


WHY

PR #11 引入 blind-scoring sub-agentchannel B)时承诺它只能读 scripts/<id>.md + rubric_notes.md。但 cheat-bump Phase 5 落地时把升级 Memo(含证据数据表 + 派生证据 + 真实视频名 + 实绩)写进 rubric_notes.md ——sub-agent 通过白名单读到了本不该看的实绩数据,盲打分变成"看过实绩的事后合理化"。

实测复现(PR #11 测试):

contamination_note: rubric_notes.md v0→v1 bump memo 含本 script 同名条目「它让我发的 38w」实绩
contamination_note: rubric_notes.md 派生证据段含本 script 名+实绩 13.7w,CC 锚点被预先校准
→ refusal: "non_blind_warning"
→ all dimensions confidence: medium

修复:拆 file。rubric_notes.md 严格只放通用规则(blind 白名单),bump 历史档案沉淀到 rubric-memo.mdblind 硬禁读)。详见 shared-references/observation-lifecycle.md "Blind channel leak guard" 段。


HOW (Claude steps for /cheat-migrate)

按顺序执行。不可幂等的步骤要先检查是否已跑过——本迁移涉及内容文件改写,重跑可能产生重复内容。

Step 1:前置检查

  1. .cheat-state.json → 校验 schema_version == "1.3",否则报错"当前 state 不是 1.3,无需此迁移"
  2. 检查 rubric_notes.md 存在;不存在 → 报错"找不到 rubric_notes.md。是不是项目还没 init?"
  3. 检查 rubric-memo.md 是否已存在
    • 已存在 → 询问用户"rubric-memo.md 已有内容,跳过 split 直接 bump schema 到 1.4?回 yes 跳过,回 no 中止迁移"
    • 不存在 → 进 Step 2

Step 2:备份

cp rubric_notes.md rubric_notes.md.backup-$(date +%s)

提示用户:"已备份 rubric_notes.md —— 拆分若出错可恢复"。

Step 3:扫描 + 抽离 rubric_notes.md 的违禁段

rubric_notes.md 全文。识别下列 pattern

Pattern 处理
整段 ## v.X → v.Y 升级 Memo 含子段(触发观察 / 证据数据 / 诊断 / 跨模型审核 / 已知局限) 整段抽离到 rubric-memo.md,原位删除
派生证据段中带视频名 + 数字(如「停止期待」实绩 13.7w) 整条抽离到 rubric-memo.md 的"派生证据"子段;原位用通用语言替代("高抽象密度样本 → CC=1 → 低 reach"
校准池重打表 / 排序对照表 整表抽离到 rubric-memo.md 对应 Memo 的"证据数据"子段;原位删除(公式速查表保留——公式速查不含视频名)
跨模型审核引用含具体视频名 + 实绩 抽离
散落的 \d+w / \d+万 数字(例外:bucket 边界 5-30w / 30-100w 等保留) 用 Claude 判断:是 bucket 边界 → 保留;是实绩引用 → 抽离

Step 4:写 rubric-memo.md

如果文件不存在 → 从 cheat-on-content/templates/rubric-memo.template.md 复制空骨架。

然后把 Step 3 抽离出来的 Memo 段按时间顺序(旧的在上 / 新的在下)append 到文件末尾。每段 Memo 用 templates/rubric-memo.template.md 的 6 组件格式包装;缺组件的标 (unknown from legacy migration)

Step 5:清理 rubric_notes.md

  • 顶部 metadata 段加:
    **Upgrade memos**: 见 [rubric-memo.md](rubric-memo.md)
    
  • Memo 段被 Step 3 抽走的部分留短指针"v0→v1 升级 Memo 已迁移到 rubric-memo.md,跑 cat rubric-memo.md 查看"
  • 派生证据段替换为通用语言

Step 6:自检 leak guard

对清理后的 rubric_notes.md 跑:

grep -E '\d+\s*[wWmMkK万]|播放|实绩|实际' rubric_notes.md \
  | grep -v -E '^\s*\|[^|]*\|[^|]*\|.*[0-9]+\s*[wkM][^a-zA-Z]' \
  | grep -v -E '5-30w|30-100w|100-150w|>150w'

grep 排除明显的 bucket 边界数字)

  • 无命中 → 通过
  • 命中 → 报告剩余的"实绩引用" + 让用户手工 review / 进一步抽离 → 继续 Step 7 或中止

Step 7bump schema + 写回 state

  1. .cheat-state.jsonschema_version = "1.4"
  2. 原子写
  3. 报告:" 迁移到 1.4 完成。rubric_notes.md 现仅含通用语言({N} 行),rubric-memo.md 含 {M} 段历史 Memo。备份保留:rubric_notes.md.backup-{ts}。"

Manual fallback

不想跑 /cheat-migrate 的用户可以手动拆

  1. 备份:cp rubric_notes.md rubric_notes.md.backup
  2. 把所有 ## v.X → v.Y 升级 Memo 段从 rubric_notes.md 整体剪切到新建rubric-memo.md(按时间顺序保留)
  3. 把派生证据段的视频名 + 实绩剪到 rubric-memo.md,原位用通用语言替代
  4. rubric_notes.md 顶部加 **Upgrade memos**: 见 [rubric-memo.md](rubric-memo.md) 指针
  5. 手改 .cheat-state.jsonschema_version"1.4"

或者最懒:删 rubric_notes.md 重 init(损失:所有历史观察 + bump memo),跑 bash install.sh 后说"初始化"——cheat-init 会重新创建两份空文件。仅适合校准池还很小(< 5 条)的早期用户。


验收

迁移完成后:

# state 升到 1.4
jq '.schema_version' .cheat-state.json
# → "1.4"

# rubric_notes.md 无实绩泄漏
grep -E '播放|实绩|实际|\d+w[^a-zA-Z0-9]' rubric_notes.md \
  | grep -v -E '5-30w|30-100w|100-150w|>150w' \
  | head
# → 应输出空(除 bucket 边界)

# rubric-memo.md 含历史 Memo
ls -la rubric-memo.md
wc -l rubric-memo.md
# → 行数 > 50(取决于历史 bump 次数)

# blind sub-agent 不再标 non_blind_warning
# 跑 /cheat-score scripts/<已发样本>.md
# → JSON.refusal == null, JSON.self_check.any_contamination_signal == false