# Backend conformance testing

The Numeric CI workflow runs `moon check --target all --deny-warn` and debug and release tests on wasm, wasm-gc, JavaScript and native. Native jobs use Linux GCC and macOS Clang with `-march=native -ffp-contract=off`; the build-plan gate checks the compiler path and contraction flag on every linked test artifact. Native package settings retain `-O2 -fwrapv -fno-strict-aliasing` because `cc-flags` overrides default optimization flags. Package settings apply at the native linking package, so downstream executable packages must repeat this policy; the library cannot enforce compiler flags on its consumers.

Each backend prints ordered `LUNA_BITS <case> <16 lowercase hex digits>` records. The gate rejects missing, duplicate, malformed, reordered or changed records, checks every transcript against the committed oracle, and compares all ten backend, compiler and optimization-mode transcripts. Logs and bit transcripts are downloadable CI artifacts. The wasm-gc job also runs `moon test --enable-coverage` and publishes summary and Cobertura coverage reports. While the module has no library source outside test files, as in the current empty root API, there is nothing to instrument; the job then records that the report was skipped instead of failing.

The bootstrap corpus checks core binary64 bit transport (signed zeros, subnormal and normal boundaries, finite extremes and infinities), signed 64-bit conversion around ties at 2^53 and at the integer endpoints, and a non-fused multiply-add. It does not implement or certify future luna-utils numerical APIs. Add operation-specific probes and cross-check oracle fixtures alongside each new API. NaN payload transport and canonicalization are deliberately excluded until the API and canonicalization policy in issue #25 are defined; raw NaN equality is not promised by this corpus.

The offline generator `tools/generate_oracles.py` uses CPython IEEE binary64 `float(int)` and exact `fractions.Fraction` operands. It rounds the product before the sum for the contraction probe: `(1 + 2^-27) * (1 - 2^-27)` rounds to 1, and subtracting 1 yields positive zero; a single rounding instead yields -2^-54. The generated probe XORs each operand's bit pattern with a mask derived from the process argument count, which is zero at run time and asserted to be zero, so an optimizing C compiler cannot constant-fold the expression and the multiply-add is evaluated at run time in both debug and release builds. Building the probe with `-ffp-contract=fast` makes it fail in both modes with Apple Clang, confirming that it detects contraction rather than a value fixed at compile time; with a constant array of operands, release builds folded the expression and the probe passed even under `-ffp-contract=fast`. The relevant model is IEEE 754-2019 binary64, roundTiesToEven, separate multiplication and addition, and contraction control (§10.4). These finite samples establish regression evidence, not a universal proof or formal verification. ISO/IEC 10967-1 language-independent arithmetic does not override the specific IEEE representation and rounding model used here.

Run `python3 tools/generate_oracles.py --check`, `python3 tools/test_ci_harness.py` and `python3 tools/run_backend_tests.py <backend>` locally. Run `python3 tools/generate_oracles.py` only when intentionally updating the committed fixtures; MoonBit's formatter is required. The generator runs offline and introduces no package dependency. CI installs the pinned MoonBit toolchain version from its official installer (`MOONBIT_INSTALL_VERSION` in the workflow), records it and fails if the installed `moonc` differs; bump the pin deliberately and rerun every gate. Pushes run the workflow only on `main`; pull requests run it on every update. Fixture drift fails rather than updating expected values. Linux GCC and macOS Clang acceptance requires the hosted CI jobs, not a claim based solely on a local macOS run.

Sources: [official MoonBit native package options](https://docs.moonbitlang.com/en/latest/toolchain/moon/package.html#native-backend-link-options), [MoonBit contraction report #2262](https://github.com/moonbitlang/moon/issues/2262), and [Python numeric conversion documentation](https://docs.python.org/3/library/functions.html#float).

The #25 representation corpus is generated by `tools/float_oracles.py`, invoked by `tools/generate_oracles.py`. Python arbitrary-precision integer field extraction supplies expectations for both widths, all classes and signs, payload boundaries and portable numeric results. For #24 round-to-integral directions, an independent model decodes finite encodings to exact `fractions.Fraction` values, applies floor, ceiling, truncation or the specified tie rule, and re-encodes the integral result while preserving the sign of zero. It does not reproduce the implementation's exponent-mask algorithm. The generated test emits actual outputs as `LUNA_BITS`, with binary32 zero-extended to 64 bits, classification encoded by a documented test-only ID, and `None` encoded as all ones. The checked-in JSON records include inputs, calls and expected outputs.

For #23 extrema and ordering, the offline oracle constructs a boundary set containing signed zeros, the largest positive subnormal, the largest negative subnormal, `1.0`, the smallest negative normal, infinities, and positive and negative qNaN/sNaN encodings with payloads, including `+qNaN` payload 2, `-qNaN` payload 0, and both `+1` and `-1`. Python integer key transforms provide a cross-check for all-pairs raw totalOrder and portable numeric order; integer comparisons also determine minimum and maximum, which return a canonical positive quiet NaN when an input is NaN, while preserving signed-zero selection. All results are emitted as `LUNA_BITS` records and checked against every backend transcript.
