# @suaveplan/api-sandbox-vm-host-bridge - Host-integration bridge that wraps a @suaveplan/api-sandbox-vm VmSandboxHandle as a PluginModule + PipelineRoute[] bundle for @suaveplan/api-host.installPlugin. Marshals host Request → SerializedRequest into the vm.Context, unmarshals SerializedResponse → host Response, delegates start/dispose lifecycle to the sandbox handle, and surfaces sandbox faults via the SAND_VM_BRIDGE.* code registry. Host-integration bridge that lets a `VmSandboxHandle` from `@suaveplan/api-sandbox-vm` install into `@suaveplan/api-host` as a first-class plugin. ## Documentation tree - [bridge](./src/bridge/bridge.md) — This module is the package's flagship factory: `createSandboxedVmPluginModule({ sandbox, manifest, registry })` → `Brid… - [bridge](./src/bridge/bridge.md) — This module is the package's flagship factory: `createSandboxedVmPluginModule({ sandbox, manifest, registry })` → `Brid… - [error-codes](./src/error-codes/error-codes.md) — This module owns the stable `SAND_VM_BRIDGE.*` error-code registry used by every public failure path inside the host br… - [error-codes](./src/error-codes/error-codes.md) — This module owns the stable `SAND_VM_BRIDGE.*` error-code registry used by every public failure path inside the host br… - [instruments](./src/instruments/instruments.md) — This module owns the OTel instrument bundle the bridge emits. Splitting the bundle off the bridge module makes the metr… - [instruments](./src/instruments/instruments.md) — This module owns the OTel instrument bundle the bridge emits. Splitting the bundle off the bridge module makes the metr… - [lifecycle](./src/lifecycle/lifecycle.md) — This module owns the idempotency wrapper around a `VmSandboxHandle`'s `start` / `dispose` lifecycle. The host's lifecyc… - [lifecycle](./src/lifecycle/lifecycle.md) — This module owns the idempotency wrapper around a `VmSandboxHandle`'s `start` / `dispose` lifecycle. The host's lifecyc… - [marshal-request](./src/marshal/marshal-request.md) — This module turns the host's per-request `RequestContext` into a plain-data `SerializedRequest` value that the sandbox… - [marshal-response](./src/marshal/marshal-response.md) — This module turns the value returned by a sandboxed handler into a host `Response`. The sandbox-side handler returns a… - [route-discovery](./src/route-discovery/route-discovery.md) — This module owns the route-discovery protocol that lets a sandboxed plugin tell the host which HTTP routes it wants to… - [route-discovery](./src/route-discovery/route-discovery.md) — This module owns the route-discovery protocol that lets a sandboxed plugin tell the host which HTTP routes it wants to… - [vm-host-bridge-conformance](./src/testing/vm-host-bridge-conformance/vm-host-bridge-conformance.md) — This module ships `runVmHostBridgeConformance({ buildBridge })` — a five-invariant conformance suite that every concret… - [vm-host-bridge-conformance](./src/testing/vm-host-bridge-conformance/vm-host-bridge-conformance.md) — This module ships `runVmHostBridgeConformance({ buildBridge })` — a five-invariant conformance suite that every concret… ## What it does A `VmSandboxHandle` is a frozen `vm.Context` running a `SourceTextModule` with permission-gated `__suaveplan` capabilities — but it is NOT a `PluginModule`. The host's `installPlugin({ module, manifest, routes })` takes a plain TS object with `start/stop/dispose/health` hooks plus a `PipelineRoute[]` registration list. This package builds that `PluginModule + routes` bundle by: 1. Asking the sandbox (via a host-installed `bridge.registerRoute` capability) for the plugin's route registrations. 2. Wrapping every registered handler in a marshal closure that turns the host `Request` into a `SerializedRequest`, calls the sandbox-side handler, and turns the returned `SerializedResponse` into a host `Response`. 3. Delegating `start()` / `dispose()` to the underlying sandbox handle, idempotently. ## Quickstart ```ts import { createSandboxedVmPluginModule, createBridgeRouteRegistry, } from "@suaveplan/api-sandbox-vm-host-bridge"; import { createVmSandbox } from "@suaveplan/api-sandbox-vm"; const registry = createBridgeRouteRegistry(); const sandbox = createVmSandbox({ pluginId: "demo", pluginModule: { kind: "source", identifier: "demo.mjs", source }, checker, // PermissionChecker proxies: { fs, fetch, capabilities: { bridge: registry.capability }, }, logger, }); const bridged = await createSandboxedVmPluginModule({ sandbox, manifest, registry, }); await host.installPlugin({ module: bridged.module, manifest, manifestHash, specifier, routes: bridged.routes, }); ``` ## Error codes `SAND_VM_BRIDGE.*` — five stable codes covering plugin-surface discovery (`INVALID_PLUGIN_SURFACE`), wire marshalling (`MARSHAL_FAILED` / `UNMARSHAL_FAILED`), handler throws (`HANDLER_REJECTED`), and lifecycle delegation (`LIFECYCLE_FAILED`). ## Conformance `@suaveplan/api-sandbox-vm-host-bridge/testing` ships `runVmHostBridgeConformance({ buildBridge })` with the five invariants the spec mandates: route registration, request round-trip, idempotent lifecycle, error propagation with `cause` chain, and capability passthrough including denied capability surfacing `SAND_PERM.DENIED`.