ID: ADR-009 タイトル: WITコンポーネントと直接的なwasmtimeによるExtismプラグインブリッジの置き換え 日付: 2026-07-04 ステータス: 受理済み 関連:
- ADR-003
- crates/zeroclaw-plugins
- wit/v0
- docs/book/src/foundations/fnd-001-intentional-architecture.md
ADR-009: WIT コンポーネントと直接 Wasmtime が Extism プラグインブリッジを置き換える
このADRはADR-003に取って代わります。ADR-003は初期のExtismブリッジを記録したものです。現在採用されているアーキテクチャは、wasmtimeによって直接ホストされるWITで定義されたWASM Component Modelサーフェスです。
コンテキスト
Extism は、外部 WASM プラグインが ZeroClaw ツールとして登場できることを証明するための有用なブートストラップでした。また、プロジェクトにシンプルな JSON プロトコルと、権限でゲートされたホスト関数モデルも提供しました。
マイクロカーネルアーキテクチャが成熟するにつれ、プラグインサーフェスにはより強力な互換性境界が必要になりました:
- プラグインコントラクトは明示的で、バージョン管理され、レビュー可能である必要がありました。
- ツール、チャネル、メモリバックエンドには、それぞれ独立した型付けの世界が必要でした。
- ホストはリリースターゲット固有の実行バックエンドを必要としていました。
- リンク時にパーミッションへアタッチするために必要なホストインポート;
- プラグイン作者は、その場しのぎの JSON エクスポートではなく、永続的な ABI を必要としていました。
- ストア制限とWASIホストサーフェスはZeroClawが所有する必要がありました。
WASM コンポーネントモデルと WIT がその境界を提供します。wasmtime を直接統合することで、ホストはバックエンドを選択し、WASI Preview 2 のサーフェスをアタッチし、リソース制限を適用し、ゲストのワールドを ZeroClaw の Rust トレイトにブリッジするのに十分な制御を得られます。
決定
ZeroClawのプラグインABIは、wit/v0配下のWITインターフェースで記述されたWASMコンポーネントに基づいています。ホストはcrates/zeroclaw-plugins内で直接wasmtimeコンポーネントモデルの配線を使用し、ツール、チャネル、メモリバックエンド用にワールドごとのブリッジを備えています。
実行モデルは次のとおりです。
wit/v0/tool.wit、channel.wit、memory.witはゲストのコントラクトを定義します。crates/zeroclaw-plugins/src/component.rsは、共有コンポーネントホストのプラミング、ストアの状態、リソース制限、WITバインディング、およびWASI配線を管理します。wasm_tool.rs、wasm_channel.rs、wasm_memory.rsは、これらの世界を Rust のTool、Channel、Memoryトレイトへと橋渡しします。- プラグインの
manifest.tomlは、プラグイン名、バージョン、ケイパビリティタイプ、権限、設定、および署名材料を宣言します。 - Ed25519 マニフェスト検証はプラグインホストの一部のままです。
実行バックエンドの選択は明示的です:
plugins-wasmは、メインワークスペースでプラグインホストのサーフェスを有効にします。plugins-wasm-runtime-onlyは、最小のランタイム専用ホストを有効にします。plugins-wasm-craneliftはサポートされている環境で Cranelift コンパイルを有効にします。plugins-wasm-pulleyは、Cranelift が利用できない、または望ましくないターゲット向けに Pulley インタープリターを有効にします。
ホストサーフェスはパーミッションでゲートされています:
HttpClientは、送信 HTTP 状態をアタッチし、WASI HTTP をリンクする権限です。ConfigReadは、ホストが解決済みの値をツールの__configに注入したり、チャネルのconfig.getを提供したりする前に必要です。ツールまたはチャネルのコンシューマーは、トップレベルの文字列プロパティにx-secret = trueを指定できます。これらの値が公開オブジェクトに入ることはなく、インスタンススコープのsecretsインポートを介して読み取られます。ツールはexecute中にシークレットへのアクセスを受け取ります。チャネルはconfigureおよび運用呼び出し中にconfig.getとsecrets.getを受け取ります。両方の読み取りは、呼び出しごとに 1 つの正規の構成解決を共有します。インスタンス化と静的メタデータの検出は引き続き利用できません。ホストは各呼び出しのマテリアライズされたビューを破棄します。準拠するチャネルゲストは使用時点で解決し、返された構成や平文を保持してはなりませんが、ホストは配信後にこれを強制できません。静的な識別情報と機能のエクスポートはロード時に読み取られるため、これらの値を変更するにはチャネルのライフサイクルを再構築する必要があります。- ホストは生の環境変数読み取り関数を公開していません。
- ストアの制限、fuel、テーブル制限、インスタンス制限、メモリ上限は、ストアが構築される前に解決されます。
結果
Positive:
- プラグインは、プラグインの種類ごとにアドホックなJSON規約を用いるのではなく、Rustホストとの単一の型付き契約サーフェスを共有します。
- WITファイルは、凍結してレビューできる互換性の境界となります。
- ツール、チャネル、メモリのプラグインは、ランタイムに対してネイティブなトレイト実装として見えるようにできます。
- 実行バックエンドは、1つの汎用機能フラグに隠されるのではなく、リリースターゲットによって選択されます。
- 権限チェックはマニフェストに記載されるだけでなく、ホストインポートにアタッチされます。
ネガティブ:
- 直接的な
wasmtimeコンポーネント統合は、元の Extism ブリッジよりも複雑です。 - リリースビルドでは、各ターゲットに適した実行バックエンドを選択する必要があります。
- プラグイン作成者は、JSON関数をエクスポートするのではなく、WASI Preview 2コンポーネントをビルドしてWITインターフェースに従う必要があります。
- WIT サーフェスには互換性の規律が求められるようになりました。これを変更することは、ローカルなクレートの編集ではなく、プラグイン横断的なアーキテクチャの決定です。
フォローアップ:
- WITのバージョニングおよび互換性ルールは、WITのドキュメントに記載されています。互換性ポリシーが変更される場合は、このADRを無断で編集するのではなく、新しいADRを作成してください。
- 新しいゲストワールドは、対応するホストブリッジコードと権限レビューを伴うバージョン付きの WIT サーフェスとして追加する必要があります。
参照
- ADR-003: WASMプラグインは初期実行ブリッジとしてExtismを使用する
- FND-001: 意図的なアーキテクチャ
- プラグインプロトコル
wit/v0/wit/VERSIONING.mdcrates/zeroclaw-plugins/src/component.rscrates/zeroclaw-plugins/src/wasm_tool.rscrates/zeroclaw-plugins/src/wasm_channel.rscrates/zeroclaw-plugins/src/wasm_memory.rscrates/zeroclaw-plugins/src/host.rscrates/zeroclaw-plugins/src/signature.rscrates/zeroclaw-infra/src/net_guard.rs