Problem Framing 和 Spec-Driven Development 不是孤立的技法,它們在一個更大的工程實踐生態系中有明確的位置。這篇把相關技法的分工說清楚——哪個在上游、哪個在下游、哪個是平行輔助、哪個是事後驗證。

Interview Me(上游:意圖萃取)

時機:Problem Framing 之前。

Problem Framing 假設你已經知道「我們在討論的是什麼問題」。Interview Me 的工作更早:它用一個問題一個問題的結構訪談,確認需求方真正想要的是什麼(而不只是他們說出口的話)。

分工

  • Interview Me 輸出「確認過的意圖聲明」(outcome / user / success / constraint / out of scope)
  • Problem Framing 拿到這份聲明,做根因分析、用工具萃取問題陳述句
  • 兩者銜接點是「意圖聲明」→「問題陳述句」的轉換

為什麼分開? 一個 PM 說「我們需要一個 dashboard」,Interview Me 會發現他真正需要的是「每週站會時能在 10 秒內回答「這週跑了幾個 experiment」這個問題。這個意圖確認之後,Problem Framing 才能有效運作;沒有這步,framing 可能在錯的問題上做得非常扎實。

Planning & Task Breakdown(下游:拆解執行)

時機:Spec 完成、審核通過之後。

Planning & Task Breakdown 是 Spec-Driven 工作流程裡 Plan → Tasks 兩個階段的核心技法,它本身不改問題定義,也不寫規格,它的工作是:把一份已經審核過的 spec,拆解成有正確依賴順序、有驗收標準的可執行任務清單

關鍵原則:垂直切片(Vertical Slicing)

不要按技術層次橫向切(「先做所有資料庫、再做所有 API、再做所有 UI」),而要按功能路徑垂直切(「先讓這個功能能跑起來:schema + API + UI 一起」)。每個垂直切片完成後系統都是可運作的,不是一半。

任務大小指引

大小預期改動範例
XS1 個函式或設定改動新增一條驗證規則
S1–2 個檔案新增一個 API endpoint
M3–5 個檔案一個完整功能切片
L5–8 個檔案多元件功能,考慮再拆
XL8+ 個檔案必須再拆分

一個任務如果你無法在三條以內寫完它的驗收標準,代表它還不夠小。

Test-Driven Development(平行:把驗收標準化為可執行測試)

時機:Tasks 定義完成後,Implement 開始時。

TDD 的 RED 步驟(先寫一個失敗的測試)是把 Spec 的驗收標準化為機器可執行形式的動作。兩者的對應關係:

Spec success criteria        →   TDD red test
「用戶登入後,session 有效期 30 天」  →   test: session TTL = 30 days, assert expired after 29 days = false

Spec 與 TDD 的粒度差異

Spec 的驗收標準往往是「業務語言」,TDD 的測試是「技術語言」。兩者之間有一個翻譯步驟:

  • Spec:「已驗證用戶在 iOS 升級後仍維持登入狀態」
  • TDD test:keychain.readRefreshToken(after: .simulateOSUpgrade) should return validToken

這個翻譯不是自動的,需要工程判斷。但當翻譯做完,spec 的驗收標準就有了可回歸的機器保護。

Spec-Driven 沒有指定你用 TDD 實作——但 TDD 是把 spec 驗收標準落地為可執行形式的自然方法。兩者相容,互相補充,不互相取代。

Architecture Decision Records(ADR,平行:記錄重要決策的理由)

時機:Specify 和 Plan 階段,遇到需要做出架構選擇時。

Spec 記錄「我們決定做什麼」,ADR 記錄「我們為什麼做這個決定,當時有哪些選項,我們為什麼不選另一個」。

ADR 的典型格式:

## ADR-001:使用 Keychain + kSecAttrAccessibleAfterFirstUnlock 儲存 refresh token
 
**狀態**:已採用(2026-06-29)
 
**情境**:iOS 17 → 18 升級改變了 default Keychain access policy,
        原本用 kSecAttrAccessibleWhenUnlocked 儲存的 token 在升級後無法讀取。
 
**決策**:改用 kSecAttrAccessibleAfterFirstUnlock,並在升級後做一次 migration。
 
**考慮過的替代方案**
- UserDefaults:安全性不足,不考慮
- 重設 token(強制重登一次):短期代價大,且不解決根因
 
**後果**:用戶在設備重開機後才需要解鎖一次,之後 token 可在背景讀取(符合 Push Notification 的需求)。

ADR 不是 Spec 的替代品,而是 Spec 的補充:Spec 說「做什麼」,ADR 說「為什麼這樣做」。沒有 ADR,六個月後有人接手這份程式碼時,完全不知道當初為什麼不選比較「簡單」的方案。

Doubt-Driven Development(平行:決策點的對抗性審查)

時機:Implement 階段,遇到任何「非顯然」的決策時。

Doubt-Driven 的核心是:在任何重要決策站穩之前,以對抗性提示(adversarial prompt)生成一個「試圖推翻它」的審查,而不是「確認它沒問題」的審查。

與 Spec-Driven 的關係:

Spec-DrivenDoubt-Driven
定義「我們要做什麼、成功是什麼樣子」檢驗「我們的實作決策是否有盲點、邊界 case 是否遺漏」
工作在計畫層工作在決策層
輸出是文件輸出是「發現問題或確認無問題」的審查報告

何時在 Spec-Driven 流程裡使用 Doubt-Driven:

  • 任何影響資料結構的決策(一旦落 production 很難回頭)
  • 任何跨模組邊界的決策(影響範圍難以預測)
  • 任何「我確定這是對的」的時刻——「確定」往往是盲點藏匿的地方

技法全景:時間軸

─────────────────────────────────────────────────────────────────────────────▶ 時間

[Interview Me]  →  [Problem Framing]  →  [Specify]  →  [Plan]  →  [Tasks]  →  [Implement]  →  [Verify]
                                              │              │           │          │
                                             ADR            ADR      Planning   Doubt-Driven
                                         (架構決策)       (建置順序)  & Task     (每個非顯然決策)
                                                                    Breakdown
                                                                                    │
                                                                                   TDD
                                                                              (驗收標準 → red test)

每個技法都有它的時機,沒有一個能替代另一個。這個全景的用途是:當你不確定「現在應該用哪個工具」時,對照時間軸找到你目前在哪個階段,用那個階段的工具。

進一步閱讀

Spec-Driven Development(業界資源):

Problem Framing(業界資源):

延伸