Skip to content

Kandelo roadmap #382

Description

@mho22

❌ Next

Layer 0 — Headline goals

  • WordPress Playground integration with --experimental-posix-kernel — make the Wasm kernel a selectable runtime in Playground web/CLI behind a flag (the broader Playground beta-flag work is in Layer 10; this is the concrete entry point). Proof-of-concept PRs open against WordPress/wordpress-playground: #3634 (CLI), #3635 (Web).
  • Explore Node.wasm — bring the Node.js runtime onto the kernel (libuv event loop, native addons via dlopen, child_process via fork+exec). Shipped via QuickJS-NG–based Node-compatible runtime (#482) covering node:crypto, zlib, TCP sockets, TLS, real http/https, and end-to-end npm install lodash/express/vite.

Layer 1 — Stabilize what already works

  • Fix the web server service worker losing context and failing to load WordPress
  • Migrate from the deprecated Wasm try instruction to try_table (currently pinned via -wasm-use-legacy-eh=false and -mllvm -wasm-use-legacy-eh=true workarounds)

Layer 2 — Finish the browser surface protocols

  • HTTP relay protocol — extract from demo code into a documented, versioned spec
  • Service Worker interface — multi-tab routing + connected-client visibility (see "Partially landed")
  • A non-isolated tunnel for secrets — a side channel that does not require COOP/COEP, so credentials/API keys can flow into a Kandelo session without granting the isolated context full access to them
  • Query params as inputs to the boot process — let demo URLs pre-seed argv, env, or boot scripts
  • fbDOOM mouse support — mouse input device alongside the existing keyboard scancode injection (currently called out as a limitation in docs/browser-support.md) @mho22
  • fbDOOM sound support — audio output device (/dev/dsp) for sound effects @mho22
  • fbDOOM music support — background music playback for fbDOOM @mho22

Layer 3 — Distribution & ecosystem

  • Software installer like apt (the resolver in cargo xtask build-deps resolve is the plumbing — this is the user-facing layer on top)
  • Standalone published packages for the libraries that aren't yet first-class binary artifacts
    • readline as its own package (not just bundled into bash)
  • Deploy multiple kernel versions on the same web server, allowing staging and switching between live versions

Layer 4 — Observability

  • A thorough OS trace facility (syscalls, signals, scheduling, IPC)
  • An MCP server for OS tracing — exposes the trace stream to agents
  • A living diagram of system components, current state, and relationships, served by the running kernel
    • Process listing (procfs already exists per #220 — needs a UI consumer)
    • Memory visualizer
    • File system visualizer and browser

Layer 5 — Agent integration

  • Run Claude within the kernel
  • More agentic guidance (CLAUDE.md is a start; codify SDK / build / debug workflows further)
  • Agent skills for using the SDK
    • Software building (autoconf/CMake/Makefile flow with wasm32posix-*)
    • Image building (VFS image authoring)
    • Boot script writing (dinit /etc/dinit.d/* authoring)

Layer 6 — Multi-host & networking

  • Multi-computer network running in a single browser (multiple kernels, virtual L2/L3 between them)
  • WebRTC remote login — let other clients log into your in-browser computer
    • DOOM multiplayer over the WebRTC tunnel (now that fbDOOM mouse + sound + music have landed, this is the obvious payoff)
  • Store and load kernel VFS images from IPFS

Layer 7 — Branding

  • Lock in a memorable name — Kandelo is now in README, docs, the live UI host, and Kandelo.dev demo gallery wiring (#427, #467, #483, #485). Repo rename and host/ npm package rename still pending.
  • Logo

Layer 8 — Additional runtimes & ports

Runtime

  • Explore Go.wasm — bring the Go runtime onto the kernel (goroutine scheduler interaction with our threads, syscall interface, GC behavior under shared WebAssembly.Memory) @mho22

Port

Layer 9 — Miscellaneous

  • Explore SDL2 — cross-platform input/audio/video library; depends on the framebuffer (shipped), mouse input + audio output (Layer 2). Unlocks a large catalogue of games and tools. @mho22
  • Explore ScummVM.wasm — fun/stretch: classic adventure game engine on the framebuffer + audio stack (depends on Layer 2 audio work) @mho22
  • ALSA sound device — implement alongside /dev/dsp so software targeting the modern Linux audio stack works without falling back to OSS @mho22
  • WebGPU - implement alongside WebGL @mho22

Layer 10 — External suggestions

  • wp-load.php benchmark: native vs wasm (the existing WordPress benchmark in benchmarks/run.ts --suite=wordpress measures HTTP first response, not the bare wp-load.php cost)
  • Support both the Wasm kernel and PHP-WASM in Playground web, with the kernel behind a beta flag
  • Raw Rust build command — no equivalent SDK wrapper today; user programs are C-only

🟡 Partially landed

Started, but not yet at the level Brandon's note describes:

  • Protocol for relaying HTTP requests
    • Working pipeline exists: service worker → MessagePort → kernel worker connection pump (examples/browser/lib/http-bridge.ts, connection-pump.ts, lib/init/service-worker-bridge.ts)
    • Missing: documented, versioned protocol spec independent from demo glue, with a stable contract for non-Kandelo embedders
  • A clean, focused Service Worker interface
    • Current SW is a unified dual-mode file (examples/browser/public/service-worker.js) that already routes HTTP via a single bridgePort
    • Still owed: route HTTP requests to the right client when multiple browser tabs are connected
    • Still owed: provide visibility for all connected clients (an enumerable list of attached kernel workers)
  • Solid E2E tests
    • Playwright covers most browser demos (examples/browser/test/demos.spec.ts, playwright.config.ts)
    • Coverage gaps remain for daemonized stacks under failure injection
  • Shareable computer URL — fold a running kernel's VFS + boot state into a URL another browser can rehydrate

✅ Shipped

Kernel & POSIX coverage

  • 170+ syscalls across file I/O, fcntl, process, threads, signals, memory, networking, time, terminal, IPC, eventfd/timerfd/signalfd, poll/select/epoll
  • POSIX.1-2024 header overlays + constants — major XFAIL reductions across libc-test, sortix, open-posix-testsuite (#147 #148 #149 #160 #161)
  • Procfs (/proc/self, /proc/<pid>/{stat,status,cmdline,environ,maps,fd}, /proc/net/{tcp,unix}) #220
  • Virtual devfs — /dev/{null,zero,urandom,full,fd/N,tty,ptmx,pts/*} (#228 + earlier batch)
  • EPERM multi-user model #326, deferred pthread cancellation #333, per-thread signal routing #332, kernel-side PTHREAD_PROCESS_SHARED primitives #324
  • AIO XFAIL closure + pthread_setcanceltype XPASS #334

Multi-process

  • fork via Asyncify snapshot/restore #81
  • fork() from non-main threads (#468); fork+dlopen replay so children inherit parent dlopens (#466); host reaps child workers that die without SYS_EXIT_GROUP (#465)
  • execve with argv/envp #123, posix_spawn attribute handling + fd actions (#167 #168), execveat/fexecve
  • Non-forking posix_spawn via SYS_SPAWN (ABI 7→8) (#439)
  • Cross-process pipes, signals, waitpid/waitid/zombies, process groups, sessions
  • Cross-process advisory file locking (OFD) via SharedArrayBuffer
  • Cross-process PTHREAD_PROCESS_SHARED mutexes/condvars #324 #327
  • O_CLOFORK / FD_CLOFORK (POSIX.1-2024) #159

Threads & synchronization

  • clone(CLONE_VM|CLONE_THREAD) via Workers + shared WebAssembly.Memory
  • pthread_create in centralized mode, futex w/ timeout, RT signals + sigqueue si_value
  • pthread_atfork, dladdr, POSIX mqueues #147

Memory

  • mmap with MAP_ANONYMOUS, MAP_PRIVATE file-backed #99, MAP_SHARED file + msync writeback #100
  • mremap, splice, preadv2/pwritev2, readahead #67, memfd_create + copy_file_range #66, shm_open/sem_open
  • Growable VFS with inodes sized for max capacity
  • dlopen data allocated through guest mmap (#434)

Networking

  • AF_INET sockets — connect, send/recv, sendmsg/recvmsg, getsockopt/setsockopt, SO_RCVTIMEO/SO_SNDTIMEO #115, TCP_INFO + extra TCP options #271
  • AF_UNIX (stream + dgram) with SCM_RIGHTS #112, AF_UNIX bind() creates filesystem inode #356
  • In-kernel loopback TCP/UDP, MSG_OOB + SIOCATMARK #104
  • DNS via host __lookup_name, getaddrinfo
  • Virtual MAC for network ioctls #270, SIOCGIFCONF ptrWidth-aware for wasm64 #277
  • Host network backends: TCP, fetch, TLS-intercepting (#240)
  • Git HTTP clone over HTTPS in browser shell #229, AF_UNIX + git HTTP clone tests #287

Filesystem & VFS

  • MemoryFileSystem (SharedArrayBuffer-backed), OpfsFileSystem (browser persistence), DeviceFileSystem
  • *at() family with stored OFD paths, realpath, hard links, chmod/utimensat
  • Lazy VFS files — defer fetch until first read #206
  • Pre-built VFS images replacing JSON bundles #286
  • zstd-compressed .vfs.zst browser demo images (#384)
  • Lazy archive-backed files (e.g. vim.zip in shell demo) #279
  • Kernel-owned VFS + dinit-supervised demos #370
  • VFS uid/gid foundation — chown stores values, stat reports honestly (#417)
  • mkrootfs CLI — declarative rootfs image builder (#440); rootfs source tree + image build wiring (#441); mount-table cutover + remove synthetic_file_content (#442)

Browser runtime

  • Centralized kernel architecture w/ channel IPC over SharedArrayBuffer + Atomics
  • Dedicated kernel worker (NodeKernelHost) #289 + browser kernel worker #194
  • Service worker COOP/COEP bootstrap + HTTP bridge #117
  • TLS MITM for transparent HTTPS in demos #240
  • Configurable CORS proxy for GitHub Pages #248
  • GitHub Pages deployment of demos #198
  • PTY support + xterm.js terminal panel (#181 #182)
  • Framebuffer (/dev/fb0) + canvas renderer + fbDOOM (#349 #350 #351 #364)
  • fbDOOM mouse input via /dev/input/mice + Pointer Lock (#459)
  • fbDOOM sound output via /dev/dsp + Web Audio (#460)
  • fbDOOM MUS/MIDI music through OPL2 → /dev/dsp (#461)
  • fbDOOM IWAD fetched at runtime (#462)
  • dinit init system across daemon demos (#234 #370)
  • WASI Preview 1 shim + 14 Unix utility build scripts #205
  • Hybrid wasm32/wasm64 kernel with i64 channel ABI #269
  • Git revision link in demo sidebar #280
  • WordPress LAMP demo install: ~30 s → ~2 s (#425)
  • wasm64 mariadbd boot + MySQL/Redis demo handshake fixes (#420)
  • Terminal pane on WordPress demos + shell-based VFS (#463)
  • Kandelo live UI host (#467, #483) + Node.js live gallery demo (#485)

Runtimes on the kernel

  • Node.js–compatible runtime via QuickJS-NG — node:crypto, real zlib, TCP, TLS, real http/https with Mozilla cacert.pem, npm install lodash/express/vite end-to-end, plus browser Node/npm demo (#482, design #470, implementation plan #471)

SDK & toolchain

  • All 8 CLI wrappers — wasm32posix-{cc,c++,ar,ranlib,nm,strip,pkg-config,configure} (#sdk batch)
  • WebAssembly dynamic linking — dylink.0 parser + dlopen runtime #62, end-to-end shared library load #63
  • setjmp/longjmp via Wasm exception handling, exnref for setjmp #79
  • Asyncify-onlylist fork support for Git 2.47.1 #218
  • Nix flake providing reproducible dev shell #376
  • Fork instrumentation tool (#488)

Ported software (~40 packages)

  • Servers/DBs: nginx 1.27, PHP 8.4 (CLI + FPM, opcache enabled #423), MariaDB 10.5 (Aria + InnoDB #291, dual-arch wasm32/wasm64 #294), Redis 7.2, SQLite, WordPress 6.7
  • Languages: CPython 3.13, Perl 5.40, Ruby 3.3, QuickJS-NG, Erlang/OTP 28 BEAM (#255 #258 #260 #263), bash 5.2 + readline #293
  • Editors: Vim 9.1 + ncurses, GNU nano 8.3, NetHack 3.6.7
  • Tooling: Git 2.47, GNU coreutils 9.6, grep, sed, gawk, findutils, diffutils, make, m4, bc, tar, less, file, lsof
  • Compression: gzip, bzip2, xz, zstd, zip, unzip #222
  • Network: curl + libcurl, wget
  • Demo headliners: TeX Live (pdfTeX) #285, fbDOOM #351, full LAMP stack #121

Testing infrastructure

  • musl libc-test runner (539+ tests passing, 0 unexpected failures)
  • Vitest host integration tests (276 tests)
  • Open POSIX Test Suite integration #38ac0b1a
  • Sortix os-test integration (4817+ pass) #40399442
  • Browser test infrastructure — Playwright libc-test + POSIX runners #152 #153
  • Browser sortix runner #155, browser E2E demo tests #131
  • MariaDB mysql-test suite (185 tests in browser) #256, nginx + SQLite test suites #257, SQLite TCL upstream suite #264
  • Performance benchmark suite (5 suites, Node.js + browser) #282
  • CI gating on every PRcargo test, vitest, run-libc-tests.sh, run-posix-tests.sh, and check-abi-version.sh all run in .github/workflows/prepare-merge.yml (Phase B-1/B-2 #428 #432, staging release #438)

ABI, packaging, releases

  • Structural ABI snapshot + enforced version bump #295
  • Kernel-wasm exports included in snapshot #296
  • Runtime ABI version enforcement on kernel and user programs #297
  • Additive ABI snapshot changes allowed without version bumps (#490)
  • Per-package manifests, content-addressed cache, binaries-abi-v<N> release scheme #365
  • Binary resolution via index.toml ledger — replaces the in-package [binary] schema with a per-release index, atomic publish via scripts/index-update.sh, project-state split into build.toml (#464, design #457)
  • Decoupled package builds — Phase B-1 per-package matrix + content-hash gating (#428), Phase B-2 sticky PR comment + kernel_abi required check (#432), Phase C resolver cutover + legacy publish pipeline removal (#438)
  • libc++ published as a binary package, bundling libunwind (#368)
  • dinit published as a package #371; lockfile + sha refresh flow (#372 #377 #379)

Documentation

  • Architecture, SDK, porting, browser-support, posix-status, profiling, package-management, binary-releases, abi-versioning, wasm-limitations docs in docs/
  • TypeDoc API docs auto-deployed to GitHub Pages #265
  • CLAUDE.md test-verification + ABI checklist
  • Relicensed to GPL-2.0-or-later with MIT runtime #223

Mapping to Brandon's manual list

These are the items from the original list that are now closed:

  • Protocol for rendering to a frame buffer — #349 #350 #351 #364
  • Protocol for TTY — #181 #182 #221
  • CORS proxy workaround for COOP/COEP — #248 #240
  • Each demo build tagged with git revision — #280
  • Prebuilt disk images — #286 #279 #370
  • Binary registry of prebuilt programs and libraries — #365 #371 #372 #464
    • libcurl, ncurses, libc++ (#368) all shipped as standalone packages; readline still only via bash #293 (standalone package still in Layer 3)
  • Raw C build command (Dennis) — wasm32posix-cc + 7 sibling SDK wrappers

Last updated: May 17, 2026 (originally April 30, 2026)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions