# Systematic Debugging

> 在遇到任何 bug、測試失敗或非預期行為、尚未提出修復方案之前使用

- Skill: `shumingyang-opencode/systematic-debugging` (Agent Skill, multi-file: 11 files)
- Install (CLI): `npx skillmds@latest add shumingyang-opencode/systematic-debugging`
- Raw SKILL.md: https://api.skillmd.com/api/skills/shumingyang-opencode/systematic-debugging/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: shumingyang-opencode (https://skillmd.com/u/shumingyang-opencode)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/shumingyang-opencode/systematic-debugging

---


# 系統化除錯

## 概述

**核心原則：** 一律先找出根因再嘗試修復。只修症狀等於失敗。

**違反本流程的字面規定，就是違反除錯的精神。**

## 鐵律

```
未先調查根因，不得提出任何修復
```

如果沒有完成第一階段，就不能提出修復方案。

## 使用時機

任何技術問題都適用：
- 測試失敗
- 生產環境的 bug
- 非預期行為
- 效能問題
- 建置失敗
- 整合問題

**尤其是以下情況時使用：**
- 時間壓力下（緊急狀況更容易讓人想用猜的）
- 「就修一下而已」看似顯而易見
- 你已經嘗試過多種修復
- 之前的修復沒有效
- 你沒有完全理解問題

**以下情況不可跳過：**
- 問題看似簡單（簡單的 bug 一樣有根因）
- 你很趕時間（越急越容易返工）
- 主管要你「現在就修好」（系統化比亂槍打鳥更快）

## 四個階段

你必須依序完成每個階段，才能進入下一個。

### 第一階段：根因調查

**在嘗試任何修復「之前」：**

1. **仔細閱讀錯誤訊息**
   - 不要跳過錯誤或警告
   - 它們往往就包含確切的解法
   - 完整閱讀堆疊追蹤
   - 記下行號、檔案路徑、錯誤碼

2. **穩定重現**
   - 你能可靠地觸發它嗎？
   - 確切的步驟是什麼？
   - 每次都會發生嗎？
   - 無法重現 → 蒐集更多資料，不要用猜的

3. **檢查最近的變更**
   - 是什麼變更可能導致這個問題？
   - Git diff、最近的 commit
   - 新的相依套件、設定變更
   - 環境差異

4. **在多元件系統中蒐集證據**

   **當系統含有多個元件時（CI → 建置 → 簽署、API → 服務 → 資料庫）：**

   **在提出修復方案之前，先加入診斷儀器：**
   ```
   對每個元件的邊界：
     - 記錄進入元件的是什麼資料
     - 記錄離開元件的是什麼資料
     - 驗證環境/設定的傳遞
     - 檢查每一層的狀態

   先執行一次，蒐集可顯示在哪裡壞掉的證據
   然後分析證據，找出失敗的元件
   再深入調查該特定元件
   ```

   **範例（多層系統）：**
   ```bash
   # 第一層：工作流
   echo "=== Secrets available in workflow: ==="
   echo "IDENTITY: ${IDENTITY:+SET}${IDENTITY:-UNSET}"

   # 第二層：建置腳本
   echo "=== Env vars in build script: ==="
   env | grep IDENTITY || echo "IDENTITY not in environment"

   # 第三層：簽署腳本
   echo "=== Keychain state: ==="
   security list-keychains
   security find-identity -v

   # 第四層：實際簽署
   codesign --sign "$IDENTITY" --verbose=4 "$APP"
   ```

   **這能顯示出：** 哪一層失敗（secrets → workflow ✓、workflow → build ✗）

5. **追蹤資料流**

   **當錯誤位在呼叫堆疊深處時：**

   本目錄中的 `root-cause-tracing.md` 提供完整的回溯追蹤技術。

   **簡短版：**
   - 壞值的源頭在哪裡？
   - 是什麼用壞值呼叫了這裡？
   - 持續往上追蹤，直到找出源頭
   - 在源頭修復，不要在症狀處修復

### 第二階段：模式分析

**先找出模式再修復：**

1. **尋找可運作的範例**
   - 在同一個 codebase 中找出類似的可運作程式碼
   - 跟壞掉的部分相似、卻能正常運作的是什麼？

2. **對照參考實作**
   - 若在實作某種模式，請「完整」閱讀參考實作
   - 不要略讀——每一行都要讀
   - 套用前先徹底理解模式

3. **找出差異**
   - 可運作與壞掉的部分差在哪？
   - 列出每一項差異，不管多小
   - 不要假設「那個不可能有影響」

4. **理解相依關係**
   - 這需要哪些其他元件？
   - 需要什麼設定、組態、環境？
   - 它做了什麼假設？

### 第三階段：假設與測試

**科學方法：**

1. **形成單一假設**
   - 清楚陳述：「我認為 X 是根因，因為 Y」
   - 把它寫下來
   - 要具體，不要模糊

2. **最小化測試**
   - 做「最小」的變更來測試假設
   - 一次只改一個變數
   - 不要同時修多個東西

3. **繼續前先驗證**
   - 有效嗎？有 → 進入第四階段
   - 沒有效？形成「新的」假設
   - 不要再往上疊加更多修復

