# Blind Prediction Protocol(盲预测协议) 被这些子 skill 引用:`cheat-predict`、`cheat-retro`、主 SKILL.md。 这是项目原则 #1 的完整规范。任何子 skill 在写预测前都必须执行本协议。 --- ## 核心定义 **盲预测**:在预测者(人或模型)看到任何关于该作品发布后真实表现数据**之前**完成的预测。 预测一旦写入 `predictions/*.md` 的 `## 预测` 段,该段即为 **immutable**——只能在文件末尾追加 `## 复盘` 段,不能修改预测段任何字符。 --- ## "见过数据"的边界(关键,常被违反) 下列任一条件成立 → 已不再 blind,**禁止写预测**: | 信息 | 是否破坏 blind | 例外 | |---|---|---| | 该作品任何平台的播放数 / 阅读数 | ✗ 破坏 | 无 | | 该作品的点赞 / 评论 / 转发数 | ✗ 破坏 | 无 | | 该作品的具体评论内容 | ✗ 破坏 | 无 | | 该作品的算法推荐位 / 热门榜位置 | ✗ 破坏 | 无 | | 该作品发布后的截图 / 后台数据 | ✗ 破坏 | 无 | | **同期发布的其他人**作品的表现 | ○ 不破坏 | — | | **历史上类似主题**作品的表现 | ○ 不破坏(这正是锚点对比要做的) | — | | 该作品**发布前**的稿子内容 | ○ 不破坏 | 这是预测的输入 | | 用户口述的"我感觉这条还行" | △ 谨慎 | 用户的主观感觉不算"数据",但要在预测里标注用户偏见 | **判断捷径**:只要这条信息**只能在作品发布后才能获得**,就算"数据"。 --- ## 预测者必须主动声明的情况 子 skill 在启动 `cheat-predict` 前,必须自检并向用户**主动声明**: 1. **作品已发布超过 RETRO_WINDOW_DAYS 天**(默认 3 天)→ 必须拒绝写"预测",改记为 `**Reconstructed retrospective**`,明确标注非预测 2. **作品已发布但 < RETRO_WINDOW_DAYS 天,用户尚未透露任何数据**→ 允许 blind 预测,但在文件头部标记 `published_before_prediction: true` + `blind_status: confirmed_no_data_seen` 3. **用户在对话里已粘贴了任何后续数据**→ 同 #1 处理,记为 reconstructed `BLIND_CHECK=strict`(默认):上述任何破坏条件命中,**拒绝执行**。 `BLIND_CHECK=lenient`:仅警告 + 强制标注,允许继续——只用于离线测试或学术演练,**不推荐用于真实校准**。 --- ## Immutable 的工程边界 `## 预测` 段的不可修改是**用户体验承诺**,由 hook 层强制: - `hooks/prediction-immutability.sh` 在 PreToolUse(Edit|Write) 上检查 `predictions/` 下文件 - 命中 `## 预测` 与下一个二级标题之间任何 diff → exit 1 阻塞 - `## 复盘` 段的追加 → 放行 **禁止的"绕开"模式**(子 skill 必须拒绝): - "把预测段重写得更准一点" → 拒绝。如有正当理由重做,创建新文件 `<原文件名>_redo.md`,原文件保留 - "我的概率分布写错了 0.5%,让我改一下" → 拒绝。在复盘段追加 `修正:原概率分布 X% 应为 Y%,于 发现笔误` - "我前面没考虑 SR=4,重打一下分" → 拒绝。同上路径 唯一允许编辑预测段的场景:**纯 markdown 排版错误**(标题层级错误、列表 bullet 格式错),且用户明确说明这是格式修复。这种情况 hook 仍会阻塞,需要用户显式 bypass(手动设置环境变量 `CHEAT_BYPASS_IMMUTABILITY=1` 单次)——bypass 应在 git history 留痕。 --- ## 文件名约定(**三处一致**) 一个内容三处文件,**用同一组 `__` 命名**: ``` scripts/__.md ← pre-shoot 草稿(cheat-seed 写或用户写) predictions/__.md ← immutable 预测(cheat-predict 写) videos/__/ ← 拍后才建(cheat-shoot 创建) ├── script.md ← 用户提供的最终拍摄稿 └── report.md ← T+3d 数据(cheat-retro 写) ``` - ``:**草稿首次落盘日期**(即 `scripts/.md` 的创建日),不是预测日 / 拍摄日 / 发布日。理由:保持 ID 稳定——草稿大改后 hash 变了仍想保持文件可追溯 - ``:12 位 sha256 前缀,对**草稿首次落盘的内容**做 hash。用户 edit 草稿后**不变**——便于跨文件引用 - ``:3-8 字中文或英文短名,便于人类辨识 Reconstructed 重做:在 `` 后加 `_redo`,三处都加: - `scripts/___redo.md` - `predictions/___redo.md` - `videos/___redo/` 原文件保留(不删)。 --- ## 子 skill 必须做的检查清单 `cheat-predict` 启动时: 1. 读 `BLIND_CHECK` 常量 2. 询问用户该作品当前发布状态(未发 / 已发 < RETRO_WINDOW_DAYS / 已发 ≥ RETRO_WINDOW_DAYS) 3. 询问对话历史里是否提到过该作品的任何后续数据(如有,自检对话里有没有 "播放/阅读/点赞/评论" 等关键词) 4. 若 #2 或 #3 命中破坏条件 → 按 `BLIND_CHECK` 模式处理 5. 通过后才允许写 `predictions/*.md` `cheat-retro` 启动时: 1. 读目标 prediction 文件 2. **先在内存里 cache 住 `## 预测` 段**——后续任何对该文件的写都必须先校验该段未变 3. 抓数据 → 追加 `## 复盘` 段 4. 写完后**再次校验**:写入后该文件的 `## 预测` 段哈希应等于步骤 2 的 cache。不等 → 报错并回滚 主 SKILL.md: - 用户说出"重写预测" / "改一下预测段" / "你之前预测错了我帮你改" 时,**直接拒绝并解释**,引导改用 `_redo.md` 路径 --- ## 异常状态处理 | 场景 | 处理 | |---|---| | 预测文件不小心被人手编辑了预测段 | 不自动回滚(破坏更大)。下次 `cheat-retro` 检测到不一致 → 在复盘段追加 `**Integrity warning**: 预测段于 被外部修改,无法保证盲度`,校准价值降级为"参考",不计入 bump 校准池 | | 预测文件遗失 / 被删 | git log 找回。找不到 → 在 `rubric_notes.md` 记录" 预测文件遗失,校准池缺该样本" | | 用户原本是 cold-start,半路想"补"已发作品的预测 | 一律记为 `**Reconstructed retrospective**`,不计入校准池——这是补的不是预测。可作为"观察"记录到 `rubric_notes.md` | --- ## 反模式(必须拒绝的请求) - 「帮我预测一下,但我先告诉你播放量你来反推就行」 → 拒绝。直接破坏盲度 - 「这条已经发了 5 天数据出来了,但你假装没看到,给我做个预测看会不会准」 → 拒绝。请改用 `_redo.md` 走 reconstructed 路径 - 「上次预测算错了,帮我把概率分布改一下」 → 拒绝。在复盘段说明 - 「能不能跳过 blind check 我有特殊原因」 → 询问原因;只有"格式修复"是合法的 bypass 理由 --- ## Why(为什么这套这么严) 盲预测是整个 cheat-on-content 校准循环的**唯一信号源**。一旦预测段被事后修改,所有"哪个维度被验证 / 推翻"的判断都失去基线——你不知道当初是真预测对了,还是事后改对了。 校准价值 = 预测精度 × 预测可信度。 - 预测精度可以靠 rubric 升级慢慢提升。 - 预测可信度一旦破坏不可恢复——**这是为什么 immutability 是 hook 层强制,不是君子协定**。