Staging — 僅供部落格預覽。
跳至主要內容

共用密碼學套件要有 100% 覆蓋率底線

排程中

閱讀時間 6 分鐘 作者 NT²

規格界定範圍。安全否決承擔剩餘風險。覆蓋率底線做更窄的事:封印、包裝與描述保管箱事實的共用套件, 不容許未執行的一行——否則 agents 會把「做完了」連同缺口一起出貨。

共用密碼學套件要有 100% 覆蓋率底線

主張:地基不接受「夠好就好」的覆蓋率

AI coding agents 很擅長綠燈。你要一個功能,它們常會補一個走快樂路徑的單元測試、斷言一輪加解密,然後宣告做完。對行銷頁或設定開關,這或許夠用。對那些編碼密文容器、包裝內容金鑰、承載型別化保管箱事件的共用套件來說,不夠。

NT² Vault 是零知識、local-first 的保管箱。產品對外的承諾——salt 留在裝置、信封為每個物件包裝一組新的內容金鑰、結構化欄位以封印後的 blob 離開 RAM——都建立在一小組每個 shell、每個功能都會重用的共用函式庫上。那裡漏掉一個分支,不是單一畫面的 UI bug,而是每個呼叫端底下的沉默缺口。

因此本篇主張是可操作的:

共用的密碼學與事件套件帶有硬覆蓋率底線:陳述、行與函式皆須 100%。Pre-push 與 CI 失敗即關閉。「幾乎蓋滿」對這層地基不是可合併狀態。

這是 與 agents 一起打造 系列的第四篇。規格說可以出什麼(規格先於 agents 寫 code)。安全否決說碰觸祕密的變更是否准許(安全否決是角色,不是氣氛)。覆蓋率底線更冷:界定密文與事件如何運作的套件裡,不容許留下未執行的一行——即使 agent 很自信、功能示範看起來沒問題。

約束:agents 優化綠路徑;地基放大遺漏

三股壓力讓「軟覆蓋率目標」在產品是保管箱時失敗。

快樂路徑測試是預設補完。 模型看過數百萬個「斷言加密再解密」的例子。它們較少產出彆扭案例:錯誤的 tag 長度、空 payload、壞掉的版本位元、重複包裝、事件解析拒絕。沒有硬底線,「我們有測試」等於「我們有讓示範能跑的那條路」。

共用套件會放大衝擊半徑。 UI 元件漏掉 null 檢查,傷的是一個畫面。解析或包裝輔助漏掉檢查,傷的是每個項目、每個附件、每個呼叫它的同步信封。Agents 感受不到這種倍增;它們只看到小套件裡的小 diff,把它當普通工單。

覆蓋率表演看起來像盡責。 把 monorepo 平均從 62% 拉到 71%,或貼個「高覆蓋率」徽章,都不能證明密碼學路徑被跑過。平均會掩蓋真正重要的套件。Agents 樂於改善好寫的檔案,把難的留到「之後」。「之後」就是神諭與 unwrap bug 出貨的方式。

因此約束很明確:當地基是共用的,你不能把覆蓋率當成氣氛或投資組合平均。 底線必須壓在那些 bug 會變成每個功能之 bug 的套件上。

設計:分層,而不是整棵樹一個數字

我們不要求保管箱 PWA 每一行都 100%。那會凍結產品 UI、懲罰探索性 shell,並訓練團隊玩弄指標。我們改成分層。

層級涵蓋什麼(白話)底線
共用地基密文容器、金鑰包裝輔助、型別化事件與同步形狀,以及其他每個 app 都會 import 的純套件陳述、行、函式 100%——push 與 CI 失敗即關閉
關鍵 app 接縫緊鄰 UI、但仍編碼安全敏感純邏輯的保管箱端密碼學、deep-link 與共用輔助在我們劃下那條線的地方,同樣以 100% 閘門約束
其餘一切路由、版面、長生命週期 UI、平台膠合單元測試在划算處寫;行為靠整合與瀏覽器流程——不是全面百分比表演

設計規則很簡單:百分比底線屬於小、純、高衝擊半徑的套件。 解鎖與備份仍需要端到端走查;它們不能取代「包裝輔助的每個分支都跑過」的行級證明。

flowchart LR
  A[Agent 變更共用套件]
  U[單元測試]
  C{100% 底線?}
  P[Push / CI]
  M[合併路徑]

  A --> U --> C
  C -->|失敗| A
  C -->|通過| P --> M

底線在實務上強迫什麼:

  • 每個函式在測試裡都有呼叫端。 Agent 不能留下永遠不跑的「之後再用的輔助」。
  • 每個陳述都有執行紀錄。 重構分支、錯誤路徑、版本開關,無法躲在快樂 round-trip 後面。
  • 閘門是機械的。 人類仍擁有威脅判斷(見否決那篇)。覆蓋率閘門只管更窄的拒絕:未覆蓋的地基程式碼不准離開筆電。

