| name | cheat-predict |
| description | 給任務/學習主題/Coding Session 寫一份 immutable 盲預測日誌。是 cheat-on-content 整個校準循環的核心動作——預測段一旦寫完不可改,由 hook 強制。打分通過 Task tool 委派給 cheat-score-blind sub-agent(context-isolated channel B),主 Claude review 後落盤。觸發詞:"啟動預測"/"start prediction"/"寫預測日誌"。 |
/cheat-predict — AI 主導的盲預測 + 用戶 review
這個工具是"作弊器"——AI 幫你做判斷。所以 cheat-predict 的核心是:
- Claude 自己讀任務規格 + 打維度分 + 給 bucket + 概率分布 + 反事實場景
- 用戶 review 後回 "ok" 接受,或指出哪個維度 / 哪個判斷不對
- 默認走快路徑:用戶直接 ok → 落盤
- 慢路徑:用戶挑刺某個維度 → Claude 改 → 再 review → 直至確認
嚴格遵守 shared-references/blind-prediction-protocol.md——見過任何實際結果就不能寫預測,只能記 reconstructed。
Overview
[用戶:啟動預測 scripts/<id>.md]
↓
[Phase 0: blind check 自檢] ← 觸犯就拒絕
↓
[Phase 0.5: 入參解析]
↓
[Phase 1: 讀 script + rubric + state + 派生 confidence]
↓
[Phase 2: **委派 cheat-score-blind sub-agent**(Task tool)拿 N 維盲打 + per-dim confidence]
↓
[Phase 2.5: 主 Claude 對 blind 輸出做 review — 若任意維度 |delta| ≥ 2 vs 主估,彈給用戶裁定]
↓
[Phase 3: **Claude 自己**找錨點對比]
↓
[Phase 4: **Claude 自己**給 bucket + 概率分布 + 中樞] ← confidence 低時分布更平
↓
[Phase 5: **Claude 自己**寫反事實場景 + 關鍵校準假設]
↓
[Phase 5.5: **用戶 review**——展示完整草擬版,等用戶 "ok" 或挑刺]
↓
├─ "ok" → Phase 6 落盤
└─ "X 維度應該 Y 不是 Z" → Claude 改 → 再 review → 循環
↓
[Phase 6: 落盤 — 寫預測文件]
↓
[Phase 7: 更新 state.in_progress_session]
Constants
- SCRIPTS_DIR = scripts/ — 任務規格源目錄
- PREDICTION_DIR = predictions/ — 落盤目錄
- BLIND_CHECK = strict — strict(默認)/ lenient(僅警告,不推薦)
- BLIND_SCORING = on(默認)/ off —— 是否走 cheat-score-blind sub-agent。off 等價於
--skip-blind flag,標 last_prediction_self_scored: true
- DISAGREEMENT_THRESHOLD = 2 —— blind 與主 Claude 自評的單維度差異 |Δ| ≥ 此值 → Phase 2.5 彈用戶裁定
- MIN_ANCHORS = 2 — 錨點對比期望 2 個;不夠時顯式標"錨點 N/A"段
Inputs
| 必填 | 來源 |
|---|
<script-path> | 用戶參數;缺失則詢問 |
rubric_notes.md | 用戶項目根 |
.cheat-state.json | 狀態文件 |
predictions/*.md(可選) | 歷史預測,作為錨點 |
入參解析(Phase 0.5,在 blind check 之後)
用戶給的路徑應該是 scripts/<date>_<id>_<short>.md。如不在 scripts/ 下:
| 形態 | 處理 |
|---|
scripts/<date>_<id>_<short>.md | 標準路徑,直接用 |
<id> 或 <short> 簡寫 | glob scripts/*_<id>_*.md 或 scripts/*<short>*.md 找匹配 |
| 任意外部 .md 文件 | 警告 + 詢問:"建議把規格文件放到 scripts/.md 讓 cheat-on-content 管理。要我幫你 cp 過去並算 id 嗎?"用戶同意 → 建標準路徑再繼續 |
如 scripts/.md 不存在 → 報錯並詢問"你想 predict 的規格文件在哪?"
Workflow
Phase 0: Blind check 自檢(最關鍵,觸犯立即終止)
按 blind-prediction-protocol.md 的"子 skill 必須做的檢查清單"執行:
-
詢問用戶該任務 / Session 當前狀態:
- 尚未開始 / 進行中 → 通過
- 已完成且看過實際結果(K%/RW%、Q 分、完成時間、留存分等)→ 立即拒絕寫"預測",建議改用
_redo.md 路徑記 reconstructed retrospective
-
自檢對話歷史裡是否含實際 K%/RW%、實際任務完成時間、實際留存分等具體結果數字 → 命中則視為已見數據,按 strict 模式處理
-
BLIND_CHECK=lenient 模式:僅警告 + 強制在文件頭標注 **Reconstructed retrospective — NOT a blind prediction**,但仍允許繼續
通過 → 進入 Phase 0.5。
Phase 1: 讀規格 + rubric + state + 派生 confidence
- 按 Phase 0.5 解析後的路徑,讀
scripts/<id>.md 全文
- 計算
script_hash = sha256(script 內容)[:12] → header 用
- 讀
rubric_notes.md,識別當前公式 + 維度
- 讀
.cheat-state.json 拿 rubric_version、content_form、calibration_samples、typical_duration_seconds
- 從
calibration_samples 派生 confidence 等級 → 後續寫入 prediction header
Phase 2: 委派 cheat-score-blind sub-agent 拿盲打分
BLIND_SCORING=on(默認)—— 主 Claude 不再 inline 打分。通過 Task tool spawn cheat-score-blind,讓一個 context-isolated 的 sub-agent 只看 script + rubric_notes.md 給出 N 維分。
詳見 cheat-score-blind/SKILL.md 的"主 Claude 調用契約"段。Task prompt 必須精簡:
Spawn cheat-score-blind sub-agent.
Input:
script_path: <Phase 0.5 解析出的 scripts/<id>.md>
rubric_notes_path: rubric_notes.md
Task: 按 rubric_notes 當前公式給上面 script 打分。返回嚴格 JSON(見 cheat-score-blind SKILL.md Phase 2 schema)。
不要讀 state file / predictions/ / sessions/ 任何其他文件。
不要詢問用戶 —— 你沒有用戶。
調用前自檢:把 Task prompt 串過 grep -Ei '實際|retro|復盤|實績|K%|RW%|完成時間|留存'——命中 → 改 prompt 重發。
主 Claude 自己也內心估一份(不發 sub-agent)——純為 Phase 2.5 disagreement 檢測,不落盤、不替代 sub-agent 輸出。
沙盒 escape:BLIND_SCORING=off 或 --skip-blind —— 主 Claude 自己打 N 維。state 立刻標 last_prediction_self_scored: true + last_self_scored_at: <ISO>,cheat-status 持續提示警告。僅用於 Task tool 不可用的情況。
按當前公式算 composite——用 sub-agent 回傳的 dim 分,不用主 Claude 自估。
Phase 2.5: Blind 輸出 review + disagreement detection
拿到 sub-agent JSON 後,主 Claude 必做的事:
- JSON validity check:應能解析;不能解析 → 主 Claude 重發 Task(最多 3 次重試),仍敗 → abort,向用戶報告
- Contamination check:
self_check.any_contamination_signal == true → 警告用戶"sub-agent 自報疑似 contamination",但仍接受打分(confidence 降一檔)
- Refusal check:
refusal != null → 按 cheat-score-blind/SKILL.md Phase 2 的處理表對應路徑
- Disagreement detection(核心):
- 主 Claude 內心估一份 N 維分(Phase 2 末尾的"自估")
- 對每個維度算
delta = |主估 - blind|
- 任何維度
delta >= DISAGREEMENT_THRESHOLD(默認 2) → 彈給用戶裁定
彈裁定 UX(以 ai-coding 為例):
⚠️ blind sub-agent 跟主 Claude 在某些維度差異較大:
| 維度 | blind (sub) | 主 Claude 自估 | delta | sub-agent 理由 |
|---|---|---|---|---|
| SP | 3 | 5 | 2 | "Spec 描述模糊,邊界不清" |
| IR | 2 | 4 | 2 | "依賴鏈複雜,集成風險高" |
誰更準?
a) 信 sub-agent(隔離打分,但同 Claude 模型)
b) 信主 Claude 自估(有更多對話上下文,可能是 contamination)
c) 我自己定(你直接給分)
回 a / b / c <你的分數>
用戶選:
- a → 用 sub-agent 全套分進 Phase 3
- b → 用主 Claude 自估全套分(視為有意接受 contamination)→ 強制標
last_prediction_self_scored: true
- c → 用戶給的分覆蓋該維度,其他維度仍走 sub-agent → 記到
User Override
所有 delta —— 即使全 < THRESHOLD —— 都記錄到 prediction header 的 BlindScore Disagreement 字段。delta=0 也要記錄。
Phase 3: 錨點對比
所有階段都跑此 phase——錨點不夠時顯式標 N/A,不刪段。
- Glob
predictions/*.md,讀每個文件 header(提取 composite、實績 bucket、duration_seconds)。注意排除 reconstructed predictions
- 優先找同時長樣本(
Target Duration (s) 與本次差 ±20% 內)
- 在同時長(或全部)池里,找 2-4 個 composite 與本次預測 ±0.5 範圍內的樣本
- 如果池子太小(< 2 個)→ 輸出"錨點對比 N/A 段"——仍寫這段,告訴讀者錨點為何缺
- 列對照表;如跨時長,每行額外列"時長 vs 本次"列
- 關鍵診斷:如果某個錨點的 composite 幾乎相同但實績差異 ≥3x → 說明 rubric 沒捕獲關鍵維度。在文件里明確標注作為新觀察的種子
Phase 4: Bucket + 概率分布 + 中樞
所有階段都寫——confidence 低時分布更平,不是省略。
- 從
starter-rubrics/<content_form>.md 讀默認 bucket 邊界(除非用戶在 rubric_notes.md 自定義了)
- 選擇最可能的 bucket(headline call)
- 必須給出所有 bucket 的概率分布——加起來 100%
- 必須給出該 bucket 內的"中樞"點估計
反誠實陷阱:如果你給一個 bucket 95% 概率,下次預測錯了你沒法說"我其實不太確定"。真實的概率分布通常在 headline bucket 是 40-65%,剩下 ≥35% 散布在鄰近 buckets。
Phase 5: 反事實場景 + 關鍵校準假設
所有階段都寫——校準池小時關鍵校準假設可能沒有合適對照樣本,那就寫"無可對照樣本——仍寫下我對這次的核心賭注"+ 1-2 條這次想測的事。
反事實場景(4 段,每段對應一個可能的 bucket,寫"如果落在這里,意味著什麼 rubric 假設被驗證 / 推翻")。
關鍵校準假設(強烈推薦):
- 找一個對照樣本(最好是上一次預測)
- 明確寫"我押本次 vs 對照 = X 倍 / X 分差"
- 寫"如果反過來 / 差距 < N → 哪個 rubric 假設被推翻"
Phase 5.5: 用戶 review(核心——決定寫什麼進文件)
Phase 2-5 全部在內存里做完後,一次性展示完整草擬版給用戶(以 ai-coding 為例):
我的預測草稿(寫文件前 review):
📊 5 維分(rubric: v0):
| 維度 | 分 | 理由 |
|---|---|---|
| SP | 4 | "Spec 完整,邊界清晰" |
| LV | 3 | "依賴 3 個外部庫,中等槓桿" |
| TS | 3 | "tkinter + openpyxl,有測試難點" |
| CO | 4 | "功能邊界明確,複雜度可控" |
| IR | 2 | "多庫協同,集成風險偏高" |
→ composite ≈ 3.20
🎯 押 bucket:K 60-80%(中樞 ~70%),RW 20-35%(中樞 ~28%)
K% 概率分布: <40% 5% / 40-60% 25% / **60-80% 45%** / >80% 25%
RW% 概率分布: <20% 25% / **20-35% 45%** / 35-50% 25% / >50% 5%
confidence: 🔴 極低(第 1 個校準樣本)
🔍 錨點對比:N/A(首個樣本,無歷史錨點)
🤔 反事實:
如果 K > 80% → 驗證 AI 在這類任務高留存,LV 偏保守
如果 K < 40% → 推翻 Spec 完整性假設,IR 應更高
如果 RW > 50% → 說明集成層踩坑,IR 預測偏保守
🎲 關鍵校準假設:IR=2 押的是"多庫協同但各庫文檔完整"——如果有版本衝突這個假設就倒
——————————————————————————————
回 "ok" 我直接落盤,
或指出哪些維度 / 判斷不對(如 "IR 給 4,太保守" / "K 中樞應該 50% 不是 70%")。
用戶三種回應:
- "ok" / "可以" / "繼續" → 直接 Phase 6 落盤,header 標
Scored By: claude
- "X 不對,應該 Y" → Claude 改對應字段(不光改值,要更新 composite + 概率分布等連鎖影響),重新展示 → 循環回 Phase 5.5
- "全部重做" → Phase 2-5 重跑
用戶挑刺的字段記錄到 prediction header 的 User Override 段(Phase 6 寫入)。
Phase 6: 落盤
文件名約定:
predictions/YYYY-MM-DD_<id>_<short-title>.md
YYYY-MM-DD:今天日期(預測寫下的日期)
<id>:12 位 hash,對規格文件全文做 sha256 取前 12 位
<short-title>:3-8 字,去標點
header 必填字段:
Script Path(指向 scripts/.md)
Script Hash(Phase 1 算出的)
Calibration Samples + Confidence(從 state 派生)
Scored By:claude / claude+user_override
BlindScored By:subagent-v1 / main-claude-self(--skip-blind 時)/ mixed
BlindScore Disagreement:JSON 字段列表,每維度 {dim, blind, self, delta, decided_as},所有維度必記
User Override(如有覆蓋):列出哪些字段被用戶改了
留一個空的 ## 復盤 段:
通用域(daily-work / daily-learning):
## 復盤
(待填——T+RETRO_WINDOW_DAYS 天後跑 /cheat-retro)
ai-coding 域:
## 復盤(迭代式)
(每次 bug 修復後追加迭代復盤;功能完成後做最終復盤)
共用規則:寫文件前自檢所有組件齊全(缺錨點 / 關鍵校準假設 → 寫"N/A 解釋段",不刪段)。
Phase 7: 更新 state file
更新 .cheat-state.json:
{
"in_progress_session": {
"type": "prediction",
"file": "predictions/YYYY-MM-DD_<id>_<short>.md",
"started_at": "<ISO timestamp>",
"rubric_version": "<v0/v1/...>"
},
"last_prediction_self_scored": false,
"last_self_scored_at": null
}
last_prediction_self_scored:
true 僅當本次預測走了 --skip-blind 或 Phase 2.5 用戶選了 b
- 一旦
true → cheat-status 持續提示直到下次 normal cheat-predict(走 sub-agent)觸發後清回 false
in_progress_session 在對應 /cheat-retro(最終復盤)完成時清除。如果用戶預測後從未跑 retro(棄坑),下次 /cheat-status 檢測到陳舊 in_progress 會詢問是否清理。
Phase 8: 控制台總結
Cold-start 模式:
✅ 預測落盤(cold-start):predictions/2026-05-29_a3f2c1d4e5b6_PDF轉Excel.md
5 維打分:SP4 / LV3 / TS3 / CO4 / IR2
主要押注:K ~70%,RW ~28%
對比對象:N/A(首個樣本)
⚠️ ## 預測 段已 immutable(hook 鎖定)。
⚠️ Confidence 🔴 極低——前 2 個 session 是數據採集期,不是決策期。
進度:第 N 個 / 共 2 個 cold-start 期
下一步:
- 開始執行 → 每次 bug 修好後 → "/cheat-retro 這個 bug 修好了"
- 功能完成後 → "/cheat-retro 功能完成"
Complete 模式:
✅ 預測落盤:predictions/2026-05-29_a3f2c1d4e5b6_PDF轉Excel.md
K 押注:60-80%(中樞 70%)
RW 押注:20-35%(中樞 28%)
關鍵校準假設:IR=2 押的是"多庫協同但各庫文檔完整"
⚠️ ## 預測 段已 immutable(hook 鎖定)。
⚠️ 不要向我透露實際的 K%/RW% 直到你跑 /cheat-retro。
下一步:
- 每次 bug 修好後 → "/cheat-retro 這個 bug 修好了"
- 功能完成後 → "/cheat-retro 功能完成"
Key Rules
- blind check 是硬門檻。BLIND_CHECK=strict 模式下,觸犯即終止,不允許"軟處理"
- 整數維度分。不允許小數
- 概率分布 = 100%。不允許 95% + 8%;要誠實給分布
- 必須有
## 復盤 占位空段——否則 hook 不知道哪里是 immutable 邊界
- 不允許"先寫文件再討論分數"——落盤後預測段就鎖了;討論必須在 Phase 6 之前
- id 是規格文件 hash——重寫 _redo.md 時 id 不變,便於跨文件追溯
Refusals
- 「我已經做完了,但你假裝不知道給我做個預測」 → 拒絕。BLIND_CHECK=strict 直接終止
- 「我把預測段先寫一版,等數據出來再調」 → 拒絕。這是把 immutable 協議反著用
- 「跳過反事實場景,太麻煩」 → 拒絕。反事實是復盤診斷的依據,缺它復盤退化為"準 / 不準"
- 「可不可以只寫 bucket,不寫概率分布」 → 拒絕。概率分布是逼你誠實的工具
- 「sub-agent 太慢,你直接打就行」 → 用
--skip-blind flag 顯式聲明。不接受主 Claude 自作主張跳過 sub-agent
- 「Phase 2.5 選 b 後我不想標 last_prediction_self_scored=true」 → 拒絕。選 b 必須留下污染追蹤軌跡
- 「我是 cold-start 但想跑完整版預測」 → 允許,但在文件頭醒目標
**Numerical predictions in cold-start are NOT predictive — for self-education only**
Integration
- 前置:
/cheat-init 必須完成 + rubric_notes.md 存在
- 上游可選:
/cheat-score 反復嘗試不同規格版本
- 下游:
/cheat-retro(每次 bug 修復後 / 任務完成後)→ 累計 ≥ MIN_SAMPLES 後 /cheat-bump
- hook 依賴:
hooks/prediction-immutability.sh 必須已安裝在用戶 .claude/settings.json,否則 immutability 僅靠 SKILL.md 自律——cheat-status 會持續提示