Skip to content
CAI
Software that uses CAICheck a score

benoitc/erlang_wasm

68.4

Adequate · 2 October 2026

51.7k

lines of production code

Erlang

primary language

2

measurements over time

CAI band scale
CAI trend line
CAI lens gauges

What this system is

This system is an Erlang-based WebAssembly runtime that executes tenant scripts via a language-neutral worker kernel supporting QuickJS, CPython, and Lua. It provides comprehensive WASI 0.2 capabilities, including HTTP communication, file system access, and socket networking, while ensuring security through hardened native backends and strict sandboxing. The architecture emphasizes performance and reliability through snapshot-based instance management, granular memory tracking, and robust resource cleanup mechanisms.

Features

Add build and verification scripts for WebAssembly test fixtures

Added a suite of build and verification scripts to generate and validate the WebAssembly test fixtures used by the integration and conformance suites. The new \scripts/build-component-fixture.sh\ builds component-model test cases (including WASI 0.2 worlds like clocks, sockets, and filesystems) targeting \wasm32-unknown-unknown\ and \wasm32-wasip2\. Language-specific reactor fixtures for Lua, QuickJS, and Python are now built via \scripts/build-lua-reactor.sh\, \scripts/build-quickjs-reactor.sh\, and \scripts/build-python-reactor.sh\, which compile the interpreters as \init()/handle()\ reactors using WASI SDK 34. Additional scripts handle fetching pre-built Python artifacts (\fetch-python-fixture.sh\), extracting CPython link lines (\python-link-line.sh\), building wasmtime's native WASI 0.2 test programs (\build-wasmtime-p2.sh\), and verifying fixture checksums (\verify-fixtures.sh\).

scripts · high confidence

Introduce WASI 0.2 HTTP support with pluggable transports

Components can now make outbound HTTP requests and host HTTP reactors using the WASI 0.2 \wasi:http\ interface. The implementation provides a pluggable transport layer, defaulting to HTTP/1.1 (\wasi\_http\_h1\) but also supporting HTTP/2 (\wasi\_http\_h2\), allowing guests to perform requests over granted network authorities with configurable TLS and timeouts. Additionally, a new HTTP listener (\wasi\_http\_listener\) enables hosting \wasi:http\ reactor components, translating incoming HTTP requests into component handles and returning responses.

src · high confidence

Introduce language-neutral worker kernel for script execution

Added a new execution bootstrap (\script\_v1\) that provides a consistent interface for running tenant scripts in both QuickJS and CPython environments. This kernel enforces a strict contract where tenants define a single \main(context)\ entry point, ensuring safe, streaming output via a delimiter marker rather than buffered stdout. It handles context loading from \/context.json\, manages error framing for non-serializable results or missing entry points, and isolates execution by loading tenant modules by explicit path to prevent access to host modules.

priv · high confidence

New WASM worker adapters and cleanup infrastructure

This change introduces a new worker subsystem in \src/worker\ featuring adapters for JavaScript (both command and reactor modes), Python (reactor mode), and Lua, enabling execution of these languages via WebAssembly snapshots. It also adds a robust cleanup management system, including a node-wide cleanup manager, per-request cleanup stewards, and a dynamic supervisor, to handle resource teardown and state recovery reliably. Additionally, a comprehensive conformance test suite is provided to validate adapter behavior against the kernel's acceptance rules.

src/worker · high confidence

New benchmark harnesses for JIT adoption, allocation, and request latency

Added a suite of new benchmark modules in \bench/paths\ to measure specific performance characteristics of the WASM runtime. \adopt.erl\ verifies whether a second instance can adopt compiled code raised by a first, one-call guest. \allocwords.erl\ provides a per-process heap allocation estimator using GC trace events, replacing node-wide statistics. \compileheap.erl\ compares memory usage across OTP, inline, and child compiler processes. \guestarm.erl\ measures the cost of a single guest request startup. \phasing\_adapter.erl\ times the five adapter boundaries of a worker request. \pyarms.erl\ profiles four CPython execution configurations (cold, pre-lowered, whole, adopted). \reqbench.erl\ drives a pool of script workers to measure throughput and queue depths. \restorebits.erl\ isolates the time spent in \wasm:restore/3\ components (new, alloc, fill, runs).

bench · high confidence

Behavioural changes

Documentation overhaul and new WASI 0.2 interop fixtures

The project now includes \AGENTS.md\ and \CLAUDE.md\ to guide AI coding agents, and the \README\ has been restructured with a task-oriented 'Where to start' table and a new documentation index. The \rebar.config\ has been updated to include \h1\ and \h2\ dependencies for WASI HTTP support, and the documentation build now includes a new set of runnable examples and guides. Additionally, new fixture directories for wasmtime p2 interop tests have been added to \.gitignore\.

