架構決策
將架構問題轉化為具體、有依據、可驗證的決策。
此技能負責決策方法、記錄生命週期和交付成果。engineering-philosophy 負責共享的設計和寫作原則。執行中的 agent 和任務擁有權限、委派和輸出意圖。
1. 建立決策
陳述問題、受影響的系統、所需的結果和範圍排除。
當決策會實質影響跨元件契約、品質需求、所有權、信任、運作、依賴或未來變更成本時,它值得一份 ADR。
常規的局部設計不需要 ADR。除非呼叫者明確要求正式記錄,否則回傳 no-adr-needed 以及答案和簡短理由。
識別相關的決策。將可獨立逆轉的選擇分開記錄,但不要將一個連貫的決策分解成每個實作步驟的 ADR。
對於現有的 ADR,確定任務是釐清、重新評估還是替換。不要將歷史解釋默認轉換為新的建議。
2. 建立情境和驅動因子
閱讀適用的指示、相關的已接受決策,以及足夠的實作證據,以了解受影響的邊界。
在描述應該存在的東西之前,先確定現有的東西。對於全新專案,使用提供的需求並標明缺少實作證據。
分開:
- 硬性限制:必需的契約、政策、相容性、資料規則或明確的限制。
- 決策驅動因子:區分可行選項的品質和權衡。
- 假設:建議所依賴的未經驗證的條件。
確定哪些驅動因子最重要。僅在可辯護時推斷出暫定的優先順序,並標記它。當未解決的優先順序會實質改變產品行為、成本或風險承受度時,請向授權單位詢問。
將模糊的目標具體化。對於效能或可靠性要求,在已知時識別工作負載、失敗情境、可觀察的結果和閾值。將為討論而發明的閾值標記為「提議的」,絕不能作為「要求」。
不要為了證明設計合理性而捏造流量、服務層級目標、截止日期、團隊容量、成本或未來需求。
3. 解決決策關鍵未知項
調查可能改變可行性、排名、安全性或實作範圍的不確定性。
優先使用當前系統的本地證據。對於外部行為使用主要文件,並檢查相關版本和環境。
區分直接觀察、提供的證據、推論和未經測試的假設。供應商的能力並不能確定本地配置已啟用它。
當證據足以支持決策或進一步閱讀不太可能改變它時,停止研究。
當需要測量時,定義一個有範圍的實驗:問題、代表性工作負載、比較基準、可觀察結果、通過/失敗標準,以及結果如何改變選擇。
不要聲稱實驗已執行。當執行或原始碼存取超出當前 agent 的權限時,回傳具體的證據請求。
4. 比較可行選項
考慮保留當前設計和最小足夠的變更。解釋何時其中之一不符合硬性限制。
僅比較可行的替代方案。不要為了讓偏好選項勝出而發明薄弱的候選方案、要求固定的選項數量,或研究某個類別中的所有產品。
根據相同的決策驅動因子評估選項。包括相關的遷移工作、運作所有權、故障處理、經常性成本、耦合性和可逆性。
明確拒絕硬性限制違規。不要用加權分數將其平均掉。
偏好帶有具體理由的定性比較。僅在其輸入和權重可辯護時使用數值評分;暴露對不確定輸入的敏感性。
一項技術的流行度、一個命名的架構模式或聲稱的可擴展性本身並不是專案特有的好處。
5. 挑戰偏好選項
在提議的邊界內追溯重要的成功路徑和後果最嚴重的可信失敗路徑。
僅考慮相關的關注點:
- 所有權和契約:權威狀態、允許的依賴、相容性、交易和生命週期所有權。
- 故障和恢復:部分完成、重複傳遞、排序、重試、超時、取消、過載和修復。
- 安全性和隱私:信任邊界、授權、隔離、敏感資料和可信的濫用路徑。
- 運作和變更:部署、可觀測性、資源限制、容量證據、遷移、持續支援和退出成本。
使用架構參考來獲取設計原則,而不是在此處複製其法則。
陳述對建議的最強烈反對意見以及可能推翻它的證據。檢查是否有更簡單的選項能滿足相同的限制。
對於風險較高的轉換,描述共存和恢復。找出回滾不安全或不可能的臨界點。當回逆會導致資料遺失或破壞相容性時,使用前進或修復策略。
僅在差異重要時描述當前、過渡和目標狀態。不要為了裝飾決策而產生圖表。
6. 做出決策
當證據支持時,推薦一個方向。說出決定性的驅動因子以及團隊將接受的成本或限制。
在揭露的假設下進行,前提是這些假設不會使安全的建議無效。不要因無關緊要的未知項而卡住。
當一個重要的假設仍未解決時,陳述暫定的偏好以及會改變它的確切條件。不要將其呈現為無條件承諾。
當沒有選項能滿足硬性限制時,請明確說出。確定最小的限制變更或所需的實驗;不要悄悄削弱需求。
使用一個任務結果:
| 結果 | 含義 |
|---|---|
recommended | 在陳述的限制和假設範圍內支持一個具體建議。正常的批准可能仍然待定。 |
needs-evidence | 一個已命名的證據缺口阻礙了可靠的選擇。在可能時包含暫定偏好和解決檢查。 |
needs-authority | 一個重要的需求、例外或風險決策必須由授權人解決。解釋技術建議和所需的確切權限。 |
no-adr-needed | 問題是常規局部設計。回答它,不要強加正式的架構流程。 |
這些結果描述的是任務結果,而不是 ADR 批准、實作完成或程式碼審查結論。
7. 記錄決策
當儲存庫有 ADR 慣例時,使用它。否則,閱讀 ADR 模板 並使其適應決策。
一份記錄必須保留問題、情境、決定性的驅動因子、選擇的方向、可行的替代方案、接受的缺點、不確定性和驗證條件。保持簡短以便維護。
一份記錄包含一個連貫的架構決策。連結相關記錄,而不是複製其理由。
如果沒有儲存慣例,建議使用 docs/decisions/。在提議最終識別碼之前,檢查現有編號。建議的路徑不是已儲存的檔案。
生命週期和權威
預設新的 ADR 為 proposed。
僅當接受有指定權威的證據,或專案明確將該決策委派給呼叫者或當前 agent 時,才使用 accepted。記錄接受的基礎。要求推薦、草擬或評估不等於接受。
一個選定的技術選項在正常批准之前可能保持 proposed。不要僅僅因為批准尚未發生就使用 needs-authority。
遵循專案其餘的生命週期狀態。沒有慣例時,酌情使用 rejected、deprecated 和 superseded。
保留已接受的歷史理由。一個實質改變的決策會獲得一個帶有取代關係的新記錄。舊記錄仍然可用;當新決策被接受時,授權作者會更新其狀態和取代連結。
與 ADR 矛盾的實作並不會自動取代它。確定需要修正的是實作、記錄的決策還是管理要求。
接受並不建立實作、運作驗證或部署權限。
證據和確認
在上下文或它們所支持的理由旁邊引用重要的主張。在可能時使用持久化的儲存庫參考和特定版本的外部來源。
不要使用無法存取的 session 識別碼作為持久化 ADR 中的唯一證據。保留指向基礎來源的連結,或清楚標明所提供的證據。
定義確認架構符合性和預期結果的檢查。將每個重要的不變量連接到一個可觀察的檢查。
僅在已知時使用專案支援的命令。否則,描述測試或檢查,不要發明可執行的指令。
將未來的檢查標記為未執行。在已知時根據既定角色識別負責人,否則讓所有權未解決。不要將工作分配給未參與的人。
定義一個具體的重新檢視觸發條件:驗證失敗、限制改變、測量到的閾值或相關依賴變更。「需要時重新檢視」是沒有用的。
交付物
遵循明確的呼叫者格式。否則,以一個簡潔的決策摘要開頭:
- 建議:選擇的方向和決定性原因,或未解決的選擇。
- 結果:四個任務結果之一。
- 範圍:受影響的邊界和重要的排除項。
- 信心:高、中或低,附帶證明該標籤合理的證據和假設。不要將其呈現為測量到的機率。
對於重要的決策,回傳完成的 ADR。當選擇仍然受阻時,保持其為 proposed 並將選擇標記為暫定或未解決。
僅在需要時添加簡短的交接說明。識別約束條件、未解決的證據或權限,以及下一個負責的角色。參考 ADR 而不是重複其內容。
不要將交接變成階段性實作計劃、程式碼審查報告或未經請求的修補程式。
對於 no-adr-needed,回傳答案、結果和理由,不要包含空的模板章節,除非呼叫者要求記錄。
最終檢查
確認結果回答了實際的決策,在可支持時識別出偏好選項,並解釋為什麼沒有選擇最強的替代方案。
檢查硬性限制、現有決策、運作後果、驗證聲明、接受權限和範圍邊界。
移除發明的事實、裝飾性的分數、不必要的層次、重複的理由,以及聲稱未執行的工作已完成的主張。