namesystematic-debugging
description (EN)Use when encountering any bug, test failure, or unexpected behavior, before proposing fixes
說明 (繁中)在遇到任何 bug、測試失敗或非預期行為、尚未提出修復方案之前使用

systematic-debugging

遇到 bug 先別急著修:四階段根因流程,先鎖住再挖根。

Systematic Debugging

系統化除錯

Overview

概述

Core principle: ALWAYS find root cause before attempting fixes. Symptom fixes are failure.

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

Violating the letter of this process is violating the spirit of debugging.

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

The Iron Law

鐵律

NO FIXES WITHOUT ROOT CAUSE INVESTIGATION FIRST
未先調查根因,不得提出任何修復

If you haven't completed Phase 1, you cannot propose fixes.

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

When to Use

使用時機

Use for ANY technical issue: - Test failures - Bugs in production - Unexpected behavior - Performance problems - Build failures - Integration issues

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

Use this ESPECIALLY when: - Under time pressure (emergencies make guessing tempting) - "Just one quick fix" seems obvious - You've already tried multiple fixes - Previous fix didn't work - You don't fully understand the issue

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

Don't skip when: - Issue seems simple (simple bugs have root causes too) - You're in a hurry (rushing guarantees rework) - Manager wants it fixed NOW (systematic is faster than thrashing)

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

The Four Phases

四個階段

You MUST complete each phase before proceeding to the next.

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

Phase 1: Root Cause Investigation

第一階段:根因調查

BEFORE attempting ANY fix:

在嘗試任何修復「之前」:

  1. Read Error Messages Carefully - Don't skip past errors or warnings - They often contain the exact solution - Read stack traces completely - Note line numbers, file paths, error codes
  1. 仔細閱讀錯誤訊息 - 不要跳過錯誤或警告 - 它們往往就包含確切的解法 - 完整閱讀堆疊追蹤 - 記下行號、檔案路徑、錯誤碼
  1. Reproduce Consistently - Can you trigger it reliably? - What are the exact steps? - Does it happen every time? - If not reproducible → gather more data, don't guess
  1. 穩定重現 - 你能可靠地觸發它嗎? - 確切的步驟是什麼? - 每次都會發生嗎? - 無法重現 → 蒐集更多資料,不要用猜的
  1. Check Recent Changes - What changed that could cause this? - Git diff, recent commits - New dependencies, config changes - Environmental differences
  1. 檢查最近的變更 - 是什麼變更可能導致這個問題? - Git diff、最近的 commit - 新的相依套件、設定變更 - 環境差異
  1. Gather Evidence in Multi-Component Systems
  1. 在多元件系統中蒐集證據

WHEN system has multiple components (CI → build → signing, API → service → database):

當系統含有多個元件時(CI → 建置 → 簽署、API → 服務 → 資料庫):

BEFORE proposing fixes, add diagnostic instrumentation: ``` For EACH component boundary: - Log what data enters component - Log what data exits component - Verify environment/config propagation - Check state at each layer

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

Run once to gather evidence showing WHERE it breaks THEN analyze evidence to identify failing component THEN investigate that specific component ```

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

Example (multi-layer system): ```bash # Layer 1: Workflow echo "=== Secrets available in workflow: ===" echo "IDENTITY: ${IDENTITY:+SET}${IDENTITY:-UNSET}"

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

# Layer 2: Build script echo "=== Env vars in build script: ===" env | grep IDENTITY || echo "IDENTITY not in environment"

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

# Layer 3: Signing script echo "=== Keychain state: ===" security list-keychains security find-identity -v

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

# Layer 4: Actual signing codesign --sign "$IDENTITY" --verbose=4 "$APP" ```

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

This reveals: Which layer fails (secrets → workflow ✓, workflow → build ✗)

這能顯示出: 哪一層失敗(secrets → workflow ✓、workflow → build ✗)

  1. Trace Data Flow
  1. 追蹤資料流

WHEN error is deep in call stack:

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

See root-cause-tracing.md in this directory for the complete backward tracing technique.

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

Quick version: - Where does bad value originate? - What called this with bad value? - Keep tracing up until you find the source - Fix at source, not at symptom

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

Phase 2: Pattern Analysis

第二階段:模式分析

Find the pattern before fixing:

