The Determinism Contract
MIND is deterministic. The same source code, the same inputs, the same compiler/runtime version, and the same target settings produce the same output — every time, on every conforming implementation.
This is not a claim that every mathematical question has one truth. It is a claim that the language defines one exact behaviour for every operation and never leaves the result to accident — to undefined behaviour, backend quirks, hidden global state, race conditions, or the order a parallel runtime happens to execute in.
Every questionable operation falls into exactly one bucket:
- define — the spec picks one rule; the operation always produces that result.
- reject — a compile error or a defined domain error.
- mark non-deterministic — explicitly opted into a
fast/ unordered mode the spec labels non-deterministic.
The forbidden fourth bucket — “sometimes 1, sometimes 0, sometimes NaN, depending on backend / GPU / optimization level” — does not exist in MIND.
Status, honestly: ✅ shipped means implemented and gated in CI today. 📋 specified — enforcement in progress means the rule is fixed by this contract and we are working towards full enforcement. We do not claim a behaviour is enforced before it is.
Verifiable, not promised
Determinism in MIND is checkable. Each artifact embeds an evidence chain whose trace_hash = SHA-256 of the canonical mic@3 bytes. Identical (source, inputs, version, target) ⇒ identical trace_hash. mind verify ./artifact confirms it without trusting the build host. ✅ shipped
1. Integer semantics ✅ shipped
Fully deterministic and byte-identical across substrates.
x / 0 = 0andx % 0 = 0— defined; no trap, no UB.INT_MIN / -1 = INT_MIN— defined; no overflow trap.- Integer overflow wraps two’s-complement — identical on x86 and ARM.
- Oversized shift (
count ≥ bit-width) is given a defined result, never UB. - Condition truthiness:
if ctestsc != 0— the whole value, not the low bit.
2. Floating-point semantics
MIND follows IEEE 754 and pins every edge case. The Q16.16 fixed-point tier is fully deterministic and byte-identical across substrates today ✅ shipped.
Scalar IEEE-754 f64 and f32 now compile and run on the strict deterministic path — arith.mulf / arith.addf with no fmuladd contraction, no fast-math, no reassociation, in fixed source order — and are run-to-run bit-identical ✅ shipped. Cross-substrate bit-identity is verified on hardware two ways. In the open stack, the same f64 Lorenz–Euler integrator produces results identical to the last bit across an x86_64 (AVX2) CPU and an ARM64 (NEON) CPU ✅ shipped — anyone can reproduce it, gated by cross_substrate. The same scalar no-FMA-contraction contract is also verified bit-identical across an x86 CPU and an NVIDIA GPU (CUDA, sm_86) ✅ shipped, because -ffp-contract=off on the CPU and --fmad=false on the GPU forbid the fused multiply-add the hardware would otherwise apply behind your back; running that path yourself requires the commercial mind-runtime GPU backend. Turn contraction back on and the trajectories diverge — worse the longer they run — the chaotic system amplifying a single fused-op rounding difference into a reproducibility bug. Broader GPU vector reductions remain the frontier; additional substrate coverage is expanded as it is verified on hardware.
The remaining IEEE edge cases are fixed by this contract 📋 specified — enforcement in progress:
1.0 / 0.0 = +Inf,-1.0 / 0.0 = -Inf,0.0 / 0.0 = NaN(IEEE).sqrt(-1.0) = NaN(IEEE);strict_domain→ a defined domain error.- NaN comparisons are all
falseexcept!=;min/max/sortuse a defined total order (NaN sorts last) so results are deterministic. - Rounding is round-to-nearest-even (IEEE default), fixed.
0^0 — worked example
0^0is the canonical “vague” case. MIND removes the vagueness by choosing the function, not the mood:
pow(0, 0) // 1 — integer / exact arithmetic, deterministic pow(0.0, 0.0) // 1.0 — IEEE pow, deterministic (x^0 == 1 for all x) powr(0.0, 0.0) // NaN — IEEE powr (real power), deterministic limit_form(0^0) // indeterminate — symbolic/calculus, not a runtime number
pow(0,0) = 1 matches the empty-product convention and every mainstream language, and keeps polynomial / tensor x^0 well-behaved. powr is the honestly-NaN real power. Both are deterministic — you pick which one. Mathematically honest and never an accident. 📋 specified — enforcement in progress
3. The backend must not change meaning
Two execution tiers. The contract is bit-identity, never “within tolerance” — tolerance-equal is a correctness-testing notion, not a determinism guarantee.
- Strict tier (default). Integer and Q16.16 results are byte-identical across substrates (x86 == ARM), gated by
cross_substrate. ✅ shipped Scalarf64/f32arithmetic runs on the strict path with no reassociation or FMA-contraction and is run-to-run bit-identical, and verified bit-identical acrossx86_64(AVX2) andARM64(NEON) CPUs (2026-07-05) — and, for the scalar path, across anx86CPU and an NVIDIA GPU (CUDAsm_86) under the same--fmad=falsecontract. ✅ shipped Running the GPU path yourself requires the commercialmind-runtimebackend; broader GPU vector reductions are still frontier. 📋 specified — enforcement in progress Thef32vector BLAS reductions (dot/L1/matmul) are now strict too — their FMA is unfused and their horizontal sum is a pinned fixed-order fold, so they are bit-exact (verified free of fused FMA onx86; ARM re-verification pending). ✅ shipped Broader vector reductions (tensorsum,f64, GPU) and transcendentals remain the frontier: fixing the reduction order (canonical reduction trees) and pinning one correctly-rounded implementation per transcendental across substrates is still in progress. 📋 specified — enforcement in progress - Fast tier (opt-in). Explicitly labelled non-deterministic; results may differ by substrate. You opt into it — you never get it by accident.
GPU and accelerator execution (CUDA, Metal, ROCm, WebGPU) ships in the commercial mind-runtime; bit-identical determinism across those substrates is on the roadmap. The open-source mindc emits for the CPU.
4. Parallel execution must not randomise results
For floating-point, (a + b) + c != a + (b + c). A parallel runtime that reorders a reduction can change the result. MIND’s rule: strict is the default (defined reduction order / stable kernel, reproducible regardless of thread or lane count); fast is opt-in and labelled non-deterministic.
sum(x) // strict: defined reduction order, reproducible sum(x, mode = "fast") // explicitly non-deterministic
Fixed-reduction-order kernels are the active work. 📋 specified — enforcement in progress
5. Compiler optimizations cannot change observable behaviour
strict_math(default). Nox * 0 → 0(becauseNaN * 0 = NaN,Inf * 0 = NaN), no reassociation, no FMA-contraction. NaN, Inf, and rounding are preserved exactly.fast_math(opt-in). Permits those rewrites; the spec labels the result non-deterministic.
The native-ELF backend emits an image that is a pure function of the IR — there is no external toolchain whose -ffast-math can leak in. ✅ shipped The strict_math / fast_math surface is being finalised. 📋 specified — enforcement in progress
6. Randomness must be explicit
There is no implicit rand() reading hidden global state. Randomness is always seeded and explicit:
let rng = Random(seed = 42) let x = rng.normal(shape = [1024]) // same seed => same tensor, every run
The generator is counter-based (Philox / Threefry), keyed by (seed, element_index). Because each element’s draw is a stateless function of its index, parallel generation is reproducible regardless of execution order, and the result is identical across substrates. This is the basis of MIND’s reproducible-across-hardware randn. 📋 specified — enforcement in progress
In one sentence
MIND does not depend on undefined behaviour, backend quirks, hidden randomness, race conditions, or accidental execution order. Every questionable case is either precisely defined, explicitly rejected, or explicitly marked non-deterministic — and the result is verifiable through the artifact’s trace_hash.
The normative source is determinism.md in star-ga/mind-spec.