# 04 — 事故轉守衛（這一條產生複利）

> **目標：同一型錯誤只會花你一次。**

## 它防的是什麼

事故的第一句如果是「我下次會小心」，那句話**不可證偽**，所以它擋不住第二次。

而且有一個很殘酷的實證：某條規則白紙黑字寫在規則檔裡，**還是連續發作三次**。
三次都不是不知道規則。前兩次我的反應是「把規則寫得更醒目」——**三次都沒用**。

---

## 直接複製（踩坑之後用）

```
剛才那個問題，我要把它變成一條不會再發生的攔截。依序做：

1. 寫進 POSTMORTEMS.md，四段：
   · 症狀：我／使用者看到的是什麼（通常是「畫面全對」）
   · 表面原因：第一眼以為的
   · 結構原因：真正的。🚨 這一段不可以是「忘了」「沒注意」——
     那不是原因，是症狀的重述。要寫「為什麼這個系統讓人容易忘」。
   · 現在誰接住它：hook / 守衛 / 規則正文 / 誠實寫「沒有人」

2. 然後分流，由上往下問，接不住才往下掉：
   · 指令樣式、檔案事件、時間     → 加一條 hook（＋正向與反向各一個演練方向）
   · 「做完了也不會知道出錯」     → 加一支守衛（＋故障演練）
   · 只能靠判斷                   → 才留在規則正文裡

3. 如果答案落在「規則正文」，先停一下再問一次：
   真的接不住嗎？有九成的東西其實接得住，只是需要多想十分鐘。

4. 🚨 如果這是**同一條規則第二次**被違反 ——
   不要再改規則的寫法了（加粗、加驚嘆號、搬到最前面都沒用），
   直接去問「機器怎麼接住它」。
```

---

## 分流的判斷表

| 症狀 | 接得住的層 | 為什麼 |
|---|---|---|
| 「我又忘了先跑 X」 | **hook**（指令樣式） | 忘記是常態，不是意外 |
| 「這個檔改了，另一個沒跟上」 | **hook**（檔案事件，note） | 兩步編輯中間必然不對齊 ⇒ 不能 block |
| 「文件說 84，實際 103」 | **守衛**（現算 vs 宣稱） | 錯的那一刻沒有症狀 |
| 「某些地方漏掛了保護」 | **守衛**（數覆蓋率） | 漏掛不會報錯 |
| 「這是 demo 資料還是模板？」 | **規則正文** | 要看使用者能不能動它 —— 機器判斷不了 |
| 「需求本身就錯」 | **沒有人** | 誠實寫沒有人 |

---

## 🚨 加規則時必附反向案例

**一支「全部擋掉」的守衛，在只有正向測試的演練裡會拿滿分。**

而且誤報的代價比漏報高：

> **誤報會讓人乾脆把守衛關掉，然後你連漏報都不會知道。**

真實案例：一條規則的正則寫得太粗，**連續誤報六次** ——
它擋掉了偵測器自己的程式碼，也擋掉了正在解釋這條規則的文件。
六次全部是誤報，一次漏報都沒有。

⇒ **判準：偵測「值」，不要偵測「描述值的樣式」。**

建議的反向比例：**40% 左右**（41 個演練方向裡 18 個是反向）。

---

## 寫進 POSTMORTEMS 的時候，注意「結構原因」那一段

這一段是整篇的價值所在，也是最容易寫壞的一段。

❌ **不合格**（都是症狀的重述，不是原因）：
```
· 忘了跑守衛
· 沒注意到那個參數
· 應該要更仔細
```

✅ **合格**（回答「為什麼這個系統讓人容易犯這個錯」）：
```
· 這個參數預設是 False，所以漏傳＝沒有防護，**而且沒有任何錯誤訊息**
  ⇒ 覆蓋率必須由守衛去數，不能靠人記得。

· 本機的綠燈在回答一個不同的問題（邏輯沒壞 ≠ schema 在正式環境成立），
  但兩者在終端機上印出來的東西一模一樣。

· 一條規則躺在 700 行裡，注意力份額趨近於零。
```

**判準：結構原因那一段，應該要能推導出「該加哪一層防線」。**
推導不出來，代表你還沒找到真正的原因。
