Conformance corpus
The executable contract for the scripting language (see ../SPEC.md). An implementation of the language is conforming iff it reproduces every fixture in this directory. The Rust core at rust/theta-script is the engine every shipped runtime wraps; the pure-JS interpreter in js/src/ is a retained independent implementation and the generator of these fixtures — two implementations agreeing bit-for-bit is what keeps the corpus honest.
Known conforming implementations: the Rust core (cargo test runs this corpus; its wasm build is exercised by js/test-wasm/), and the JS interpreter (jest conformance in js/).
Layout
tapes.json— named OHLCV bar arrays, the shared inputs. Bars are{ date, open, high, low, close, volume }withdatein ms since epoch. Generated bytapes.jsusing only exact double arithmetic (minstd LCG + triangle waves, no transcendentals), so regeneration is bit-identical on any engine — but treat the committed JSON as frozen data of record.expected/<case>.json— one fixture per case:{ lang, name, tape, opts, script, expected }whereexpectedis the fullrunScriptoutput in the wire encoding (below).optsis{ inputs?, timezone?, session? }ornull; anull/absenttimezonemeans the spec default,America/New_York. Fixtures never use'local', so they are host-independent.cases.js/encode.js/conformance.test.js— JS-side case source, encoder and runner. Ports don't need these; they consume only the JSON.
Wire encoding
JSON cannot represent IEEE-754 specials, so encoded outputs map:
| runtime value | encoded |
|---|---|
NaN | null |
Infinity / -Infinity | "Infinity" / "-Infinity" |
-0 | 0 |
Comparison happens in encoded space: a port encodes its own result the same way and diffs the two trees. No decoder exists, which is what keeps null-vs-NaN and string-vs-"Infinity" unambiguous.
Port runner contract
For each expected/*.json:
- Load
tapes.json[fixture.tape]as the bar input. - Run the script with
fixture.opts(defaulting timezone/session per spec). - Encode the result and compare to
fixture.expected.
- Numbers: exact equality is the target. A port MAY apply a relative tolerance of 1e-9 to values produced through the transcendental builtins (log, exp, pow, sqrt, rsi's divisions, stdev's square root) where libm implementations legitimately differ in the last ulp; everything else (arithmetic, comparisons, rolling sums) must match bit-for-bit. - err-* cases: the port must produce a non-null error and empty draw collections. The error message text is informative, not normative — compare only that an error occurred (and its collections match).
- All other fields (colors, spans, titles, input metadata) compare exactly.
Regenerating
npm run conformance:update
Only regenerate when the language deliberately changes, and bump LANG_VERSION in ../interpreter.js (mirrored in each fixture's lang field) in the same commit. A diff in regenerated fixtures is a language behavior change and should be reviewed as one.