4. **不懂就說不懂**
   - 說「我不理解 X」
   - 不要裝懂
   - 尋求協助
   - 再多做研究

### 第四階段：實作

**修根因，不是修症狀：**

1. **建立會失敗的測試案例**
   - 最簡單的重現方式
   - 盡可能自動化測試
   - 沒有測試框架就寫一次性測試腳本
   - 修復前「必須」先有
   - 使用 `superpowers:test-driven-development` 技能來撰寫正確的失敗測試

2. **實作單一修復**
   - 針對已確認的根因處理
   - 一次只做「一個」變更
   - 不要「順手」改善
   - 不要夾帶重構

3. **驗證修復**
   - 現在測試通過了嗎？
   - 沒有其他測試壞掉嗎？
   - 問題真的解決了嗎？
   - 宣稱成功前，先使用 `superpowers:verification-before-completion` 技能

4. **如果修復沒有效**
   - 停下來
   - 數一下：你已經試過幾次修復？
   - 少於 3 次：回到第一階段，帶著新資訊重新分析
   - **大於等於 3 次：停下來，質疑架構（見下方第 5 步）**
   - 未經架構討論，不要嘗試第 4 次修復

5. **如果 3 次以上修復都失敗：質疑架構**

   **顯示架構問題的模式：**
   - 每次修復都在不同地方揭露新的共享狀態/耦合力/問題
   - 修復需要「大規模重構」才能實作
   - 每次修復都會在別處產生新症狀

   **停下來質疑根本：**
   - 這個模式從根本上就是對的嗎？
   - 我們是否「純粹因為慣性而硬撐」？
   - 應該重構架構，還是繼續修症狀？

   **在嘗試更多修復之前，先與你的人類夥伴討論**

   這不是假設失敗——這是架構錯誤。

## 紅旗——停下來，照流程走

如果你發現自己正在這樣想：
- 「先快速修一下，之後再調查」
- 「就試試改 X 看有沒有用」
- 「一次改多個地方，跑測試」
- 「跳過測試，我手動驗證就好」
- 「大概是 X，我來修」
- 「我沒完全理解，但這也許有用」
- 「模式說要做 X，但我可以改一下做法」
- 「主要的問題如下：[列出一堆未經調查的修復]」
- 在追蹤資料流之前就提出解決方案
- **「再試一次修復」（已經試過 2 次以上時）**
- **每次修復都在不同地方揭露新問題**

**以上任何一種情況都代表：停下來。回到第一階段。**

**如果 3 次以上修復失敗：** 質疑架構（見第四階段第 5 步）

## 表示你做錯方向的人類夥伴訊號

**留意這些轉向提示：**
- 「那不是沒發生嗎？」——你在未經驗證的情況下就下結論
- 「這會顯示給我們看嗎……？」——你應該加入證據蒐集
- 「別再猜了」——你在未理解的狀況下提出修復
- 「好好深入想一下」——要質疑根本，不要只修症狀
- 「我們卡住了？」（感到挫折）——你的做法行不通

**看到這些訊號時：** 停下來。回到第一階段。

## 常見的合理化藉口

| 藉口 | 真相 |
|--------|---------|
| 「問題很簡單，不需要流程」 | 簡單的問題一樣有根因。簡單的 bug 用流程反而快。 |
| 「緊急狀況，沒時間走流程」 | 系統化除錯比亂猜亂試「更快」。 |
| 「先試這個，之後再調查」 | 第一次修復會定下方向。一開始就做對。 |
| 「確認修復有效後再寫測試」 | 沒測過的修復留不住。先有測試才算數。 |
| 「一次修多個省時間」 | 無法隔離是哪個起了作用。還會製造新 bug。 |
| 「參考文件太長，我改一下模式就好」 | 只理解一半必然出 bug。要完整讀完。 |
| 「我看到問題了，我來修」 | 看到症狀 ≠ 理解根因。 |
| 「再試一次修復」（失敗 2 次以上之後） | 3 次以上失敗 = 架構問題。質疑模式，別再修。 |

## 快速參考

| 階段 | 關鍵活動 | 成功準則 |
|-------|---------------|------------------|
| **1. 根因** | 閱讀錯誤、重現、檢查變更、蒐集證據 | 理解「是什麼」與「為什麼」 |
| **2. 模式** | 尋找可運作範例、對照比較 | 找出差異 |
| **3. 假設** | 形成理論、最小化測試 | 假設得到確認或產生新假設 |
| **4. 實作** | 建立測試、修復、驗證 | bug 解決、測試通過 |

## 當流程揭露「沒有根因」時

如果系統化調查顯示問題確實是環境性、時間相關或外部的：

1. 你已完成流程
2. 記錄你調查了什麼
3. 實作適當的處理方式（重試、逾時、錯誤訊息）
4. 加入監控/日誌，供日後調查使用

**但：** 95% 的「沒有根因」其實是調查不完整。

## 輔助技術

這些技術屬於系統化除錯的一環，皆在本目錄中：

- **`root-cause-tracing.md`** —— 沿著呼叫堆疊回溯 bug，找出最初的觸發點
- **`defense-in-depth.md`** —— 找出根因後，在多個層次加入驗證
- **`condition-based-waiting.md`** —— 用條件輪詢取代任意逾時

