The differential oracle
A program specification executes the same MIR twice: once as native machine code and once in a MIR interpreter. The test compares a structured record containing output, errors, traps, source traces, host changes, and live objects.
What agreement means
Independent dispatch, shared semantics
The interpreter owns instruction dispatch, frames, traceback, and host adaptation. Both paths call the same runtime implementations for containers, ARC, text, and other dynamic operations, so the comparison focuses on compiler lowering and MIR dispatch. Keeping the two dispatch mechanisms independent lets a mismatch reveal an error in either path.
What the execution record adds
Printed text covers one observable channel. The execution record also captures leaked objects, trap frames, ownership after a failed store, and mutations to host fixtures. Every program specification receives these checks from the harness automatically.
The oracle's responsibilities
- Serve the test harnessThe product build graph leaves the interpreter out of
luceandloom. - Interpret MIR independentlyIts own instruction switch, register file, and frame stack exercise a second route through the protocol.
- Call shared semanticsDynamic operations go through the runtime used by native code.
- Compare every program specificationContinuous use makes a drift visible as soon as the two records differ.
Why program tests are specifications
Anything that runs a Luce program makes a claim about observable behavior and therefore belongs under src/luce/specs/, where both paths run. A test that inspects an internal structure—parser node shape, verifier rejection, or interpreter frame storage—lives beside that implementation.
How a disagreement is resolved
The interpreter has exposed native lowering bugs, and the native path has exposed a stale-register bug in the interpreter. A mismatch identifies the affected program and every differing field. The source contract and focused structural tests then determine which implementation must change.