
Day 11 把取消訂單的核心規則寫進程式,Day 12 再查 API、訂單狀態與通知,修掉整合時發現的問題。功能一步步往前走,接下來要把修改交給人審查。
但如果只附一句「測試都過了,請幫忙 Review」,接手的人仍得自己查:這次改了什麼、哪些結果可以核對、還有哪些事要由我決定?
今天要交出的,就是一份有依據的審查結果與待決單。沿用同一個訂單案例,但本次實跑回到 Day 11 的 Domain 規則修改,使用當時既有的 API 整合紀錄;不是把昨天的通知修復當成同一份程式接著重審。
我把這份修改交給 Day 4 包好的 Claude Code 審查工具 review-kit。它是自訂 plugin,裡面的 review-pr skill 引導 Claude 讀需求、查差異、核對證據,再列出缺件與待決事項。這次回覆是 OWNER_REQUIRED:需要有決策權的人確認。
這個結果只告訴我該找誰,還沒回答要請他決定什麼。接下來就把這件事整理清楚。
這次不是等程式寫完,才開始問「已付款訂單取消,要不要提出退款要求」。教學用的 rules-v2.md 早已指定答案:
RefundRequested 只是旗標,不連付款服務,也不執行退款。Day 11 按這些規則改程式與測試。其中一行修改是:
+ var refundRequested = order.Paid && !order.Cancelled;
這一行結合周圍既有的條件判斷,決定取消結果裡的退款旗標。不能單看這行,就認定出貨、重送與所有例外都已處理。
教學規格中有模擬的 Owner 決定,但那是實作題目的前提。這份 PR 也明寫「指定教學目標,非正式公司批准」,沒有真人接受紀錄。
Owner 不是來重新出一次考卷,而是核對這份交付,是否落在有權接受的規則、範圍與風險之內。 這個人可能是負責業務規則的產品負責人或領域負責人,不是隨便找一位工程師按 Approve。
需求與授權應在開工前釐清。到了審查,我會把問題分開處理:

