跳到內文
coograph 17

深度審查

/coograph-review 是一個審查者讀一遍工作樹:對大多數改動來說,這個尺寸正好。/coograph-ultra-review 面向的是那種大到、或者危險到一個人讀不全的改動。多個對抗式審查者,每人只問一個問題;每條發現在進入報告前都要被獨立的反駁者攻擊一遍;一個結論;一條停止規則。

它是刻意做成可選的。一次執行大約 100 萬 token、二十分鐘。改動符合條件時代理會指出它的存在,但從不擅自執行。

僅限 Claude Code:它作為儲存好的工作流程透過 Workflow 工具執行。在其他工具裡,skill 描述的是同一套手動流程——每個維度一個 @Reviewer,然後再過一遍去反駁每條發現。

什麼時候執行

小而局部的改動不需要。日常審查就夠了。

在它誕生的那疊程式碼上——21 個 pull request,大約 176 次提交——它在常規審查已經通過之後找到了:一把被釋放了兩次的鎖,一個拿掉修復也能通過的測試,以及一個可能覆蓋客戶檔案的佇列任務。故事在部落格文章裡。

一次執行做什麼

階段發生什麼
Scope一個偵察代理(Haiku)把 PR 或提交解析成檔案和改動的行範圍,並向程式碼圖查詢被改符號的呼叫方和匯入方
Review每個維度一個審查者,在被審查的提交上讀程式碼,回傳發現:每條都帶原文引用、檔案:行號和一個具體的失敗情境——一邊是輸入和狀態,另一邊是錯誤結果。沒有引用,就不算發現。
Verify每條 Critical 和 Warning 都交給視角各異的反駁者:引用的那行存在嗎、真的做了聲明裡說的事嗎;情境真的會發生嗎,還是有守衛擋住了它;有沒有現成測試與這個解讀矛盾。只有沒人能反駁,發現才算成立。
Report一份 Markdown 報告:每個提交的 Critical / Warning / Nit、後續項、已驗證無誤的部分、缺失的測試、被反駁的發現及理由,以及一個結論。頁尾寫著模式、代理數和 token 數。

預設維度是通用的:狀態、生命週期與並行;資料遺失與破壞性路徑;契約與相容性;怎麼都能通過的測試。專案可以用 dimensions 傳自己的。

落在提交改動行內的發現是阻塞項。落在相鄰的、原有程式碼裡的發現是後續項:報告、記錄,但從不作為阻塞理由,也從不循環。只有阻塞項才會讓結論變成 REQUEST_CHANGES。

模式

模式什麼時候審查者視角成本(實測)
full對一個 PR 或一批提交的第一次審查,以及所有修復到位後對整個 PR 的那一次(pr: N)4 個,用工作階段模型,程式碼圖提供影響範圍2(Opus,高強度)120 萬–160 萬 token,17–22 分鐘;33 個提交的 PR:310 萬,39 分鐘
deltafull 之後的一批修復:上次的發現修好了嗎,改動的行又弄壞了什麼2 個,用 Sonnet,不查影響範圍1約 50 萬,約 17 分鐘
plan在寫會碰生命週期或並行的程式碼之前2 個,用工作階段模型,讀方案文字以及它點名的程式碼和呼叫方1100 萬–140 萬,約 20 分鐘——和一次完整執行一樣貴;值得,因為它在程式碼存在之前執行

mode 會自動推斷:給了 plan 就是 plan,給了 previous 就是 delta,否則是 full。

怎麼執行

skill 先在對話裡確定範圍,為這次執行提出模型方案——專案的 openspec/config.yaml 裡有 models 區塊就讀它,否則用該模式的預設值——然後先問你再開始。接著:

Workflow scriptPath: "<absolute path to the project>/.github/skills/coograph-ultra-review/workflow.js"
args: {"repo": "<absolute path to the project>", "pr": 364}
args: {"repo": "...", "commits": ["c78bdd7", "f04a228"]}
args: {"repo": "...", "commits": ["3d6046a8"], "previous": [{"severity": "critical", "file": "app/Jobs/X.php", "line": 105, "claim": "...", "fix": "..."}]}
args: {"repo": "...", "plan": "<the plan text>", "files": ["app/Jobs/X.php"]}
參數含義
repo儲存庫的絕對路徑——必填
pr / commits審查什麼:一個 pull request 編號,或提交雜湊(最新的放最後)。堆疊的 PR:只看它自己的提交,不看基底的
previousdelta 模式:上次執行的 findings(file、line、claim、fix、severity)
plan、filesplan 模式:方案文字(或審查者能讀到的路徑)和它點名的檔案
models{scout, reviewer, verifier, report, post},別名 haiku、sonnet、opus、inherit(工作階段模型)
dimensions取代該模式的預設維度:字串,或 {key, title, questions}
votes3 表示加第三個驗證視角(現有測試覆蓋);full 預設 2,其他預設 1
allowCommands允許審查者執行的專案唯讀檢查(go vet ./...、linter)。測試套件、建置、格式化和伺服器一律不許
post配合 pr,把報告作為 PR 審查留言送出——只在使用者明確要求時

結果包含 verdict、report(Markdown)、findings(阻塞項——也是下一次 delta 執行要餵回去的 previous)、followups、previous_status(delta)、dropped(被反駁的,附理由)、nits、agents、tokens。

每個審查者都在同一份約束下工作:git 唯讀;程式碼圖優先,grep 兜底;專案慣例,以及使用 OpenSpec 時當前變更的 proposal、spec 和 tasks;每條引用背後都是在被審查提交上的一次新讀取;除 allowCommands 外什麼都不執行。

停止規則

用它的第一週,一個修復跑了四次完整執行,大約 500 萬 token,每一輪都在上一輪的程式碼邊緣找到真問題——大多落在改動根本沒碰的行裡。工具每次都對;錯的是循環。於是:

  1. 執行之後 git status 不能出現任何新東西。出現了就是某個審查者違反了約束:撤銷它。
  2. 在擁有那段程式碼的分支上修阻塞項(delta 模式下還包括任何未確認修好的上次發現),發現點名了測試的就補測試。
  3. 後續項不循環。記進變更的筆記和 PR 描述。只有當它是這次改動才讓它可達的 Critical 時才順手修,並且說明。
  4. 帶著上次的 findings 以 delta 模式重跑。結論是 APPROVE 就停。最多兩輪 delta,到了也停,把 PR 交給人:同樣幾行上出現第三輪機器發現,說明需要看的是設計而不是程式碼——下次先跑 plan。
  5. 所有修復到位後,用 pr: N 對整個 PR 跑一次 full,然後交給人審查。
  6. 記錄每一輪——模式、代理數、token 數、發現 → 修復 → 提交——並把報告表格貼進 PR 描述。

被反駁的發現留在報告裡,附反駁者的理由。要讀;反駁者也會錯,人不同意就重新打開它。

它在哪

.github/skills/coograph-ultra-review/——SKILL.md 和 workflow.js,基於 Workflow 工具 API 的普通 JavaScript。初始化器把它複製進每個專案;同步腳本保持它最新;外掛以 /coograph:coograph-ultra-review 的形式提供。Retro 的 defect 規則把一次深度審查算作一次審查。它在 Plan → Propose → Apply → Review → Archive 中的位置見工作流程。