Emetgate:LLMとソースコードの間に置く検証ゲート
Emetgate は GitHub 上のオープンソースの検証カーネルで、Windows 上の言語モデルと TypeScript/JavaScript のソースツリーの間に入ります。モデルは変更を提案するだけで、ファイルは書けません。カーネルがハッシュ、パース結果、影響範囲を検査し、必要ならサンドボックスでテストしてから、アトミックにコミットまたは却下します。README は初期段階と述べています。
Emetgateとは何か
Emetgate は GitHub 上のオープンソースプロジェクト(emetgate/emetgate)です。README は自らを「言語モデルとソースツリーの間に置かれる、決定論的な検証カーネル」と説明しています。合言葉は「Nothing passes but the truth.」(真実だけが通る)です。README によれば、プロジェクトはまだ初期段階で、範囲を意図的に絞っています。対象は Windows のみ、実装は Zig 0.16.0、扱う言語は TypeScript と JavaScript です。Model Context Protocol(MCP)でツールを公開するため、Claude Code のような MCP クライアントから使えます。
考え方は単純です。言語モデルはコードを読み、特定のシンボルへの変更を提案できます。しかしファイルを書くことも、作業の完了を宣言することもできません。すべての提案は小さなカーネルが検査し、アトミックにコミットするか、理由付きで却下します。README はこれを「モデルが提案し、カーネルが検証する。未検証のものはディスクに届かない」とまとめています。
作者が作った理由
README は、LLM 生成コードを真剣に使う人なら知っている失敗の型を挙げています。コンパイルは通るのに間違っているコード。終わっていない作業を「完了」と報告するモデル。3ターン前に決めたルールがいつの間にか忘れられること。セッション冒頭で合意した計画が、終わりには消えていること。作者は、これらが別々の問題に見えて原因は一つだと主張します。モデルとディスクの間に、モデルの出力を確認する責任を持つ存在がないのです。
README によると、現在のツールは自律性と速度を競っており、それが未検証の出力の量を増やします。モデル自身にはこの穴を埋められません。モデルは「サンプラーであり、神託ではない」うえに、永続的な記憶を持たないからです。そこで Emetgate はモデルに一切の権限を与えず、すべてをカーネルに置きます。README はこれを LCF 型の定理証明器になぞらえています。タクティクは何を提案してもよいが、定理を生み出せるのは小さな信頼済みカーネルだけ、という構造です。名前はプラハのゴーレム伝説に由来します。額に書かれた emet(「真理」)の一語がゴーレムを動かし、最初の文字を消すと met(「死」)になります。
変更がゲートを通る流れ
README は六つの段階を説明しています。
1. **アドレス指定。** 各シンボルは参照(`Class.method` や `add`)と、現在の内容の128ビットハッシュで識別されます。提案は、自分が基にしたハッシュを明示しなければなりません。その間にファイルが変わればハッシュが一致せず、提案は却下されます。モデルは見ていないコードを上書きできません。
2. **パース。** 新しい関数本体をバイト範囲で差し込み、ファイル全体を tree-sitter で再パースします。
3. **ガード。** 結果が正しくパースできるか、本体が波括弧の外へ抜け出していないか、空やプレースホルダーではないか、対象範囲外のバイトがすべて無変更かを確かめます。
4. **境界判定。** カーネルは影響範囲を計算します。この解析は肯定的な閉世界の数え上げです。外へ漏れうる経路をすべて排除できたときだけ `BOUNDED` となり、説明できないものは `UNBOUNDED` です。
5. **テスト。** `UNBOUNDED` の変更はシャドウコピーに適用され、プロジェクトのテストコマンドがサンドボックス内で走ります。サンドボックスは、kill-on-close、実時間とメモリの上限、出力の上限を備えた Windows の Job Object です。コマンドは低整合性の制限付きトークンで実行され、このトークンを作れず検証もできない場合は、制限なしで走らせずに拒否します。テストが失敗すれば変更は却下され、出力がモデルに返されます。
6. **コミット。** 受理された変更は先行書き込みジャーナルとアトミックな書き込み・リネームを通ります。クラッシュしても残るのは旧ファイルか新ファイルのどちらかで、中途半端な書き込みは残りません。`recover` コマンドはジャーナルを再生し、証明できないものは拒否します。
README はカーネルを fail-closed と呼びます。変更の安全性を証明できないときは、その変更を拒否します。
MCP ツールと lockdown
サーバーは読み取り用と変更用のツールを公開します。読み取りには `emetgate_symbols`、`emetgate_skeleton`、`emetgate_read_symbol`、`emetgate_read_file`、`emetgate_list`、`emetgate_search` があり、後ろの三つはリポジトリ内に限定されます。`emetgate_mutate` は書き込まずに構造検証だけを行います。`emetgate_try` は検証、ゲート通過、コミットを行います。`emetgate_try_batch` は複数の提案を一つの単位として扱います。`emetgate_scan` は一つのチェック式をリポジトリに対して測定し、何も書きません。
`emetgate lockdown` は、これらのツールだけを使える状態で Claude Code を起動します。そのためモデルには、ゲート以外にディスクへ至る道がありません。リポジトリには Claude Code のスキル `md-audit` も同梱されています。CLAUDE.md や AGENTS.md の各指示文を、強制可能、仕組み待ち、検証不能、信念に分類し、強制可能なものを `emetgate_scan` で測定します。何も変更しません。
カーネル自身の検証
README は、自らが検証されていない検証層は「手の込んだ願掛けにすぎない」と述べ、二つの方法を挙げます。一つ目はミューテーションテストです。ガードを変異させ(チェックの削除、条件の弱体化、比較の反転)、変異体ごとにテストスイートが失敗しなければなりません。エンジンの `cas`、`boundedness`、`symbol`、`functions` について、README は変異体44個、うち37個を撃破、4個は等価と証明、1個は多層防御として残した冗長なガード、2個は未解決と報告しています。二つ目はレッドチーム型のテストで、波括弧を抜ける本体、古いハッシュ、壊れたジャーナル項目、汚染されたリポジトリ設定、リポジトリ外のファイルへのアクセスを攻撃します。
トークンのベンチマークも報告されています。6シナリオ(うち2つは実ファイル)と `o200k_base` トークナイザーで、シンボル単位の提案は検索置換方式より中央値で1.80倍少ないトークンで済み、範囲は1.15倍から3.77倍でした。実ファイルでは1.15倍から1.17倍です。README はトークン削減を「副次効果であり、目的ではない」と述べています。
私たちの分析
注目したいのは、信頼をどこに置くかです。多くのコーディングツールは、モデルをどう信頼できるものにするかを問います。Emetgate は、モデルの信頼できなさをどう無害にするかを問います。検査は入力の決定論的な関数なので、レビュアーは読み、テストし、攻撃できます。これは、モデル自身の「終わりました」という申告とは別種の保証です。
二点が目を引きます。内容ハッシュにより、「モデルが古いコードを編集した」という静かなバグは、却下される提案に変わります。閉世界の境界判定は、迷ったときに既定でテストを走らせ、速度と引き換えに安全を取ります。
限界と未解決の点
README は限界を率直に認めています。パースでき、境界内に収まり、テストも通るコードでも、間違った挙動を実装していることはあります。テストゲートの強さはテストの質次第です。保証はゲートを通る変更にしか及ばず、他のツールによる編集は迂回するため lockdown があります。低整合性トークンはシャドウコピー外への書き込みを止めますが、読み取りとネットワークは制限しません。悪意あるテストコマンドは、権限のあるファイルを読み、ネットワークに届きうるのです。AppContainer が計画されています。アーキテクチャ、API 設計、ユーザー体験は、カーネルが検査できる性質ではありません。
状態表によれば、決定台帳はまだ MCP ツールとして公開されておらず、編集ゲートでのルール強制は進行中です。対応言語は TypeScript と JavaScript のみ、プラットフォームは Windows のみです。私たちは README を読んだだけで、ツールを実行していません。ベンチマークとミューテーションの数字は作者自身のものです。
読者への実用的なヒント
Windows で TypeScript か JavaScript を書くチームは、リリースのバイナリと SHA-256 チェックサムをダウンロードし、照合してから `claude mcp add` で登録できます。README は、バイナリにコード署名がないため、初回実行時に SmartScreen が警告すると記しています。ソースからのビルドには Zig 0.16.0 と `zig build` が必要です。型チェックとテストのコマンドは運用者が与えます。
`--typecheck` と `--test` で渡すか、`--allow-repo-config` を付けたときに `.emetgaterc.json` から読み込みます。モデルが自分で与えることは決してできません。それ以外の読者にとっても、この README は簡潔な原則の表明として読めます。モデルに書き込み権限を与えず、受理されるすべての変更に、人間が検査できる検証を通させるという原則です。
Sources
FAQ
Emetgate は何をするものですか。
言語モデルとソースツリーの間に置かれる決定論的な検証カーネルです。モデルはシンボルへの変更を提案し、カーネルが検査して、アトミックにコミットするか理由付きで却下します。
テストを走らせるかどうかはどう決めますか。
影響範囲を計算します。外へ漏れうる経路をすべて排除できたときだけ BOUNDED になります。UNBOUNDED の変更は、サンドボックス内のシャドウコピーでプロジェクトのテストコマンドを実行します。
README が認めている限界は何ですか。
検査を通ったコードでも間違いうること、テストゲートの強さはテスト次第であること、他のツールによる編集はゲートを迂回することです。サンドボックスは読み取りとネットワークをまだ制限しません。対応は Windows、TypeScript、JavaScript のみです。