Context
Part of the --suggest recommendations engine (see #135). Depends on #137, #142. This is the advanced extensibility layer — declarative YAML rules (#142) cover 80% of use cases; WASM covers the remaining 20% that need programmatic logic.
What to Build
1. WASM plugin interface via wasmtime
Add wasmtime dependency. Plugin contract:
Input: JSON-serialized SuggestContext (symbols, call graph, metrics) passed to WASM module's exported evaluate function.
Output: JSON array of Recommendation structs returned from the WASM function.
// src/suggest/wasm_runtime.rs
pub struct WasmPluginRunner {
engine: wasmtime::Engine,
plugins: Vec<WasmPlugin>,
}
pub struct WasmPlugin {
name: String,
module: wasmtime::Module,
}
impl WasmPluginRunner {
pub fn load_plugins(dir: &Path) -> Result<Self>;
pub fn evaluate(&self, ctx: &SuggestContext) -> Vec<Recommendation>;
}
2. Plugin discovery
- Load
.wasm files from .semfora/plugins/
- Each WASM module must export:
fn evaluate(context_json: &str) -> String (JSON in, JSON out)
- Provide a manifest format (
.semfora/plugins/manifest.yaml) for metadata (name, group, description)
3. SDK / template
- Provide a Rust template project (
semfora-plugin-template) that compiles to WASM
- Include helper types matching
Recommendation, SuggestContext as a shared crate
- README with instructions for building plugins in Rust, AssemblyScript, or Go
4. Security
- WASM runs sandboxed (no filesystem, no network by default)
- Configurable memory limit per plugin
- Timeout per plugin evaluation (default: 5s)
Acceptance Criteria
Notes
- This is a lower priority than Phase 3a. Consider making it a cargo feature (
--features wasm-plugins) so it's opt-in.
wasmtime adds ~10MB to binary size — feature-gate it.
References
Context
Part of the
--suggestrecommendations engine (see #135). Depends on #137, #142. This is the advanced extensibility layer — declarative YAML rules (#142) cover 80% of use cases; WASM covers the remaining 20% that need programmatic logic.What to Build
1. WASM plugin interface via
wasmtimeAdd
wasmtimedependency. Plugin contract:Input: JSON-serialized
SuggestContext(symbols, call graph, metrics) passed to WASM module's exportedevaluatefunction.Output: JSON array of
Recommendationstructs returned from the WASM function.2. Plugin discovery
.wasmfiles from.semfora/plugins/fn evaluate(context_json: &str) -> String(JSON in, JSON out).semfora/plugins/manifest.yaml) for metadata (name, group, description)3. SDK / template
semfora-plugin-template) that compiles to WASMRecommendation,SuggestContextas a shared crate4. Security
Acceptance Criteria
wasmtimeintegrated, plugins load from.semfora/plugins/SuggestEngine--suggestflag behindwasmcargo feature (optional dependency)Notes
--features wasm-plugins) so it's opt-in.wasmtimeadds ~10MB to binary size — feature-gate it.References