Some checks failed
standards workspaces build + test / jouleclaw-rs (pull_request) Successful in 1m39s
standards workspaces build + test / aac-rs (pull_request) Successful in 32s
standards workspaces build + test / joule-code-rs (pull_request) Successful in 1m8s
standards workspaces build + test / joulecontract-rs (pull_request) Successful in 37s
standards workspaces build + test / map-rs (pull_request) Successful in 40s
standards workspaces build + test / mesh-rs (pull_request) Successful in 35s
standards workspaces build + test / openpay (pull_request) Successful in 2m53s
wai cross-architecture byte-equality / linux-aarch64 (pull_request) Successful in 24s
WAI conformance / cargo-class corpora · linux-arm64 (pull_request) Failing after 42s
WAI conformance / cross-arch byte-equality · linux-arm64 (pull_request) Successful in 26s
WAI energy receipts / energy receipts · linux-arm64 (pull_request) Successful in 50s
no-vanity-metrics / Scan committed Markdown for vanity metrics (pull_request) Successful in 3s
standards workspaces build + test / eoc-rs (pull_request) Successful in 1m48s
standards workspaces build + test / jcp-rs (pull_request) Successful in 1m17s
standards workspaces build + test / proof-rs (pull_request) Successful in 1m12s
standards workspaces build + test / sandbox-rs (pull_request) Successful in 2m6s
standards workspaces build + test / arl-rs (pull_request) Successful in 1m48s
standards workspaces build + test / smart-byte-rs (pull_request) Successful in 2m34s
wai cross-architecture byte-equality / linux-x86_64 (pull_request) Successful in 22s
standards workspaces build + test / joule-ui-rs (pull_request) Successful in 2m0s
WAI conformance / cargo-class corpora · linux (pull_request) Successful in 2m20s
WAI conformance / cross-arch byte-equality · linux (pull_request) Successful in 26s
standards workspaces build + test / jouledesk-rs (pull_request) Successful in 1m58s
WAI conformance / C2PA manifest emission · signed, read back, validated (pull_request) Successful in 44s
WAI energy receipts / energy receipts · linux (pull_request) Successful in 44s
standards workspaces build + test / joulehook-rs (pull_request) Successful in 2m5s
standards workspaces build + test / sense-rs (pull_request) Successful in 1m53s
wai formal verification (integer core) / kani (pull_request) Successful in 4m4s
standards workspaces build + test / macOS energy backend (jcp-energy) (pull_request) Successful in 1m50s
WAI JPEG-AI whole decode (pinned inputs, required) / fetch pinned JPEG-AI inputs → whole decode + pixel hash, required (pull_request) Successful in 54s
wai cross-architecture byte-equality / macos-arm64 (reference) (pull_request) Successful in 22s
WAI neural decoders end-to-end / synthetic fixtures → Rust decode → reference (±4) (pull_request) Failing after 1m11s
WAI neural sink gates / model-free refusals of the neural sink (pull_request) Successful in 26s
WAI conformance / cargo-class corpora · macos (pull_request) Successful in 2m29s
WAI conformance / cross-arch byte-equality · macos (pull_request) Successful in 22s
WAI energy receipts / energy receipts · macos (pull_request) Successful in 58s
WAI mbt2018_mean integer decode (regenerated vectors) / regenerate mbt2018_mean integer vectors → Rust decode, required (pull_request) Successful in 2m35s
wai cross-architecture byte-equality / windows-x86_64 (pull_request) Has been cancelled
WAI conformance / cargo-class corpora · windows (pull_request) Has been cancelled
WAI conformance / cross-arch byte-equality · windows (pull_request) Has been cancelled
A JWP receipt says what was delivered, by whom and at what energy cost, and binds to its object one way. Other statements about the same objects had nowhere to go, and energy-measurement §2 requires an acquisition class beside every non-zero figure, which the object receipt has no member for. jwp-receipts §2.4.3-§2.4.7 adds a `claim` kind with one envelope, one canonical form (RFC 8785) and one signature rule for the classes energy, lawful-basis and log-inclusion. §2.6 and §3.2 add a second, deliberately weaker binding class: a publisher-signed soft binding with a resolution endpoint, under the ancestor rule. §3.1 step 3 fixes a strict Ed25519 rule. A declaration that a decision or a recovery record is checked against is verified before anything is compared with it (`context_invalid`). OER as settled on main is authoritative: this adds no second OER reader and changes no OER rule, vector, verifier or document. An OER receipt an energy claim names is read by oer::load under the document profile, verified by oer::verify_receipt, and its figure read by the exact quantity reader the composition checks use, through a new crate-private oer::rounds_to_micro. claim_verify.py does the same with the OER reference's load, verify_receipt and dec. The claim envelope keeps its own step-1 reader (claim_text.rs), which reads claims only. - Acquisition classes are the refined ones. The energy body carries the class as energy-measurement §2.7 writes it in JSON (energy_provenance, energy_uncertainty, energy_counter_filtering, energy_calibration_ref), present and null where a class has none, so a claim keeps one canonical form. Legacy HwShunt is refused, since no claim predates the refinement (energy_legacy_acquisition); missing, misplaced or sub-floor evidence is energy_acquisition_evidence. The grade correspondence is oer-receipts §2's, an exhaustive match over all five variants. - §3.1 step 2's member tables give exactly the type step 2 checks, and step 2 lists what the class rules add to a type as step 4's, never field_type. Both verifiers read a declaration in its table's order (they had read purposes before vocabulary and fragment, and every encoding after every member, so a declaration with two defects gave another reason than the text). - oer::py_float_repr writes a double at a tie between two shortest decimals as CPython's repr does (round half to even at the shortest length). No content address or verdict depended on it: main's number profile keeps floats out of every receipt body. It changed the printed name of a vector named by such a number, which both OER verifiers print and the OER fuzzer compares. Fourteen doubles CPython 3.14.7 wrote are pinned. - claim-conformance/: 154 vectors covering all 40 reasons, the canonical fixture recomputed by claim_verify.py and pinned, a second verifier (claim_verify.py) that shares no code with wai-rs, and differential.py, which runs both on inputs the corpus does not hold. receipt_claims joins the conformance library tests and both corpus loops. Checked on this machine (macOS arm64) on the stream's tree: - library tests with receipt_claims (dev; oer + receipt_claims also release); - wai_claim_vectors and wai_oer_vectors verify their corpora; - claim_verify.py reports every vector's declared outcome; - differential.py: its default families and 20,000 random inputs (seed 7): no verdict differs and nothing crashes; - oer2_verify.py passes every OER vector file and refuses every unreadable document, the C kernel's output equals firmware_vectors.json, and fuzz_differential.py (seed 1, 20,000 documents) finds no divergence. And on this commit's tree, the per-link gate: build, library tests, carriage, every corpus in the conformance loop, byte-exact, wasm32. Not run here: the Linux and Windows legs (CI runs Linux; the Windows runner is offline). The Python scripts are run by hand, not in CI. Not done: key discovery (every claim signature presumes the verifier holds the key), an authority class for who may sign which class, region- or time-scoped soft bindings, and checking a log's receipt under its profile. Co-Authored-By: Claude Opus 5.5 <[email protected]>
297 lines
16 KiB
YAML
297 lines
16 KiB
YAML
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-rs path-depends on wai-quantum, and the quantum corpora below are
|
|
# verified through it: a change there changes what this workflow checks.
|
|
- 'wai/wai-quantum/**'
|
|
- 'wai/*-conformance/**'
|
|
- 'wai/byte-exact-conformance/**'
|
|
- '.github/workflows/wai-conformance.yml'
|
|
pull_request:
|
|
paths:
|
|
- 'wai/wai-rs/**'
|
|
# wai-rs path-depends on wai-quantum, and the quantum corpora below are
|
|
# verified through it: a change there changes what this workflow checks.
|
|
- 'wai/wai-quantum/**'
|
|
- '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
|
|
rustup component add --toolchain 1.98.0 clippy
|
|
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,receipt_claims
|
|
# The JPEG AI exact decoder reproduces across platforms only if no platform math
|
|
# library is on its path. Two guards, each failing the step: clippy's
|
|
# disallowed-methods (wai-rs/clippy.toml), which each module on the decode path
|
|
# denies, rejects a listed float method however it is spelled; and
|
|
# tests/jpegai_decode_symbols.rs lists the linked decoder's symbols with `nm` and
|
|
# rejects any C math-library function it imports, whatever made the call, and any
|
|
# it defines other than the round-to-integral ones (see its doc). `-A clippy::all`
|
|
# keeps the output to that guard. Unix legs only: `nm` is not on the Windows
|
|
# runner, and for clippy the unix legs already cover both architectures.
|
|
- name: JPEG AI exact decode calls no platform math library (unix)
|
|
if: matrix.os != 'windows'
|
|
shell: bash
|
|
working-directory: wai/wai-rs
|
|
run: |
|
|
set -euo pipefail
|
|
cargo clippy --lib --no-default-features --features neural_int -- -A clippy::all
|
|
cargo test --no-default-features --features world,audio_scene,haptic,splat4d,score,provenance,neural_int,film --test jpegai_decode_symbols
|
|
|
|
# The integer decoders run fast kernels (src/int_kernels.rs) that must give
|
|
# the same integer as the scalar reference kernels for every output element.
|
|
# The feature list above leaves out audio_int, video_int, world_int and
|
|
# splat_int, so without these two steps int_audio's kernel-equivalence tests
|
|
# and tests/int_kernels_vectors.rs (every committed integer-decoder vector
|
|
# decoded under the reference and under each fast policy, against its frozen
|
|
# hash) would run nowhere. `--lib` also carries the other kernels' equivalence
|
|
# modules; tests/int_kernels_geometry.rs runs edge geometry (strides up to
|
|
# usize::MAX, padding far beyond the kernel) through the public decoders
|
|
# under every policy. Both profiles, because the overflow-parity tests assert
|
|
# different things in each: with overflow checks on (dev) that the fast path panics
|
|
# where the reference panics, with them off (release) that it returns the
|
|
# same integers. All pure Rust, so every leg runs them.
|
|
# tests/int_mlicpp.rs decodes the committed wai.neural.int_mlicpp vector against
|
|
# its pinned hashes (image, every scale bucket, every symbol) under every kernel
|
|
# policy and thread count, and checks that damaged payloads are refused rather than
|
|
# overflowing — which is why it runs in both profiles too.
|
|
# tests/int_mlicpp_preflight.rs (its own binary: it installs a counting global
|
|
# allocator) checks that a header the model cannot fit is refused before the
|
|
# decode allocates anything sized from it.
|
|
- name: Fast integer kernels ≡ reference kernels (overflow checks on)
|
|
working-directory: wai/wai-rs
|
|
run: cargo test --no-default-features --features neural_int,video_int,audio_int,world_int,splat_int --lib --test int_kernels_vectors --test int_kernels_geometry --test int_mlicpp --test int_mlicpp_preflight
|
|
- name: Fast integer kernels ≡ reference kernels (release, overflow checks off)
|
|
working-directory: wai/wai-rs
|
|
run: cargo test --release --no-default-features --features neural_int,video_int,audio_int,world_int,splat_int --lib --test int_kernels_vectors --test int_kernels_geometry --test int_mlicpp --test int_mlicpp_preflight
|
|
- 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,receipt_claims
|
|
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
|
|
v claims wai_claim_vectors ../claim-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,receipt_claims"
|
|
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
|
|
v claims wai_claim_vectors ../claim-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"
|