Files
wehub-resource-sync 9740bc64c9
Continuous Deployment / Deploy to Production (push) Blocked by required conditions
Continuous Deployment / Rollback Deployment (push) Blocked by required conditions
Continuous Deployment / Post-deployment Monitoring (push) Blocked by required conditions
Continuous Deployment / Notify Deployment Status (push) Blocked by required conditions
Firmware QEMU Tests (ADR-061) / QEMU Test (edge-tier1) (push) Has been skipped
Firmware QEMU Tests (ADR-061) / QEMU Test (full-adr060) (push) Has been skipped
Firmware QEMU Tests (ADR-061) / QEMU Test (tdm-3node) (push) Has been skipped
Firmware QEMU Tests (ADR-061) / Swarm Test (ADR-062) (push) Has been skipped
npm packages / tools/ruview-mcp (node 22) (push) Failing after 1s
nvsim-server → ghcr.io / build-and-publish (push) Failing after 1s
ruview-swarm CI guard / tests (full+train) (push) Failing after 2s
Bench Regression Guard / bench compile-verify (--no-run) (push) Failing after 0s
Bench Regression Guard / bench fast-run (informational, non-gating) (push) Has been skipped
Firmware CI / Verify version.txt matches release tag (push) Has been skipped
Dashboard a11y + cross-browser / a11y (push) Failing after 0s
nvsim Dashboard → GitHub Pages / build-and-deploy (push) Failing after 2s
Firmware CI / Build firmware (esp32s3 / 4mb) (push) Failing after 15s
Firmware QEMU Tests (ADR-061) / Build Espressif QEMU (push) Failing after 1s
Firmware QEMU Tests (ADR-061) / Fuzz Testing (ADR-061 Layer 6) (push) Failing after 1s
Continuous Deployment / Pre-deployment Checks (push) Has been skipped
Continuous Deployment / Deploy to Staging (push) Waiting to run
Firmware CI / Build firmware (esp32c6 / c6-4mb) (push) Failing after 15s
Firmware CI / Build firmware (esp32s3 / 8mb) (push) Failing after 15s
Firmware QEMU Tests (ADR-061) / QEMU Test (boundary-max) (push) Has been skipped
Firmware QEMU Tests (ADR-061) / QEMU Test (boundary-min) (push) Has been skipped
Firmware QEMU Tests (ADR-061) / QEMU Test (default) (push) Has been skipped
Firmware QEMU Tests (ADR-061) / QEMU Test (edge-tier0) (push) Has been skipped
Firmware QEMU Tests (ADR-061) / NVS Matrix Generation (push) Failing after 1s
Security Scanning / Security Policy Compliance (push) Failing after 0s
Security Scanning / Security Report (push) Waiting to run
Security Scanning / Dependency Vulnerability Scan (push) Failing after 0s
Security Scanning / Static Application Security Testing (push) Failing after 1s
Security Scanning / Infrastructure Security Scan (push) Failing after 1s
Security Scanning / Secret Scanning (push) Failing after 1s
npm packages / harness/ruview (node 22) (push) Failing after 17s
Security Scanning / License Compliance Scan (push) Failing after 1s
Security Scanning / Container Security Scan (push) Failing after 4s
three.js demos → GitHub Pages / build-and-deploy (push) Failing after 1s
Verify Pipeline Determinism / Verify Pipeline Determinism (3.11) (push) Failing after 1s
Fix-Marker Regression Guard / Verify fix markers (push) Failing after 1s
ADR-115 MQTT integration tests / mqtt-integration (push) Failing after 1s
npm packages / harness/ruview (node 20) (push) Failing after 1s
npm packages / tools/ruview-mcp (node 20) (push) Failing after 1s
npm packages / tools/ruview-cli (node 20) (push) Failing after 1s
npm packages / tools/ruview-cli (node 22) (push) Failing after 1s
BFLD MQTT Integration / cargo test --features mqtt (live mosquitto) (push) Failing after 29s
ruview-swarm CI guard / build train_marl bin (push) Failing after 2s
ruview-swarm CI guard / clippy (-D warnings, --no-deps) (push) Failing after 3s
ruview-swarm CI guard / tests (ruflo) (push) Failing after 1s
ruview-swarm CI guard / tests (train) (push) Failing after 2s
ruview-swarm CI guard / tests (default) (push) Failing after 2s
Point Cloud Viewer → GitHub Pages / build-and-deploy (push) Failing after 8s
ruview-swarm CI guard / ITAR / publish guard (push) Failing after 0s
wifi-densepose sensing-server → Docker Hub + ghcr.io / build · push · smoke-test (push) Failing after 1s
chore: import upstream snapshot with attribution
2026-07-13 11:59:54 +08:00
..

homecore-plugins

WASM integration plugin runtime for HOMECORE with native Rust runtime (P1) and Wasmtime JIT sandbox support (P2).

Crates.io License MSRV: 1.89+ Tests ADR-128

P1 scaffold: manifest parsing, plugin traits, and in-memory native Rust plugin registry. Wasmtime sandbox (P2) and hot-reload (P3) are deferred.

What this crate does

