Agent Skills: /bugfix - 證據驅動除錯流程

證據驅動除錯流程。Use for: (1) Bug 修復的結構化流程(重現 -> failing test -> 根因 -> 最小修復 -> 回歸防護), (2) 防止盲目猜測修復, (3) 確保每次修復可驗證、可追溯、可累積。Use when: 收到 bug report、測試失敗需要調查、生產環境問題需要修復、任何非新功能的程式碼修正。

UncategorizedID: tarrragon/claude/evidence-driven-bugfix

Install this agent skill to your local

pnpm dlx add-skill https://github.com/tarrragon/claude/tree/HEAD/skills/evidence-driven-bugfix

Skill Files

Browse the full folder contents for evidence-driven-bugfix.

Download Skill

Loading file tree…

skills/evidence-driven-bugfix/SKILL.md

Skill Metadata

Name
evidence-driven-bugfix
Description
"證據驅動除錯流程。Use for: (1) Bug 修復的結構化流程(重現 -> failing test -> 根因 -> 最小修復 -> 回歸防護), (2) 防止盲目猜測修復, (3) 確保每次修復可驗證、可追溯、可累積。Use when: 收到 bug report、測試失敗需要調查、生產環境問題需要修復、任何非新功能的程式碼修正。"

/bugfix - 證據驅動除錯流程

核心原則:先有證據,才能動手。

沒有最小重現、沒有 failing test、沒有根因證據之前,禁止直接改程式碼。


反模式

| 反模式 | 後果 | |--------|------| | 「我大概知道怎麼修,先 patch 再說」 | 修到症狀不是根因 | | 跳過 failing test 直接改 code | 不知道到底修對沒 | | 沒有調查紀錄 | 下次同類 bug 又得重查一次 | | 一邊查一邊改 | 改動範圍失控,引入新問題 | | 修改測試斷言來讓測試通過 | 測試失去防護價值,bug 仍存在 | | 硬編碼預期值繞過測試 | 下次資料變動立即再次失敗 | | 不查根因直接改程式碼試試看 | 表面通過但根因未解,同類 bug 反覆出現 |


流程模式

本流程有兩種執行模式,依據緊急程度選擇:

| 模式 | 適用場景 | 必做階段 | 可延後階段 | |------|---------|---------|-----------| | 標準模式 | 一般 bug 修復 | Stage 1-8 全部 | 無 | | Hotfix 模式 | 生產環境緊急問題 | Stage 1-5 | Stage 6-8(24 小時內補齊) |


與 pre-fix-eval 的銜接

/pre-fix-eval 是錯誤的入口分類器/bugfix修復執行流程

| pre-fix-eval 產出 | bugfix 入口 | 說明 | |-------------------|------------|------| | 有初步根因定位(Stage 4 完成) | 從 Stage 2 開始 | 根因假設已有,直接補 failing test 驗證 | | 只有錯誤分類(Stage 1-3 完成) | 從 Stage 1 開始 | 需要完整重現和分析 | | 直接由用戶觸發(無 pre-fix-eval) | 從 Stage 1 開始 | 完整流程 |


八階段流程

Stage 1: 最小重現         [執行者: 認領 Ticket 的開發者]
    |
Stage 2: 補 Failing Test  [執行者: 同上]
    |
Stage 3: 驗證根因假設      [執行者: 同上 / incident-responder]
    |
Stage 4: 實作最小修復      [執行者: 語言對應的 developer agent]
    |
Stage 5: 回歸防護         [執行者: 同 Stage 4]
    |
Stage 6: 規格合規審查      [執行者: /parallel-evaluation 派發]
    |
Stage 7: 程式碼品質審查    [執行者: /parallel-evaluation 派發]
    |
Stage 8: 結案報告         [執行者: 認領 Ticket 的開發者]

與既有工具的銜接

| 階段 | 對應的專案工具 | |------|--------------| | 進入本流程前 | /pre-fix-eval(錯誤分類 + Ticket 開設) | | Stage 3 深度分析 | incident-responder(複雜根因需要時派發) | | Stage 4 實作 | 語言對應的 developer agent | | Stage 6-7 審查 | /parallel-evaluation(派發後以其檢查清單為準) | | Stage 8 結案 | /doc-flow(工作日誌)、/error-pattern add(錯誤模式) |


Stage 1:最小重現

目標:把「使用者描述的症狀」轉成「可判斷的重現條件」。

執行者:認領 Ticket 的開發者。

產出:重現步驟或腳本 + 環境條件記錄。

標準路徑(確定性 bug)