先找出模式再修復:

  1. Find Working Examples - Locate similar working code in same codebase - What works that's similar to what's broken?
  1. 尋找可運作的範例 - 在同一個 codebase 中找出類似的可運作程式碼 - 跟壞掉的部分相似、卻能正常運作的是什麼?
  1. Compare Against References - If implementing pattern, read reference implementation COMPLETELY - Don't skim - read every line - Understand the pattern fully before applying
  1. 對照參考實作 - 若在實作某種模式,請「完整」閱讀參考實作 - 不要略讀——每一行都要讀 - 套用前先徹底理解模式
  1. Identify Differences - What's different between working and broken? - List every difference, however small - Don't assume "that can't matter"
  1. 找出差異 - 可運作與壞掉的部分差在哪? - 列出每一項差異,不管多小 - 不要假設「那個不可能有影響」
  1. Understand Dependencies - What other components does this need? - What settings, config, environment? - What assumptions does it make?
  1. 理解相依關係 - 這需要哪些其他元件? - 需要什麼設定、組態、環境? - 它做了什麼假設?

Phase 3: Hypothesis and Testing

第三階段:假設與測試

Scientific method:

科學方法:

  1. Form Single Hypothesis - State clearly: "I think X is the root cause because Y" - Write it down - Be specific, not vague
  1. 形成單一假設 - 清楚陳述:「我認為 X 是根因,因為 Y」 - 把它寫下來 - 要具體,不要模糊
  1. Test Minimally - Make the SMALLEST possible change to test hypothesis - One variable at a time - Don't fix multiple things at once
  1. 最小化測試 - 做「最小」的變更來測試假設 - 一次只改一個變數 - 不要同時修多個東西
  1. Verify Before Continuing - Did it work? Yes → Phase 4 - Didn't work? Form NEW hypothesis - DON'T add more fixes on top
  1. 繼續前先驗證 - 有效嗎?有 → 進入第四階段 - 沒有效?形成「新的」假設 - 不要再往上疊加更多修復
  1. When You Don't Know - Say "I don't understand X" - Don't pretend to know - Ask for help - Research more
  1. 不懂就說不懂 - 說「我不理解 X」 - 不要裝懂 - 尋求協助 - 再多做研究

Phase 4: Implementation

第四階段:實作

Fix the root cause, not the symptom:

修根因,不是修症狀:

  1. Create Failing Test Case - Simplest possible reproduction - Automated test if possible - One-off test script if no framework - MUST have before fixing - Use the superpowers:test-driven-development skill for writing proper failing tests
  1. 建立會失敗的測試案例 - 最簡單的重現方式 - 盡可能自動化測試 - 沒有測試框架就寫一次性測試腳本 - 修復前「必須」先有 - 使用 superpowers:test-driven-development 技能來撰寫正確的失敗測試
  1. Implement Single Fix - Address the root cause identified - ONE change at a time - No "while I'm here" improvements - No bundled refactoring
  1. 實作單一修復 - 針對已確認的根因處理 - 一次只做「一個」變更 - 不要「順手」改善 - 不要夾帶重構
  1. Verify Fix - Test passes now? - No other tests broken? - Issue actually resolved? - Use the superpowers:verification-before-completion skill before claiming success
  1. 驗證修復 - 現在測試通過了嗎? - 沒有其他測試壞掉嗎? - 問題真的解決了嗎? - 宣稱成功前,先使用 superpowers:verification-before-completion 技能
  1. If Fix Doesn't Work - STOP - Count: How many fixes have you tried? - If < 3: Return to Phase 1, re-analyze with new information - If ≥ 3: STOP and question the architecture (step 5 below) - DON'T attempt Fix #4 without architectural discussion
  1. 如果修復沒有效 - 停下來 - 數一下:你已經試過幾次修復? - 少於 3 次:回到第一階段,帶著新資訊重新分析 - 大於等於 3 次:停下來,質疑架構(見下方第 5 步) - 未經架構討論,不要嘗試第 4 次修復
  1. If 3+ Fixes Failed: Question Architecture
  1. 如果 3 次以上修復都失敗:質疑架構

Pattern indicating architectural problem: - Each fix reveals new shared state/coupling/problem in different place - Fixes require "massive refactoring" to implement - Each fix creates new symptoms elsewhere

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

STOP and question fundamentals: - Is this pattern fundamentally sound? - Are we "sticking with it through sheer inertia"? - Should we refactor architecture vs. continue fixing symptoms?

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

Discuss with your human partner before attempting more fixes

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

This is NOT a failed hypothesis - this is a wrong architecture.

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

Red Flags - STOP and Follow Process

紅旗——停下來,照流程走

