Skip to content

Mod system: WASM mod loading scaffold (extism sandbox) #278

@mark-ik

Description

@mark-ik

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    architectureImported from backlog ticket stubsfeatureImported from backlog ticket stubslane:viewer-platformViewer embedding parity + Wry foundation lanestatus:queuedImported from backlog ticket stubstype:childMergeable child slice under a hub issue

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions