論述基礎與限制

這張卡來自本站規則檔(給 agent 讀的 AGENTS.md、docs/rules/ 的八份分冊與 CLAUDE.md)的一次多輪審查。審查跑到第五輪時,用同一組題目、只餵入口檔的三份低階模型理解探針,回報的歧義從第四輪的 18 處升到 25 處;另一位審查者在拋棄式 git repo 裡實跑規則檔寫的每一條指令,第五輪找出 19 則問題,其中 5 則是照做會做錯。單一 repo、單一個工作階段、兩輪的量測,所以卡上的數字是這一次的比例,不是通則;卡要歸納的是成因的分類與修法的方向。之後的同檔重測顯示,三份探針的歧義總數在同一份檔案上就會差到 20 對 13,「從 18 升到 25」這個比較沒有鑑別力(見要理解探針列出「有兩種讀法的位置」是審查題:同一份檔案兩批的總數差得比輪與輪之間還大,改用封閉案例題加預期答案);成因的分類來自逐則歸因,不受影響。

核心原則

規則檔逐條修補不收斂,成因多半出在三種結構:規則檔裡寫了沒有測試的程式、同一個概念在幾條規則裡各定義一次、觸發條件寫成執行者查不到的事實。三種結構都讓「修一處」產生新的缺陷,所以下一輪的 finding 落在上一輪新寫的句子裡。收斂的方向是縮小可能出錯的文字面:程序搬進有測試的工具,共用的概念只在一個位置定義,觸發條件換成指令輸出、diff、路徑這類查得到的事實。

第五輪的 19 則實測問題與 14 處探針歧義,逐則歸到最根本的成因,分布如下:

成因實測問題探針歧義
規則檔裡寫了沒有測試的程式104
同一件事寫在兩處(含摘要與轉述)63
邊界寫成封閉列舉或類別名25
同一個句子交代兩種讀者各自怎麼做02

規則檔裡的程式缺少放正對照的位置。一條 shell 管線寫進散文,作者讀起來是對的,審查者讀起來也是對的,只有實際跑才知道它在某個狀態下會失敗。這一次的例子:取新增行的管線讓每一行保留 diff 的 + 前綴,字句層 bank 裡以 ^ 錨定的 pattern 因此恆為零命中;補新檔用的 git add -N 寫的是共用的 index,別的工作階段持有 lock 時失敗;在 git worktree 裡照「先切到 main」做,git 回 already used by worktree;改名讓 staged 清單的比對失敗。四條都是前一輪修法新寫進去的。程式碼有測試、有 exit code,散文裡的程式兩者都沒有,而照做的 agent 會逐字照抄。

共用的概念各寫一份,例外就各自漂移。「小改動不用做 X」這個概念同時服務叫用寫作 skill、多輪審查、skill 版號三條規則,三條各寫了一份例外:第一份是「錯字的單一字元、標點、連結、對齊、空白」,第二份是「修錯字、補連結、格式調整」加上「只改措辭」,第三份是「修錯字、補連結、格式調整、改措辭而語意不變」。三份的成員不同,探針問「刪掉一整句算不算」「frontmatter 的數值算不算」時,三條規則各給出不同的答案。同一個機制也出在宣告全集的句子上:入口寫「要先問使用者的只有兩種情形」,同一次修改在分冊新增了一節「推上共用庫之前先問使用者」,那一句就默默失效。封閉的列舉只有在它是那類情形的唯一住址時才保持正確。

執行者查得到的是 context 與路徑,查不到自己的身分。入口用同一個句子交代 Claude Code(已經載入全部分冊)與 Codex(只自動讀入口)各自怎麼做,兩輪的探針都判斷不出自己屬於哪一種。執行者查得到的是自己的 context 裡有沒有分冊的全文,以及這次要改的檔案路徑;把觸發條件換成這兩件事,判斷就不依賴身分。

反模式

  • 照 finding 逐條補句子,每一則都補得對,下一輪的 finding 換一批出現在新句子裡。
  • 規則檔裡的指令寫完沒有跑過,或只在一種狀態下跑過(乾淨的 index、主 worktree、沒有改名)。
  • 同一個例外在每條用到它的規則裡各寫一份,每一份都只列那條規則的作者想到的成員。
  • 「只有 N 種」「不跑的只有兩種」寫在不是唯一住址的位置。
  • 路由表或入口用自己的話轉述分冊的觸發條件,分冊改了之後轉述留在舊版。
  • 觸發條件寫成「Claude Code 的話……Codex 的話……」,讀者要先判斷自己是誰。

修法

  • 程序寫成工具:要照順序跑兩條以上指令、或依輸出走不同分支的程序,寫成工具並附測試,實測出錯過的每一種狀態寫成一個測試案例。規則檔改寫成「什麼時候跑、輸出怎麼讀、非零的 exit 怎麼處置」。這一次寫成四支:取新增行與判定改動級別、只提交列出的檔案、只回報新增的 lint 問題、推送並在推送範圍有別人的 commit 時停下。單一條、沒有分支的指令可以留在規則檔,寫之前跑一次正對照。
  • 共用的概念先定義再引用:在一個位置定義並命名,其他規則寫名字。這一次把「小改動」定義成三個級別(排版級、措辭級、規則級),排版級由工具依 diff 判定;三條規則各自只寫「哪一級以上要做」。「要先問使用者的情形」收成一節,是那類情形的唯一住址,別處連過去。
  • 觸發條件換成查得到的事實:讀者身分換成「context 裡有沒有分冊全文」,工作類型的轉述換成「這次要改的路徑」。
  • 語意判斷留下痕跡:工具判不了的分界(措辭是否改到規則的條件)由執行者判,判定寫進 commit message:改了哪一條規則的哪一項,或「條件、判斷標準、處置都沒變」。

判讀徵兆

徵兆判讀
下一輪的 finding 多數落在上一輪新寫的句子修法在擴大可出錯的文字面,逐條補句子不會收斂
實跑規則檔的指令找到的問題,比讀規則檔找到的多規則檔裡寫了沒經過測試的程式,該搬進工具
探針對同一種邊界情形,在不同的規則裡給出不同的答案同一個概念在那幾條規則裡各有一份定義
「只有 N 種」的宣告被同一組檔案別處的一條規則推翻列舉不在唯一住址
同一處歧義改寫過一次仍然出現在下一輪觸發條件依賴讀者查不到的事實(身分、主觀狀態),措辭改不掉

跟其他抽象層原則的關係