Skip to content

Runtime

Repository: tidemarksh/runtime

Tidemark Runtime is the browser/Node host executor around kernel WebAssembly. It turns kernel exports and supervisor decisions into running guest processes by coordinating workers, host memory, filesystem backing, stdio, network bridges, timers, diagnostics, and state transport.

The runtime is written in TypeScript. The current package metadata identifies the package as runtime at version 0.0.0.

Design Intent

The runtime is deliberately not the Linux semantic authority. It should not decide what a syscall means. Its job is to preserve the kernel's guest-visible state across browser execution boundaries.

Its responsibilities are:

  • Instantiate kernel WebAssembly bytes.
  • Create and manage the kernel worker.
  • Create process owner workers and thread workers.
  • Move explicit state snapshots between workers.
  • Submit thread events and host completions to the kernel supervisor.
  • Execute supervisor-requested worker, memory, backing-store, network, stdio, timer, and resume effects.
  • Expose generic filesystem operations and file layer application.
  • Bridge stdout, stdin, PTY/pipe modes, and network connections to the host application.
  • Provide diagnostics without making diagnostics define production semantics.

Reference Sources

Runtime design is grounded in platform APIs and the kernel ABI, not in workload-specific behavior.

Area Reference source
WebAssembly host integration WebAssembly specifications and browser WebAssembly APIs
Shared memory substrate SharedArrayBuffer and Atomics
Worker execution model Web Workers API
Node-compatible worker execution Node.js worker_threads
Guest semantics Kernel WebAssembly ABI and kernel tests

The runtime can use workload failures to locate orchestration bugs, but generic runtime behavior should not branch on package manager names, language runtime names, URL shapes, or registry behavior.

Execution Model

The runtime has three main host execution roles around the kernel supervisor:

flowchart TB
  API["Runtime API"]
  KernelWorker["kernel worker<br/>canonical runtime-facing state"]
  ProcessOwner["process owner worker<br/>host executor and state transport"]
  ThreadWorker["thread worker<br/>guest execution step loop"]
  Host["host bridges<br/>stdio, network, file operations"]
  Kernel["kernel wasm exports<br/>supervisor decision authority"]

  API --> KernelWorker
  API --> ProcessOwner
  API --> Host
  ProcessOwner <--> KernelWorker
  ProcessOwner <--> ThreadWorker
  ThreadWorker <--> Kernel
  KernelWorker <--> Kernel
  ProcessOwner <--> Host

This topology exists because guest programs expect process, fd/OFD, pipe, socket, filesystem, and signal state to remain coherent even though the browser isolates execution across workers and asynchronous host events.

Supervisor And State Synchronization

Runtime state movement is explicit. The runtime message contracts include kernel state, fd snapshots, OFD snapshots, pipe slots, socket state, child-exit records, guest memory writes, and blocking/resume hints.

That is intentional. The runtime makes ownership and host-execution transitions visible rather than hiding them behind broad global mutation. Transporting or mirroring state does not make TypeScript the authority for its Linux meaning.

Examples of supervisor-owned decisions:

  • runnable, blocked, and dead thread state,
  • futex wake selection and timer-backed retry,
  • fork, vfork, exec, wait, child publication, and exit ordering,
  • fd/OFD lifetime and pipe/epoll/socket control state,
  • signal delivery timing and filesystem control-plane disposition.

Examples of runtime-owned host effects:

  • creating and terminating browser or Node workers,
  • allocating and copying host WebAssembly.Memory,
  • performing backing-store reads and writes,
  • connecting host network and stdio bridges,
  • arming host timers and delivering supervisor-selected resumes,
  • recording diagnostics and transporting state between worker boundaries.

Threaded Guest Workloads

Thread workers are not only an implementation detail for parallel JavaScript execution. They are the runtime mechanism that maps guest thread execution onto browser or Node worker infrastructure while keeping shared process memory and kernel-visible state coherent.

Each thread worker executes a guest thread step loop against the process memory prepared by the process owner. When execution stops, it returns structured status and synchronization data. The runtime submits the relevant event to the supervisor, executes any resulting host operation, reports completion, and resumes only the worker selected by the supervisor.

This is the substrate needed by threaded Linux userland workloads such as language runtimes, compiler drivers, build tools, thread pools, futex waits, and signal-aware runtimes. Those workloads exercise the same generic runtime design; the runtime should not contain language-specific threading logic.

Test Strategy

Runtime tests are organized by what they verify, not by helper language or file location.

The current test structure has three major families:

  • generic runtime invariants and ownership boundaries,
  • language, runtime, and toolchain workload checks,
  • shared harness code for workload and snapshot tests.

Current runtime invariant tests cover retained host-executor behavior:

  • public Runtime and Process API behavior,
  • bridge and runtime-state behavior,
  • filesystem and page-cache synchronization,
  • kernel-worker lifecycle and primitive state,
  • thread-worker execution, blocking, session, signal, and sync-effect behavior,
  • worker lifecycle, supervisor ABI adapters, host operations and completions, status transport, stdio, kernel RPC, fork/exec host effects, diagnostics, and supervisor-selected resume consumption.

Current workload tests cover broad guest behavior across shells, dynamic startup, script runtimes, package module drivers, toolchains, large file I/O, network streams, and language/runtime-specific startup or toolchain execution.

flowchart TB
  RuntimeTests["generic invariants"]
  Workloads["guest workload checks"]
  Support["shared harnesses"]
  Runtime["runtime implementation"]
  Kernel["kernel wasm"]
  GuestFiles["external guest files"]

  Runtime --> RuntimeTests
  Runtime --> Workloads
  Kernel --> RuntimeTests
  Kernel --> Workloads
  GuestFiles --> Workloads
  Support --> RuntimeTests
  Support --> Workloads

The invariant tests should lead. Workload tests are valuable, but they should confirm behavior after the relevant kernel boundary and runtime host-executor gate are understood.