收據
收據是「篡改可察覺」的簽章紀錄,但它分五個層級,每一張都必須自己宣告做到哪一層。2026-09-20 的稽核發現「拒交」只是旗標——從此之後我們不再說「擋在出口」。
#五層語彙
2026 年 9 月 20 日,一次內部稽核發現某批實驗的「拒交」只是一個旗標與退出碼——外層腳本不讀退出碼,就把被拒的檔案複製了出去。391 格稽核裡,59 個拒交格中有 7 格的檔案被複製出去並評分。
那次稽核之後,專案改用五層語彙描述系統「證明了什麼」,並要求每一層各自宣告涵蓋範圍。
| 層級 | 系統證明了什麼 | 2026 年 9 月的狀態 |
|---|---|---|
| Observed 觀察到 | 看到了某些行為、流量或產物 | 已成立:中介看到的對話沒有缺口(2,755 輪全部對得上,195/195 條鏈驗得過) |
| Decided 判決了 | 獨立判斷這份交付通過或不通過 | 已成立:代理自稱完成,系統仍可判為拒交並簽章 |
| Withheld 扣住了 | 不通過的產物沒有被對外送出 | 預設不成立;以 release/publish 能力分離補上 |
| Mediated 中介了 | 代理找不到繞過系統的替代路徑 | 預設不成立;以 bwrap 圍牆實驗性成立 |
| Attested 認證了 | 上述事實不可竄改地綁到產物、政策與身分 | 部分成立:以收據等級 A/B/B′/C 表示 |
這套語彙的好處是把「有沒有閘門」這種二元說法拆開。我們不是沒有閘門;我們是不能假設閘門擋得住。
#事件鏈的格式
每位居民(參與者)維護一條只能附加的事件鏈。每一筆事件恰好包含八個欄位:
{
"stream_id": "z…",
"branch_id": "…",
"seq": 42,
"prev_hash": "…",
"ts_ms": 1758…,
"type": "DELIVERED",
"payload": { },
"sig": "…"
}
驗證三件事:序號連續、前一筆雜湊對得上、Ed25519 簽章有效。
#簽章能證明什麼、不能證明什麼
所有簽章都覆蓋正規化 JSON 的位元組(鍵排序、無多餘空白、UTF-8),而不是程式語言的資料結構——否則跨機器驗章時位元組不一致。
#鏈驗證抓不到的三件事
這三件事是鏈的結構性限制,不是設定問題。
| 抓不到 | 為什麼 |
|---|---|
| 截斷 | 鏈沒有可信的鏈頭。砍掉尾巴一樣通過。 |
| 分叉 | 同一個人對同一事件簽兩條不同內容的鏈,兩條都驗得過。 |
| 漏記 | 從來沒被寫下的事件,收據無法宣稱自己是其中一筆。 |
所以收據的用語是「篡改可察覺」(tamper-evident),不是「事後不可能改」。
#實測:鏈驗證通過
| 批次 | 鏈數 | 筆數 | 結果 |
|---|---|---|---|
| R460R(五次複製) | — | 6,674 | 全部通過 |
| R529(跨題庫四集) | — | 3,167 | 全部通過 |
| 合計 | 194 | 9,841 | 全部通過獨立驗簽 |
| R454(多方執行真跑) | — | 5,519 條證言 | 0 次簽章驗證失敗 |
| E10(通道分離改版後) | — | 180/180 份評審信封 | 仍可驗證 |
| ABPI 稽核 | 195 | — | 全部通過 |
說謊的金鑰 273/273 被指名,誠實者 0/1,840 被誣告
#收據等級
等級由探針結果決定,不是由「我們裝過了」的推論。
| 等級 | 條件 | 收據能說的話 |
|---|---|---|
| A | 圍牆成立、框架掛鉤的探針已觸發、未解釋的呼叫數為 0 | 每一通模型呼叫都經過 Vacant,且都對得上一個工具事件 |
| B | 圍牆成立,沒有掛鉤 | 每個離開的位元組都有紀錄,但分不出哪一通是模型發出的 |
| B′ | 模型通道不在(或不完整在)Vacant 眼前,但工具層有紀錄 | 只能說明工具層事件 |
| C | 兩者皆無 | 拒發收據 |
所有涵蓋性欄位採三態(真/假/未量)。未量到的值不得寫成零或假。 第一張真實代理的 A 級收據簽於 2026-09-20(pi 0.85.1,未解釋呼叫數為 0)。
#出口:能力分離
「判定拒絕」不等於「不可能發布」。出口的問題以能力分離處理:
release模組只在通過時鑄造放行憑證(結構取自 SLSA 的驗證摘要證明)。publish模組是唯一有對外寫入能力的元件。它驗證憑證的簽章、產物雜湊、判決、有效期與涵蓋範圍。publish不讀退出碼,也刻意沒有強制發布的選項。
專案據此寫下一條設計原則:
可以繞過的閘門,在需要它的那天一定會被繞過。
#離線檢視器的結構性界線
我們自己做的單檔離線檢視器(exhibit/receipts/receipt_viewer.html)把收據內嵌在檔案裡,零外部資源、零網路請求,file:// 開啟也跑得完全鏈驗證。
但 R455 實驗找到它的極限:
攻擊者用自己的金鑰把整條鏈重鑄一遍,再把內嵌的收據改成一致的,它仍然驗得過。
這是離線檢視器的結構性限制,不是漏洞——簽章指認的是金鑰,不是主體。緩解做法是把三個 vacant_id 印在實體標籤上,讓外部有一份無法一起重鑄的錨。