| 檢查項 | 說明 | |--------|------| | 重現步驟是否穩定? | 連續執行 3 次都能觸發 | | 環境條件是否記錄? | 瀏覽器版本、OS、資料狀態 | | 是否為最小條件? | 移除任何一步就無法重現 |

替代路徑(非確定性 bug)

適用場景:race condition、時序問題、Chrome Service Worker 生命週期問題、特定網站結構下觸發。

| 替代條件 | 說明 | |---------|------| | 有觸發條件描述 | 能說明在什麼狀態/時序下容易觸發 | | 有日誌或錯誤截圖證據 | 至少有一次觸發的完整記錄 | | 有機率估計 | 如「十次操作約觸發三次」 |

滿足以上三項即可通過閘門,進入 Stage 2 時使用防禦性測試策略(測試邊界條件而非精確重現)。

閘門:標準路徑或替代路徑任一滿足即可進入 Stage 2。兩者皆不滿足 → 回頭補充資訊。


Stage 2:補 Failing Test

目標:把重現步驟轉成穩定失敗的測試或結構化驗證計畫。

執行者:認領 Ticket 的開發者。

標準產出(可自動化)

至少一個 failing test,精確描述「預期行為」與「實際行為」的差異。

| 要求 | 說明 | |------|------| | 測試命名 | 描述 bug 行為,如 test_should_not_crash_when_empty_input | | 斷言精確 | 斷言預期的正確行為,不是斷言「不 crash」 | | 獨立可執行 | 不依賴其他測試的副作用 |

替代產出(無法自動化)

適用場景:Chrome 跨 context 通訊、popup/background 互動、UI 渲染問題等 Jest mock 無法真實覆蓋的場景。

產出一份結構化手動驗證計畫

## 手動驗證計畫

### 前置條件
[環境設定、資料準備]

### 驗證步驟
1. [具體操作步驟]
2. [預期結果]
3. [實際結果欄位(執行時填寫)]

### 通過標準
[明確的 pass/fail 判斷條件]

手動驗證計畫視為技術債,在 Stage 8 記錄,後續版本補自動化測試。

閘門:標準產出或替代產出任一完成即可進入 Stage 3。


Stage 3:驗證根因假設

目標:帶著 failing test 回頭讀 code,找出真正失敗的原因。

執行者:認領 Ticket 的開發者。複雜問題可派發 incident-responder

流程

  1. 列出所有合理的根因假設(不限數量;若超過 5 個,先依影響範圍排序,取前 3 個驗證)
  2. 執行「假設粒度自檢」(見下方清單,反模式 3 防護)
  3. 對每個假設設計驗證方式(加 log、讀 code、LSP 追蹤引用)
  4. 逐一排除,直到定位唯一根因
  5. 記錄排除過程(供日後參考)

假設粒度自檢清單(W17-104 反模式 3 防護)

Why:W17-102 Test G 設計時用「PM 是否已 Edit 過該檔」(檔案層級)作變因,否證後直接跳到「不是 PM 接觸史」結論。但真正的變因可能在不同粒度——「PM 是否已 Edit 過 prefix(.claude/)內任一檔」(前綴層級)。同一個變因在不同粒度可能得到相反結論。

Consequence:粒度錯誤會讓對照實驗的否證跳到錯誤結論。否證「該檔層級的 PM 接觸史」≠ 否證「整個 PM 接觸史變因」。

Action:列假設後、設計驗證實驗前,對每個假設執行粒度自檢:

| 粒度層 | 範例(以「檔案修改史」為變因)| 範例(以「session 狀態」為變因) | |------|----|----| | 檔案層 | 該特定檔是否被改過 | 該檔在當前 session 是否被觸碰 | | 前綴 / 目錄層 | .claude/ 下任一檔是否被改 | session 內是否曾操作該前綴 | | 模組 / 命名空間層 | 同模組任一檔是否被改 | session 內是否載入該模組 | | Session 層 | 任一 session 內檔案修改紀錄 | 當前 session 是否處於某狀態(已 commit / 已 pytest) | | 跨 session 層 | 跨 session 累積修改 | 跨 session 累積觸發狀態 | | 時間層 | 修改時間段(過去 N 分鐘 / N 小時 / N 天)| session 啟動時間距今 | | 全域層 | 系統全域狀態(CC 版本 / 環境變數 / OS) | runtime 全域狀態 |

