「反正 AI review code 就是看程式碼寫得對不對,誰送的 PR 應該都一樣吧?」
如果只看語法對不對、邏輯通不通,確實一樣。但維護一個真實的 open source 專案久了會發現:外部貢獻者的 PR 缺的往往不是程式能力,而是「這個專案沒寫在任何地方,但維護者心裡都知道」的隱性慣例——這個 monorepo 裡哪些套件互相依賴、CI 矩陣涵蓋了哪些作業系統、某個看似單純的路徑處理背後藏著哪個歷史坑。維護者自己寫 PR 時會下意識避開這些坑,外部貢獻者不會,AI 也不會——除非你把這些隱性知識明確餵給它。
${workspaceFolder} 在兩個地方被解析成不同結果PHPUnit & Pest Test Explorer 這個專案的 PR #413 是一個很典型的外部貢獻案例。一位外部貢獻者在使用 monorepo 結構(測試專案放在 apps/api 子目錄)時發現:設定檔裡的 ${workspaceFolder} 這個變數,在「探索測試」(discovery)階段被解析成專案根目錄,但在「實際執行測試」時卻被解析成 apps/api 子目錄——同一個變數,兩個地方給出不一樣的答案。(這個專案圍繞 workspaceFolder 路徑解析陸續收到好幾個相關但獨立的 PR,明天 Day 06 會審查另一個症狀類似、但改動內容完全不同的 PR #412,兩者是不同的貢獻,不是同一個 PR 前後改了編號。)
這個 PR 改動了三個檔案:負責組出實際執行指令的 ProcessBuilderFactory.ts、負責路徑替換邏輯的 PathReplacer.ts,以及對應的測試檔案。貢獻者的 PR 描述裡誠實寫著「@recca0120 你能確認這樣改對不對嗎?」——這句話本身就透露了一個關鍵事實:貢獻者對這個修法有沒有踩到專案裡其他隱性假設,並沒有把握。
如果用「維護者自己寫 PR」的標準去審查這個 PR——語法對、邏輯通、有補測試——它幾乎會直接過關。但一個真正熟悉這個專案的人看到這個修法,腦中會自動浮現幾個問題:這個變數解析邏輯除了「探索」跟「執行」這兩個路徑之外,還有沒有第三個地方也在用同一套邏輯?改了 PathReplacer.ts 之後,會不會影響到 Docker/SSH 這幾種遠端執行模式下的路徑解析(這個專案同時支援本機、Docker、SSH、Laravel Sail 好幾種執行環境)?
這些問題不是「這段程式碼寫得好不好」的問題,是「這個專案裡還有哪些地方依賴同一份假設」的問題——而這正是外部貢獻者最容易缺的資訊,因為這些依賴關係從來沒有被寫進任何文件,只存在維護者的經驗裡。
用一組對照來看這個差異:
❌ 只用「程式碼品質」標準審查外部 PR:
「語法正確、邏輯合理、有補測試,看起來可以合併。」
→ 完全沒有檢查這個修法是否影響到專案裡其他依賴同一份邏輯的地方,
貢獻者自己都在 PR 描述裡承認沒把握,審查卻沒有針對這個不確定性追問
✅ 針對外部貢獻者的落差設計審查清單:
「這個修法動到的 PathReplacer 邏輯,在 Docker/SSH 執行模式下
有沒有被同樣呼叫到?測試只涵蓋了 discovery vs execution 這兩種情境,
遠端執行模式有沒有對應的回歸測試?」
→ 針對「這個專案特有、貢獻者不會知道」的隱性依賴主動提問,
而不是只確認眼前這段程式碼本身合不合理
有效的清單不是一份通用的「程式碼品質檢查表」,而是把維護者腦中的隱性知識,轉譯成外部貢獻者跟 AI 都看得懂的具體問題。對 PHPUnit & Pest Test Explorer 這個專案來說,這類清單至少要涵蓋:
這份清單本身要持續更新——每次抓到一個外部貢獻者沒意識到的隱性依賴,都是把它寫進清單的機會,讓下一份 PR 不用重新踩一次同樣的坑。
AI 拿著這份清單,能有效地把「這個改動有沒有觸碰到已知的隱性依賴點」這件事系統化地檢查一遍,這比讓貢獻者或審查者憑記憶想「這裡是不是還有別的地方要注意」可靠得多。但AI 沒辦法判斷「這個貢獻要不要接受」這個更上層的問題——這牽涉到這個功能是不是專案想要的方向、這個修法的取捨是不是跟專案既有設計理念一致,這些是需要維護者本人拍板的事,清單只是幫忙把「值得追問的地方」都攤開來,不是幫忙做最終決定。
回想你維護(或參與過)的專案:有沒有哪個隱性依賴、只有老手才知道的坑,從來沒有寫進任何文件?如果今天有個外部貢獻者送出一個看起來完全正確的 PR,你有把握 AI 審查會不會踩到你腦中那個沒寫下來的知識嗎?
${workspaceFolder} 在探索/執行兩階段解析不一致的問題,貢獻者自己都不確定有沒有踩到其他隱性依賴明天用同一個 PR 當案例,往下深挖一層:AI 實際 review 這個外部貢獻的 PR 時,抓到了什麼、又漏掉了什麼——把今天講的清單放到真實情境裡驗證。
案例真實性說明:本篇引用的 PR #413 是 recca0120/vscode-phpunit 專案上真實存在、已合併的外部貢獻,PR 描述、改動檔案清單均直接查證自 GitHub(gh pr view 413),未經改寫。審查清單本身的具體條目是基於這個專案的已知架構特性(多執行環境、雙測試框架支援)推演出的示範設計,不是逐字引用某次真實審查紀錄。