id: ADR-003 title: WASMプラグインは初期実行ブリッジとしてExtismを使用する date: 2026-03-15 status: superseded-by-ADR-009 relates-to:
- ADR-009
- crates/zeroclaw-plugins
- crates/zeroclaw-api
ADR-003: WASM プラグインは Extism を初期実行ブリッジとして使用する
これは復元された遡及的な記録です。元の ADR は docs/architecture/decisions/adr-003-wasm-extism-plugin-model.md の下に追加されましたが、mdBook への移行中に削除されました。これは 2026-03-15 に承認された、歴史的な Extism ベースのプラグインブリッジを記録したものです。現在の WIT および直接的な wasmtime モデルは、ADR-009 においてこれに取って代わります。
コンテキスト
ZeroClaw は多くのツールやチャネルを単一のバイナリにコンパイルしていました。すべてのユーザーが、使うことのない機能のためにコンパイル時間とバイナリサイズを負担していました。サードパーティの開発者は、リポジトリをフォークして内部 API に対する Rust コードを書かない限り、ZeroClaw を拡張できませんでした。
インテンショナルアーキテクチャRFCでは、コア以外のツールやチャネルをロード可能なプラグインにするマイクロカーネルターゲットを定義しました。これには、次のようなサンドボックス化された実行モデルが必要でした:
- ホストプロセスを危険にさらすことなく、信頼できないコードを実行します。
- Linux、macOS、Windows、ARM、x86_64 の各ターゲットで動作します。
- HTTPアクセス、環境変数の読み取り、ファイルI/Oといったケイパビリティベースの権限をサポートします。
- WASM にコンパイルできる任意の言語でプラグインを記述できるようにします。
- 機能が未使用の場合、バイナリサイズへの追加は最小限です。
元の評価では、3つのWASMランタイムオプションが検討されました:
| ランタイム | 利点 | 欠点 |
|---|---|---|
| Extism | 高レベルSDK、組み込みホスト関数システム、複数のゲスト言語向けPDK、活発なメンテナンス | フィーチャーフラグの裏にバイナリサイズを追加 |
| 生の wasmtime | 最大限のコントロール、成熟したランタイム | ABI、メモリプロトコル、ホスト関数システムを直接構築する必要があります |
| Wasmer | LLVM と Cranelift バックエンド | エコシステムが小さく、Rustネイティブなホスト関数のエルゴノミクスが劣る |
決定
ZeroClaw は、plugins-wasm 機能フラグの背後で、初期の WASM プラグインランタイムとして Extism 1.x を使用します。
プラグインは 2 つの JSON 関数をエクスポートする WASM モジュールでした:
tool_metadata(String) -> String。name、description、parameters_schemaフィールドを含む JSON を返します。execute(String) -> Stringは、ツールの引数を JSON として受け取り、success、output、およびオプションのerrorフィールドを持つ JSON 結果を返します。
ランタイムは、パーミッションで制御される2つのホスト関数を提供しました。
zc_http_request(String) -> String、PluginPermission::HttpClientによって制御されます。zc_env_read(String) -> String(PluginPermission::EnvReadによりゲート制御)。
Extismの組み込みHTTPサポートは、ZeroClawの権限の強制をバイパスしてしまうため、意図的に使用されませんでした。
各プラグインは .wasm ファイルと共に manifest.toml を同梱していました。マニフェストは名前、バージョン、tool、channel、memory、observer などのケイパビリティ、および http_client、env_read、file_read、file_write、memory_read、memory_write などの必要なパーミッションを宣言していました。
プラグインマニフェストは、disabled、permissive、strict の3つの適用モードでオプションのEd25519署名をサポートしていました。
プラグイン作者は extism-pdk に依存し、wasm32-wasip1 にコンパイルしていました。このプロトコルは、ZeroClaw 固有のゲスト SDK crate ではなく、文書化された JSON 契約を使用していました。
結果
Positive:
- WASM のリニアメモリ分離により、プラグインがホストメモリにアクセスすることを防止しました。
- 権限で制御されるホスト関数により、初期のブリッジに明確なケイパビリティモデルがもたらされました。
- 基盤となるランタイムがサポートするあらゆるプラットフォームで、WASM モジュールを実行できます。
wasm32-wasip1ターゲットを持つ言語はプラグインを生成できる可能性があります。plugins-wasmを無効にしたユーザーは、バイナリサイズやコンパイル時間のコストを負担しませんでした。
ネガティブ:
- Extism はバイナリサイズをフィーチャーフラグの背後に追加しました。
- プラグイン作者は外部SDKである
extism-pdkに依存していました。 - 最初のブリッジにより、チャネルプラグインより先にツールプラグインが機能するようになりました。
- Extism の呼び出しは同期的でしたが、ZeroClaw の
Toolトレイトは async だったため、呼び出しにはブロッキングタスクのブリッジングが使用されていました。
既知のギャップ:
zc_http_requestは、ネイティブの HTTP ツールで使用されているのと同じプライベート IP、ループバック、リンクローカルの制限なしに、プラグインが指定した URL を転送する可能性がありました。env_readは、プラグインごとの許可リストではなく、名前によって任意の変数へのアクセスを許可していました。- CPU実行には燃料制限またはエポック割り込みがありませんでした。
こうした隙間があったため、当初の権限モデルは文書化された取り決めにとどまり、信頼できない作者によるプラグインに対する堅牢な境界にはまだなっていませんでした。
参照
- ADR-009: WIT コンポーネントと wasmtime プラグインの直接実行
- 履歴上のソースパス:
docs/architecture/decisions/adr-003-wasm-extism-plugin-model.md - 過去の実装パス:
crates/zeroclaw-plugins/src/runtime.rs、crates/zeroclaw-plugins/src/wasm_tool.rs、crates/zeroclaw-plugins/src/host.rs、およびcrates/zeroclaw-plugins/src/signature.rs - 元の ADR からの追跡 issue: #5918 と #5919