レシート
レシートは「改ざんが察知できる」署名付きの記録ですが、五つの段階に分かれており、どのレシートもどの段階まで達したかを自分で宣言しなければなりません。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 を物理的なラベルに印刷し、外部に一緒には作り直せない錨を一つ置くことです。

