產品、QA 與品質保證
- 撰寫對象
auditor- 它導向的那個決定
- 決定什麼可以測試、什麼可以簽核,以及什麼必須寫下來成為一條已知限制。
這一切從哪裡開始
你被要求為一套系統背書它可以發行,而這套系統的行為並不具決定性、它的失效模式是一項副作用而不是一個錯誤答案,而它的測試判準 — 那件壞事有沒有沒發生 — 是一個「不存在」。
傳統的斷言確認的是有錯誤被拋出,而那並不是同一件事實。
為什麼它成了這一季的問題
一項以代理為底的功能進到你的發行版本裡,而驗收條件第一次寫著「必須不能夠」。
Agent Assembly 對此做了什麼 — 以及每個答案能走多遠
在你導流的路徑上,這個產品會把「必須不能夠」變成一項決策。有四個情境備有已核可、可重複使用的措辭 — 旗艦級的對外流量拒絕、機密外洩、一次破壞性的正式環境動作,以及失控的花費 — 每一個都點名了它的決策者、它的預設狀態與它的界線。它們背後的登錄項目列在下面。
底下每一張卡片,都是這四個頁面共用的十六筆主張登錄表中的一筆項目,皆為原句引用而非改寫。用語是登錄表自己的用語,是從證據抄下來的,而不是為了配合句子挑選的;旁邊的界限是這項主張的一部分,不是它的背景說明。每一筆項目 — 包含這一頁沒有引用的那些 — 都會連同背後的能力清單列一起公開:共用主張登錄表。
在你導流經過 Agent Assembly 的路徑上所建立的連線,會依你所設定的目的地清單進行檢查,並在代理伺服器撥號之前遭到拒絕。
它到哪裡為止。 這次拒絕出自代理伺服器自身的本機對外流量組態,而非控制平面的決策。目的地清單預設為空 — 這次拒絕之所以存在,是因為有維運者設定了它。在 Linux 上是發行產物;在 macOS 上,cargo install aa-proxy 是唯一的途徑;在 Windows 上沒有任何本機中介。如果代理伺服器不在這條連線前面,這條連線就只是單純地被建立起來。
在 Agent Assembly 會檢查的模型供應商主機上,被辨識出來的憑證會在請求被轉發之前從中移除。
它到哪裡為止。 共三個內建主機,因為 llm_only 預設開啟。預設行為是遮蔽後轉發,而非拒絕。偵出率受限於樣式集合 — 並沒有 Stripe 的偵測器。該路徑上的模型回應不會被掃描。
MCP 工具呼叫可以由控制平面依你的政策進行檢查,並在代理伺服器轉發之前遭到拒絕。
它到哪裡為止。 這是本產品中唯一一個由閘道決定、且發生在撥號之前的拒絕,而它預設關閉。它涵蓋的是在已設定閘道端點的被攔截非 LLM 主機上,以一般 HTTP/1.1 POST 送出的 MCP。以 stdio 執行的工具伺服器 — 最常見的設定方式 — 以及 SSE 與 WebSocket 都沒有攔截機制;Streamable HTTP 則被記錄為在功能上就是壞的,而不只是未被涵蓋。
已宣告的花費上限是否真的在決策路徑中被檢查,並沒有任何能力清單列可以確立。
它到哪裡為止。 與 RC6 同樣的形狀,也同樣的補救方式。能力清單中關於預算的唯一一列,是儲存區讀不到或損毀的那一列,帶著 coverage: unmeasured、failure_posture: fail_open_silent 與 evidence: gap — 它的缺口理由記載了一項正向對照,顯示預算這條路徑從來不會去查詢控制平面的儲存區。風險情境的 T3 達到已評估,並在同一張表裡載明它沒有任何正向的列;本登錄表不會在一列並不承載該用語的列上,重述 T3 的用語。無論如何都成立的界限是:上限只存在於政策有宣告它的地方;未宣告的預算等於沒有上限;要達到執行前拒絕,需要有一個會等待答案的呼叫端;而損毀的儲存區會無聲地把上限重設為零花費。請見那兩個缺口。
某一項決策的記錄是否持久地抵達稽核鏈,並未被確立。驗證工具是真實存在的 — aasm audit verify-chain 隨開放原始碼版本一併提供 — 但它所證明的是現存項目的完整性,而不是任何一項特定的決策確實產生了一筆記錄。
它到哪裡為止。 能力清單中關於這個主題的唯一一列,是寫出失敗時會發生什麼的那一列,而該列帶著 coverage: unmeasured、failure_posture: fail_open 與 evidence: gap。所以誠實的用語就是該列自己的用語。關於這條鏈的其他一切都是界限,不是能力:它可察覺竄改,但既非不可變更,也未經簽章 — 它是一個無金鑰摘要,所以任何能改寫輸出目的地的人都能重新算出它。鏈首會在送出之前就先推進,而通道滿載時會丟掉該筆項目、該次呼叫卻仍然返回,這使得被丟棄的項目與被刪除的項目無從分辨。一份被清空的日誌驗證起來也會是乾淨的。除非代理伺服器的稽核路徑已設定,否則它根本不會寫出任何本機記錄。請見那兩個缺口。
之後有什麼不一樣
一次拒絕會變成一項可觀測的決策,所以測試可以針對這項決策做斷言。
請針對決策、並針對一個獨立觀測者做斷言,不要針對稽核日誌。RC6 是未量測,所以一筆缺漏的項目無法分辨「那項決策沒有做成」與「那筆記錄被丟掉了」,而讀日誌的測試會把這份模糊繼承成一次不穩定的通過。隨風險情境一起發布的反向對照,正是為了這個理由才建立在一個獨立的監聽器之上。
至於針對「被避免掉的後果」所做的斷言,又是另一回事,而且更嚴格 — 在你動手寫之前,先看底下的限制一節。
你可以查證什麼,以及在哪裡查
那四個情境,每一個都附有一項判定與它所依據的能力清單列 — 特別是反向對照那一節,它明定了「不存在」的檢查、用來證明該檢查看得見該效果的配對正向對照,以及斷言的執行順序。
風險情境與反向對照 →逐列的證據:「證據」與「是否在主線上執行」這兩個欄位,全部 80 列都有。引用之前先讀那一列 — 有些是由常設的整合測試釘住的,有些只由單元測試釘住。
能力清單 →哪些是刻意還不主張的 — 產品承諾頁上的「暫定」表就是那份被保留下來的主張清單,也是最快看出一條驗收條件不能建立在什麼之上的方式。
「暫定」表 →發行與版本的位置 — 在某一個平台上錄下的展示,不能作為關於另一個平台上已發行產物的證據。
相容性對照表 →
那些你原本會比較晚才發現的事
- 核准是缺口,不是一項功能。今天,任何針對人工核准步驟所寫的驗收條件都無法通過。需要核准RC12
不作任何主張。
它到哪裡為止。 能力清單裡沒有任何一列達到這個用語。這個擱置在閘道這條路徑上確實存在,且逾時會失效關閉,但沒有任何已出貨的維運者介面能夠回應它;而在 MCP 通道之內,待決的決策會直接被降級成一次拒絕,所以在那裡也同樣找不到人來處理。AAASM-5657。
- 「已阻止某後果」的主張是被卡住的。設計出一個反向對照,跟真的執行過一次,並不是同一件事。在 AAASM-5532 與 AAASM-5529 結案之前,請描述所做出的決策,不要描述被避免掉的後果。
- 一個錯誤並不等於一個「不存在」。一個代理可以收到一次拒絕,同時仍然已經透過另一條路徑抵達了那個端點。只針對錯誤、而不針對獨立觀測者做斷言的測試,量到的是錯的東西。
- 證據的品質並不一致。有些列是由常設的整合測試釘住的;有些只由單元測試釘住;有些則完全沒有任何證據,被記為缺口。有兩列被明確標示為僅有單元測試。引用之前先讀那一列。
- 一份空的稽核日誌是關於觀測者的證據,不是關於代理的證據。而鏈驗證通過,並不代表這份日誌是完整的(RC6)。
- 十六筆登錄項目之中,有兩筆根本沒有任何能力清單列作為依據。RC6 與 RC13 之所以是未量測,是因為能力清單中關於證據管線與關於預算的唯一列,都是這兩個子系統失效時的那一列。任何針對「這項決策在稽核日誌裡」或「上限有被套用」所寫的驗收條件,目前主張的都是證據基礎並不承載的東西。追蹤於 AAASM-5531。
- 預算上限只存在於政策有宣告它的地方。未宣告的預算等於沒有上限,而損毀的預算儲存區會無聲地把上限重設(RC13)。
- 沒有任何涵蓋率數字可用。不得推導出任何百分比、受治理動作的計數,或橫跨整個機群的數值 — 包含從那四個情境推導出來。某個層級自行回報自己可用,並不能作為涵蓋率的證據。
- 有三種訊號看起來像涵蓋率,但其實不是。一個會直接取代探測結果的環境變數、一個只要路徑上存在某個執行檔就算通過的代理伺服器探測,以及一個被無條件斷定為真的 SDK 層級旗標。不要在其中任何一個之上建立檢查。
- 平台與通路會改變答案。在 macOS 上錄下的展示,不能作為關於某個已發行 Linux 產物的證據(RC8、RC9、RC14)。