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.
compute(policy_parameters)compute(policy_parameters) function, deterministic by construction.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.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.
| Door | Source (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. |
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.
compute() step, and Proving It Ran, the third-runtime deep dive.