論述基礎與限制

本卡由一個併行專案交來的設計檢討抽出。那項工作的形態是多輪審查的極端版本:低階探針讀條文作答,兩名獨立判定者判讀作答結果,據以判斷條文寫得夠不夠明確。它抓出大量真實缺陷而沒有收斂——單一工作階段新建 82 張票、關閉 35 張,新增速度持續高於關閉速度。題庫在同一段期間從第 6 批長到第 21 批,累積成 261 個題目區塊、140 個題目檔、118 份答案鍵。

限制有三項。單一專案、單一審查形態:成本結構的式子由該專案的器材配置推出,沒有在第二個專案上驗證過。發散的數值取自一次工作階段,換題材與換批次節奏都要重新量。處置的效力在證據範圍外:改成判定之後會不會收斂,是該專案接下來要走的路,本卡記的是診斷與那個診斷怎麼下,不是療效。

可推翻的地方明確:找到一個累積式題庫而歸因成本維持常數的配置,本卡的成本結構那一段就要收窄。

處置那一側另有一項未量測的價差:拋棄式題庫比累積式便宜這個判斷由結構演繹得出(維護成本隨題數成長),沒有實際量過兩種配置的總成本。它因此要照 #334 的要求當成未驗證的假設看待——那張卡的推論是「這是理性的成本選擇」在套用之前要先驗那個差價存不存在,而本卡的處置清單自己還沒過那一關。


核心原則

一輪審查要先宣告它的產出是判定還是歸因,而預設應該是判定。 判定回答「被審查的對象現在讀得懂嗎」,產出是通過或不通過;歸因回答「這一句改動有沒有效」,產出是某次改動與某個結果之間的因果宣稱。兩者看起來是同一件事的粗細兩級,實際上是兩種產物,成本差一個量級。

歸因需要單變數實驗,而單變數實驗的定義就是一次只准動一個變數。 於是 N 次改動要 N 次全量驗證——「每新增一小段就要完整重新檢驗排查」是這個目標的直接推論,不是執行不當。把它讀成紀律問題會讓人去優化執行,而真正要改的是那一輪在問什麼。

判別的問句是:這一輪結束的時候,要能說出「它現在通過了」,還是要能說出「是那一句讓它通過的」。 後者才是歸因,而它值不值得買,要在派發之前決定。


成本結構:分母一直長而分子固定

累積式產物上的歸因成本由既有存量決定,而每次改動的價值是常數。 那項工作每改一句條文,驗證成本是既有題目、既有答案鍵、既有節錄檔三者的乘積,而改動的價值固定為修好一個缺陷。存量持續成長、價值不動,這個比值只會越來越差。

累積讓題庫從產出變成維護面。 每出一題,它的答案鍵、餵入的節錄、字面通路狀態、歷輪讀數對照就永久進入維護面。題庫因此是一份只增不減的資產,而不是一批批用完就過去的材料;它的每一項都可能被下一次條文改動波及。

這裡沒有收斂點可以等。發散的判斷標準不看新增與關閉的差額往哪個方向走——差額是結果——而看那個比值的分母由什麼決定:由一份只增不減的存量決定時,多跑幾輪只會讓它更差。


器材會凍結在第一批的形狀

量測器材的設計普遍預設「只有當前這一批」,而累積下來器材有一大半是凍結的歷史。 這是同一件事在工具層的表現,也是那項工作七項器材缺陷裡五項的共同根因。

缺陷凍結的形態
隔離檢查單向自查擋得住新批次撞既有詞,擋不住既有詞日後被撞
引文驗證固定比對最新版本「條文已改、引文仍是當時事實」與「器材被誤改」輸出同形
節錄檔同名覆蓋早期批次的餵入材料已遺失,那幾輪的讀數無法重現
歷輪對照欄落後一批查歷史讀數最自然的位置,落後而沒有訊號
自檢對「前寫」與「損壞」同形答案鍵已寫下批生效的引文,而節錄檔還是這一批的

這些工具在只有一個批次的時候全部是對的。 那時「當前」等於「全部」,固定檔名、固定比對最新版本、單向自查各自成立。批次累積之後這個等式失效,而工具不會告訴任何人——它照樣跑、照樣輸出數字,只是那些數字描述的是一個已經不存在的世界。

器材缺陷因此不該逐項修。逐項修等於承認那個等式還會繼續失效,而每修一項就多一份要跟著批次成長的東西。


每一道防護單獨看都是對的

選錯目標的成本不會表現成任何一個錯誤的決定。 那項工作建立的防護機制——守恆式對帳、正向對照輸入、以不變量排除混淆因子、計量口徑並列、空窗期警語——每一個單獨看都正確,沒有一個多餘。它們全部為了讓單變數歸因成立而存在,而那個目標本身選錯了。

約一半的工作量花在讓歸因成立,而不是花在改條文上:字面通路盤點、涵蓋數守恆對帳、帶入判斷標準拆訊號、計量口徑並列、基線重建、不可判讀的定義、雙臂派發設計。

