id: ADR-003 title: Los plugins WASM usan Extism como el puente de ejecución inicial date: 2026-03-15 status: superseded-by-ADR-009 relates-to:
- ADR-009
- crates/zeroclaw-plugins
- crates/zeroclaw-api
ADR-003: Los plugins WASM usan Extism como el puente de ejecución inicial
Este es un registro retroactivo restaurado. La ADR original se añadió en docs/architecture/decisions/adr-003-wasm-extism-plugin-model.md y se eliminó durante la migración a mdBook. Registra el histórico puente de complementos basado en Extism que fue aceptado el 2026-03-15. El modelo actual de WIT y de wasmtime directo lo sustituye en ADR-009.
Contexto
ZeroClaw compiló muchas herramientas y canales en un único binario. Cada usuario pagaba el tiempo de compilación y el tamaño del binario por capacidades que quizá nunca usaría. Los desarrolladores de terceros no podían ampliar ZeroClaw sin hacer un fork del repositorio y escribir código Rust contra APIs internas.
El RFC de Arquitectura Intencional definió un objetivo de microkernel en el que las herramientas y canales no esenciales se convierten en plugins cargables. Eso requería un modelo de ejecución aislado que:
- Ejecuta código no confiable sin comprometer el proceso anfitrión.
- Funciona en Linux, macOS, Windows, ARM y objetivos x86_64.
- Admite permisos basados en capacidades, como acceso HTTP, lecturas de variables de entorno y E/S de archivos.
- Permite que los plugins se escriban en cualquier lenguaje que compile a WASM.
- Añade un tamaño binario mínimo cuando la función no se usa.
La evaluación original consideró tres opciones de tiempo de ejecución de WASM:
| Tiempo de ejecución | Ventajas | Contras |
|---|---|---|
| Extism | SDK de alto nivel, sistema de funciones de host integrado, PDKs para varios lenguajes invitados, mantenimiento activo | Añade el tamaño binario detrás del flag de función |
| Raw wasmtime | Máximo control, tiempo de ejecución maduro | Requiere compilar directamente la ABI, el protocolo de memoria y el sistema de funciones del host |
| Wasmer | Backends de LLVM y Cranelift | Un ecosistema más pequeño y una ergonomía de funciones anfitrionas menos nativa de Rust |
Decisión
ZeroClaw usaría Extism 1.x como el tiempo de ejecución inicial de complementos WASM detrás del indicador de función plugins-wasm.
Los complementos eran módulos WASM que exportaban dos funciones JSON:
tool_metadata(String) -> String, devolviendo JSON con los camposname,descriptionyparameters_schema.execute(String) -> String, recibiendo argumentos de la herramienta como JSON y devolviendo un resultado JSON con los campossuccess,outputyerroropcional.
El entorno de ejecución proporcionó dos funciones del host controladas por permisos:
zc_http_request(String) -> String, restringida porPluginPermission::HttpClient.zc_env_read(String) -> String, restringido porPluginPermission::EnvRead.
El soporte HTTP integrado de Extism no se usó deliberadamente porque eludiría la aplicación de permisos de ZeroClaw.
Cada plugin incluía un manifest.toml junto a su archivo .wasm. El manifiesto declaraba el nombre, la versión, capacidades como tool, channel, memory y observer, y permisos requeridos como http_client, env_read, file_read, file_write, memory_read y memory_write.
Los manifiestos de plugins admitían firmas opcionales de Ed25519 con tres modos de aplicación: disabled, permissive y strict.
Los autores de plugins dependían de extism-pdk y compilaban a wasm32-wasip1. El protocolo utilizaba contratos JSON documentados en lugar de un crate de SDK para guest específico de ZeroClaw.
Consecuencias
Positivo:
- La aislamiento de la memoria lineal de WASM impidió que los complementos accedieran a la memoria del host.
- Las funciones del host controladas por permisos dieron al puente inicial un modelo de capacidades claro.
- Los módulos WASM podrían ejecutarse en cualquier plataforma que admitiera el runtime subyacente.
- Los lenguajes con destinos
wasm32-wasip1podrían generar plugins. - Los usuarios que deshabilitaron
plugins-wasmno pagaron el costo del tamaño binario ni del tiempo de compilación.
Negativo:
- Extism añadió el tamaño binario detrás del indicador de función.
- Los autores de plugins dependían de
extism-pdk, un SDK externo. - El puente inicial hizo que los complementos de herramientas fueran funcionales antes que los complementos de canal.
- Las llamadas de Extism eran síncronas mientras que el trait
Toolde ZeroClaw era asíncrono, por lo que las llamadas usaban puenteo mediante tareas de bloqueo.
Gaps conocidos:
zc_http_requestpodría reenviar URLs proporcionadas por complementos sin las mismas restricciones de IP privada, loopback y link-local que usan las herramientas HTTP nativas.env_readconcedía acceso a cualquier variable por nombre en lugar de una lista de अनुमति por plugin.- La ejecución de la CPU no tenía un límite de combustible ni interrupción por época.
Esas brechas significaban que el modelo de permisos era inicialmente un contrato documentado, no todavía un límite reforzado para plugins de autores no confiables.
Referencias
- ADR-009: Componentes WIT y ejecución directa del plugin de wasmtime
- Historical source path:
docs/architecture/decisions/adr-003-wasm-extism-plugin-model.md - Rutas de implementación históricas:
crates/zeroclaw-plugins/src/runtime.rs,crates/zeroclaw-plugins/src/wasm_tool.rs,crates/zeroclaw-plugins/src/host.rsycrates/zeroclaw-plugins/src/signature.rs - Seguimiento de incidencias del ADR original: #5918 y #5919