(repo-wide) · high confidence

Hardened WASI file backend against escapes and DoS

The native WASI file backend now prevents path-escape vulnerabilities and directory-read denial-of-service attacks. Symlink resolution for stat and set-times operations is performed internally with strict depth and budget limits, ensuring that relative symlinks cannot traverse outside the preopened sandbox. Directory listings are optimized by lazily opening and reusing a duplicated file descriptor, avoiding costly rescans on every read call.

_c\src · high confidence

Renamed script\_worker to qjs\_worker to clarify its role as a baseline interpreter

The example module previously named \script\_worker\ has been renamed to \qjs\_worker\ to better reflect that it is a specific implementation using QuickJS rather than a generic script runner. This change updates the module name, documentation references, and temporary file prefixes throughout the example code. The commit notes that this module now serves as the unchanged baseline against which a new language-neutral worker kernel is measured, distinguishing the specific JavaScript interpreter from the broader kernel concept.

examples · high confidence

Snapshot support and memory tracking refinements

The system now supports capturing and restoring WebAssembly instances via a new snapshotting mechanism. This introduces a node-wide byte-budget counter for snapshots, managed via persistent terms with versioning to ensure safety across upgrades. Instance records now track snapshot state (open, capturing, destroying) and reader counts using atomics, alongside a \module\_handle\ to preserve provenance for cached modules. Additionally, memory tracking has been refined by replacing the \MEM\_SIZE\ index with a new \MEM\_DIRTY\ index, allowing for more granular tracking of memory changes during snapshot operations.

include · high confidence

Test coverage

Add WASI 0.2 component fixtures and property tests for the Canonical ABI; Added test fixtures and documentation for Lua, CPython, and QuickJS language runtimes; Added test fixtures for WASI 0.2 compliance testing; Added test fixtures for composed Wasm components; Added test support adapters for WASI and component runtime verification; Added tests for composed counter components; Expanded component-model test fixtures for WASI 0.2 and Canonical ABI validation.

Dependencies

Add component test fixtures using wit-bindgen 0.62

Added a suite of new test fixtures under test/fixtures/component/ (including asyncimp, asyncval, counter, echo, wasifs, wasisock, and others) to support testing the WebAssembly Component Model. These Rust-based fixtures depend on wit-bindgen version 0.62 (or wit-bindgen-rt 0.44.0 for composed components) and are configured as cdylib crates or binaries, providing the necessary code generation bindings for WASI interfaces and component composition scenarios.

(dependencies) · high confidence

Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.

How this codebase got here

Score

  • CAI 74 → 68 (-6.1)
  • Rubric changed (rubric-2026.09.12 → rubric-2026.09.18) — scores are not directly comparable.

Lenses

  • Code Health 86 → 85 (-0.8)
  • Architecture 100 → 84 (-16.3)
  • Maturity 61 → 61 (+0.3)
  • Readiness 78 → 59 (-18.7)
  • Security 100 → 100 (+0.0)
  • Event Sourcing 100 → 100 (+0.0)
  • Performance 100 (new)

Resolved (35)

  • Coverage not measured — no coverage collector is wired up
  • Duplicated block (10–13 lines × 3) (examples/lua_reactor_adapter.erl)
  • Duplicated block (12 lines × 2) (examples/py_adapter.erl)
  • Duplicated block (12 lines × 3) (examples/lua_reactor_adapter.erl)
  • Duplicated block (4–5 lines × 5) (examples/lua_reactor_adapter.erl)
  • Duplicated block (5 lines × 2) (examples/lua_reactor_adapter.erl)
  • Duplicated block (5 lines × 2) (examples/py_adapter.erl)
  • Duplicated block (5 lines × 4) (examples/lua_reactor_adapter.erl)
  • Duplicated block (6 lines × 2) (examples/py_adapter.erl)
  • Duplicated block (6 lines × 3) (examples/lua_reactor_adapter.erl)
  • Duplicated block (6 lines × 3) (examples/lua_reactor_adapter.erl)
  • Duplicated block (6 lines × 5) (examples/lua_reactor_adapter.erl)
  • Duplicated block (7 lines × 2) (examples/lua_reactor_adapter.erl)
  • Duplicated block (7–9 lines × 2) (examples/lua_reactor_adapter.erl)
  • Duplicated block (8 lines × 2) (examples/py_adapter.erl)
  • Duplicated block (8 lines × 3) (examples/lua_reactor_adapter.erl)
  • Duplicated block (8–10 lines × 2) (examples/qjs_adapter.erl)
  • Duplicated block (8–10 lines × 3) (examples/py_adapter.erl)
  • Duplicated block (9 lines × 2) (examples/lua_reactor_adapter.erl)
  • Duplicated block (9 lines × 2) (examples/py_adapter.erl)
  • …and 15 more