If you catch yourself thinking: - "Quick fix for now, investigate later" - "Just try changing X and see if it works" - "Add multiple changes, run tests" - "Skip the test, I'll manually verify" - "It's probably X, let me fix that" - "I don't fully understand but this might work" - "Pattern says X but I'll adapt it differently" - "Here are the main problems: [lists fixes without investigation]" - Proposing solutions before tracing data flow - "One more fix attempt" (when already tried 2+) - Each fix reveals new problem in different place

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

ALL of these mean: STOP. Return to Phase 1.

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

If 3+ fixes failed: Question the architecture (see Phase 4.5)

如果 3 次以上修復失敗: 質疑架構(見第四階段第 5 步)

your human partner's Signals You're Doing It Wrong

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

Watch for these redirections: - "Is that not happening?" - You assumed without verifying - "Will it show us...?" - You should have added evidence gathering - "Stop guessing" - You're proposing fixes without understanding - "Ultra-think this" - Question fundamentals, not just symptoms - "We're stuck?" (frustrated) - Your approach isn't working

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

When you see these: STOP. Return to Phase 1.

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

Common Rationalizations

常見的合理化藉口

Excuse Reality
"Issue is simple, don't need process" Simple issues have root causes too. Process is fast for simple bugs.
"Emergency, no time for process" Systematic debugging is FASTER than guess-and-check thrashing.
"Just try this first, then investigate" First fix sets the pattern. Do it right from the start.
"I'll write test after confirming fix works" Untested fixes don't stick. Test first proves it.
"Multiple fixes at once saves time" Can't isolate what worked. Causes new bugs.
"Reference too long, I'll adapt the pattern" Partial understanding guarantees bugs. Read it completely.
"I see the problem, let me fix it" Seeing symptoms ≠ understanding root cause.
"One more fix attempt" (after 2+ failures) 3+ failures = architectural problem. Question pattern, don't fix again.
藉口 真相
「問題很簡單,不需要流程」 簡單的問題一樣有根因。簡單的 bug 用流程反而快。
「緊急狀況,沒時間走流程」 系統化除錯比亂猜亂試「更快」。
「先試這個,之後再調查」 第一次修復會定下方向。一開始就做對。
「確認修復有效後再寫測試」 沒測過的修復留不住。先有測試才算數。
「一次修多個省時間」 無法隔離是哪個起了作用。還會製造新 bug。
「參考文件太長,我改一下模式就好」 只理解一半必然出 bug。要完整讀完。
「我看到問題了,我來修」 看到症狀 ≠ 理解根因。
「再試一次修復」(失敗 2 次以上之後) 3 次以上失敗 = 架構問題。質疑模式,別再修。

Quick Reference

快速參考

Phase Key Activities Success Criteria
1. Root Cause Read errors, reproduce, check changes, gather evidence Understand WHAT and WHY
2. Pattern Find working examples, compare Identify differences
3. Hypothesis Form theory, test minimally Confirmed or new hypothesis
4. Implementation Create test, fix, verify Bug resolved, tests pass
階段 關鍵活動 成功準則
1. 根因 閱讀錯誤、重現、檢查變更、蒐集證據 理解「是什麼」與「為什麼」
2. 模式 尋找可運作範例、對照比較 找出差異
3. 假設 形成理論、最小化測試 假設得到確認或產生新假設
4. 實作 建立測試、修復、驗證 bug 解決、測試通過

When Process Reveals "No Root Cause"

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

If systematic investigation reveals issue is truly environmental, timing-dependent, or external:

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

  1. You've completed the process
  2. Document what you investigated
  3. Implement appropriate handling (retry, timeout, error message)
  4. Add monitoring/logging for future investigation
  1. 你已完成流程
  2. 記錄你調查了什麼
  3. 實作適當的處理方式(重試、逾時、錯誤訊息)
  4. 加入監控/日誌,供日後調查使用

But: 95% of "no root cause" cases are incomplete investigation.

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

Supporting Techniques

輔助技術

These techniques are part of systematic debugging and available in this directory:

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

  • root-cause-tracing.md - Trace bugs backward through call stack to find original trigger
  • defense-in-depth.md - Add validation at multiple layers after finding root cause
  • condition-based-waiting.md - Replace arbitrary timeouts with condition polling
  • root-cause-tracing.md —— 沿著呼叫堆疊回溯 bug,找出最初的觸發點
  • defense-in-depth.md —— 找出根因後,在多個層次加入驗證
  • condition-based-waiting.md —— 用條件輪詢取代任意逾時