debug-protocol · git:20260826.9a280e1 · 2026-08-26 · sha256 8a70ec629464b315
debug-protocol git:20260826.9a280e1A
Immutable. This exact content never changes and is served at /api/v1/blob/8a70ec629464b315.
--- name: debug-protocol description: 系統化除錯協定,含停損規則。在除錯卡住、同一問題修了 2 次以上還沒好、或開始想「隨便改改看會不會好」時使用。防止亂槍打鳥式修改把程式碼越改越爛。 --- # debug-protocol:系統化除錯 核心原則:**一次一個假設,一個假設一個最小改動,改完立刻驗證。** 沒有失敗重現指令之前,不准動任何程式碼。 ## 步驟 ### 1. 重現(沒有這步就沒有下一步) - 找到一條指令能穩定重現失敗(測試指令、curl、script)。貼出失敗輸出。 - 無法穩定重現 → 先解決重現問題(加 log、固定 seed、記錄環境),不要修「猜的 bug」。 ### 2. 建立假設日誌 在回覆中(或 scratchpad)維護一張表,之後每輪更新: ``` | # | 假設 | 驗證方式 | 結果 | |---|------|---------|------| | 1 | token 過期沒被 refresh | 在 refresh 處加 log 重跑 | 排除:有進 refresh | ``` ### 2.5 假設從哪來(想不出假設時照此優先序) 1. **最近改動優先**:`git log -p <相關檔>`、`git diff main`——大多數新 bug 來自新改動。 2. **差異分析**:能重現與不能重現的情境差在哪(環境、輸入、版本、時序)?差異處就是嫌疑處。 3. **按症狀查常見嫌疑**: - 間歇性失敗 → 時序/競態、共享狀態、外部依賴逾時 - 邊界值出錯 → off-by-one、型別轉換、空集合/None - 只在某環境出錯 → 設定、路徑、版本、環境變數 4. 以上都想不出 → 用二分縮小範圍(git bisect 或註解掉一半邏輯),別憑空猜。 ### 3. 驗證假設(先觀察,後修改) - 優先用「唯讀」手段驗證:讀碼、加 log、下斷點、bisect(`git bisect` 或手動二分註解)。 - 假設被證實之後才改程式碼;改動必須是針對該假設的**最小修改**。 ### 4. 每輪改動後 - 重跑步驟 1 的重現指令。 - 沒修好 → 把這輪改動 **revert 乾淨**(不留半套修改疊加),更新假設日誌,回步驟 2。 ## 停損規則(3-strike) 連續 3 輪修改都失敗時,**強制停手**,依序做: 1. `git checkout` / revert 回最後乾淨狀態。 2. 寫下:已排除的假設清單、目前掌握的事實、還沒看過的區域。 3. 擴大情報面(擇一): - 往上游讀更多程式碼(呼叫鏈、設定載入、初始化順序) - 用 `git log -p <file>` 查該區域最近改動 - 開一個 subagent 平行調查另一條假設線 - `git bisect` 找出引入問題的 commit 4. 帶著新事實重新進 plan mode 再開始。 5. 若再 3 輪仍失敗 → 停止,如實向使用者回報:事實、已排除假設、卡點、建議方向。**如實回報卡住遠優於硬掰一個「可能修好了」。** ## 修好之後(缺一不可) 1. 用一句話說出**根因**(說不出根因 = 可能只是碰巧不噴錯了,回步驟 2)。 2. 加一個會在此 bug 回歸時失敗的測試。 3. 跑 /done-check(其固定模板已含「已驗證:/範圍外發現:/AUTH:」三個逐字必填欄位)。 4. 檢查修法是不是貼補:自問「知道根因後,這是優雅解嗎?」 除錯過程中最常踩到 hard-rules #4:查根因時會看到一堆順眼想改的東西。**一律記到 `tasks/todo.md` 不順手修**,並在收工回報寫「範圍外發現: <項目,或「無」>」。 ## 禁止事項 - 禁止一輪改多個地方然後「看哪個有效」。 - 禁止用 try/except 吞掉錯誤來「修好」。 - 禁止沒讀過相關程式碼就套 Stack Overflow / 訓練記憶裡的通用解。 - 禁止修改測試的預期值來讓測試通過(除非能證明測試本身錯,且在總結中說明)。