Goal
Implement the WASM mod loading tier of the ModRegistry using extism — the capability-restricted WASM plugin runtime. This unlocks third-party mod distribution without recompilation.
Scope
- Add
extism (1.13.0, BSD-3-Clause) to Cargo.toml
- Implement
ModType::Wasm loading path in mod_loader.rs
- Define the host-side capability interface exposed to WASM mods:
- Read-only graph snapshot access
- Intent submission via a bounded queue (mods cannot call
apply_intents directly)
- Registry query (ViewerRegistry, PhysicsProfileRegistry, ActionRegistry)
- Diagnostics channel write (via DiagnosticsRegistry namespace)
ModManifest validation for WASM mods: provides + requires checked against registered capabilities
- Sandbox invariants: no filesystem access, no network access, no keychain access unless declared and granted
- Hot-reload: WASM mods can be updated without app restart (re-load extism plugin from file)
- Capability denial path emits
diagnostics event (not panic)
Non-Goals (Phase 1)
- Physics profile mods (tracked separately in canvas lane)
- Viewer mods (require compositor pass hooks — speculative)
- Cross-mod communication
Crate
extism (BSD-3-Clause) wraps wasmtime internally. BSD-3 is license-compatible. wasmtime is pulled transitively; direct dep not needed unless custom host interface is required beyond extism ABI.
Source Docs
design_docs/graphshell_docs/implementation_strategy/subsystem_mods/SUBSYSTEM_MODS.md
design_docs/graphshell_docs/implementation_strategy/system/2026-02-22_registry_layer_plan.md (§ModRegistry)
design_docs/graphshell_docs/implementation_strategy/canvas/2026-02-24_physics_engine_extensibility_plan.md (extism ABI rationale)
design_docs/graphshell_docs/technical_architecture/2026-03-01_dependency_inventory.md (extism: 🟢 Adopt when ready)
design_docs/TERMINOLOGY.md (WASM Mod definition)
Dependencies
ModRegistry native mod tier already active (inventory::submit! path)
DiagnosticsRegistry channel schema active
ActionRegistry routing active
Done Gate
- A minimal WASM mod (hello-world physics profile) loads, executes, and registers via
ModRegistry
- Sandbox violation (filesystem open attempt) is caught and emits diagnostics, does not crash
ModManifest provides/requires validation rejects mods with missing capability declarations
- Hot-reload: mod file can be replaced on disk and reloaded without app restart
- Capability grant/deny flow documented in
SUBSYSTEM_MODS.md
Goal
Implement the WASM mod loading tier of the
ModRegistryusingextism— the capability-restricted WASM plugin runtime. This unlocks third-party mod distribution without recompilation.Scope
extism(1.13.0, BSD-3-Clause) toCargo.tomlModType::Wasmloading path inmod_loader.rsapply_intentsdirectly)ModManifestvalidation for WASM mods:provides+requireschecked against registered capabilitiesdiagnosticsevent (not panic)Non-Goals (Phase 1)
Crate
extism(BSD-3-Clause) wrapswasmtimeinternally. BSD-3 is license-compatible.wasmtimeis pulled transitively; direct dep not needed unless custom host interface is required beyond extism ABI.Source Docs
design_docs/graphshell_docs/implementation_strategy/subsystem_mods/SUBSYSTEM_MODS.mddesign_docs/graphshell_docs/implementation_strategy/system/2026-02-22_registry_layer_plan.md(§ModRegistry)design_docs/graphshell_docs/implementation_strategy/canvas/2026-02-24_physics_engine_extensibility_plan.md(extism ABI rationale)design_docs/graphshell_docs/technical_architecture/2026-03-01_dependency_inventory.md(extism: 🟢 Adopt when ready)design_docs/TERMINOLOGY.md(WASM Mod definition)Dependencies
ModRegistrynative mod tier already active (inventory::submit!path)DiagnosticsRegistrychannel schema activeActionRegistryrouting activeDone Gate
ModRegistryModManifestprovides/requiresvalidation rejects mods with missing capability declarationsSUBSYSTEM_MODS.md