Keyboard shortcuts

Press or to navigate between chapters

Press ? to show this help

Press Esc to hide this help


id: ADR-003 title: Les plugins WASM utilisent Extism comme pont d’exécution initial date: 2026-03-15 status: remplacé-par-ADR-009 relates-to:

  • ADR-009
  • crates/zeroclaw-plugins
  • crates/zeroclaw-api

ADR-003 : les plugins WASM utilisent Extism comme pont d’exécution initial

Ceci est un enregistrement rétroactif restauré. L’ADR original a été ajouté sous docs/architecture/decisions/adr-003-wasm-extism-plugin-model.md et a été supprimé lors de la migration mdBook. Il documente le pont de plugins historique basé sur Extism qui a été accepté le 2026-03-15. Le modèle actuel WIT et wasmtime direct le remplace dans ADR-009.

Contexte

ZeroClaw a compilé de nombreux outils et canaux en un seul binaire. Chaque utilisateur payait le temps de compilation et la taille du binaire pour des capacités qu’il n’utiliserait peut-être jamais. Les développeurs tiers ne pouvaient pas étendre ZeroClaw sans forker le dépôt et écrire du code Rust s’appuyant sur les API internes.

La RFC Intentional Architecture a défini une cible microkernel où les outils et canaux non essentiels deviennent des plugins chargeables. Cela a nécessité un modèle d’exécution en bac à sable qui :

  1. Exécute du code non fiable sans compromettre le processus hôte.
  2. Fonctionne sur les cibles Linux, macOS, Windows, ARM et x86_64.
  3. Prend en charge les permissions basées sur les capacités telles que l’accès HTTP, les lectures de variables d’environnement et les E/S de fichiers.
  4. Permet d’écrire des plugins dans n’importe quel langage compilé en WASM.
  5. Ajoute une taille minimale au binaire lorsque la fonctionnalité n’est pas utilisée.

L’évaluation originale a considéré trois options de runtime WASM :

ExécutionAvantagesInconvénients
ExtismSDK de haut niveau, système de fonctions hôte intégré, PDKs pour plusieurs langages invités, maintenance activeAjoute la taille du binaire derrière le feature flag
Brut wasmtimeContrôle maximum, runtime matureNécessite de construire l’ABI, le protocole de mémoire et le système de fonctions hôte directement
WasmerBackends LLVM et CraneliftÉcosystème plus petit et ergonomie des fonctions hôtes moins native à Rust

Décision

ZeroClaw utiliserait Extism 1.x comme runtime de plugins WASM initial derrière le feature flag plugins-wasm.

Les plugins étaient des modules WASM exportant deux fonctions JSON :

  • tool_metadata(String) -> String, renvoyant du JSON avec les champs name, description et parameters_schema.
  • execute(String) -> String, recevant les arguments d’outil sous forme de JSON et renvoyant un résultat JSON avec les champs success, output et error optionnel.

Le runtime a fourni deux fonctions hôtes soumises à des permissions :

  • zc_http_request(String) -> String, soumis à PluginPermission::HttpClient.
  • zc_env_read(String) -> String, soumis à PluginPermission::EnvRead.

Le support HTTP intégré d’Extism n’a pas été utilisé délibérément car il contournerait le contrôle des autorisations de ZeroClaw.

Chaque plugin livrait un manifest.toml accompagné de son fichier .wasm. Le manifeste déclarait le nom, la version, les capacités telles que tool, channel, memory et observer, ainsi que les permissions requises telles que http_client, env_read, file_read, file_write, memory_read et memory_write.

Les manifests de plugins prenaient en charge des signatures Ed25519 optionnelles avec trois modes d’application : disabled, permissive et strict.

Les auteurs de plugins dépendaient de extism-pdk et compilaient vers wasm32-wasip1. Le protocole utilisait des contrats JSON documentés plutôt qu’une crate SDK guest spécifique à ZeroClaw.

Conséquences

Positif :

  • L’isolation de la mémoire linéaire WASM a empêché les plugins d’accéder à la mémoire de l’hôte.
  • Les fonctions hôtes soumises à des permissions ont donné au pont initial un modèle de capacités clair.
  • Les modules WASM pouvaient s’exécuter sur n’importe quelle plateforme prise en charge par le runtime sous-jacent.
  • Les langages disposant de cibles wasm32-wasip1 peuvent produire des plugins.
  • Les utilisateurs qui ont désactivé plugins-wasm n’ont pas payé le coût en taille binaire ou en temps de compilation.

Négatif :

  • Extism a ajouté la taille du binaire derrière le drapeau de fonctionnalité.
  • Les auteurs de plugins dépendaient de extism-pdk, un SDK externe.
  • Le pont initial a rendu les plugins d’outils fonctionnels avant les plugins de canaux.
  • Les appels Extism étaient synchrone, tandis que le trait Tool de ZeroClaw était asynchrone, les appels ont donc utilisé un pont de tâches bloquantes.

Lacunes connues :

  • zc_http_request pouvait transmettre des URL fournies par des plugins sans les mêmes restrictions d’IP privées, de loopback et de link-local utilisées par les outils HTTP natifs.
  • env_read accordait l’accès à n’importe quelle variable par nom au lieu d’une liste d’autorisations par plugin.
  • L’exécution CPU n’avait pas de limite de carburant ni d’interruption d’époque.

Ces lacunes signifiaient que le modèle de permissions était initialement un contrat documenté, pas encore une frontière renforcée pour les plugins d’auteurs non de confiance.

Références

  • ADR-009 : Composants WIT et exécution directe de plugins wasmtime
  • Chemin source historique : docs/architecture/decisions/adr-003-wasm-extism-plugin-model.md
  • Chemins d’implémentation historiques : crates/zeroclaw-plugins/src/runtime.rs, crates/zeroclaw-plugins/src/wasm_tool.rs, crates/zeroclaw-plugins/src/host.rs et crates/zeroclaw-plugins/src/signature.rs
  • Suivi des issues de l’ADR original : #5918 et #5919