自查問句(每個假設都要問):

  • 我選的粒度是「檔案層」「前綴層」「模組層」還是更高?
  • 是否有更細粒度(檔案內的特定行)或更粗粒度(整個目錄/session)的同類變因?
  • 否證該粒度後,是否需要驗證其他粒度才能完整否證該假設族?

強制動作:每個假設至少考慮 2 個相鄰粒度層;若只考慮單一粒度即進入驗證實驗,標記為「粒度未充分」並補實驗或在結論中明示。

粒度修正的教訓:先以大粒度否證後,若未驗證相鄰粒度即下結論,假設族否證不完整(需補相鄰粒度實驗)。

工具選擇

| 需求 | 工具 | |------|------| | 追蹤函式呼叫鏈 | Serena find_referencing_symbols | | 搜尋特定模式 | Grep / search_for_pattern | | 理解符號結構 | Serena get_symbols_overview |

外部因素退出點

若 Stage 3 確認根因不在本專案(如外部平台 API 行為變更、目標站點改版、上游套件行為變更):

  1. 記錄證據(API 文件、changelog、網站截圖)
  2. 開 workaround Ticket(類型 IMP,標題含「workaround」)
  3. 退出本流程,在 Stage 8 產出簡化報告

閘門:根因已確認(含外部因素確認) → 進入 Stage 4。禁止「看起來像是這裡的問題」就動手。

迭代上限:Stage 3↔4 來回不超過 3 次(Hotfix 模式下為 2 次)。超過上限仍無法定位 → 升級為 incident,派發 incident-responder 深度分析。Stage 6/7 回退到 Stage 4 後,迭代計數器重置(因根因已確認,問題性質不同)。


Stage 4:實作最小修復

目標:只改讓 failing test 通過的最小範圍。

執行者:語言對應的 developer agent。

| 原則 | 說明 | |------|------| | 最小變更 | 修改檔案數 <= 3,diff 行數建議 < 50 行 | | 超過需說明 | 超過上述範圍須在 Ticket log 記錄理由 | | 不擴大範圍 | 發現周圍有問題 → 開新 Ticket,不在此修 | | 確認 test 變綠 | 修完立即執行 Stage 2 的 failing test | | 修產品程式碼,不修測試 | 見下方「測試完整性保護」 |

測試完整性保護

修復的目標是讓產品程式碼符合測試描述的正確行為,而非反過來。

| 禁止行為 | 範例 | 為什麼禁止 | |---------|------|-----------| | 修改斷言值 | expect(result).toBe(3) 改成 toBe(5) | 測試描述的是正確行為,改斷言 = 改需求 | | 硬編碼通過 | 函式直接 return 3 讓測試過 | 沒有解決邏輯問題,只騙過斷言 | | 刪除失敗測試 | 刪掉「不方便」的測試案例 | 測試覆蓋率下降,bug 不被偵測 | | 放寬驗證條件 | toEqual 改成 toBeTruthy | 降低測試精度,喪失防護力 |

唯一允許修改測試的場景:Stage 3 根因分析確認測試本身的預期值有誤(如需求變更但測試未同步)。此時必須:

  1. 在 Ticket log 記錄「測試預期值修正」及修正理由
  2. 引用需求文件或 use case 作為新預期值的依據
  3. 修正後的測試仍必須能驗證正確行為

閘門:Stage 2 的 failing test 變綠 → 進入 Stage 5。未變綠 → 回到 Stage 3(受迭代上限約束)。


Stage 5:回歸防護

目標:避免同一個 bug 之後偷偷回來。

執行者:同 Stage 4。

| 動作 | 說明 | |------|------| | 確認 failing test 已納入 CI | 不是臨時腳本,是正式測試 | | 補邊界測試 | 根因相同但輸入不同的場景,至少補 1 個測試 | | 執行完整測試套件 | npm test 確認無回歸 |

測試失敗分流

完整測試套件出現失敗時:

| 情況 | 判斷方式 | 處理 | |------|---------|------| | 本次修復導致 | git stash 後失敗消失 | 回到 Stage 4 修正 | | 既有 flaky test | git stash 後仍失敗 | 開獨立 Ticket 追蹤,不阻擋本流程 |

閘門:完整測試套件通過(排除已記錄的 flaky test) → 進入 Stage 6。未通過 → 依分流表處理。


Stage 6:規格合規審查

目標:確認修復符合原始需求與驗收條件。

執行者:透過 /parallel-evaluation 派發,以其檢查清單為準。

以下為最低檢查項(若 /parallel-evaluation 已涵蓋則不重複):