homecore-plugins provides a trait-based plugin system that can host both native Rust plugins (in-process) and WASM plugins (Wasmtime sandbox, P2). It defines:

  • PluginManifest — JSON schema for plugin metadata (superset of Home Assistant's manifest.json), validated at load time
  • HomeCorePlugin trait — async lifecycle hooks (setup, teardown, state changed handlers)
  • PluginRuntime trait — abstraction over execution environments (native vs WASM)
  • InProcessRuntime — built-in runtime for first-party Rust plugins (P1)
  • PluginRegistry — manages loading, unloading, and querying plugins
  • Host ABI (stubs) — C-compatible function signatures for WASM ↔ homecore calls (wiring in P2)

The system is designed to be feature-gated: compile with --features wasmtime to unlock JIT sandbox support for untrusted third-party plugins.

Features

  • Native Rust plugins — first-party integrations compiled into the binary, zero sandbox overhead (P1)
  • WASM plugin framework — trait-based abstraction ready for Wasmtime JIT (P2) or wasm3 interpreter (P3)
  • PluginManifest validation — required fields enforced at load time; superset of HA manifest fields
  • Async plugin lifecyclesetup() and teardown() for resource management
  • State change subscriptions — plugins can subscribe to entity state changes with handler callbac
  • Config entry lifecycle — plugin receives config when registered; P3 adds hot-reload
  • Feature-gated runtimes — Wasmtime (30 MB, P2) and wasm3 (50 kB, P3) are optional dependencies
  • Manifest inheritance from Home Assistantcodeowners, requirements, documentation, issue_tracker, IoT classification

Capabilities

Capability Type Method Notes
Load native plugin Runtime InProcessRuntime::load(manifest, handler) Sync; handler is a Rust type implementing HomeCorePlugin
Load WASM plugin Runtime WasmtimeRuntime::load(wasm_bytes, manifest) (P2) Async; JIT compiles via Cranelift; requires --features wasmtime
List loaded plugins Registry PluginRegistry::list() Returns Vec<(PluginId, PluginManifest)>
Query plugin config Registry PluginRegistry::get_config(plugin_id) Returns Arc<ConfigEntryJson>
Call plugin handler Host ABI hc_state_changed(event) (P2) WASM plugin receives state change events via exported function
Unload plugin Registry PluginRegistry::unload(plugin_id) Calls teardown(), frees memory (P3 = hot-reload)

Comparison to Home Assistant

Aspect Home Assistant homecore-plugins
Plugin language Python (.py integrations) Rust (P1) + WASM (P2+)
Sandbox None (all Python in same process) None (P1); Wasmtime sandbox (P2)
Plugin discovery homeassistant/components/ directory PluginManifest JSON + registry
Config lifecycle YAML + dynamic reload Config entry + manifest (hot-reload P3)
Host ABI CPython C API C types + Wasmtime exported functions (P2)
Manifest format Home Assistant's manifest.json subset Superset with ioc_class, cog_publisher
Feature gating Integration-specific Feature flags: wasmtime, wasm3

Performance

  • Native plugin overhead — same as regular Rust function calls; no sandbox cost
  • WASM plugin sandbox — Wasmtime JIT ~5 ms per call (after warmup); memory overhead ~10 MB per instance
  • Manifest parsing — < 1 ms (serde_json)
  • Registry operations — O(1) plugin lookup (DashMap); O(n) for list()
  • No per-crate benchmarks yet — a follow-up issue tracks baseline measurements

Usage

Native plugin (P1):

use homecore_plugins::{HomeCorePlugin, PluginManifest, InProcessRuntime};
use async_trait::async_trait;

struct MyPlugin;

#[async_trait]
impl HomeCorePlugin for MyPlugin {
    async fn setup(&mut self) -> Result<(), homecore_plugins::PluginError> {
        println!("Plugin setup");
        Ok(())
    }

    async fn teardown(&mut self) -> Result<(), homecore_plugins::PluginError> {
        println!("Plugin teardown");
        Ok(())
    }

    async fn on_state_changed(&mut self, _event: &homecore_plugins::StateChangedEventJson) -> Result<(), homecore_plugins::PluginError> {
        Ok(())
    }
}

#[tokio::main]
async fn main() {
    let manifest = PluginManifest {
        domain: "my_plugin".to_string(),
        name: "My Plugin".to_string(),
        ..Default::default()
    };

    let mut runtime = InProcessRuntime::new();
    let plugin_id = runtime.load(manifest.clone(), MyPlugin).await.expect("load plugin");
    println!("Loaded plugin: {:?}", plugin_id);
    runtime.unload(&plugin_id).await.ok();
}

WASM plugin (P2 example):

# Build a WASM plugin (requires --features wasmtime)
cargo build -p homecore-plugin-example --target wasm32-unknown-unknown --release

# The WasmtimeRuntime will be available at P2:
# let mut runtime = WasmtimeRuntime::new();
# let plugin_id = runtime.load(wasm_bytes, manifest).await?;

Relation to other HOMECORE crates

homecore-plugins (plugin registry + runtime abstraction)
├─ homecore (state machine; plugins receive state changes)
├─ homecore-plugin-example (reference WASM plugin)
├─ homecore-server (loads plugins at startup)
└─ homecore-automation (can invoke handlers via service calls)

Security Notes

P1 (this release): No sandbox. Native Rust plugins have full process access.

P2 (planned): Wasmtime JIT sandbox is opt-in via --features wasmtime. WASM plugins run in isolated memory with explicit host ABI calls to access homecore state. The host ABI is frozen before P2 begins (ADR-128 §8 risk mitigation).

P4+: Ed25519 signature verification and permission enforcement for third-party Cog registry distribution.

References