這是依本案例整理的待決範圍,不是簽核紀錄。
這輪沿用 review-kit 0.1.0,沒有另外修改 skill。啟動時以 --plugin-dir 指向 plugin,再要求 Claude Code 呼叫 review-kit:review-pr。工具紀錄確認它實際載入了 skill,接著讀取:
ticket.md:這次採用的教學需求。diff.patch:Domain 改動。PR.md:五個交接項目、證據入口與未決事項。模型唯讀查核,測試由外層程式執行。Claude 在這一步的用途,是讓接手的人看得見「改了什麼、依據在哪、還缺什麼」,減少從對話裡重新找背景的工作。
第一輪要求補綠燈輸出與前後狀態/循序圖。我核對後,圖確實沒附,但測試輸出早已存在,直接讀檔就能看見七個情境的 PASS。把三個檔案的時間戳排在一起:
| 時間(09-22) | 事件 | 來源 |
|---|---|---|
| 07:25:38 | runs/impl/tests.txt 寫入,七個情境 PASS |
檔案 mtime |
| 07:27:21 | 審查開始 | plugin-review-01/trace.jsonl 第一筆 |
| 07:29:32 | 審查報告寫出:「tests.txt does not exist」 | result.md mtime |
檔案在審查開始前 1 分 43 秒就已經存在;報告說它不存在時,它已經存在近四分鐘。
所以這次要做兩件不同的事:補上缺的圖,更正「測試輸出不存在」這項誤判。搜尋為何失敗尚未查明;我沒有為了補件重跑測試,也沒有把原本就有的結果當成新成果。
第二輪補上圖與綠燈檔案的直接位置,再交給同一個 skill:
| 項目 | 第一輪 | 第二輪 |
|---|---|---|
| 綠燈輸出 | 誤判不存在 | 直接讀檔,確認七個情境 PASS |
| 狀態與循序圖 | 確實未附 | 已讀新增圖檔 |
| 核心規則人審 | OWNER_REQUIRED |
仍是 OWNER_REQUIRED |
第二輪仍把圖裡沒有的規則編號說成有,這項描述也不能直接採用。核對後留下的是可追查的檔案與結果;查核資料補齊了,Owner 的接受決定仍待處理。
Claude 看見這次修改涉及 Paid,要求 Owner。它同時指出,技術上只是從既有欄位推出布林值,沒有新增外部呼叫、套件或改動簽名。
修改小,不代表它改變的規則不重要。這次模型有遵守政策,但寫在 skill 裡的指令,還不能當成強制執行的限制。
因此另用兩個檔案處理明確的升級條件:
routing-policy.json:列出必須找 Owner 的核心路徑 src/Domain/。route-review.py:讀取 diff 的檔案路徑並套用政策;無法判讀 diff,也不自動降級。這份修改的本機輸出:
{
"route": "OWNER_REQUIRED",
"paths": ["src/Domain/Cancellation.cs"],
"owner_hits": ["src/Domain/Cancellation.cs"],
"accepted": false,
"reason": "core path"
}
core path 表示命中核心路徑,不是模型評分。在政策與執行器未被改動的前提下,Claude 說「只是布林值」不會解除這個條件。非核心路徑仍要審查,也不是自動接受。
accepted:false 只是這支腳本的輸出欄位,不是合併限制。 判級在本機執行,還沒接上遠端 PR。
現在手上有規則版本、修改差異、測試結果,也知道哪些模型說法需要更正。我把它們收成一頁,讓接手的人先看已知結果,再看要自己決定的部分。
這是依現有證據整理的示範寫法,尚未取得真人簽核:
本次變更
已付款且尚未出貨的訂單,首次取消會提出退款要求;
再次取消不重複提出。
已核對的依據
rules-v2 BR-03/BR-04、diff、七個情境的測試輸出,
以及本次審查使用的既有 API 整合檢查。
缺的圖已補上;「綠燈輸出不存在」已更正。
需要誰接手
具備本次取消/退款規則決策權的 Owner;本例尚未指定真人。
請確認
1. 本次交付是否符合被授權採用的規則版本與適用情境?
2. 接受範圍是否僅限退款要求旗標,不包含真實退款?
3. 通知契約、並行、重啟與正式環境尚有缺口,
哪些必須補驗後才能接受,哪些明確排除於本次範圍?
決定紀錄
目前狀態:待接受,未核准合併。
由 Owner 填寫:接受/要求補件/不接受,
留下姓名、理由、接受範圍與對應版本。
需要補件時,另記負責人與重驗條件。
例如「旗標符合教學規格」不能被轉述成「退款功能可以上線」。若需求包含正式金流,現有證據就不夠,不能靠一個簽名把未驗證的部分變成已通過。
Owner 接住的是具體選擇與責任。Claude 可以先列出選項和依據,人核對重要推論後做決定,再把決定留給下一個接手者。
今天往前走的一步,是把「請幫我看一下」整理成一份可以做決定的審查結果。這份修改仍待 Owner 接受,但要查的依據、要補的東西與要做的決定,已經分開列出。是否因此減少人的審查時間,還需要另外記錄。
接下來,已經確認要執行的檢查,不能每次都靠人記得。下一步是把它們接進固定流程,再故意放回一份不合格的修改:流程會在該停的地方停下來嗎?還是只是程式跑壞了,卻被我當成成功攔截? Owner 的接受決定仍另外保留,不會被 CI 綠燈代填。
參考資料:
本文實作說明
| 實跑 | 材料 | 回合/秒/費用估值 | 結果 |
|---|---|---|---|
plugin-review-01 |
ticket、diff、PR.md、測試定義與輸出 | 28/132/US$0.35 | OWNER_REQUIRED;兩項退件,其中一項誤判 |
plugin-review-02 |
同上,補兩張圖與綠燈檔的直接位置 | 24/91/US$0.33 | 仍是 OWNER_REQUIRED;補件解決材料問題,沒有改變人審條件 |
route-review.py |
只讀 diff 的檔案路徑,不呼叫模型 | 不適用 | OWNER_REQUIRED、accepted:false、reason:core path |
plugin-review-01/trace.jsonl 第一筆與 result.md mtime。這些紀錄支持更正缺件判斷,不足以判定搜尋失敗根因。examples/sdlc-development/runs/plugin-review-01/、plugin-review-02/,包含提示、trace 與回覆;第一次 PR 快照另外保存。第二輪補件與目標來源明確,不是提示優劣的受控比較。--plugin-dir 本機載入,工具為 Read/Grep/Glob/Skill。沒有宣稱已在公司分發或遠端 PR 自動執行。runs/plugin-review-01、plugin-review-02、routing-policy.json、route-review.py 隨本篇一起公開於 days/day11/lab-dev/(Day 11–13 共用同一份開發包,所以路徑掛在 day11)。