# V8 Runtime

- Guest WebAssembly compilation is enabled by default. Do not install a `set_allow_wasm_code_generation_callback` deny hook on fresh isolates or snapshot restores; package compatibility depends on `WebAssembly.Module` and `WebAssembly.Instance` working inside the isolate.
- WebAssembly safety still comes from V8's built-in limits. Conformance coverage should prove guest WASM works while oversized memory declarations still fail with V8 errors instead of reintroducing an embedder-level deny path.
- Async guest WASM (`await WebAssembly.instantiate(...)` / `await WebAssembly.compile(...)`) only settles once the session driver pumps both halves of V8's deferred work: `run_event_loop()` must keep calling `pump_v8_message_loop()` to drain platform foreground tasks posted by async WASM compilation, then `perform_microtask_checkpoint()` to settle the returned Promise. If either step is skipped, sync `WebAssembly.Module` still works while async WASM appears to hang until the outer wall-clock timeout.
- Keep `BinaryFrame` at the compatibility boundary only. In-process embedded-runtime session plumbing should use `runtime_protocol::{RuntimeCommand, SessionMessage, RuntimeEvent}` so bridge responses, stream events, and execution results do not bounce through IPC framing inside the same process.
- In `src/session.rs`, a session may reuse its isolate only while the effective bridge code is unchanged. Snapshot-restored contexts clone the snapshot's default context, so changing bridge code between `Execute` calls must rebuild the isolate or the session will keep restoring the old bridge snapshot.
- In `src/session.rs`, top-level `SessionMessage` handling must never silently drop late `BridgeResponse`, `StreamEvent`, or `TerminateExecution` frames after an execution finishes. If there is no active event loop to consume them, emit a structured `RuntimeEvent::Log` warning with an explicit `ERR_LATE_*` code so host-side diagnostics can see the loss.
- In `src/session.rs`, sync bridge waits need the same per-execution abort path for both CPU timeouts and explicit `TerminateExecution` requests. If a terminate signal only hits `isolate_handle.terminate_execution()` and does not also close the active bridge-wait receiver, a guest blocked inside a sync host call will hang until the host replies.
- In `src/session.rs`, `run_event_loop()` must consult `_getPendingTimerCount()` directly in its exit checks, not only pending promises or `_waitForActiveHandles()`. Some callers enter the loop without first registering the keepalive promise, and otherwise a lone ref'd `setInterval()` can let the session exit between ticks.
- Session-quota regressions now live in `src/embedded_runtime.rs`, not a removed daemon `main.rs`: keep one `SessionManager` per `EmbeddedV8Runtime`, share it across every runtime handle/connection to that instance, and cover quota behavior in `tests/embedded_runtime_session.rs`.
- In `tests/embedded_runtime_session.rs`, shared-quota assertions must saturate the runtime slots before registering any session that is supposed to stay queued. `SessionManager` acquires slots during `CreateSession`, so relying on creation order alone makes queued-session tests race with the sessions meant to hold the slots.
- Guest `process.memoryUsage()`, `process.cpuUsage()`, `process.resourceUsage()`, and live `process.versions.{v8,openssl}` should be resolved locally on the V8 session thread in `src/bridge.rs`, using `v8::HeapStatistics`, `getrusage(RUSAGE_THREAD)`, and the bundled library version APIs. Do not reintroduce stale JS literals or route these per-isolate values back through sidecar RPC.
- Guest `node:vm` isolation belongs in `src/bridge.rs` local bridge calls (`_vmCreateContext`, `_vmRunInContext`, `_vmRunInThisContext`), not sidecar RPC. Those callbacks must keep sandbox-to-context mirroring, restricted-global scrubbing (`Buffer`, `require`, etc.), and timeout-driven `terminate_execution()` behavior aligned with the JavaScript-facing shims in `crates/execution`.
