修法是新違規的來源、且常引入同類變體
結論
修法是新違規的來源。改寫一個違規句、補一條 lint 規則、改一個 pattern——這些動作本身會引入新問題,而且引入的常是同一類問題的變體:修掉「不是 X、而是 Y」、就暴露「不是 X — 是 Y」;補一條 pattern 抓某變體、下一個變體又漏。
兩個推論直接影響 review 流程:review 的 scope 要涵蓋「修法後的產物」、不只「原始內容」;停止判斷不能停在「修完這批」、因為修法本身產生新一批。
為什麼修法引入的是同類變體
修法用的是跟原作者同一套文體直覺、同一個對問題的理解。改一個表面實例時,注意力放在「這一處」、而同一個底層成因(重點後置的偏好、某個高頻句型)在別處或下一個變體仍在。修「而是」連接詞、沒動到「重點後置」這個成因,於是「— 是」「不在…而在」這些同成因的近親一個個浮現。補 pattern 也一樣:每補一個連接詞、成因(重點後置)沒被判準收斂、下一個連接詞的變體就漏。
這跟全新違規不同:全新違規是不同成因,同類變體是同一成因的不同表面。修法最容易產生後者——因為修的人盯著表面、放過成因。
這次的實證(同一批 retrospective 反覆出現)
| 修法動作 | 引入 / 暴露的同類變體 | 誰抓到 |
|---|---|---|
| Round 1 修字句層 | Round 2 抓到新引入的跨 surface 近逐字 | 下一輪不同 frame |
| Round 3 修 80/20 段 | Round 4 抓到修法又植入一處新近逐字 | 下一輪 frame |
| 補 POS pattern「而是」 | 漏「不是 X — 是 Y」 | 人複核 |
| 補「— 是」變體 | 漏「不在 X、而在 Y」 | 對抗文體 agent |
| 補「不在…而在」 | 漏「不是 X、是 Y」頓號版 | 人複核 |
| 修觸發句「不是二元、而是有深度」(三 surface) | 漏第 2 觸發句「不是吹噓技術 — 是…」(不同連接詞變體) | 人複核 |
每一次修法都暴露下一個同類變體。POS pattern 的連接詞清單擴了兩次(而是 → 加「— 是」→ 加「不在…而在」)、每次擴完就暴露下一個變體、第四個「、是」頓號版發現後決定不補——這正是「打地鼠」:表面層追不上成因層。
理想做法
review scope 涵蓋修法產物
修完一批不假設它乾淨。修法產物要重新過一次同樣的 frame——尤其修的是「會引入同類變體」的改寫或規則。這是 #95「scope 蓋同類風險區」的時間軸延伸:修法後的產物也是同類風險區、且是剛產生的。
同類變體靠判準收斂、不靠窮舉
成因層的判準(#166 的「核心概念在不在最前」)一次涵蓋所有連接詞變體;表面層的 pattern 永遠枚舉不完(擴兩次仍冒出第四個變體)。所以工具鏈的 pattern 定位是「曝光候選」、收斂靠判準——pattern 漏一個變體只是讓候選 silent、判準仍能在人讀到時抓出。有些變體(「、是」頓號版)誤判率高、刻意不補進 pattern、正是「判準優於窮舉」的活證明。
停止判斷含修法產物
「修完這批違規」不是停止訊號。修法產生新一批、停止判斷要看「frame 涵蓋 + 判準到位」(#148 的延伸)、不看「這批修完了」。
沒這樣做的麻煩
修完回報 clean、新引入的違規 silent
修法後直接回報「修好了」、不重審修法產物——新引入的同類變體帶著「已修」標籤留下。這次 Round 2 / Round 4 抓到的、都是前一輪「修完回報 clean」後才被下一輪 frame 揭出的。
補 pattern 永遠追不上變體
把希望放在「補完所有 pattern 變體」上、就會無限打地鼠——每補一個、下一個浮現。連接詞清單擴兩次仍冒出第四個變體(「、是」),證明表面層的窮舉追不上成因層。
跟其他抽象層原則的關係
- #166 重點優先陳述是跨語言的資訊結構原則:#166 講「句型 grep 枚舉不完、判準是重點位置」(靜態原則),本卡是它的過程面——修法 / 補 pattern 的動作會反覆暴露同類變體,正是「枚舉不完」在 remediation 過程的動態展現。#166 self-case 記了完整的 pattern 連接詞擴展軌跡。
- #95 Multi-pass review scope 要蓋同類風險區:#95 是空間軸(同類違規分布整個 corpus),本卡是時間軸(修法後的產物是剛產生的同類風險區)——兩個一起才是完整 scope:橫向蓋 corpus、縱向蓋修法產物。
- #153 Review 漏抓先分 design gap 與 execution gap:本卡補一類 gap 的來源——修法本身引入的新 gap。修法後沒重審,是把「修法產物」排除在 scope 外的 execution gap。
- #148 跨輪 review 停止訊號是 frame 涵蓋:本卡補「修法產生新批」這個維度——停止判斷不能停在「修完這批」、要含修法產物的重審。
- #149 keyword bank 命中是候選、不是判決:補 pattern 抓變體是偵測層、收斂靠判準是判定層——本卡的「靠判準不靠窮舉」是 #149「判定優先」在 remediation 的應用。
判讀徵兆
| 徵兆 | 該做的行動 |
|---|---|
| 剛修完一批就回報「clean / 修好了」 | 停 —— 修法產物還沒重審、新引入的同類變體可能 silent |
| 修的是「同一類問題」(批量改寫 / 補規則 / 改 pattern) | 預期它引入同類變體、修完重掃同類、別假設乾淨 |
| 補 pattern / 規則後沒重掃同類風險區 | 補完只解了已知變體、下一個變體要靠重掃或判準 catch |
| 把希望放在「補完所有 pattern 變體」 | 打地鼠訊號 —— 表面層追不上成因、回到判準(成因層)收斂 |
| 停止判斷的理由是「這批修完了」 | 不是停止訊號 —— 修法產生新批、看 frame 涵蓋 + 判準到位 |
適用範圍與邊界
- 適用:批量改寫違規、補 lint 規則 / pattern、multi-round-review 的修法階段、任何「修一類問題」的 remediation。
- 不適用:修單一孤立 bug(無同類變體、修完即止);確定性違規的工具鏈修法(emoji / broken link,補一條規則就窮舉完、無成因層變體)。
- 邊界:「修法引入同類變體」不等於「不該修」——該修、但修完要把修法產物納入下一輪 scope,且收斂靠成因層判準不靠表面窮舉。
Self-case:本卡的觸發來源
本卡抽自一次 backend + skill 的 register 違規 retrospective。整個過程是一連串修法、每次修法都暴露下一個同類變體:四輪 multi-round-review 每輪修完、下一輪不同 frame 都抓到前輪修法引入的新近逐字;POS-negation-lead pattern 的連接詞清單擴了兩次(而是 → 加「— 是」→ 加「不在…而在」)、每次擴完就暴露下一個變體、第四個「、是」頓號版發現後決定不補;修第 1 觸發句「不是二元、而是有深度」後、漏了第 2 觸發句「不是吹噓技術 — 是…」(不同連接詞變體),由使用者複核才抓到。
這條軌跡共同指向一個教訓:修法是新違規的來源、且引入的是同類變體;表面層的 pattern 窮舉追不上成因層、收斂要靠判準(#166 的重點位置)、review scope 要把修法產物納進來。