Initial Commit
This commit is contained in:
81
openspec/changes/api-sandbox-wasm-host-bridge/proposal.md
Normal file
81
openspec/changes/api-sandbox-wasm-host-bridge/proposal.md
Normal file
@@ -0,0 +1,81 @@
|
||||
# Sandbox WASM Host Bridge
|
||||
|
||||
**Package**: `@suaveplan/api-sandbox-wasm-host-bridge`
|
||||
**Status**: PROPOSED
|
||||
**Type**: new-package (host-integration layer)
|
||||
|
||||
## Why
|
||||
|
||||
Same shape as `api-sandbox-vm-host-bridge` but for the WASM tier. `@suaveplan/api-sandbox-wasm` ships a `WasmSandboxHandle` — a `WebAssembly.Instance` running under WASI `snapshot_preview1` with permission-gated `suaveplan_caps.*` imports. `@suaveplan/api-host.installPlugin(spec)` takes a `PluginModule`. The bridge between them does not exist, so gate 2.8's "deploy under wasm tier" requirement is unreachable.
|
||||
|
||||
## Concrete consumer
|
||||
|
||||
- `@suaveplan/api-host.installPlugin(spec)` — consumes the `PluginModule` produced by this bridge.
|
||||
- `@suaveplan/e2e-foundation-stack-full` Stage-8 closure smoke — deploys the WASM artifact produced by `@suaveplan/wasm-compiler-javy` (sibling change) through this bridge under the wasm tier.
|
||||
|
||||
## Host bridge
|
||||
|
||||
This package IS the host-integration for `api-sandbox-wasm`. Required by §19.
|
||||
|
||||
## End-to-end test
|
||||
|
||||
- `e2e/foundation-stack-full/tests/sandbox-wasm-deployment.spec.ts` — deploys a WASM-compiled `api-plugin-example` via this bridge, drives an HTTP request through the host, asserts response was produced by the WASM-sandboxed plugin.
|
||||
|
||||
## What changes
|
||||
|
||||
### Package surface
|
||||
|
||||
```ts
|
||||
import { createWasmSandbox } from "@suaveplan/api-sandbox-wasm";
|
||||
import { createSandboxedWasmPluginModule } from "@suaveplan/api-sandbox-wasm-host-bridge";
|
||||
|
||||
const sandbox = createWasmSandbox({
|
||||
pluginName: "example",
|
||||
policy,
|
||||
capabilities,
|
||||
checker,
|
||||
wasmModule: await WebAssembly.compile(wasmBytes),
|
||||
});
|
||||
|
||||
const module = await createSandboxedWasmPluginModule({
|
||||
sandbox,
|
||||
manifest: pluginManifest,
|
||||
});
|
||||
|
||||
await host.installPlugin({ kind: "wasm-sandboxed", module, manifest });
|
||||
```
|
||||
|
||||
### Marshalling
|
||||
|
||||
Same `SerializedRequest` / `SerializedResponse` shapes from `@suaveplan/api-types/sandbox-bridge` (authored by the `api-sandbox-vm-host-bridge` change as the shared contract). Both bridges use the same wire format.
|
||||
|
||||
WASM-specific marshalling uses linear-memory buffer passing:
|
||||
1. Bridge allocates a buffer via the WASM `__suaveplan_alloc(len)` export.
|
||||
2. Writes the JSON-encoded `SerializedRequest` bytes into linear memory at the allocated offset.
|
||||
3. Calls the WASM `__suaveplan_handle_request(ptr, len)` export, which returns `(responsePtr, responseLen)`.
|
||||
4. Reads the response bytes from linear memory.
|
||||
5. Frees both buffers via `__suaveplan_free(ptr)`.
|
||||
6. Parses the `SerializedResponse` and returns the host `Response`.
|
||||
|
||||
The WASM plugin must export `__suaveplan_alloc`, `__suaveplan_free`, `__suaveplan_handle_request`, `__suaveplan_routes` (returns a JSON-encoded routes array at init time), `__suaveplan_start`, `__suaveplan_dispose`. The `@suaveplan/wasm-compiler-javy` sibling produces artifacts that conform to this ABI.
|
||||
|
||||
### Error codes
|
||||
|
||||
`SAND_WASM_BRIDGE.*` registry:
|
||||
- `INVALID_PLUGIN_SURFACE` — WASM module didn't export required functions.
|
||||
- `MEMORY_ALLOC_FAILED` — `__suaveplan_alloc` returned 0 or trapped.
|
||||
- `MARSHAL_FAILED` — JSON-encoding of the request failed.
|
||||
- `UNMARSHAL_FAILED` — WASM returned non-conformant response bytes.
|
||||
- `HANDLER_TRAPPED` — WASM execution trapped.
|
||||
- `CAPABILITY_DENIED` — capability import returned WASI ACCES.
|
||||
- `LIFECYCLE_FAILED` — start/dispose export call trapped.
|
||||
|
||||
### Conformance harness
|
||||
|
||||
`runWasmHostBridgeConformance({ buildBridge })` with five invariants mirroring the vm-bridge harness: route-registration, request-round-trip, lifecycle, error-propagation, capability-gate.
|
||||
|
||||
## Out of scope
|
||||
|
||||
- The WASM compilation pipeline itself (sibling change `wasm-compiler-javy`).
|
||||
- Component-model-based WASM plugins (this bridge targets WASI `snapshot_preview1`; component-model is a follow-up).
|
||||
- Cross-instance shared memory (WASM linear-memory isolation is by design).
|
||||
Reference in New Issue
Block a user