diagnosing-bugslisted
Install: claude install-skill shumingyang-opencode/mattpocock-skills-zh-tw
# 診斷 Bug
一套應付硬 bug 的紀律。只有明確證成時才可跳過階段。
探索程式碼時,先讀 `CONTEXT.md`(如果存在)以取得相關模組的清晰心智模型,並檢查你要觸及的區域中的 ADR。
## 第一階段——建立回饋迴圈
**這就是本技能的核心。** 其他一切都是機械性作業。如果你對這個 bug 有一個**緊密**的通過/失敗訊號——一個會因為_這個_ bug 而變紅的訊號——你就會找到原因;二分、假設檢驗與插樁都只是在消耗它。如果你沒有這樣的訊號,再怎麼瞪著程式碼看也救不了你。
在這裡投入不成比例的精力。**要積極。要有創意。拒絕放棄。**
### 建立回饋迴圈的方法——大致依此順序嘗試
1. **失敗測試**,在任何觸及 bug 的接縫——單元、整合、e2e。
2. **curl / HTTP 腳本**,對著正在執行的開發伺服器。
3. **CLI 呼叫**,搭配固定裝置輸入,把 stdout 跟已知良好快照做 diff。
4. **無頭瀏覽器腳本**(Playwright / Puppeteer)——驅動 UI,對 DOM / 主控台 / 網路做斷言。
5. **重播擷取的追蹤**。把真實的網路請求 / payload / 事件日誌存到磁碟;在隔離環境中透過程式碼路徑重播。
6. **一次性測試架**。啟動系統的最小子集合(一個服務、模擬過的相依),用單一函式呼叫去觸發 bug 的程式碼路徑。
7. **屬性 / 模糊測試迴圈**。如果 bug 是「輸出偶爾錯誤」,跑 1000 個隨機輸入,找出失敗模式。
8. **二分測試架**。如果 bug 出現在兩個已知狀態之間(commit、資料集、版本),自動化「在狀態 X 啟動、檢查、重複」,讓你能 `git bisect run`。
9. **差異迴圈**。把相同輸入跑過舊版 vs 新版(或兩種設定),diff 輸出。
10. **HITL bash 腳本**。最後手段。如果必須由人點擊,用 `scripts/hitl-loop.template.sh` 驅動_他們_,讓迴圈仍然結構化。擷取的輸出會回饋給你。
建立正確的回饋迴圈,bug 就完成九成了。
### 收緊迴圈
把迴圈當產品來經營。一旦有了_一個_迴圈,就**收緊**它:
- 能不能讓它更快?(快取設定、跳過無關的初始化、縮小測試範圍。)
- 能不能讓訊號更銳利?(斷言具體症狀,而不是「沒有崩潰」。)
- 能不能讓它更確定?(釘住時間、播種 RNG、隔離檔案系統、凍結網路。)
一個要花 30 秒的搖擺迴圈只比沒有迴圈好一點點;一個 2 秒且確定的是緊密的——這是除錯的超能力。
### 非確定性 bug
目標不是乾淨的重現,而是**更高的重現率**。把觸發器重複 100 次、平行化、加壓力、收窄時間窗、注入 sleep。50% 會搖擺的 bug 可以除錯;1% 的不能——持續拉高重現率,直到它能被除錯。
### 當你真的無法建立迴圈
停下來,明確說出來。列出你試過什麼。向使用者要求:(a) 存取能重現它的任何環境,(b) 一個擷取的產物(HAR 檔、日誌傾倒、核心傾倒、帶時間戳的螢幕錄影),或 (c) 加入暫時正式環境插樁的權限。**不要**在沒有迴圈的情況下繼續做假設。
### 完成標準——一個會變紅的緊密迴圈
第一階段完成的條件是迴圈**緊密**且**能變紅**:你能指認出**一個指令**——一個腳本路徑、一次測試呼叫、一個 curl——你**至少已經跑過一次**(貼出該呼叫及其輸出),而