Skip to content

Real Linux kernel in the browser — Phases 1–3 (boot, persistence, networking)#1

Draft
ETPDEV wants to merge 25 commits into
mainfrom
feat/kernel-spike
Draft

Real Linux kernel in the browser — Phases 1–3 (boot, persistence, networking)#1
ETPDEV wants to merge 25 commits into
mainfrom
feat/kernel-spike

Conversation

@ETPDEV

@ETPDEV ETPDEV commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

What this is

Replaces the simulated shell with a real Linux 6.6 kernel running in-browser via v86, behind ?engine=kernel (default stays sim). 19 commits across three phases, all gates verified locally.

Done & verified

  • Phase 1 — Kernel boot (Gate G1): Buildroot 6.6 boots to an interactive shell through the existing xterm UI. Honest e2e (a panicking kernel was caught false-passing and fixed: nolapic noapic, panic-reject, computed-marker assertion).
  • Phase 2 — Persistence (Gate G2): VM snapshot → gzip → IndexedDB → reload → warm-restore. Warm boot ~267ms vs ~14.5s cold.
  • Phase 3 — Networking: real DHCP/DNS/TCP/HTTPS via a hardened WISP proxy (proxy/) with allowlist + port-restrict + SSRF guards + rate-limit + audit. Capability proven; finishing items below.
  • Linux conformance suite: ~55 checks across 6 domains (filesystem, text, scripting, permissions, processes, archives) — all green. docs/LINUX-CONFORMANCE.md.

Verified green

runtime-sdk 23 unit tests · web build · kernel/persistence/conformance e2e (local; need image binaries).

NOT done (see gap analysis)

  • Auto-login + auto-DHCP image; automated Gate-G3 e2e; DNS-variance + egress-redaction; proxy deploy (CF vs Railway).
  • Phase 4 (tier truth-alignment), 5 (agent sandbox), 6 (productionize) — not started.
  • Paid-tier runtimes (Python/Node/agent) still don't exist; store must stay TEST until Phase 4.

Notes

  • Image binaries (bzImage, rootfs.cpio.gz, v86 engine) are gitignored — rebuild via image/build.sh (WSL).
  • Draft: this is mid-program (Phase 3 of 6), not merge-ready.

ETPDEV added 25 commits June 4, 2026 14:46
…nst false-pass

Kernel panicked at setup_IO_APIC (i386_defconfig SMP/APIC vs v86's incomplete
APIC emulation). Fixed via cmdline nolapic noapic. A panicking kernel had passed
the old gate because (a) promptPattern matched stray boot-log #/$/% and (b) the
version regex matched the kernel banner not uname. Now: boot() rejects on Kernel
panic; promptPattern = login prompt only; e2e requires a computed shell marker
(READY_$((6*7))_$(uname -r)) + asserts no panic + reached login.
VM snapshot -> gzip -> IndexedDB -> reload -> warm-restore. Warm boot 267ms vs
14.5s cold. Key fix: restore via v86 initial_state config + emulator-ready event
(manual restore_state on a fresh emu throws set_state). initialState accepts an
async thunk; snapshot-store compresses (~73MB raw VM state). 23 unit + G1 + G2 green.
Boots the kernel once and verifies real Linux behavior across 6 domains (~55
checks): filesystem, text processing, shell scripting, permissions, processes,
archives — all green. Plus command-availability matrix (63/88) + extended-gap
audit (networking transport / packages / languages = Phase 3+ roadmap). Helper
uploads scripts via chunked base64 to survive the ~255-char serial tty line limit.
Full report: docs/LINUX-CONFORMANCE.md.
… (PROVEN)

KernelSession networkRelayUrl option (?net=wisp://host/). proxy/ = hardened WISP
server (@mercuryworkshop/wisp-js) with host allowlist (resolved to IPs, since v86's
WISP client sends IPs), port allowlist [53,80,443], SSRF guards (no private/loopback),
per-client rate limit, and connection audit. Proven via Playwright: real DHCP/DNS/
TCP/HTTPS; allowlist refuses non-allowlisted IPs. Key: v86 uses URL SCHEME to pick
protocol — wisp:// for WISP. node_modules gitignored.
…se 3 finish)

Cold boot now lands at a networked root shell with ZERO manual steps (verified:
whoami=root, eth0 auto-leases 192.168.86.100 via the relay, ~6.9s boot). post-build.sh
auto-logins root on ttyS0; BR2_SYSTEM_DHCP brings eth0 up; nano baked in. main.ts:
promptPattern now matches the auto-login '# ' shell + app re-runs udhcpc post-boot
(boot-time DHCP races the relay). KNOWN GAPS for next toolset rebuild: busybox wget
has NO TLS (HTTPS fails; HTTP works) + bash/python3/git/coreutils.
…rdened proxy

Image: openssl + ca-certificates + libcurl/curl + python3(+ssl) + nano (VERIFIED:
python3 3.11 with ssl; curl http+HTTPS both 200 w/ real body). bash/coreutils need a
wchar/glibc toolchain (deferred, documented). Proxy: egress default is 'public web +
SSRF + ports + rate-limit + audit' (strict per-IP allowlist now opt-in via
WISP_STRICT_ALLOWLIST — it's impractical with v86's local DNS). FIXED the real
blocker: wisp-js 0.4.1 'connection.streams is not iterable' (filter.mjs:103) triggered
by stream_limit_per_host — removed it, streams flow now.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant