name: WAI conformance # WAI's load-bearing claim is bit-exact reconstruction on every machine, # no tolerance parameter. This workflow enforces it mechanically: every # cargo-class corpus — and the one neural decoder that can make the same # promise, the integer-synthesis path (i64-only, no float ONNX) — is # re-derived on a four-platform matrix (x86-64 + arm64 across Linux, macOS, # Windows) and must reproduce its frozen BLAKE3 hashes; and the integer # byte-equality goldens (rANS / int_synth / JPEG-AI mANS, generated once on # a reference machine) must decode identically everywhere. All of it is pure # Rust (no C codec chain, no ONNX Runtime), so the matrix needs no system # dependencies. on: push: branches: [main] paths: - 'wai/wai-rs/**' - 'wai/*-conformance/**' - 'wai/byte-exact-conformance/**' - '.github/workflows/wai-conformance.yml' pull_request: paths: - 'wai/wai-rs/**' - 'wai/*-conformance/**' - 'wai/byte-exact-conformance/**' - '.github/workflows/wai-conformance.yml' # No global `shell:` default. The Windows runner is a host executor whose # `bash` is the WSL stub (a different OS), so shell-specific steps below pick # their shell per-OS: bash on unix, pwsh on Windows. Bare `cargo …` steps take # each runner's native default, which runs cargo identically either way. jobs: cargo-classes: name: cargo-class corpora · ${{ matrix.os }} runs-on: ${{ matrix.os }} strategy: fail-fast: false matrix: # Self-hosted fleet labels. Both architectures across all three OS # families: x86_64 by linux + windows, arm64 by linux-arm64 + macos — # what matters for the Fx integer floor is the arch, not the OS. No # Intel-Mac runner exists in the fleet, and it would add no arch # coverage anyway. os: [linux, linux-arm64, macos, windows] steps: - uses: actions/checkout@v5 # unix: the docker runners (linux / linux-arm64) ship no Rust, so rustup # is bootstrapped; the macOS `host` runner has it but launchd's PATH omits # ~/.cargo/bin. dtolnay/rust-toolchain is unusable — it calls a `rustup` # the docker image lacks. - name: Install Rust 1.98.0 (unix) if: matrix.os != 'windows' shell: bash run: | export PATH="$HOME/.cargo/bin:$PATH" command -v rustup >/dev/null 2>&1 || \ curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --profile minimal --default-toolchain 1.98.0 rustup toolchain install 1.98.0 --profile minimal rustup default 1.98.0 echo "$HOME/.cargo/bin" >> "$GITHUB_PATH" # Windows: a host executor with rustup already installed. Only ensure the # pinned toolchain is present + default. pwsh, never bash (that is WSL here). - name: Install Rust 1.98.0 (Windows) if: matrix.os == 'windows' shell: pwsh run: | rustup toolchain install 1.98.0 --profile minimal rustup default 1.98.0 - name: Build the cargo classes (pure Rust, no C codec chain) working-directory: wai/wai-rs # neural_int joins the pure-Rust set: the integer-synthesis decoder is # i64-only (no ONNX, no float), so it carries the same bit-exact promise # and is checkable on this matrix with no ONNX Runtime present. run: cargo build --no-default-features --features world,audio_scene,haptic,splat4d,score,provenance,neural_int,film - name: Library unit tests (the fixed-point determinism floors) working-directory: wai/wai-rs run: cargo test --lib --no-default-features --features world,audio_scene,haptic,splat4d,score,provenance,neural_int,film,oer - name: Carriage conformance — every registered capability round-trips byte-exact working-directory: wai/wai-rs run: cargo test --no-default-features --test carriage # The corpus-verify loop is genuinely shell-specific (a helper that groups # log output and propagates the first non-zero exit), so it ships once per # shell family. The command it runs is identical; only the wrapper differs. - name: Every cargo-class corpus reproduces its frozen hashes (unix) if: matrix.os != 'windows' shell: bash working-directory: wai/wai-rs run: | set -euo pipefail F=world,audio_scene,haptic,splat4d,score,provenance,neural_int,film,quantum,quantum_ops,oer v() { echo "::group::$1"; cargo run -q --no-default-features --features "$F" --bin "$2" -- verify "$3"; echo "::endgroup::"; } v worlds wai_world_vectors ../world-conformance v spatial-audio wai_audio_vectors ../audio-conformance v haptics wai_haptic_vectors ../haptic-conformance v state-feeds wai_feed_vectors ../feed-conformance v avatars wai_avatar_vectors ../avatar-conformance v volumetric wai_splat4d_vectors ../volumetric-conformance v score wai_score_vectors ../score-conformance v int-synth wai_int_synth_vectors ../neural-conformance v film wai_film_vectors ../film-conformance v quantum wai_quantum_vectors ../quantum-conformance v quantum-ops wai_quantum_ops_vectors ../quantum-ops-conformance v oer wai_oer_vectors ../oer-conformance # OER's second implementation is portable C, not Rust. Rebuild it from source and # require its output to match the pinned corpus byte for byte: the kernel is # deterministic, and wai_oer_vectors above has already verified the pinned copy, # so equality carries that verification to what the source produces today. # `cc` with the Makefile's flags, so the step needs no `make` on the runner. - name: OER C kernel reproduces its pinned receipts (unix) if: matrix.os != 'windows' shell: bash working-directory: wai/oer-conformance/settle run: | set -euo pipefail cc -O2 -std=c99 -Wall -Wextra -Wno-unused-parameter -Wno-sign-compare \ -o "$RUNNER_TEMP/settle_host" host_main.c settle.c sha256.c tweetnacl.c -lm "$RUNNER_TEMP/settle_host" "$RUNNER_TEMP/firmware_vectors.json" 400 cmp "$RUNNER_TEMP/firmware_vectors.json" ../firmware_vectors.json - name: Every cargo-class corpus reproduces its frozen hashes (Windows) if: matrix.os == 'windows' shell: pwsh working-directory: wai/wai-rs run: | $F = "world,audio_scene,haptic,splat4d,score,provenance,neural_int,film,quantum,quantum_ops,oer" function v($grp, $bin, $path) { Write-Output "::group::$grp" cargo run -q --no-default-features --features $F --bin $bin -- verify $path if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE } Write-Output "::endgroup::" } v worlds wai_world_vectors ../world-conformance v spatial-audio wai_audio_vectors ../audio-conformance v haptics wai_haptic_vectors ../haptic-conformance v state-feeds wai_feed_vectors ../feed-conformance v avatars wai_avatar_vectors ../avatar-conformance v volumetric wai_splat4d_vectors ../volumetric-conformance v score wai_score_vectors ../score-conformance v int-synth wai_int_synth_vectors ../neural-conformance v film wai_film_vectors ../film-conformance v quantum wai_quantum_vectors ../quantum-conformance v quantum-ops wai_quantum_ops_vectors ../quantum-ops-conformance v oer wai_oer_vectors ../oer-conformance byte-exact: name: cross-arch byte-equality · ${{ matrix.os }} runs-on: ${{ matrix.os }} strategy: fail-fast: false matrix: # Self-hosted fleet labels. Both architectures across all three OS # families: x86_64 by linux + windows, arm64 by linux-arm64 + macos — # what matters for the Fx integer floor is the arch, not the OS. No # Intel-Mac runner exists in the fleet, and it would add no arch # coverage anyway. os: [linux, linux-arm64, macos, windows] steps: - uses: actions/checkout@v5 - name: Install Rust 1.98.0 (unix) if: matrix.os != 'windows' shell: bash run: | export PATH="$HOME/.cargo/bin:$PATH" command -v rustup >/dev/null 2>&1 || \ curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --profile minimal --default-toolchain 1.98.0 rustup toolchain install 1.98.0 --profile minimal rustup default 1.98.0 echo "$HOME/.cargo/bin" >> "$GITHUB_PATH" - name: Install Rust 1.98.0 (Windows) if: matrix.os == 'windows' shell: pwsh run: | rustup toolchain install 1.98.0 --profile minimal rustup default 1.98.0 - name: Integer rANS + int_synth + JPEG-AI mANS goldens (one machine → every machine) working-directory: wai/byte-exact-conformance run: cargo test --release # The C2PA emitter is gated behind an off-by-default feature, so the four-platform # job above — which builds a fixed feature list — never compiles it. A feature no # workflow enables has no CI coverage at all: the suite passes, and the tests in it # simply do not run. # # One platform, deliberately. Everything the matrix above exists to prove is about # byte-identical reconstruction across architectures; a signed manifest makes no # such claim and would not become more true for being emitted on four machines. What # this job proves is that the manifest is still well-formed, still carries the three # assertions, and still validates — which is architecture-independent. c2pa-emitter: name: C2PA manifest emission · signed, read back, validated runs-on: linux steps: - uses: actions/checkout@v4 - name: Install Rust 1.98.0 shell: bash run: | export PATH="$HOME/.cargo/bin:$PATH" command -v rustup >/dev/null 2>&1 || \ curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --profile minimal --default-toolchain 1.98.0 rustup toolchain install 1.98.0 --profile minimal rustup default 1.98.0 echo "$HOME/.cargo/bin" >> "$GITHUB_PATH" # `rust_native_crypto` rather than the SDK's default openssl backend, so this # job needs no system libraries — the same property the matrix above depends on. # Asserted, not assumed: an openssl-linked build would still pass the tests here # while quietly making the crate undistributable to a bare runner. - name: The emitter pulls in no system crypto working-directory: wai/wai-rs shell: bash run: | for dep in openssl openssl-sys; do if cargo tree --no-default-features --features c2pa_emit -i "$dep" >/dev/null 2>&1; then echo "::error::$dep reached the c2pa_emit dependency graph" exit 1 fi done echo "no system crypto in the graph" - name: Emit, sign, read back, validate working-directory: wai/wai-rs run: cargo test --lib --no-default-features --features c2pa_emit c2pa_emit # The feature must stay optional. If `provenance` ever pulls c2pa in, every # consumer that wanted only the binding types inherits a large dependency tree # they did not ask for, and the "off by default" claim in the extension is false. - name: The feature stays optional working-directory: wai/wai-rs shell: bash run: | if cargo tree --no-default-features --features provenance -i c2pa >/dev/null 2>&1; then echo "::error::c2pa is reachable from the provenance feature; it must stay opt-in" exit 1 fi cargo build --no-default-features --features provenance echo "provenance builds without c2pa"