OpenChainGraph · Kernel VM

How the Kernel VM Works

Same JS. Three runtimes. One hash, or the run is rejected.

kernel-vm.html runs a kernel's compute(policy_parameters) twice: once inside a sandboxed QuickJS-ng WebAssembly VM, once natively in your browser tab, and shows whether the two execution_hash values agree. This page explains why that agreement is the whole point, and what a kernel is forbidden from doing to keep it.

The three runtimes, one source
One kernel source: compute(policy_parameters)
Runtime 1
Browser tab (native)
Runtime 2
QuickJS-ng WebAssembly VM
Runtime 3
risc0 zkVM guest
execution_hash agrees ✓
  1. A kernel is one compute(policy_parameters) function, deterministic by construction.
  2. It runs in your browser tab natively (no sandbox), the fast path, what a developer sees first.
  3. The identical source runs again inside a hermetic QuickJS-ng WebAssembly VM, sandboxed, zero network, zero fetch. This is what kernel-vm.html demonstrates live.
  4. The identical source proves a third time inside a risc0 zkVM guest, same bytes, same digest, and now a groth16 proof anyone can verify without re-running the code. See Proving It Ran for that runtime's own deep dive.
  5. All three emit execution_hash over the same canonical {policy_parameters, output_payload} preimage (RFC 8785/JCS). If any runtime disagrees, that disagreement is the finding, not something the page hides.
  6. The deterministic compute profile (below) explains why they agree: it names every door nondeterminism could sneak through and bans all of them at the kernel-authoring level.
The banned doors: ocg-deterministic-compute@2 (SPEC.md §24.1)

A conforming kernel MUST NOT let its output depend on any of these seven nondeterminism sources. Names and rules below are quoted verbatim from the normative spec; the gloss is a plain-English one-liner.

DoorSource (verbatim, SPEC.md §24.1)Plain English
D1**Non-finite floats** (`NaN`, `±Infinity`)No NaN or Infinity ever leaves compute() silently.
D2**Object / key iteration order**Object key order can never change the hash: one canonical sorter does it.
D3**Transcendental math** (`Math.exp/log/log2/sin/cos/pow`)No engine-native sin/cos/log/pow; every kernel ships its own portable math.
D4**Wall-clock time** (`Date.*`, timers)No reading the clock inside a kernel, ever.
D5**Randomness** (`Math.random`, CSPRNG)No dice rolls inside a kernel: Math.random and CSPRNG are both out.
D6**Locale / `Intl`**No locale-formatted numbers: one pinned formatter, or none at all.
D7**Environment / platform APIs**Anything environment-sensitive gets a fully specified deterministic stand-in.
Evidence
424gpu:false kernels, VM-verified
1069conformance vectors checked

Every gpu:false, non-private-input kernel's conformance fixtures run through the browser VM and diff byte-for-byte against the canonical worker hash on every push (chaingraph/kernels/vm-parity-gate.mjs). Both counts above are computed live from the kernel registry and its fixtures at generation time, never hardcoded.