指令用途
/code-review 對自某個固定點(commit、branch、tag、merge-base)至今的變更進行雙軸審查。兩個軸是:
- Standards(標準):這份 diff 是否遵循 repo 的編碼標準?外加一個 always-on 的 Fowler smell 基線。
- Spec(規格):這份 diff 是否忠實地實作了它的 originating issue / spec?
兩軸以平行子代理執行,這樣各自的判斷不會互相污染 —— 一個 smells 清單不會被「但它符合 spec」的念頭洗白。
兩軸
Standards 軸
檢查 diff 是否遵循 repo 自己文件化的編碼標準(CONTEXT.md、ADR、CONTRIBUTING.md 等)。在此之上疊加一個 always-on 的 Fowler「Bad Smells」基線 —— 一份精選的約 12 個高訊號 smell,內建於 SKILL.md 作為固定基線:
| Smell | 一句話 |
|---|---|
| Mysterious Name | 名字不說明意圖 |
| Duplicated Code | 重複的邏輯散落多處 |
| Feature Envy | 一個方法大量用別的物件的資料 |
| Data Clumps | 同一群資料到處一起出現 |
| Primitive Obsession | 該用值物件卻用原始型別 |
| Repeated Switches | 重複的 switch / if-else 階梯 |
| Shotgun Surgery | 一個改動要散改多處 |
| Divergent Change | 一個類別因不同理由被改 |
| Speculative Generality | 為「以後可能」而過早抽象 |
| Message Chains | a.b().c().d() 的長鏈 |
| Middle Man | 類別只轉發,沒自己的行為 |
| Refused Bequest | 子類不要繼承來的大部分東西 |
兩條約束規則保持安全:
- repo 文件化的標準覆寫基線 —— 你的專案明說的優先。
- 每個 smell 都是判斷呼叫,不是硬性違規 —— 報告為「值得考慮」而非「必犯」。
Spec 軸
檢查 diff 是否忠實實作了 originating issue / spec。它的搜尋順序:先找 originating issue,再找 spec,逐項對照 diff 是否覆蓋。
運作流程
- 固定比較點:依使用者指定的 commit、branch、tag 或 merge-base,確認 ref 可解析,擷取
git diff <fixed-point>...HEAD與 commit 清單,並確認 diff 非空。 - 找 spec 來源:依序檢查 commit message 的 issue reference、使用者提供的路徑、
docs/、specs/或.scratch/下對應的 spec;找不到時明確標記沒有 spec。 - 找標準來源:讀取 repo 內描述 coding standards 的文件,再套用 Fowler smell 基線;repo 自己的標準優先,smell 永遠是判斷呼叫而非硬性違規。
- 平行雙軸:啟動兩個與目前 harness 無關的平行 agent,一個跑 Standards、一個跑 Spec,並把必要的 diff、標準與 spec 脈絡傳給它們。
- 並列報告:兩份結果並列呈現,而非合併或重新排序,最後分別統計兩軸 finding。
實戰對話範例
範例一:commit 前審查
-
You:
幫我 review 這次 feature branch 的變更,base 是 main。
-
AI:
我會從
main...HEAD的 diff 進行雙軸審查。找到 originating issue:
#142 — 新增訂閱功能。我啟動兩個平行子代理:- Standards 子代理:檢查是否符合 repo 標準 + Fowler smell 基線。
- Spec 子代理:逐項對照 issue #142 的需求與 diff。
完成後並列報告。
-
AI(完成後):
Standards 軸
- ⚠️ Duplicated Code:折扣計算在
CartService和CheckoutService各出現一次。 - ✅ 其餘符合標準。
Spec 軸
- ✅ 滿千打九折 — 已實作。
- ❌ 「不滿千原價」— diff 找不到對應處理,可能漏了邊界。
- ✅ 顯示折扣後總價 — 已實作。
- ⚠️ Duplicated Code:折扣計算在
範例二:Fowler smell 基線觸發
- You:
review 一下這段 refactor。
- AI:
Standards 軸
- ⚠️ Middle Man:
SubscriptionService.subscribe()只是轉發給PlanRepository.create(),沒自己的行為。考慮這個類別是否必要,或該有真正的職責。 - ⚠️ Primitive Obsession:到處用
string planId,但PlanId是個值物件候選。
兩者都是判斷呼叫,不是硬性違規 —— 你的專案脈絡可能合理。
- ⚠️ Middle Man:
何時應該使用
- 實作完成後、commit / PR 前:上傳前的最後檢查。
- 完成重要功能:在合併前驗證。
/implement的收尾步驟:/implement驅動/tdd後會以/code-review收尾。- review 一個 branch / PR / work-in-progress 變更。
何時不應該使用
- 還在實作中、頻繁變動:等穩定下來再 review,否則白忙。
- 純探索性原型:用
/prototype,原型不上 review。 - 想找人類 opinions:這是結構性審查,主觀取捨用
/grilling。
重點:基線 vs 專案標準
Fowler smell 基線是固定底線,不會取代你 repo 的標準。優先順序:
- repo 文件化的標準最高優先 —— 它明說的算。
- Fowler smell 基線是 always-on 的補充 —— 在 repo 沒明說的地方提供判斷。
- 每個 smell 都是判斷呼叫 —— 從不是硬性違規。
與其他技能的關係
/code-review 是 /implement 的收尾步驟(/implement → /tdd → /code-review)。它從 /domain-modeling 取領域詞彙來判讀 diff,refactor 階段也從這裡接手(/tdd 已不做 refactor)。不確定該用哪個 skill 時,用 /ask-matt 來路由。