最後一項做完之後否定了自己的前提。設計者誠實寫下的結論是:兩臂測的是兩個不同的量,相減等於把兩個不同問題的答案相減。付了七倍成本,做一件做完才發現測不到的事。

這是這種失效最難察覺的地方——它在每一個局部都給出正回饋。 每一道防護都補上了一個真實的漏洞,每一次補上都讓下一次更貴,而沒有任何一個時刻會有人說「這裡不對」。


處置

派發之前寫下這一輪的產出層級,歸因要另外授權。 成本是一行,而它讓「我們在做歸因」變成一個被看見的選擇,不是一個滑進去的預設。

判定的驗收取整體通過,失敗時才定位。 定位可以用二分,成本只在失敗時付。逐項歸因把定位成本前置到每一次改動上,而多數改動不會失敗。

改動批次化。 所有待修的地方一次改完再驗一次。這一條與逐項歸因直接衝突,也正是放棄歸因換到的東西。

題庫改為拋棄式,只保留出題規格。 規格是恆定大小,題庫不是。跨批可比性、歷輪對照、節錄同步的維護成本會歸零,因為它們全部由「舊題目還在」產生。

停損寫進判斷標準:只有會使判定翻面的發現才開票。 沒有這一條,發散會以「每一張票都是真缺陷」的形式繼續——而它們確實都是真缺陷。

四項的共同點是放棄「每一步都可解釋」,換取「整體可完成」。


放棄歸因會連帶取消一些驗收條件,而那件事在砍的當下不會顯現

歸因的器材同時是某些驗收條件的指涉基礎,所以砍掉器材會讓那些條件失去語意,而不是讓它們判定為未達成。 砍的時候看到的是成本那一面——那份材料每一批都變大、維護它的工作沒有上限——而它另一個身分(某個閘門的量詞靠它才有所指)不在同一個視野裡。

一次實測的形態:該專案的舊閘門要求「全部範例同時達到三份中的三份」,而「同時」這個量詞要跨輪的材料才判得出來。改成拋棄式題庫之後,逐輪的節錄檔被明文刪除且禁止回加,於是那個閘門不再有「同時」這個維度可以指涉。結案時它被記為未達成,而更準確的描述是不可判定。

不可判定與未達成在結案報告上長得一樣,處置卻相反。 未達成的下一步是再跑一輪;不可判定的下一步是先改條件,因為再跑幾輪都不會產生它要的那個量。兩者混在一起時,團隊會照未達成的處置走,然後每一輪都得到同一個結果。

處置是在砍之前做一次逐條檢查:列出現行驗收條件裡量詞跨輪的那幾條(「同時」「連續 N 輪」「相較上一輪」「累計」),逐條問它靠哪一份材料才判得出來。靠的材料要留下的就不能砍;砍掉的那些,對應的條件要在同一次改動裡改寫成單輪可判的形式,而不是留在清單上等它靜默失效。


判讀徵兆

  • 一輪審查的新增待辦持續高於關閉,而每一張票單獨看都是真缺陷
  • 修一處要重跑全部既有的驗證,且那個「全部」每一批都更大
  • 器材缺陷逐項出現,而每一項的描述都可以改寫成「舊批次的東西沒跟上」
  • 一半以上的工作量花在讓量測成立,而不是花在改被量測的對象上
  • 某個量測設計做完之後發現它測的是兩個不同的量
  • 說得出這一輪找到幾個缺陷,說不出這一輪的產出是判定還是歸因

跟其他抽象層原則的關係

  • #345 修法沒有寫進檔案,而同一輪的無關改善替它簽了名:那張卡確立了歸因的門檻——一批多項時改善只能歸給整批,要歸給某一條,那一條得是該輪唯一的變項。本卡接在它後面問下一個問題:這個門檻要花多少錢,以及這一輪買不買它。兩張卡合起來是完整的判斷——那裡擋的是沒有單變項而宣稱歸因,這裡擋的是在不需要歸因的地方付單變項的成本。
  • #346 門檻要在派發之前寫死:同一個「派發前寫下來」的形式,而寫下的項目不同。那張寫的是處置門檻(哪些命中要修),本卡寫的是產出層級(這一輪要交付什麼)。順序上本卡在前——產出層級決定要不要有處置門檻這件事。
  • #337 審查的射程只涵蓋被審查的對象:那張卡說工具不在任何 frame 的射程裡,所以要靠一份起跑前的清單補。本卡給那些工具缺陷一個共同的成因——它們凍結在第一批的形狀上,而讓它們必須跟著批次成長的正是歸因這個目標。拿掉歸因,那一類缺陷有一大半當場消失,清單要顧的東西也跟著少。
  • #334 代理比本體便宜:那張卡要求套用「這是理性的成本選擇」之前先驗那個成本差是不是真的存在。本卡是反方向的同一個要求——歸因的成本差確實存在而且很大,卻沒有被算過,因為它從來沒有被表述成一個選擇。