New (68)

  • Documentation: contradicts the code (docs/architecture.md)
  • Documentation: contradicts the code (docs/compiled-tier.md)
  • Documentation: contradicts the code (docs/features.md)
  • Documentation: no project overview (README.md)
  • Duplicated block (10 lines × 2) (scripts/build-snapshot-fixtures.py)
  • Duplicated block (10–13 lines × 2) (src/worker/wasm_javascript.erl)
  • Duplicated block (12 lines × 2) (src/worker/wasm_javascript_command.erl)
  • Duplicated block (12 lines × 3) (src/worker/wasm_javascript.erl)
  • Duplicated block (3–9 lines × 5) (scripts/build-snapshot-fixtures.py)
  • Duplicated block (4–5 lines × 5) (src/worker/wasm_javascript.erl)
  • Duplicated block (5 lines × 2) (src/wasi_fs.erl)
  • Duplicated block (5 lines × 2) (src/wasi_preview2.erl)
  • Duplicated block (5 lines × 2) (src/wasm_component_link.erl)
  • Duplicated block (5 lines × 2) (src/worker/wasm_javascript_command.erl)
  • Duplicated block (5 lines × 2) (src/worker/wasm_lua.erl)
  • Duplicated block (5 lines × 4) (src/worker/wasm_javascript_command.erl)
  • Duplicated block (6 lines × 2) (bench/paths/workerbench.erl)
  • Duplicated block (6 lines × 2) (scripts/build-snapshot-fixtures.py)
  • Duplicated block (6 lines × 2) (scripts/build-snapshot-fixtures.py)
  • Duplicated block (6 lines × 2) (src/wasi_http.erl)
  • …and 48 more

Changes since last survey

  • 241 commits — 238 feature/other, 3 fixes

By area

  • test/fixtures — 36 commits
  • (root) — 32 commits
  • src/wasi_preview2.erl — 27 commits
  • src/worker — 26 commits
  • (repo) — 25 commits
  • bench/paths — 11 commits
  • docs/architecture.md — 9 commits
  • test/audit — 8 commits
  • test/support — 8 commits
  • src/wasm_canon.erl — 6 commits
  • src/wasi_http.erl — 5 commits
  • src/wasm_component.erl — 5 commits
  • src/wasm.erl — 3 commits
  • src/wasm_component_link.erl — 3 commits
  • c_src/wasi_file_nif.c — 2 commits
  • docs/examples — 2 commits
  • docs/getting-started.md — 2 commits
  • docs/javascript.md — 2 commits
  • docs/worker-reference.md — 2 commits
  • src/wasi_fs.erl — 2 commits

Notable commits

  • fix: Fix directory and zero-length reads on descriptor streams
  • fix: Label every code block, and fix the ones that were not code
  • fix: Merge pull request #40 from benoitc/fix-runner-exit-stall
  • change: Accept finish past the operation ceiling
  • change: Add a Component Model guide
  • change: Add a user layer: concepts, a path in, and ten runnable examples
  • change: Add a writable wasi:filesystem, over the same sandbox (Phase 2)
  • change: Add an entry mode to wasm_python
  • change: Add reqbench: a worker pool under many callers, with its queues
  • change: Add restore_ahead: restore the next instance while the worker waits
  • change: Add the Phase 0 component-model fixture
  • change: Add the cleanup manager and steward supervision
  • change: Add the cleanup steward fault-injection seam
  • change: Add the wasi:http outbound path over h1
  • change: Add the wasmtime p2 interop track and an opt-in network grant
  • change: Assert the entered count for every arm ordering
  • change: Authenticate cleanup operations by the steward that reserved them
  • change: Await an async host import that completes at once
  • change: Bound WASI 0.2 clock waits and report failed stream writes
  • change: Bound request startup by the request's own deadline
  • …and 221 more

Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.

Survey your own repository

benoitc/erlang_wasm was measured the same way every project in this corpus was: the same rubric, at a pinned commit, with the result published in full. Point a surveyor at a repository you know and see whether you agree with it.

About this page

  • The score is its most recent published measurement, taken on 2 October 2026 at a pinned commit. It is not a live figure and does not change until the project is measured again.
  • Measured at commit 68ba50460158b670d8827fccaf6589b1efe92017 — the exact code this score is about.
  • Scored under rubric-2026.09.18 — the same rubric and the same method as every other entry in this index.
  • Measured by watchdog.canine.dev using codehealth-analyzer preprod-e569280dd5e2.