# Constraints — In-Browser Swactor Runtime ## Threading Model - **wasm-threads is mandatory** — the runtime uses SharedArrayBuffer + WebAssembly atomics for multi-worker parallelism. There is no single-threaded degraded mode for MVP. - Browsers must serve pages with COOP/COEP headers: - `Cross-Origin-Opener-Policy: same-origin` - `Cross-Origin-Embedder-Policy: require-corp` - Build requires nightly Rust + `-Z build-std=std,panic_abort` + target features `+atomics,+bulk-memory,+mutable-globals`. ## Architecture Rules - **Platform abstractions live in core swactor** (`src/`), gated by `#[cfg(target_arch = "wasm32")]`. They do not belong in the wasm crate. - **Do not add new modules** to `src/` — modify existing files only (TASK.md style rule). - **Do not restructure** existing module boundaries. The abstraction is a thin layer (type aliases, cfg-gated imports), not a trait-based HAL. - The browser crate (`crates/wasm-browser/` or evolved `crates/wasm/`) is a **thin wasm-bindgen shell**. All scheduling, routing, and actor logic stays in core Rust. ## Actor Model - **Rust-only actors** — actors are written in Rust and compiled to wasm. JavaScript does not define actor behavior. - JS interacts through the wasm-bindgen API: create runtime, spawn actors (by registered type), send messages, receive results. - Actor types are registered at compile time via Rust generics, not dynamically from JS. ## Performance Priorities - Maximize throughput: auto-scheduling via `setTimeout(0)` tight loop, not `requestAnimationFrame` (which caps at display refresh rate). - Web Worker count defaults to `navigator.hardwareConcurrency` for full core utilization. - Zero-copy where possible: SharedArrayBuffer eliminates serialization between workers. - Minimize JS↔Wasm boundary crossings — batch operations where feasible. ## Feature Scope - All core features that compile for wasm32: spawn, send, receive, tick, actor lifecycle, watching, extensions. - swactor-std features (naming, groups, monitoring) should work if they compile. - Transport: WebSocket adapter for distributed clusters. STUN/TURN (WebRTC) deferred to later. - Features that require OS primitives not available in wasm (filesystem, raw TCP) are excluded. ## Testing - Tests must pass on both native (`cargo test`) and wasm targets. - Wasm tests use `wasm-pack test --headless --chrome` or Node.js with `--experimental-wasm-threads`. - No test-only code paths that diverge native vs wasm behavior — if it works differently, it's a bug. - Prefer scenario tests over structural tests (per project testing rules). ## Dependencies - `web-time` — drop-in replacement for `std::time::Instant` on wasm32 - `wasm-bindgen` + `js-sys` + `web-sys` — browser API bindings (in the wasm crate only, not core) - `gloo-timers` — optional, for ergonomic setTimeout/setInterval - No new dependencies in core swactor beyond `web-time` (which is no-op on native) ## What We Don't Do - No async/await runtime (tokio, async-std) — swactor is synchronous tick-based - No Emscripten — target is `wasm32-unknown-unknown` only - No WASI — browser environment, not server-side wasm - No JS actor definitions — Rust only - No polyfills for missing atomics — if SharedArrayBuffer isn't available, the runtime doesn't start