---
name: lesson
description: 被使用者糾正後，把教訓寫成可長期沿用的規則記入 tasks/lessons.md。在使用者說「不對」「不是這樣」「我說過」或任何形式指出錯誤後立即使用；也用於定期把重複的 lesson 升級成 CLAUDE.md 規則、skill 或 hook。
---

# lesson：教訓落地與升級

目的：讓每次糾正只發生一次。lesson 寫得太抽象等於沒寫——下次的模型（可能更弱）必須能拿它直接比對情境。

## A. 記錄一條新 lesson

### 1. 先查重
在 `tasks/lessons.md` 內搜尋關鍵字。已有同類條目 → 不新增，改走「B. 升級」。

### 2. 用固定格式追加（檔案不存在才建立，放在 `tasks/lessons.md`）

```markdown
## [YYYY-MM-DD] <一行標題：動詞開頭>
- 觸發情境：<具體到下一個 session 能比對，含檔名/指令/使用者原話>
- 錯誤行為：<我實際做了什麼>
- 正確行為：<應該做什麼，可執行的一步步>
- 判準：<一句 if-then，讓弱模型能機械式套用>
- 狀態：first-hit
```

### 3. 品質判準：好壞範例

**壞例（禁止這樣寫）：**
```markdown
## [2026-07-05] 要更小心測試
- 觸發情境：測試出問題
- 正確行為：更仔細地處理測試
```
太抽象，無法比對，無法執行。

**好例：**
```markdown
## [2026-07-05] 改 API 回傳格式前先 grep 所有呼叫端
- 觸發情境：改了 `get_user()` 的回傳型別（dict→dataclass），沒查呼叫端，弄壞 3 處
- 錯誤行為：只改了函式本體與其單元測試就宣稱完成
- 正確行為：改任何公開函式簽名前，先 `grep -rn "get_user(" --include="*.py"` 列出所有呼叫端，逐一確認相容或一起改
- 判準：if 改動會變更函式簽名或回傳格式 → then 先列出全部呼叫端再動手
- 狀態：first-hit
```

## B. 升級（同一 lesson 第 2 次被觸發時）

1. 把該條目的 `狀態：first-hit` 改為 `狀態：promoted-to:<位置>`。
2. 依「制度分層」選升級目的地：
   - **規則可用程式判定**（如「禁止 commit 含 console.log」）→ 用 /update-config 做成 hook。最優先。
   - **1–2 行寫得完、每次都適用** → 加進 `~/.claude/CLAUDE.md`（全域通用）或 `<repo>/CLAUDE.md`（只限該專案）的「硬規則」。注意行數預算：加一條前先看能否刪一條或降級一條到 skill。
   - **多步驟程序** → 寫成 `~/.claude/skills/<name>/SKILL.md`，並在 CLAUDE.md 留一行觸發指引。
3. lessons.md 的原條目保留（作為升級紀錄），不刪除。

## 鐵則

- 糾正發生的**當下**就記，不要等任務結束（會忘）。
- 一條 lesson 只記一個模式；混多個就拆開。
- 判準欄位不可空白：寫不出 if-then 表示還沒想清楚，再想。
