Recording a direction settled in discussion (2026-08-20), for eventually — not scheduled.
Current state (post the visor extraction, #44)
The blast zone is isolated for pixels and faults, not for time or memory:
- Pixels: app DOM lives in an opaque-origin sandboxed iframe (
visor/frame/) — structurally unreadable, unpaintable.
- Traps: a guest trap surfaces as a promise rejection on the runner chain, which survives by construction (
visor/surface/runner.ts); flush-on-trap applies pre-trap ops. Tested differentially: the lab guest commits one surface violation per probe id and the harness requires identical trap vectors across backends (spikes/todomvc/host/harness.ts).
- CPU: the guest executes on the visor's main thread (deltic's embedder instantiates in the calling realm; no workers in the runtime). An app that spins wedges the whole tab — including the kill button. Pause/resume are cooperative gates a spinning guest never yields to.
- Memory: guest linear memory is tab memory.
So the #22 kill ceremony's promise ("input delivery stops and the app's surface is removed") holds, but "the app stops burning your CPU" does not — kill is honest against yielding guests and decorative against spinning ones.
Target
Guest execution moves into a Worker per app:
- The surface (handle table + op queue,
visor/surface/surface.ts) moves worker-side with the wasm instance — it is already architected for this split: handles allocated surface-side, serializable ops streamed out, the frame backend already consumes streamed ops.
- The worker's MessagePort can be transferred directly to the app's iframe, so ops flow guest thread → frame document with the visor's thread out of the data path entirely.
kill becomes worker.terminate(): preemptive, works mid-spin — the ceremony becomes honest. Memory becomes terminate-able too (hard caps are a separate question).
Known costs: deltic instantiation + artifact fetch move into the worker; drain becomes a two-hop round trip; the demo's engine panes each grow a worker. NOTES already records the framework-side intent ("App logic runs in workers on the framework side (deltic, runtime-linked); UI ↔ shell ↔ component is a two-hop RPC path, acceptable for UI latencies") — this issue is the spike-side execution of it.
Refs: #16 (execution model), #22 (kill/input-suspension ceremony), #5 (frame sandboxing), #44 (the extraction that makes the surface split mechanical).
Recording a direction settled in discussion (2026-08-20), for eventually — not scheduled.
Current state (post the visor extraction, #44)
The blast zone is isolated for pixels and faults, not for time or memory:
visor/frame/) — structurally unreadable, unpaintable.visor/surface/runner.ts); flush-on-trap applies pre-trap ops. Tested differentially: the lab guest commits one surface violation per probe id and the harness requires identical trap vectors across backends (spikes/todomvc/host/harness.ts).So the #22 kill ceremony's promise ("input delivery stops and the app's surface is removed") holds, but "the app stops burning your CPU" does not — kill is honest against yielding guests and decorative against spinning ones.
Target
Guest execution moves into a Worker per app:
visor/surface/surface.ts) moves worker-side with the wasm instance — it is already architected for this split: handles allocated surface-side, serializable ops streamed out, the frame backend already consumes streamed ops.killbecomesworker.terminate(): preemptive, works mid-spin — the ceremony becomes honest. Memory becomes terminate-able too (hard caps are a separate question).Known costs: deltic instantiation + artifact fetch move into the worker;
drainbecomes a two-hop round trip; the demo's engine panes each grow a worker. NOTES already records the framework-side intent ("App logic runs in workers on the framework side (deltic, runtime-linked); UI ↔ shell ↔ component is a two-hop RPC path, acceptable for UI latencies") — this issue is the spike-side execution of it.Refs: #16 (execution model), #22 (kill/input-suspension ceremony), #5 (frame sandboxing), #44 (the extraction that makes the surface split mechanical).