修法沒有寫進檔案,而同一輪的無關改善替它簽了名
論述基礎與限制
本卡由一次五輪的理解探針審查抽出,量測由併行專案執行,本站取用它的機制與判斷標準。事件是一項處置寫進了變更紀錄、該輪量測回報零命中、判定生效結案,兩輪之後同一個位置復發;回查該次提交的檔案清單才發現它從未觸及目標檔。
限制有兩項。單一實例:一次復發、一次回查,機制由那一次的歸因推出,未量測發生率。歸因依賴那一輪剛好有另一項改善——同輪沒有任何改善時這個形態不會成立(量測不會回報零命中),所以本卡描述的是一種會被掩蓋的失效,不是每次修法都會發生的事。
核心原則
一項修法有沒有寫進檔案,與那一輪的量測有沒有改善,是兩件獨立的事。 紀錄說修了、量測說好了,兩者互相背書,而它們中間缺的那一步——修法有沒有真的落在目標檔上——流程裡沒有任何一處會問到。
兩個獨立的成因各自都不罕見,湊在一起才產生這個形態:
變更紀錄照修改計畫寫,而不是照實際的 diff 寫。 寫紀錄的人手上有一份逐條的計畫,於是逐條謄完。批次套用的腳本對其中一條回報了零筆命中,而那個回報沒有進到寫紀錄的那一步。
量測項與處置項不是一對一。 一批修改通常含多項,而探針量的是位置、不是處置。那一輪的零命中來自同批另一項新增的定義表,與宣稱的那條處置無關。
一批多項時,改善只能歸給整批
把紀錄與量測分開查這件事有一個直接推論,而它比那個個案一般得多:同一輪套用了多項修改時,量測的改善不能歸給其中任何一項。 要把改善歸給某一條,那一條得是該輪唯一的變項。
所以修法的紀錄有兩種寫法,效力不同。「本輪套用了這幾項,量測從命中轉為零命中」是可以成立的陳述。「這一項讓命中歸零」是一個歸因宣稱,它要求單變項,而一批多項時那個條件不成立。
判定生效之後復發,第一件事是回查 diff
復發的時候,最順的解釋是修法設計得不好——上一輪的做法沒切中,這一輪換一個。那個解釋順到不需要查證,而它會讓人重新設計一個從未被試過的修法。
順序是先回查再重新設計:取那次提交實際動到的檔案清單,確認目標檔在裡面。成本是一條指令,而它排除的是整輪的白工。
同一條也適用在提交之前:紀錄裡提到的每個目標檔,與這次實際暫存的檔案清單逐條對照。
沒這樣做的麻煩
結案的清單會失真,而失真的方向是樂觀的——每一條都有紀錄、有量測、有判定,只是其中幾條指的事情沒有發生。清單越長,回頭逐條驗的成本越高,於是越不會有人驗。
另一層代價落在判斷標準上:那個從未被試過的修法會被記成「試過而無效」,於是下一次遇到同型缺陷時,正確的做法已經在清單上被劃掉了。
判讀徵兆
- 一項處置判定生效結案,而同一批還套用了其他修改
- 變更紀錄的條目與那次提交的檔案清單沒有逐條對照過
- 批次套用的工具對某一條回報了零筆命中,而紀錄照樣寫上了那一條
- 同一個位置在判定結案的兩輪之後復發
- 檢討時第一個浮現的解釋是「上一輪的修法設計得不好」
跟其他抽象層原則的關係
- #344 修法要落在缺陷所在的那一層:那張卡管修法動到的是不是該動的那一層,本卡管修法有沒有動到任何東西。兩者是同一條鏈上相鄰的兩個問題,而順序固定——先確認落地,再判層對不對;順序顛倒會在一個空的 diff 上討論它修在哪一層。
- #298 finding 清單列的是抽樣位置:那裡的清單形式在暗示完整性,本卡的紀錄形式在暗示已執行。兩者同屬「產物的形式提供了它沒有量到的保證」,而驗收動作相同——回到原始材料逐條對照,不讀清單本身。
- #333 「我以為觀測到的」躲在「引用的」那一欄裡:本卡是它在修法紀錄上的形態。「我修了」為真而「那個檔案改了」為假,中間那一步沒有任何人查。
- #291 掃描指令壞掉時不會報錯,它報一個數字:批次套用的腳本回報零筆命中是一個正確的輸出,而它在那個流程裡沒有消費者。工具說了實話而沒有人在聽,與工具說謊的後果相同。
- #347 審查的產出是判定還是歸因要先宣告:本卡確立了歸因的門檻——要歸給某一條,那一條得是該輪唯一的變項——而那張卡接著問這個門檻要花多少錢。累積式產物上它的成本由既有存量決定而每次改動的價值是常數,所以買不買要在派發之前決定。兩張合起來是完整的判斷:本卡擋的是沒有單變項而宣稱歸因,那裡擋的是在不需要歸因的地方付單變項的成本。