這與我們如何把祕密存於靜止狀態互相配合。CBF 是結構化欄位離開 RAM 的方式每個物件一把 CEK 的信封加密 描述那些套件必須做對什麼。覆蓋率底線則是 agent 產出如何對那些套件保持誠實:你若改了 blob 格式或包裝路徑,就繼承維持底線為綠的義務——不是「之後再補測試」的承諾。

為何是 100%,不是 95%

軟目標會招來談判。百分之九十五往往就是彆扭分支住的地方:拒絕路徑、舊版本、只在惡意輸入下才失敗的長度檢查。Agents 很擅長在差一個斷言的地方停住。硬底線拿掉談判。要嘛該陳述在測試下跑過,要嘛 push 失敗。

我們不是主張 100% 覆蓋率等於正確的威脅模型。覆蓋率不能證明產品該存在、Non-Goals 有守住,或人類在金鑰路徑變更後走查了解鎖。它證明的事更小、但仍必要:agent 剛碰過的共用地基裡,沒有明知未執行的一行。

取捨:共用套件 diff 變慢,沉默的地基缺口變少

100% 底線要花時間。共用套件變成「昂貴」工單:每個新匯出都要測試;每次重構都要維持底線;貼上輔助卻沒有呼叫端的 agents,會在人類打開 PR 之前就被 CI 擋下。

我們放棄什麼:

  • 又快又鬆的地基修改——「小輔助、沒測試,先出上面的功能」。
  • 平均覆蓋率表演——慶祝 monorepo 百分比,同時密碼學套件落後。
  • 共用密碼學上的後續工單文化——後續很少在下一個 agent 蓋在缺口上之前落地。
  • 把綠色功能示範當成證明——以為包裝與解析邏輯已被跑過。

我們得到什麼:

  • agents 無法靠話術通過的機械拒絕——底線不在乎模型有多自信。
  • 衝擊半徑的遏制——bug 仍會發生;地基裡已知未覆蓋的缺口,不再是可接受狀態。
  • 其他地方仍可相容地快——UI 與產品切片不必把每條路由都拖到 100%。
  • 與否決、規格誠實配對——規格限制空想;否決承擔剩餘風險;覆蓋率管住未執行的地基行。

昂貴的失敗模式不是「花二十分鐘寫解析拒絕測試」,而是「出貨了一條 agent 從未跑過的 unwrap 路徑,然後教會之後每次變更:示範好看時,憲章可以選擇性遵守」。

我們拒絕什麼

我們拒絕對共用密碼學與事件套件使用軟覆蓋率目標。「高覆蓋率」與「下個 sprint 再衝到 100%」不是閘門。底線就是 100%,沒有它 push 失敗。

我們拒絕用整座 monorepo 的虛榮數字證明地基安全。分層存在,是為了讓放大風險的套件比行銷頁承受更硬的規則。

我們拒絕把只有快樂路徑的測試當成完成——對包裝、解析與事件形狀程式碼而言。Round-trip 必要。拒絕與畸形路徑也是底線的一部分。

我們拒絕為了讓 agents 合得更快而降低底線。 Agent 產出是工具。產品的邊界案例不是可選作業。

我們拒絕把覆蓋率等同安全簽核。 綠覆蓋率是機械閘門的證據。人類仍擁有解鎖走查、相依判斷,以及對碰觸祕密變更的否決。

我們拒絕在那些套件裡留下「只給 agent 用」的除錯匯出與未測輔助。 若它出貨在套件裡,就要在測試下跑——否則就不要出貨。

我們拒絕把 UI E2E 當成地基單元覆蓋率的替代。 瀏覽器流程證明工作階段與畫面。它們不能證明共用密文輔助的每個分支。

這些拒絕讓流程堆疊一致:規格阻止錯誤產品,否決阻止錯誤的風險接受,覆蓋率底線阻止其他一切所信任的函式庫裡出現錯誤的空白。

比模型更長壽的底線

流暢的 agent 永遠能敘述為何缺一個測試沒關係。100% 底線不辯論。它讓 push 失敗。

權威模型與發佈紀律在 一人如何與 AI agents 共同開發並營運 NT² Vault。阻止 agents 發明範圍的契約在 規格先於 agents 寫 code。阻止綠 CI 變成解鎖路徑合併權威的角色在 安全否決是角色,不是氣氛。這條底線所保護的產品面,見 CBF payload blobs 於靜止狀態每個物件一把 CEK 的信封加密

若你要的是流程與密碼學拒絕同一批捷徑的保管箱——試試 NT² Vault,或到 nt2.me 了解更多。

最後更新 2026-10-25

相關故事