Architecture
// ARCHITECTURE
Three execution layers — one per bug.
Layer 1 browser-native WebAssembly, Layer 2 containers, Layer 3 reserved for what neither reaches. The recipe declares which layer it runs on — you don't pick. The matrix below scans the trade-offs at a glance; the deep-dive sections follow.
In the browser, instantly.
Docker / microVM, for fidelity.
Reserved for what L1 and L2 cannot reach.
~4 GB, real fork/exec, data races, building the compiler itself.wasm32-wasip1 / sqlite-wasm.Dockerfile + ghcr.io/aletheia-works/vivarium-<slug> + Codespaces badge.// 01 · LAYER 1
WebAssembly, in the page.
Reproductions run directly inside your browser tab. No account, no install — open the page and it starts. Phases 0–2 built up Python / Ruby / PHP / Rust recipes, e.g. cpython#137205 and pandas#56679; this layer is the most "browser-only" surface Vivarium ships.
Bugs this layer fits
- Algorithmic bugs (sorting, parsing, text processing).
- Data-processing regressions (pandas / polars / numpy shape bugs).
- Database behavioural bugs (SQLite query anomalies, JSON path edge cases).
- Library-internal logic where the repro doesn't touch the filesystem, network, or process model.
Startup time
- Cold load (no cache): 1–10 seconds. Dominated by runtime download (Pyodide ≈ 10 MB compressed) and instantiation.
- Warm load (cached): under a second.
- Per-run execution: milliseconds to a few seconds.
What this layer can't reach
- Memory. A browser tab degrades past ~1 GB peak; ~4 GB is the practical ceiling. Production-scale data goes to Layer 2.
- System calls. No real
fork/execor real sockets. The WASI shim covers common cases, not all. - Concurrency bugs. Single-threaded by default — data races and heisenbugs go to Layer 3.
- Compiler builds. A Rust bug reproduces fine in-browser, but building the Rust compiler itself is Layer 2.
Runtimes and live examples
- Python: Pyodide — live: cpython#137205 and pandas#56679
- Rust:
wasm32-wasip1— live: (no live example yet — see the gallery) - Ruby: Ruby.wasm — live: ruby#21709
- PHP: php-wasm — live: (no live example yet — see the gallery)
- SQLite: sqlite-wasm (via Pyodide) — recipes that hit the sqlite WASM build via Pyodide live under the Python listing above.
// 02 · LAYER 2
Docker / microVM, on your own machine.
For bugs that need a real filesystem, real processes, and real networking. Vivarium does not host execution; recipes are distributed as a catalogue that runs on your own Docker (or Codespaces).
Bugs this layer fits
- Whole-project reproductions — bugs that require dependency resolution against real package indexes.
- Syscall-dependent bugs — real
fork, real sockets, real file locks, real signals. - Toolchain-specific bugs — quirks of a specific GCC, glibc, or kernel ABI.
- Multi-process bugs where the interaction between processes is the bug.
How to use it
Each recipe page ships a pinned Dockerfile, a copy-pasteable docker run … command, and a link to a published image at ghcr.io/aletheia-works/vivarium-<slug>. The page also shows the latest CI verdict snapshot — your own docker run becomes the live confirmation. Where applicable an "Open in Codespaces" badge is provided.
What this layer can't reach
- No in-page execution. The repro runs locally or in Codespaces, not on the gallery page.
- Docker (or Codespaces) required. Without either, you can still browse recipes and verdict snapshots.
- Concurrency itself. Layer 2 runs on real threads, but reproducing heisenbugs reliably is Layer 3 territory.
// 03 · LAYER 3
Reserved for what L1 and L2 cannot reach.
For heisenbugs — bugs that don't reliably reproduce on a fresh re-run. The layer is declared, but no recipe ships here today.
Bugs this layer would fit
- Data races, memory ordering bugs, use-after-frees that resist a fresh re-run.
- Long-replay scenarios: rewind hours of captured execution in minutes.
- Distributed-system bugs that depend on a specific message interleaving.
- Post-mortem forensic analysis — stepping backwards through a recorded trace.
Why it is empty
The first attempt here was rr record-replay. It was withdrawn: rr runs only on Linux/x86_64 and needs an exposed PMU plus CPUID faulting, so a reader on Windows or macOS could not verify the recipe at all — and with so few environments able to run it, nobody could cheaply tell a genuine reproduction from a broken one.
What keeps it empty
- The admission test. A recipe has to be reproducible by whoever reads it. A verdict nobody can independently check is not evidence.
- Kernel-bound techniques. CRIU and Firecracker snapshots inherit the same Linux dependency and would have to clear the same bar.
Candidates
- Deterministic simulation (Antithesis-style) and WASI Preview 3+ are the more promising candidates, precisely because they do not depend on a host kernel feature.
- Until one lands, the gallery has no L3 entries.
Which layer a recipe runs on is declared by the recipe itself. You don't pick — opening the page runs it on the right layer automatically.