| 檢查項 | 說明 | |--------|------| | 修復是否符合 use case 描述? | 對照 docs/use-cases.md | | 是否引入行為變更? | 對使用者可見的行為改變需記錄 | | 驗收條件是否滿足? | 對照 Ticket 的驗收條件 |

閘門:審查通過 → 進入 Stage 7。不通過 → 回到 Stage 4 修正(不重置 Stage 3 的根因結論)。


Stage 7:程式碼品質審查

目標:確認修法乾淨、可維護、無副作用。

執行者:同 Stage 6(通常與 Stage 6 在同一次 /parallel-evaluation 中完成)。

以下為最低檢查項(若 /parallel-evaluation 已涵蓋則不重複):

| 檢查項 | 說明 | |--------|------| | 符合專案品質基線? | 對照 .claude/references/quality-common.md | | 無硬編碼? | 常數提取、訊息外部化 | | 可觀測性? | 錯誤路徑有日誌 | | 無過度修改? | diff 只含必要變更 |

閘門:審查通過 → 進入 Stage 8。不通過 → 回到 Stage 4 修正。


Stage 8:結案報告

目標:整理修復紀錄,讓經驗可累積。

執行者:認領 Ticket 的開發者。

最小產出

## Bug Fix Report

### 症狀
[使用者觀察到的問題]

### 根因
[Stage 3 確認的根本原因]

### 修復方式
[Stage 4 的修改摘要]

### 影響範圍
[修改的檔案清單 + 影響的功能模組]

### 排除的假設
[Stage 3 中排除的其他假設及排除理由]

### 回歸防護
[Stage 5 新增的測試]

### 殘留風險
[已知但未處理的相關問題,已開 Ticket 追蹤]

### 技術債
[Stage 2 的手動驗證計畫待自動化、其他待處理項目]

### 關聯資訊
- Ticket ID: [ID]
- 修復耗時: [時間]
- 關聯 Ticket: [相關 Ticket ID]

額外動作

  • 若為常見錯誤模式 → /error-pattern add 記錄
  • 更新工作日誌 → /doc-flow
  • 標記 Ticket 完成 → /ticket track complete

複合 bug 處理

一個 bug report 實際上包含多個獨立問題時:

| 時機 | 判斷標準 | 處理 | |------|---------|------| | Stage 1 發現 | 重現步驟觸發多個不同症狀 | 拆分為獨立 Ticket,各自走完整流程 | | Stage 3 發現 | 根因分析指向多個獨立原因 | 當前 Ticket 只修第一個根因,其餘開新 Ticket |


閘門總覽

| 階段 | 閘門條件 | 不通過時 | |------|---------|---------| | Stage 1 → 2 | 標準路徑或替代路徑任一滿足 | 回頭補充資訊 | | Stage 2 → 3 | 有 failing test 或手動驗證計畫 | 不准開始分析 | | Stage 3 → 4 | 根因已確認(含外部因素) | 不准開始修改 | | Stage 3 → 8 | 外部因素確認(捷徑) | 產出簡化報告,開 workaround Ticket | | Stage 4 → 5 | failing test 變綠 | 回到 Stage 3(上限 3 次 / Hotfix 2 次) | | Stage 5 → 6 | 完整測試通過(排除已知 flaky) | 依分流表處理 | | Stage 6 → 7 | 規格合規審查通過 | 回到 Stage 4 修正(迭代計數器重置) | | Stage 7 → 8 | 品質審查通過 | 回到 Stage 4 修正(迭代計數器重置) |


使用方式

/bugfix

顯示本流程概覽和閘門總覽。

/bugfix start [ticket-id]

從 Stage 1 開始完整流程。行為:

  1. 若提供 ticket-id,載入 Ticket 資訊作為 bug 描述
  2. 若無 ticket-id,提示用戶描述症狀
  3. 引導進入 Stage 1

/bugfix stage N [ticket-id]

跳到指定階段。行為:

  1. 檢查前置閘門是否已通過(讀取 Ticket log)
  2. 閘門未通過 → 拒絕跳轉,提示需先完成哪個階段
  3. 閘門已通過 → 進入指定階段

/bugfix hotfix [ticket-id]

啟動 Hotfix 模式。行為:

  1. 執行 Stage 1-5(與標準模式相同)
  2. Stage 5 完成後直接產出簡化結案報告
  3. 自動建立延後 Ticket:「補齊 Stage 6-8 審查」(priority: P0,due: 24 小時內,who: PM 在下一個 session 檢查)

Last Updated: 2026-04-02 Version: 2.2.0 - 新增測試完整性保護規則(禁止修改測試繞過失敗)