open-standards/.github/workflows/wai-conformance.yml
dcharlot 7a78426b78
All checks were successful
joule-moq-web browser client / joule-moq-web · does this change touch it (push) Successful in 8s
wai-app and Create / wai-app · does this change touch it (push) Successful in 9s
wai-app and Create / wai-app · tests, clippy, the line language's verifier (linux) (push) Successful in 27s
wai-app and Create / wai-app · Create, browser end-to-end (macos) (push) Successful in 7m12s
joule-moq-web browser client / joule-moq-web · browser end-to-end (macos) (push) Successful in 12m25s
wai-audit collector and player integration / does this change touch it (push) Successful in 5s
WAI operation catalogue / does this change touch it (push) Successful in 5s
wai-fleet service / does this change touch it (push) Successful in 5s
wai-ledger service / does this change touch it (push) Successful in 5s
wai-quantum docs, course and locales / does this change touch it (push) Successful in 5s
wai-quantum for JavaScript / does this change touch it (push) Successful in 5s
wai-quantum studio and desktop / does this change touch it (push) Successful in 6s
wai-sink-android native sink library / does this change touch it (push) Successful in 7s
wai-sink-swift native sink package / does this change touch it (push) Successful in 9s
wai-fleet service / service · macos (push) Successful in 47s
WAI Studio / does this change touch it (push) Successful in 8s
wai-ledger service / service · macos (push) Successful in 49s
wai-audit collector and player integration / collector · linux (push) Successful in 1m12s
wai-audit collector and player integration / collector, player integration and the browser end to end · macos (push) Successful in 1m14s
wai-quantum docs, course and locales / the Studio's words in every locale · linux (push) Successful in 9s
wai-ledger service / service · linux (push) Successful in 1m47s
repository checks / lockfiles, advisories, tests in CI, workflow hygiene, spec and section references, public text (push) Successful in 2m54s
wai-quantum docs, course and locales / the course and the command line's languages · linux (push) Successful in 2m30s
wai-fleet service / service · linux (push) Successful in 2m43s
wai-sink-android native sink library / the JNI layer and the platform-free half on the host JVM · linux-arm64 (push) Successful in 2m46s
WAI Studio / the catalogue's actions, the unit tests and the core · linux (push) Successful in 57s
wai-quantum for JavaScript / javascript · linux (push) Successful in 2m57s
WAI operation catalogue / the catalogue and every door · linux (push) Successful in 4m52s
wai-quantum studio and desktop / desktop app · macos (push) Successful in 4m44s
wai-quantum studio and desktop / studio · browser (push) Successful in 4m23s
wai-sink-android native sink library / every ABI, the AAR, and the instrumented tests in a headless emulator · macos (push) Successful in 7m22s
WAI Studio / Studio in Chromium and Firefox · macos (push) Successful in 7m6s
wai-quantum studio and desktop / desktop app · linux (push) Successful in 5m43s
wai-quantum studio and desktop / desktop app · windows (push) Successful in 9m15s
WAI Studio / Studio in WebKit · linux (push) Successful in 11m50s
wai-sink-swift native sink package / libwai slices, desktop tests, simulator tests · macos (push) Successful in 16m3s
wai-quantum docs, course and locales / every command and snippet in the docs · linux (push) Successful in 16m52s
Merge pull request 'receipt-ledger: tariff version 3 prices media jobs per operation and bills the work done' (#550) from wai/ledger-work-priced into main
2026-10-31 08:50:17 -04:00

3026 lines
212 KiB
YAML
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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 integer-exact neural decoders, which make the
# same promise (the registry's NeuralIntegerExact class: i64-only, no float
# ONNX) — is re-derived on every OS/arch leg of the matrix below (x86-64 and
# arm64) 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.
# One run per branch at a time. A push supersedes the run before it.
#
# There is one `macos` runner and it is the dev Mac, so every macOS job in this
# repo queues on it. With no concurrency group, a session pushing four versions
# of a branch queued four complete sets of runs and every one of them had to
# drain: on 2026-10-05 a PR's 21 contexts settled none in 70 minutes behind a
# backlog of 25 runs, and the queue grew faster than it cleared. Only the newest
# commit's verdict is wanted, so the older runs are cancelled.
#
# Verified on this forge (Forgejo 16.0.5) in `ci-test` before being added here:
# the key parses, and a newer push moves an older run to `cancelled` even while
# it is still queued, which is the case that matters.
#
# `cancel-in-progress: true` also applies to `main`. That is deliberate and
# safe here: main advances by merge commits whose tree contains the commits
# before them, so the newer run covers the older one's changes.
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
on:
pull_request:
paths:
- 'wai/wai-rs/**'
# `wai create` holds the examples' files (include_bytes!), and tests/cli_dx.rs holds them
# to wai/examples/ byte for byte.
- 'wai/examples/**'
# 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/**'
# The integer decoders that decode through the integer operator set depend on it.
- 'wai/wai-ops/**'
# `wai create --from app.oui`, `wai app` and `wai mcp --toolset app` (the feature `app`)
# link Create's library and the joule-ui crates it builds on.
- 'wai/wai-app/**'
- 'joule-ui/joule-ui-rs/crates/joule-ui-core/**'
- 'joule-ui/joule-ui-rs/crates/joule-ui-lang/**'
- 'joule-ui/joule-ui-rs/crates/joule-ui-interaction/**'
- 'wai/*-conformance/**'
- 'wai/byte-exact-conformance/**'
# The registry export and the two library tests that read files outside
# wai-rs (the codec glossary, SPEC.md) must fire this workflow too: a
# hand edit of an exported file, of SPEC §5 or of the glossary is checked
# here. vocab/v1's and v2's pin terms are checked by a library test.
- 'wai/registry/**'
- 'wai/vocab/**'
- 'wai/glossary/**'
- 'wai/SPEC.md'
- 'wai/REGISTRY.md'
# A library test checks SPEC §5's pinned integer payloads against this
# extension's sections, so an edit of it is checked here too.
- 'wai/extensions/integer-payloads.md'
# A library test (staged::tests::staged_delivery_text_lists_the_codes) checks
# that this extension's §4.2 and A.6 list the codes the sink reports.
- 'wai/extensions/staged-delivery.md'
# A library test (codecs::registry::tests::wire_identifiers_are_in_their_documents)
# checks every wire identifier against the section of these texts it names, and
# staged::moq::tests::moq_streaming_format_lists_the_codes checks §4.1's codes.
- 'wai/extensions/http-delivery.md'
- 'wai/extensions/moq-streaming-format.md'
- 'wai/extensions/jwp-receipts.md'
# The quantum referee requires this extension's Appendix B to state its phase tables.
- 'wai/extensions/quantum-sim.md'
# tests/live_events.rs requires this extension's §9 to list the codes the reference
# reports, and the registry's wire identifiers test reads its sections.
- 'wai/extensions/live-events.md'
# tests/live_room.rs requires this extension's §11 to list the codes the reference
# reports, and the registry's wire identifiers test reads its sections.
- 'wai/extensions/live-rooms.md'
# tests/capture_take.rs requires this extension's §12 to list the codes the reference
# reports, and the registry's wire identifiers test reads its sections.
- 'wai/extensions/capture-binding.md'
# tests/live_compose.rs requires this extension's §10 to list the codes the reference
# reports, and the registry's wire identifiers test reads its sections.
- 'wai/extensions/live-compose.md'
# tests/live_record.rs requires this extension's §9 to list the codes the reference
# reports, and the registry's wire identifiers test reads its sections.
- 'wai/extensions/live-recording.md'
# tests/timed_text.rs requires this extension's §12 to list the codes the reference
# reports, and the registry's wire identifiers test reads its sections.
- 'wai/extensions/timed-text.md'
# tests/access_services.rs requires this extension's §10 to list the codes the reference
# reports, access_services_verify.py reads that table, and the registry's wire
# identifiers test reads its sections.
- 'wai/extensions/access-services.md'
# tests/live_metering.rs requires this extension's §9 to list the codes the reference
# reports, live_metering_verify.py reads that table, and the registry's wire identifiers
# test reads its sections.
- 'wai/extensions/live-metering.md'
# tests/energy_steering.rs requires this extension's §10 to list the codes the reference
# reports, energy_steering_verify.py reads that table, and the registry's wire
# identifiers test reads its sections.
- 'wai/extensions/energy-steering.md'
# tests/live_moderation.rs requires this extension's §10 to list the codes the reference
# reports, live_moderation_verify.py reads its §9.5, §9.6 and §10 tables, and the
# registry's wire identifiers test reads its sections.
- 'wai/extensions/live-moderation.md'
# tests/live_watermark.rs requires this extension's §11 to list the codes the reference
# reports, live_watermark_verify.py reads that table, and the registry's wire identifiers
# test reads its sections.
- 'wai/extensions/forensic-watermark.md'
# e2ee_verify.py reads this extension's §13 table, and the registry's wire identifiers
# test reads its sections.
- 'wai/extensions/confidentiality.md'
# tests/live_messaging.rs requires this extension's §12 to list the codes the reference
# reports, live_messaging_verify.py reads that table, and the registry's wire identifiers
# test reads its sections.
- 'wai/extensions/live-messaging.md'
# tests/live_ads.rs requires this extension's §10 to list the codes the reference
# reports, live_ads_verify.py reads that table, and the registry's wire identifiers test
# reads its sections.
- 'wai/extensions/live-ads.md'
# tests/ad_presentation.rs requires this extension's §11 to list the codes the reference
# reports, ad_presentation_verify.py reads that table, and the registry's wire identifiers
# test reads its sections.
- 'wai/extensions/ad-presentation.md'
# tests/key_release.rs requires this extension's §3.1, §3.2, §7.2 and §11 tables to be the
# reference's codes, key_release_verify.py reads those tables and §3.3, and the registry's
# wire identifiers test reads its sections.
- 'wai/extensions/key-release.md'
# tests/conform_result.rs requires this extension's §5 to list the codes the reference
# reports, conform_result_verify.py reads that table, and the registry's wire identifiers
# test reads its sections.
- 'wai/extensions/conformance-results.md'
# The ad-presentation step runs the browser client's reference producer against the
# corpus, and the stitched-presentation step runs its stitched producer.
- 'joule-code/joule-code-rs/crates/joule-moq-web/web/ads/**'
# tests/stitched_presentation.rs requires this extension's §9 to list the codes the
# reference adds, stitched_presentation_verify.py reads that table, and the registry's
# wire identifiers test reads its sections.
- 'wai/extensions/stitched-presentation.md'
# tests/channel_lineup.rs requires this extension's §10 to list the codes the reference
# adds and runs its §9's commands as the text writes them, channel_lineup_verify.py reads
# its §10, and the registry's wire identifiers test reads its sections.
- 'wai/extensions/channel-lineup.md'
# tests/live_provenance.rs requires this extension's §12 to list the codes and the C2PA
# codes the reference reports, c2pa_live_verify.py reads that table, and the registry's
# wire identifiers test reads its sections.
- 'wai/extensions/live-provenance.md'
# tests/derive_edge.rs requires this extension's §9 to list the codes the reference
# reports and its §4 the derivations, edge_verify.py reads both tables, and the
# registry's wire identifiers test reads its sections.
- 'wai/extensions/deriving-edge.md'
# tests/synthesis.rs requires this extension's §12 to list the codes the reference
# reports and its §10.2 table to pin the reference's icons, synthesis_verify.py reads
# both, tests/synthesis_mark.rs and synthesis_mark_verify.py read its scheme's
# definition, generator, figures, table and claims (§7.4 to §7.5.8), and the registry's
# wire identifiers test reads its sections.
- 'wai/extensions/synthesis.md'
# tests/exact_upscale.rs requires this extension's §8 to list the codes the reference
# reports, upscale_verify.py reads that table, and the registry's wire identifiers test
# reads its sections.
- 'wai/extensions/exact-upscale.md'
# tests/prior_wire.rs requires this extension's §13 to list the codes the reference
# reports, prior_forms_verify.py reads that table, and the registry's wire identifiers
# test reads its sections.
- 'wai/extensions/prior-carriage.md'
# tests/scene_map.rs requires this extension's §8 to list the codes the reference
# reports, scene_verify.py reads that table, and the registry's wire identifiers test
# reads its sections.
- 'wai/extensions/scene-carriage.md'
# tests/avatar_face.rs requires this extension's §10 to list the codes the reference
# reports and its §7.9 to state the training report's figures, avatar_face_verify.py
# reads §10, and the registry's tests read SPEC §5's registration of wai.avatar.face.
- 'wai/extensions/avatars.md'
# The tool that trained the corpus's generator and wrote its inputs and its report.
- 'wai/tools/wai_avatar_face_train.py'
# tests/ai_usage.rs requires this extension's §9 to list the codes the reference reports,
# ai_usage_verify.py reads that table, and the registry's wire identifiers test reads its
# sections.
- 'wai/extensions/ai-usage.md'
# tests/contribution.rs requires this extension's §11 to list the codes the reference
# reports, contribution_verify.py reads that table, and the registry's wire identifiers
# test reads its sections.
- 'wai/extensions/contribution.md'
# live_contribution_verify.py reads this extension's §7 list of the link record's
# reasons and requires the corpus to raise each one.
- 'wai/extensions/live-contribution.md'
# tests/settlement.rs requires this extension's §11 to list the codes the reference
# reports, settlement_verify.py reads that table, and the registry's wire identifiers test
# reads its sections.
- 'wai/extensions/settlement.md'
# tests/receipt_ledger.rs requires this extension's §10 to list the codes the reference
# reports, receipt_ledger_verify.py reads that table, and the registry's wire identifiers
# test reads its sections. Its corpus is generated from the metering, settlement, ads,
# presentation and stitched corpora and the packs of pack-conformance, all under the paths
# above.
- 'wai/extensions/receipt-ledger.md'
# tests/revenue_share.rs requires this extension's §11 to list the codes the reference
# reports, revenue_share_verify.py reads that table, and the registry's wire identifiers
# test reads its sections. Its corpus is generated from the ledger corpus, under the paths
# above.
- 'wai/extensions/revenue-share.md'
# tests/opportunity_report.rs requires this extension's §13 to list the codes the reference
# reports, opportunity_report_verify.py reads that table, and the registry's wire identifiers
# test reads its sections. Its corpus is generated from fixed seeds, under the paths above.
- 'wai/extensions/opportunity-report.md'
# tests/stream_audit.rs requires this extension's §14 to list the codes the reference
# reports, stream_audit_verify.py reads that table, and the registry's wire identifiers test
# reads its sections.
- 'wai/extensions/stream-audit.md'
# tests/fleet.rs requires this extension's §10 to list the codes the reference reports,
# fleet_verify.py reads that table, and the registry's wire identifiers test reads its
# sections. Its corpus is generated from the metering corpus, under the paths above.
- 'wai/extensions/fleet.md'
# tests/route_record.rs and the module's tests require this extension's §8 to list the
# codes the reference reports, route_record_verify.py reads that table, and the registry's
# wire identifiers test reads its sections.
- 'wai/extensions/route-record.md'
# tests/native_sink.rs requires this extension's §8 to list exactly the reasons its
# corpus reaches, and native_sink_verify.py reads that table.
- 'wai/extensions/native-sink.md'
# tests/browser_sink.rs requires this extension's §11 to list the codes the reference
# reports, browser_sink_verify.py reads its §2, §4.1, §4.2 and §11 tables and
# capability-constraints' §3.1 register, and the registry's wire identifiers test reads
# its sections.
- 'wai/extensions/browser-sink.md'
- 'wai/extensions/capability-constraints.md'
# sink_energy's unit tests require this extension's §8 to list exactly the codes the
# reference reports, and sink_energy_verify.py reads that table.
- 'wai/extensions/sink-energy.md'
# The browser sink's functions for a page, held to the same corpus natively.
- 'wai/wai-live-web/**'
# tests/takedown.rs requires this extension's §11 to list the codes the reference
# reports, takedown_verify.py reads that table, and the registry's wire identifiers test
# reads its sections. The registry of clocks it reads is under wai/registry/ above.
- 'wai/extensions/takedown.md'
# tests/co_performance.rs requires this extension's §10 to list the codes the reference
# reports, co_performance_verify.py reads that table, and the registry's wire identifiers
# test reads its sections.
- 'wai/extensions/co-performance.md'
# tests/age_assurance.rs requires this extension's §11 to list the codes the reference
# reports, age_assurance_verify.py reads that table, and the registry's wire identifiers
# test reads its sections.
- 'wai/extensions/age-assurance.md'
# tests/influence.rs requires this extension's §9 to list the codes the reference adds,
# influence_verify.py reads that table, and the registry's wire identifiers test reads its
# sections.
- 'wai/extensions/influence.md'
# tests/direction.rs requires this extension's §13 to list the codes the reference reports,
# direction_verify.py reads that table, and the registry's wire identifiers test reads its
# sections.
- 'wai/extensions/direction.md'
# tests/bearer_receipts.rs requires this extension's §10 to list the codes the reference
# reports, and bearer_verify.py reads that table.
- 'wai/extensions/bearer-receipts.md'
# tests/exploration.rs requires this extension's §13 to list the codes the reference
# reports and its §3.2 table to name the reference's descriptors, exploration_verify.py
# reads §13, and the registry's wire identifiers test reads its sections.
- 'wai/extensions/exploration.md'
# tests/platform_encode.rs requires this extension's §12 to list the reasons the reference
# reports, and encode_verify.py reads that table.
- 'wai/extensions/platform-encode.md'
# tests/co_watch.rs requires this extension's §12 to list the codes the reference reports,
# co_watch_verify.py reads that table, and the registry's wire identifiers test reads its
# sections.
- 'wai/extensions/co-watch.md'
# tests/live_world.rs requires this extension's §11 to list the codes the reference reports.
- 'wai/extensions/live-worlds.md'
# The co-watch step runs the browser client's co-watch module against the corpus.
- 'joule-code/joule-code-rs/crates/joule-moq-web/web/room/cowatch*'
# tests/remote_desktop.rs requires this extension's §12 to list the codes the reference
# reports, remote_desktop_verify.py reads its four tables, and the registry's wire
# identifiers test reads its sections.
- 'wai/extensions/remote-desktop.md'
# The remote desktop step runs the browser viewer's module against the corpus.
- 'joule-code/joule-code-rs/crates/joule-moq-web/web/room/remote*'
# tests/dred_exact.rs requires this extension's §8 to list the codes the reference
# reports and its §4 to state the reference's digests, tests/dred_exact_measure.rs its §6
# table, dred_verify.py reads §4 and §8, and the registry's tests read SPEC §5 against it.
- 'wai/extensions/opus-dred.md'
# tests/telemetry_aggregate.rs requires this extension's §11 to list the codes the
# reference reports, telemetry_aggregate_verify.py reads that table, and the registry's
# wire identifiers test reads its sections.
- 'wai/extensions/telemetry-aggregation.md'
# tests/telemetry_aggregate.rs requires §3.4's table to class the keys the reference
# classes, and telemetry_aggregate_verify.py reads that table and §4.1 and §4.2's shards.
- 'wai/extensions/delivery-telemetry.md'
# tests/exact_tonemap.rs requires this extension's §9 to list the codes the reference
# reports and its §6 to state the corpus's measurement, tonemap_verify.py reads §3.3's
# table, §5.4's constant and §9, and the registry's wire identifiers test reads its
# sections.
- 'wai/extensions/exact-tonemap.md'
# tests/robustness.rs requires this extension's §12 to list the codes the reference
# reports and its §4 to register the reference's transforms, robustness_verify.py reads
# both, and the registry's wire identifiers test reads its sections.
- 'wai/extensions/robustness-evidence.md'
# tests/splat_exact.rs requires this extension's §10 to list the codes the reference
# reports and the draft schema under extensions/gltf/ to name §3.2's members,
# splat_exact_verify.py reads §10, and the registry's wire identifiers test reads its
# sections.
- 'wai/extensions/splat-exact.md'
- 'wai/extensions/gltf/**'
# splat_exact_verify.py decodes each payload with this tool's whm1/1 lowering and
# interpreter.
- 'wai/tools/wai_ops_check.py'
# tests/pq_signatures.rs requires this extension's §8 to list the codes the reference
# reports, pq_verify.py reads that table, and the registry's wire identifiers test reads
# its §2.
- 'wai/extensions/pq-signatures.md'
# tests/format_probe.rs requires format-probes §2.4 and §12 to list the reference's probes
# and codes, and projection.md §4 and §5 to state its codes; format_probe_verify.py reads
# format-probes' tables; and the registry's wire identifiers test reads projection.md,
# loc-carriage.md and delivery-telemetry.md (whose §6.6 cmsd_read_verify.py reads).
- 'wai/extensions/format-probes.md'
- 'wai/extensions/projection.md'
- 'wai/extensions/loc-carriage.md'
- 'wai/extensions/delivery-telemetry.md'
# The determinism-cost record, its verifier, and the two texts whose quoted figures
# the verifier checks against the record.
- 'wai/research/determinism-cost.md'
- 'wai/research/determinism-cost/**'
- 'wai/tools/wai_determinism_cost_verify.py'
- 'wai/extensions/determinism-tiers.md'
# tests/stream_termination.rs requires this extension's §7 to list the codes the reference
# reports and capability-constraints §4.2 to name the match's bits,
# stream_termination_verify.py reads both, and the registry's wire identifiers test reads
# its sections.
- 'wai/extensions/stream-termination.md'
- 'wai/wai-web/**'
# The audio provenance check below reads the corpora above with this tool.
- 'wai/tools/wai_audio_provenance_check.py'
- '.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. The
# Windows legs are out of the matrices for now (see the comment on each matrix);
# their pwsh steps stay, inactive, so restoring a leg is a one-line change.
schedule:
- cron: '20 5 * * *'
jobs:
# Does this pull request's own diff touch the paths below? This forge matches a
# workflow's `paths:` against the push, so a merge of main into a branch fires the
# workflow whatever the pull request changes; every job here waits on this answer.
# A push to main, a schedule, or anything the script cannot determine answers
# `true` (scripts/pr-touches-paths.py).
relevant:
name: does this change touch it
runs-on: linux-arm64
outputs:
run: ${{ steps.gate.outputs.run }}
steps:
- uses: actions/checkout@v5
with:
fetch-depth: 0
- id: gate
run: |
set -euo pipefail
r=$(python3 scripts/pr-touches-paths.py .github/workflows/wai-conformance.yml \
"${{ github.event.pull_request.base.sha }}" \
"${{ github.event.pull_request.head.sha }}")
echo "this change touches wai-conformance: $r"
echo "run=$r" >> "$GITHUB_OUTPUT"
cargo-classes:
needs: relevant
if: needs.relevant.outputs.run == 'true'
name: cargo-class corpora · ${{ matrix.os }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
# Self-hosted fleet labels. Both architectures: x86_64 by linux, 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.
# Windows x86_64 leg removed 2026-09-30: runner offline. Restore by
# re-adding `windows` here once the runner is back online.
os: [linux, linux-arm64, macos]
# No debuginfo: nothing in CI reads DWARF, and it is most of a debug target's size. Three of
# these jobs at once on the linux-arm64 VM's 196 GB data disk ran out of space mid-link
# ("No space left on device", #542 and #550). Panic messages keep their file:line, which
# comes from the panic location, not from DWARF (standards-build.yml trims jouleclaw-rs the
# same way: ~6 GB without, against the full-debuginfo target that filled its disk).
env:
CARGO_PROFILE_DEV_DEBUG: '0'
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. receipt_claims
# is in the set because the reference meters (wai_meter, wai_world_meter) write a
# measurement report by default and require it: without it they would drop out
# of this build on every leg of this matrix, without a word. staged and the integer
# media features build the staged-delivery core, its corpus tool and `wai stage`;
# stage_measure builds the staged-measurement core and wai_stage_measure; telemetry
# the delivery-telemetry mapping and wai_telemetry; http the HTTP delivery binding,
# its corpus tool and `wai http`.
run: cargo build --no-default-features --features world,audio_scene,haptic,splat4d,score,provenance,neural_int,film,receipt_claims,staged,video_int,audio_int,splat_int,stage_measure,telemetry,http
# video_package runs the package receipt's dedup tests, which content_dedup feeds.
# The dev profile keeps overflow checks on, so an arithmetic overflow in the HTTP
# binding (http_binding::tests, among them a seeded test of every parser of untrusted
# input) fails here rather than wrapping.
- 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,key_discovery,staged,video_int,audio_int,splat_int,stage_measure,telemetry,video_package,http,format_probe
# 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
# Each extension container refuses a count its bytes cannot hold, without reserving
# it first (found by the coverage-guided fuzzer, wai-rs/fuzz/, target `containers`),
# and a declared duration past the reader limits it shares with SPEC §2.
- name: Extension containers reserve no more than their bytes hold, and are held to their duration limits
shell: bash
working-directory: wai/wai-rs
run: cargo test --no-default-features --features world,audio_scene,haptic,splat4d,score,film --test container_reservations --test extension_duration_limits
# 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_synth_ops.rs holds wai.neural.int_synth to its lowering through the
# integer operator set (extensions/integer-operators.md §13.1): every committed set
# lowers to its committed graph and loads with its certificate's verdict, decodes
# through it to every committed golden, and refuses whatever the direct decode
# refuses. tests/int_ops_differential.rs (feature legacy_int: the direct decode,
# test-only) decodes random sets and payloads both ways: the same output or both
# refused, except on the planned breaks of integer-operators §15.3, where the decode
# through the operator set refuses. wai-ops-differential.yml runs it for an hour in
# each profile, nightly. tests/int_splat_ops.rs holds wai.splat.int_codec to its
# lowering whm1/1 the same way (integer-operators §13.2): its committed set lowers,
# from its bytes and from the model this crate parses, to its committed graph, and
# loads with its certificate's verdict. tests/int_audio_ops.rs does the same for
# wai.audio.int_codec and its lowering wam1/1 (§13.3), and tests/int_hyper_ops.rs
# for wai.neural.int_hyper and the keyframe of wai.video.int_hyper (whm1/1: h_s,
# then g_s with the RGB8 step), and tests/int_mlicpp_ops.rs for wai.neural.int_mlicpp
# (wmb1/1: h_s, entropy, then g_s with the RGB8 step), and tests/int_world_ops.rs for
# wai.world.model's integer renderer (world/1, informative: T with its action planes,
# then g_s with the RGB8 step).
# 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.
# tests/int_audio.rs and tests/int_splat.rs decode the committed wai.audio.int_codec and
# wai.splat.int_codec vectors against the hashes the Python integer reference computed at
# export, and check each vector's metadata. `--lib` runs int_payload's unit tests: each
# binary payload (WIV1, WIH1, WIA1, WIS1) against the JSON it is converted from, under
# every kernel policy, and decode_int for every integer capability in this build, which
# has no `neural`. tests/int_payload.rs refuses every fixture of int-payload-conformance
# with its code, every strict prefix of every payload, and runs a byte-change sweep in
# which nothing may panic; tests/int_payload_preflight.rs (its own binary, a counting
# allocator) checks that a header past the caps is refused before anything sized from it
# is allocated; tests/int_payload_cost.rs (its own binary, a live-bytes allocator) checks
# that int_payload::declared_cost bounds what each decode holds, with the store of loaded
# sets off, then on (a decode that loads its set, and one that finds it held), that the
# store counts at least the bytes it holds, and, in the release step only, decodes a
# 2^30-byte clip a 3 KB payload codes; tests/int_set_cache.rs checks that store under
# the decodes: a second decode through a set is a hit with the same bytes on every
# committed vector, sets one byte apart never share an entry, a refused set stays
# refused, refusals keep their codes, and the least recently used set goes first;
# tests/int_world_memory.rs (its own binary, the same allocator) checks that the world
# renderer, with its set loaded, holds no more than the direct renderer it replaced.
# tests/int_video_enc_memory.rs
# (its own binary, the same allocator) checks that int_video_enc::working_bytes bounds
# what the encoder holds. tests/staged_resources.rs (its
# own binary, a counting allocator) checks that the staged sink's work and memory per
# layer grow linearly in the layer's units, that a layer past the chain budget is
# refused before any stream is decoded, that what no unit holds is dropped, and that a
# WIR1 parse holds no more than its declared working bytes. tests/stage_measure.rs counts every
# committed staged envelope as exactly its length, refuses JSON, base64 and another capability's
# format, and evaluates a measured title read from a map of files to its golden, refusing a
# changed byte of a layer, the base, the source or a parameter-set file (extensions/
# staged-measurement.md). Cargo.toml declares them, and the other
# feature-gated targets named here, with required-features, so if this step ever loses a
# feature, cargo stops with an error instead of compiling an empty binary that reports ok.
# Each committed vector's decoded output is also checked against the SHA-256 in
# its sha256.json sidecar (SPEC §7 *Digests*), and
# int_kernels_vectors::every_decoded_output_states_a_sha256 requires a sidecar,
# or a named exclusion, for every corpus directory. tests/generate.rs checks the
# wai.generate.spectral vectors, which `generate` enables: the 96x96 vector, sizes.json
# and instr-v0.json, the instruction object of form v0 (SPEC §5), whose two larger
# listed sizes run only in the release step (seconds each in a debug build).
# tests/cli_generate_score.rs runs `wai generate` and `wai score build|render`, which
# the features `generate` and `score` build into the `wai` binary: every pin it prints
# against those vectors and score-conformance/ (pcm_sha256 among them), every object
# instr-v0.json lists as accepted (one at each bound) made and wrapped, every object
# it lists as refused refused for the reason it states, and each refusal writing
# nothing; tests/generate.rs holds the same lists to a second statement of form v0.
# tests/manifest_parse_memory.rs (its own binary, a counting allocator) checks that
# reading a manifest allocates within the bound SPEC §2's reader limits give, at the
# length limit and at the value limit, and tests/manifest_reader_equivalence.rs holds
# the readers to the derived reader's result on every committed envelope. Both run in
# the release step only: the first writes manifests of 2^27 bytes, which takes a debug
# build most of a minute.
# tests/int_video.rs, int_video_halfpel.rs and int_video_keyframe.rs hold the integer
# video codec to its goldens (whole clips, half-pel motion, the keyframe through the
# integer hyperprior); int_world.rs and int_world2.rs the integer world renderers;
# jpegai_bitstream_calibration.rs the JPEG AI bitstream reader against the committed
# codestream. No step named any of them until scripts/check-tests-in-ci.py asked.
# jpegai_ops.rs holds the JPEG AI scale path (integer-operators §13.6.1) to its committed
# lowered graphs and certificate here; its cases on the jpegai/v1 bundle skip here and
# run in wai-jpegai-e2e.yml, which fetches the bundle and requires them.
# jpegai_nets_ops.rs does the same for its other integer networks (§13.6.2): the
# committed synthetic networks' lowered graphs and certificate, and every kernel
# policy on them, here; its jpegai/v1 cases there.
# int_video_ops.rs and wir1_ops.rs hold WIV1 and WIR1, which decode through the
# operator set's stage operators with no graph (integer-operators §13.5), to their
# stage forms, goldens and refusals; `i32_forms` builds E9's 32-bit form, which they
# and int_ops_differential.rs hold to the exact one. tests/int_ops_conformance.rs
# decodes every graph vector of ops-conformance/ through the fast kernels and holds
# each to the integers it states. Each of these runs every kernel set the leg's
# processor runs (int_kernels::equivalence_policies: the wide kernels, and NEON on
# arm64, AVX2 with or without VNNI on x86_64); int-kernels-amd below runs AVX-512.
- 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,generate,score,staged,stage_measure,legacy_int,i32_forms --lib --test int_kernels_vectors --test int_ops_conformance --test int_kernels_geometry --test int_synth_ops --test int_ops_differential --test int_splat_ops --test int_audio_ops --test int_hyper_ops --test int_mlicpp --test int_mlicpp_preflight --test int_mlicpp_ops --test int_world_ops --test int_world_memory --test jpegai_ops --test jpegai_nets_ops --test int_video_ops --test wir1_ops --test int_audio --test int_splat --test generate --test cli_generate_score --test int_payload --test int_payload_preflight --test int_payload_cost --test int_set_cache --test int_video_enc_memory --test cli_stage --test staged_resources --test stage_measure --test stage_measure_bounds --test int_video --test int_video_halfpel --test int_video_keyframe --test int_world --test int_world2 --test jpegai_bitstream_calibration
- 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,generate,score,staged,stage_measure,legacy_int,i32_forms --lib --test int_kernels_vectors --test int_ops_conformance --test int_kernels_geometry --test int_synth_ops --test int_ops_differential --test int_splat_ops --test int_audio_ops --test int_hyper_ops --test int_mlicpp --test int_mlicpp_preflight --test int_mlicpp_ops --test int_world_ops --test int_world_memory --test jpegai_ops --test jpegai_nets_ops --test int_video_ops --test wir1_ops --test int_audio --test int_splat --test generate --test cli_generate_score --test int_payload --test int_payload_preflight --test int_payload_cost --test int_set_cache --test int_video_enc_memory --test cli_stage --test staged_resources --test stage_measure --test stage_measure_bounds --test manifest_parse_memory --test manifest_reader_equivalence --test int_video --test int_video_halfpel --test int_video_keyframe --test int_world --test int_world2 --test jpegai_bitstream_calibration
# The integer decode path builds under each of its features alone, so a sink can take
# one medium without the others, and for wasm32 (a browser sink); `int_payload` arms a
# medium only under its feature, and none needs `neural`. So does the staged-measurement
# core (`stage_measure`), which pulls no ONNX and reads no file on wasm32. The HTTP
# binding (`http`) performs no I/O, so it builds alone and for wasm32 too.
- name: Each integer feature alone, and wasm32 (unix)
if: matrix.os != 'windows'
shell: bash
working-directory: wai/wai-rs
run: |
set -euo pipefail
for f in neural_int video_int audio_int splat_int staged stage_measure telemetry http format_probe; do
cargo check --lib --no-default-features --features "$f"
done
# The decode bench prints its machine line from bench_env; no other step builds it.
cargo build --no-default-features --features neural_int,video_int,audio_int,world_int,splat_int --bin wai_decode_bench
rustup target add --toolchain 1.98.0 wasm32-unknown-unknown
cargo check --lib --target wasm32-unknown-unknown --no-default-features --features video_int,audio_int,splat_int,staged,http
# The staged-measurement core is wasm32-clean: a browser computes the same figures.
# Built, not only checked, so codegen and linking of the library run for wasm32.
cargo build --lib --target wasm32-unknown-unknown --no-default-features --features stage_measure
# With the claim classes too: a browser sink seals its reconstruct-session claim
# (jwp-receipts §2.4.12), and wai-web's measurement binding signs with them.
cargo build --lib --target wasm32-unknown-unknown --no-default-features --features receipt_claims,stage_measure
# So is delivery telemetry: a browser sink writes the same reports.
cargo build --lib --target wasm32-unknown-unknown --no-default-features --features telemetry
# And the header probes: a browser reads a payload's parameters the same way.
cargo build --lib --target wasm32-unknown-unknown --no-default-features --features format_probe
# carriage: every registered capability round-trips byte-exact. cli_wrap_intent and
# cli_registry run the `wai` binary, which builds without the codecs feature: the
# intent rule of `wai wrap`, its refusal of candidate capabilities (SPEC §5), its media
# class, and `wai registry export --check` on the tree and on a drifted copy.
# tests/manifest_builders.rs: the manifest types are #[non_exhaustive], and the
# builders write the JSON a struct literal wrote; members the types keep only
# as `extra` (and `security`) survive a round trip.
# corpus_provenance: every corpus README states where its content comes from.
- name: Carriage conformance, the wai CLI (wrap, registry export) and corpus provenance
working-directory: wai/wai-rs
run: cargo test --no-default-features --test carriage --test manifest_builders --test cli_wrap_intent --test cli_registry --test corpus_provenance
# tests/floor.rs: the mandatory floor (SPEC 5: PNG, FLAC, zstd) in a build with the
# feature floor alone, no system codec library: decoded by the library and by `wai decode`,
# PNG and zstd written by `wai encode`, a codec outside the floor refused. tests/cli_dx.rs
# (feature quickstart): `wai hello` and `wai verify` as a person runs them, a changed byte
# of the object or of the group's receipt refused; `wai create`, every template held to
# wai/examples/ file for file and byte for byte. The binary's own tests: `wai dev`'s origin
# (a service's prefix stripped, the relay's upgrade carried both ways, nothing served from
# outside its roots; WAI Studio at /_wai/, its API to this origin alone) and the project
# file's reader. tests/cli_studio.rs: `wai dev` against a stand-in relay and room service
# serves Studio at /_wai/, every socket the stack listens on is on loopback, and the
# local wai runs an operation for the page.
- name: The floor build, and wai hello, create, dev and verify
working-directory: wai/wai-rs
run: |
cargo test --no-default-features --features floor --test floor
cargo test --no-default-features --features quickstart --bin wai --test floor --test cli_dx --test cli_fleet --test cli_studio
# tests/cli_http.rs runs `wai http publish`, `codecs`, `origin` and `bench` as a user
# does: objects named by their content hash with their head proofs, a sequence's union
# and floor, the origin's headers, ranges and If-Range on loopback, and a fetch by
# the byte-range procedure whose record states energy as not measured; and `hls`,
# `mpd`, `seal-playlist` and `check-playlist`, whose receipts need video_manifest;
# and `receipts`, an object's receipt index checked over HTTP with its signers
# confirmed under a key log, which needs key_discovery: the log anchored over TLS
# (cli_tls; the binary's own tests run its TLS client against servers under a test
# CA, tests/fixtures/tls/), never over plaintext, and a plaintext test anchor
# labelled as one. The second run builds without cli_tls: the CLI then refuses to
# anchor and connects to nothing.
# Cargo.toml declares it with required-features = ["http"]. tests/dash_read_bounds.rs
# holds Appendix I's reader to the document's size under a counting allocator, and an
# element's attributes to linear CPU time; a binary of its own, one test.
- name: The wai http commands
working-directory: wai/wai-rs
shell: bash
run: |
cargo test --no-default-features --features http,video_manifest,key_discovery,cli_tls --bin wai --test cli_http --test dash_read_bounds
cargo test --no-default-features --features http,video_manifest,key_discovery --test cli_http -- receipts_never_anchors_over_plaintext
# The wai commands for coding agents. tests/cli_mcp.rs starts `wai mcp` (the feature `mcp`)
# and drives it with an MCP client over its standard input and output: the handshake, the
# tool list (every tool an operation of the catalogue named by it, `core` by default and
# `dev` when asked, an unknown toolset refused) with each tool's schema and safety hints,
# and every tool. receipt_verify agrees vector by vector with jwp-conformance (group and
# object receipts), claim-conformance (each claim with the context the tool takes),
# live-conformance/rooms and live-conformance/audit, and a receipt changed by one character
# is refused; envelope_wrap writes only inside the project directory and never through a
# link; conformance_run runs live_rooms_verify.py; --read-only offers no tool that writes,
# serves or asks for a grant; the dev tools refuse any service off this machine before
# connecting, and any target but local (the room itself, joined, published to and verified
# through the tools, is joule-moq-room's tests/mcp_dev_room.rs). `--bin wai` runs the
# binary's unit tests: the tool table held to the operation catalogue both ways (every tool
# an operation the catalogue says wai mcp serves, in its toolset, every such operation a
# tool, a tool of MCP alone taking the catalogue's input), the loopback guard and
# setup-agent's merges and diff; `--lib catalogue::` the catalogue's rules (and
# wai-catalogue.yml the rest). tests/cli_setup_agent.rs runs `wai setup-agent` in scratch
# projects as an agent does (no terminal, --json, the JSON envelope out): a fresh project, a
# second run that changes nothing, a CLAUDE.md made only where one is, a file that exists
# changed only with --yes (exit 4 and the proposed
# changes otherwise), a dry run, --toolset registered, a JSON file with comments left
# alone, nothing written through a link out of the project, and the table's exit statuses.
# Cargo.toml declares cli_mcp with required-features = ["mcp"].
- name: The wai commands for coding agents (mcp, setup-agent)
working-directory: wai/wai-rs
run: |
cargo test --no-default-features --features mcp --bin wai --test cli_mcp --test cli_setup_agent
cargo test --no-default-features --lib catalogue::
# Apps made with Create, through `wai` built with the feature `app` (wai/wai-app linked
# in). tests/cli_app.rs: `wai create --from app.oui` writes an ordinary project, its
# wai.json laid out as a template's and naming the program and the room `wai dev` runs,
# its runtime under vendor/ and LICENSE; `wai app check` passes on it and refuses it with
# its room not its app's, another audience, no room named, a runtime file changed or a
# refused line, and a watch room until its file is there; `wai create --from` refuses a
# program with errors or no room, and a directory with anything in it; `wai mcp --toolset
# app`: the tools app_guide, app_check, app_stream and app_export, a program streamed
# through the bridge to a page with the pairing code and refused to one without, an export
# inside the project directory alone, and read-only with no bridge. `--bin wai` runs the
# binary's unit tests with the app toolset in its table, and the dev front's show mode.
- name: Apps made with Create (wai create --from, wai app, wai mcp --toolset app)
working-directory: wai/wai-rs
run: cargo test --no-default-features --features app --bin wai --test cli_app
# tests/staged_moq.rs runs the MoQ trace of staged-conformance/moq/ (moq-streaming-format
# §4.1) with signed receipts: a chain for each track, a receipt held for its parent and
# admitted when it arrives, the relay's per-hop delivery timeout, dropped objects checked
# by inclusion and named by the relay's delivery-gap claims, and each base's stage claim,
# which seals and verifies; the subscriber of two tracks holds exactly their chains.
# Cargo.toml declares it with required-features = ["staged", "video_int", "receipt_claims"].
# The interactive-world tests, which no step named: world_replay.rs (the replay
# class, under `world`), world_model.rs (the signed action trace and per-frame
# provenance, under `world_model`) and int_world_shared.rs (two sinks converging on
# one integer world, under both). `world_model` is enabled by no other step.
- name: World replay, the world model and the shared integer world
working-directory: wai/wai-rs
run: cargo test --no-default-features --features world_model,world_int --test world_replay --test world_model --test int_world_shared
- name: Staged tracks over MoQ, with signed receipts
working-directory: wai/wai-rs
run: cargo test --no-default-features --features staged,video_int,receipt_claims --test staged_moq
# The machine-readable registry (wai/registry/, wai/vocab/v2.*, the table in
# wai/REGISTRY.md) is generated from wai-rs/src/codecs/registry.rs. Regenerate it in
# memory and fail on any difference; the message says how to regenerate. One leg: the
# export is the same text on every platform.
- name: The registry export is up to date (linux)
if: matrix.os == 'linux'
working-directory: wai/wai-rs
run: cargo run -q --no-default-features --bin wai -- registry export --check
# The C ABI's envelope surface builds with no codec library (feature `ffi`):
# unpack returns each manifest as the envelope carries it, the WAI2 table carries
# every component's identity and selectability, wai_envelope_select follows
# SPEC §7.1 and never picks a candidate, and the packers refuse a candidate
# (SPEC §5). Cargo.toml declares the target with required-features.
- name: C ABI envelope surface (no codec library)
working-directory: wai/wai-rs
run: cargo test --no-default-features --features ffi --test ffi_envelope
# The browser crate wraps the same envelope types (wai::container), so role,
# companion_of, component identity and the pin reach JS, and its pick is SPEC
# §7.1's. Its tests target the pure-Rust half (`core`), which runs natively; one
# leg suffices, the logic is architecture-independent. The JS surface itself runs
# under wasm32 in wai-web-wasm.yml.
- name: wai-web envelope surface (native tests)
if: matrix.os == 'linux'
working-directory: wai/wai-web
run: cargo test --locked
# jwp-receipts §7.1, §7.8: no `did:web`/`did:key` literal in a tracked .rs, .json or
# .js file under wai/ names a real web origin — every key the tree signs with has a
# published seed. Ungated: it reads the tree through `git ls-files` and classifies
# with `signer_id`, which builds with no feature.
- name: Every signer id in the tree is a label
working-directory: wai/wai-rs
run: cargo test --no-default-features --test signer_ids_are_labels
# jwp-receipts §7: `wai-keys` builds a key log from operator-supplied seeds, appends
# revocations and rotations, signs statuses and module grants, verifies a log as
# §7.3 anchors one, and checks a DID document against it. The test drives the binary.
- name: wai-keys — build, check and publish an origin key log
working-directory: wai/wai-rs
run: cargo test --no-default-features --features key_discovery --test wai_keys_cli
# key_log has no I/O, clock or threads, so a browser sink could run it before it
# instantiates a module (§7.9); no browser sink does yet. Nor do the HTTP binding's
# receipts and keys (http-delivery §8.1–§8.5), which a browser client checks what it
# fetched with. This step checks that both build for wasm32 on the unix legs (the
# target is added to the pinned toolchain here; the Windows host runner is not set up
# for it).
- name: key_log and the HTTP receipts build for wasm32 (unix)
if: matrix.os != 'windows'
shell: bash
working-directory: wai/wai-rs
run: |
set -euo pipefail
rustup target add --toolchain 1.98.0 wasm32-unknown-unknown
cargo check --lib --target wasm32-unknown-unknown --no-default-features --features key_discovery,http
# 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,key_discovery,video_int,audio_int,splat_int,staged,stage_measure,telemetry,http,video_manifest,pq_signatures
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 jwp wai_jwp_vectors ../jwp-conformance
v claims wai_claim_vectors ../claim-conformance
v pin wai_pin_vectors ../pin-conformance
v signers wai_signer_vectors ../signer-conformance
v int-payload wai_int_payload_vectors ../int-payload-conformance
v staged wai_staged_vectors ../staged-conformance
v http wai_http_vectors ../http-conformance
v staged-measure wai_stage_measure ../staged-measure-conformance
v telemetry wai_telemetry ../telemetry-conformance
v pq-signatures wai_pq_vectors ../pq-conformance
# The pin corpus's second implementation: Python standard library only, sharing no
# code with wai-rs. One leg is enough — it checks digests and listing rules, which
# do not depend on the architecture — and the macOS host has python3.
- name: The pin corpus checks against an independent verifier (macOS)
if: matrix.os == 'macos'
shell: bash
working-directory: wai
run: python3 pin-conformance/pin_verify.py pin-conformance
# Every committed audio vector must come from a seeded generator. This check reads
# each one to PCM (each audio base's stage 0 in the staged corpus, each measured
# source over one, each spatial-audio source, every audio file under wai/) and
# fails if any correlates above 0.5, at any lag, with a recording in the reference
# set the host has: its system sound directory, or the directories named in
# WAI_AUDIO_REFERENCE_DIRS. A generated signal stays near 0.2; a lossy coding of a
# recording is near 1. A host with no reference set, or no converter to read it,
# prints why and skips: the linux legs skip, the macOS leg checks.
- name: No committed audio vector is a coding of a reference recording (unix)
if: matrix.os != 'windows'
shell: bash
working-directory: wai
run: |
if command -v python3 >/dev/null 2>&1; then
python3 tools/wai_audio_provenance_check.py
else
echo "audio provenance: SKIPPED — no python3 on this host"
fi
# 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,key_discovery,video_int,audio_int,splat_int,staged,stage_measure,telemetry,http,video_manifest,pq_signatures"
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 jwp wai_jwp_vectors ../jwp-conformance
v claims wai_claim_vectors ../claim-conformance
v pin wai_pin_vectors ../pin-conformance
v signers wai_signer_vectors ../signer-conformance
v int-payload wai_int_payload_vectors ../int-payload-conformance
v staged wai_staged_vectors ../staged-conformance
v http wai_http_vectors ../http-conformance
v staged-measure wai_stage_measure ../staged-measure-conformance
v telemetry wai_telemetry ../telemetry-conformance
v pq-signatures wai_pq_vectors ../pq-conformance
# wai-quantum and the quantum corpus under wasm32-wasip2, run by wasmtime. On wasm32
# usize is 32 bits, so arithmetic that cannot overflow on a 64-bit host can there: a
# section's offset plus its length, a capacity reserved from a count a file claims, a
# shift by a qubit count. The builds are debug builds, so overflow checks are on and
# such an overflow panics instead of wrapping. Three steps:
# 1. tests/bit_identity.rs, which pins one result of each f64 layer, so the wasm32
# build must give the bits every native leg gives;
# 2. the library's unit tests in the modules that hold the circuit core, its
# container, its JSON reader and its pins (quantum, ijson, receipt_pins,
# quantum_fabric, quantum_source, quantum_channel, quantum_qudit, quantum_receipt),
# each required to have run, and each test of the fabric's groundwork for
# accelerator members required by name (the WebGPU member itself has no wasm32-
# wasip2 build; wai-quantum-webgpu.yml checks that the feature is inert there);
# 3. wai_quantum_vectors verify over all four trees of quantum-conformance/ (both
# capabilities, the reject corpus and the accept corpus), the same check the matrix
# above runs natively.
# One leg: wasm32 is the same machine on every host. Linux, so it does not queue on the
# single macOS runner.
# The fast integer kernels on the AVX-512 host (labelled linux-amd), whose processor runs
# every x86_64 kernel set (wide, AVX2, AVX2 with VNNI, AVX-512, AVX-512 with VNNI), none
# of whose AVX-512 kernels the other legs' processors run. The same tests as the kernel
# steps of cargo-classes, in both profiles; the runner declares its sets, and a set the
# tests did not find fails the job instead of passing as a skip.
int-kernels-amd:
name: fast integer kernels, every x86_64 kernel set (AVX-512 silicon)
needs: relevant
if: needs.relevant.outputs.run == 'true'
runs-on: linux-amd
timeout-minutes: 90
env:
CARGO_PROFILE_DEV_DEBUG: '0'
CARGO_BUILD_JOBS: '12'
steps:
- name: Fetch the source
shell: bash
run: |
set -euo pipefail
want="${{ github.event.pull_request.head.sha || github.sha }}"
rm -rf src && mkdir src && cd src
git init -q
# Fetch the commit itself, not the ref. The host names its own route to the
# forge (WAI_FORGE_URL).
git fetch -q --depth 1 "${WAI_FORGE_URL:-http://100.64.224.0:3400}/Transaction-Science/open-standards.git" "$want"
git checkout -q FETCH_HEAD
got="$(git rev-parse HEAD)"
[ "$got" = "$want" ] || { echo "::error::fetched $got, not $want"; exit 1; }
- name: Fast integer kernels ≡ reference kernels, every kernel set, both profiles
shell: bash
working-directory: src/wai/wai-rs
run: |
set -euo pipefail
export PATH="$HOME/.cargo/bin:$PATH"
export CARGO_TARGET_DIR="$HOME/hw-target/wai-rs-int-kernels"
# The sets this host's processor runs, declared here (or by the runner); the
# library test the_kernel_sets_found_are_the_declared_ones fails on any other.
export WAI_INT_ISAS_EXPECT="${WAI_INT_AMD_ISAS_EXPECT:-wide,avx2,avx2-vnni,avx512,avx512-vnni}"
F=neural_int,video_int,audio_int,world_int,splat_int,generate,score,staged,stage_measure,legacy_int,i32_forms
T="--test int_kernels_vectors --test int_kernels_geometry --test int_synth_ops --test int_splat_ops --test int_audio_ops --test int_hyper_ops --test int_mlicpp_ops --test int_world_ops --test jpegai_ops --test jpegai_nets_ops --test int_video_ops --test wir1_ops --test int_ops_conformance"
for p in "" --release; do
nice -n 10 cargo test --locked $p --no-default-features --features $F --lib $T
done
quantum-wasip2:
needs: relevant
if: needs.relevant.outputs.run == 'true'
name: quantum core and corpus under wasm32-wasip2 (wasmtime)
runs-on: linux
# The fabric's planner test runs fabric-v1 under every planner configuration in a
# debug wasm build, several minutes on its own; the timeout leaves it room rather
# than the test being skipped on wasm32.
timeout-minutes: 90
steps:
- uses: actions/checkout@v5
- name: Install Rust 1.98.0 with the wasm32-wasip2 target
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 target add --toolchain 1.98.0 wasm32-wasip2
echo "$HOME/.cargo/bin" >> "$GITHUB_PATH"
# The release binary, pinned by version and SHA-256, rather than a build from source.
- name: Install wasmtime 49.0.2
shell: bash
run: |
set -euo pipefail
[ "$(uname -m)" = x86_64 ] || { echo "::error::the pinned wasmtime archive is x86_64; this host is $(uname -m)"; exit 1; }
if ! command -v xz >/dev/null 2>&1; then
SUDO=""; [ "$(id -u)" -ne 0 ] && SUDO="sudo"
$SUDO apt-get update -qq
$SUDO apt-get install -y -qq xz-utils
fi
v=49.0.2
f="wasmtime-v$v-x86_64-linux.tar.xz"
curl --proto '=https' --tlsv1.2 -sSfL -o "$RUNNER_TEMP/$f" \
"https://github.com/bytecodealliance/wasmtime/releases/download/v$v/$f"
echo "a4d6e9e3a5a60f527cf7793d674c48930c80c2e8977995b8a275cad3254b9322 $RUNNER_TEMP/$f" | sha256sum -c -
tar -xJf "$RUNNER_TEMP/$f" -C "$RUNNER_TEMP"
echo "$RUNNER_TEMP/wasmtime-v$v-x86_64-linux" >> "$GITHUB_PATH"
- name: tests/bit_identity.rs under wasmtime
working-directory: wai/wai-quantum
env:
CARGO_TARGET_WASM32_WASIP2_RUNNER: wasmtime
run: cargo test --locked --target wasm32-wasip2 --features full --test bit_identity
# The filters are module paths, so a module that is renamed or loses its tests would
# leave its filter matching nothing and the run passing; the loop fails the step
# unless every module had a test that passed.
- name: The circuit core's unit tests under wasmtime
shell: bash
working-directory: wai/wai-quantum
env:
CARGO_TARGET_WASM32_WASIP2_RUNNER: wasmtime
run: |
set -euo pipefail
mods="quantum ijson receipt_pins quantum_fabric quantum_source quantum_channel quantum_qudit quantum_receipt engine::synth engine::compile engine::estimate"
filters=()
for m in $mods; do filters+=("$m::"); done
cargo test --locked --target wasm32-wasip2 --features full --lib -- "${filters[@]}" 2>&1 \
| tee "$RUNNER_TEMP/wasip2-lib.log"
for m in $mods; do
grep -q "^test $m::.* \.\.\. ok$" "$RUNNER_TEMP/wasip2-lib.log" \
|| { echo "::error::no test of $m ran"; exit 1; }
done
# The fabric's groundwork for accelerator members (certification one case at
# a time, the fabric-v1 corpus and its pins, the 32-bit-lane words and their
# range guard, run meters, metered calibration, placement for a run and the
# fabric's fallback, the program a member runs in every planner configuration,
# the WGSL kernels' host layouts, member ids and mutants), each by name: a module
# filter is satisfied by any one test of the module, so a test dropped or
# compiled out on wasm32 would otherwise go unnoticed.
for t in quantum_fabric::tests::certification_is_certify \
quantum_fabric::tests::fxmul_wide_is_the_exact_product \
quantum_fabric::tests::apply_words_is_apply \
quantum_fabric::tests::malformed_words_are_refused \
quantum_fabric::tests::z_on_the_most_negative_lane_is_flagged \
quantum_fabric::tests::simulate_checked_is_simulate \
quantum_fabric::tests::a_rounded_product_is_never_negated \
quantum_fabric::tests::the_guard_horizon_is_pinned \
quantum_fabric::tests::valid_circuits_stay_in_lanes \
quantum_fabric::tests::fabric_corpus_starts_with_random_v1 \
quantum_fabric::tests::the_fabric_v1_corpus_of_each_gateset_is_pinned \
quantum_fabric::tests::fabric_v1_covers_every_dispatch_shape \
quantum_fabric::tests::gate_words_are_the_table \
quantum_fabric::tests::a_meter_reading_is_labelled_or_dropped \
quantum_fabric::tests::a_placement_figure_is_a_measurement_or_nothing \
quantum_fabric::tests::figures_go_on_both_members_or_neither \
quantum_fabric::tests::place_for_sends_small_runs_to_the_cpu_and_large_ones_to_the_gpu \
quantum_fabric::tests::the_fabric_falls_back_and_names_the_member_that_produced_the_result \
quantum_fabric::tests::a_metered_fabric_run_seals_its_reading \
quantum_fabric::tests::a_calibration_gives_the_cpu_reference_its_figure \
quantum_fabric::plan::tests::execute_is_the_native_simulator \
quantum_fabric::plan::tests::every_configuration_is_the_native_simulator \
quantum_fabric::plan::tests::long_circuits_tile_as_they_run_gate_by_gate \
quantum_fabric::plan::tests::tiles_are_exact_on_any_words \
quantum_fabric::plan::tests::tiles_cover_every_path \
quantum_fabric::plan::tests::the_v1_tail_phases_are_not_skipped \
quantum_fabric::plan::tests::malformed_programs_are_refused \
quantum_fabric::wgsl::tests::implementation_id_is_pinned \
quantum_fabric::wgsl::tests::gate_record_layout \
quantum_fabric::wgsl::tests::grids_cover_every_item_once \
quantum_fabric::wgsl::tests::the_index_map_is_a_bijection \
quantum_fabric::wgsl::tests::member_ids_are_pinned \
quantum_fabric::wgsl::tests::the_cpu_reference_is_placed_first_when_nothing_is_metered \
quantum_fabric::wgsl::tests::mutants_apply_once \
quantum_fabric::wgsl::tests::mutant_witnesses_exist \
quantum_fabric::wgsl::tests::placement_breaks_an_implementation_tie_by_name \
quantum_fabric::wgsl::tests::tile_implementation_id_is_pinned \
quantum_fabric::wgsl::tests::tile_records_layout \
quantum_fabric::wgsl::tests::tile_grids_cover_every_tile_once \
quantum_fabric::wgsl::tests::tile_mutants_apply_once \
quantum_fabric::wgsl::tests::tile_mutant_witnesses_exist; do
grep -q "^test $t \.\.\. ok$" "$RUNNER_TEMP/wasip2-lib.log" \
|| { echo "::error::$t did not run"; exit 1; }
done
# The wai package is built as one codegen unit here. Its lib target is also a cdylib,
# and the wasm linker in Rust 1.98 (LLD 22) can crash with SIGSEGV linking that cdylib:
# the linker keeps the flags of the first object that names the function table, so
# when that object names it without NO_STRIP the table is no garbage-collection root.
# Nothing the cdylib keeps calls through the table, but it does keep function
# addresses, and writing their element segment then dereferences a table that was
# never created. Which object comes first follows the hashed names of the codegen
# units, so an unrelated change to the crate, or a different checkout path, can bring
# the crash on or off. As one unit, wai's object comes first and takes function
# addresses, so it names the table with NO_STRIP. LLD 23 keeps NO_STRIP from any
# object. The units change how the crate is split for code generation, not what the
# program computes.
- name: wai_quantum_vectors verify under wasmtime
shell: bash
working-directory: wai/wai-rs
run: |
set -euo pipefail
cargo build --locked --target wasm32-wasip2 --no-default-features --features quantum --bin wai_quantum_vectors \
--config 'profile.dev.package.wai.codegen-units=1'
wasmtime run --dir ../quantum-conformance::/corpus \
target/wasm32-wasip2/debug/wai_quantum_vectors.wasm verify /corpus
# The face generator under wasm32-wasip2, run by wasmtime (extensions/avatars.md §7.8):
# wai_avatar_face_vectors verify, built for wasm32, regenerates every file of
# live-conformance/avatar-face from its seeds and inputs, every frame through the integer
# operator set's interpreter compiled to wasm32, and requires the committed bytes, which a
# native build wrote: the frames are the same on wasm32 as on the CPU. One leg: wasm32 is
# the same machine on every host. Linux, so it does not queue on the single macOS runner.
avatar-face-wasip2:
needs: relevant
if: needs.relevant.outputs.run == 'true'
name: faces from keypoints under wasm32-wasip2 (wasmtime)
runs-on: linux
timeout-minutes: 60
steps:
- uses: actions/checkout@v5
- name: Install Rust 1.98.0 with the wasm32-wasip2 target
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 target add --toolchain 1.98.0 wasm32-wasip2
echo "$HOME/.cargo/bin" >> "$GITHUB_PATH"
# The release binary, pinned by version and SHA-256, rather than a build from source.
- name: Install wasmtime 49.0.2
shell: bash
run: |
set -euo pipefail
[ "$(uname -m)" = x86_64 ] || { echo "::error::the pinned wasmtime archive is x86_64; this host is $(uname -m)"; exit 1; }
if ! command -v xz >/dev/null 2>&1; then
SUDO=""; [ "$(id -u)" -ne 0 ] && SUDO="sudo"
$SUDO apt-get update -qq
$SUDO apt-get install -y -qq xz-utils
fi
v=49.0.2
f="wasmtime-v$v-x86_64-linux.tar.xz"
curl --proto '=https' --tlsv1.2 -sSfL -o "$RUNNER_TEMP/$f" \
"https://github.com/bytecodealliance/wasmtime/releases/download/v$v/$f"
echo "a4d6e9e3a5a60f527cf7793d674c48930c80c2e8977995b8a275cad3254b9322 $RUNNER_TEMP/$f" | sha256sum -c -
tar -xJf "$RUNNER_TEMP/$f" -C "$RUNNER_TEMP"
echo "$RUNNER_TEMP/wasmtime-v$v-x86_64-linux" >> "$GITHUB_PATH"
# One codegen unit for the wai package: see the quantum job's last step for the LLD 22
# cdylib crash this avoids.
- name: wai_avatar_face_vectors verify under wasmtime
shell: bash
working-directory: wai/wai-rs
run: |
set -euo pipefail
cargo build --locked --release --target wasm32-wasip2 --no-default-features --features avatar_face --bin wai_avatar_face_vectors \
--config 'profile.release.package.wai.codegen-units=1'
t="${CARGO_TARGET_DIR:-target}"
wasmtime run --dir ../live-conformance/avatar-face::/corpus \
"$t/wasm32-wasip2/release/wai_avatar_face_vectors.wasm" verify /corpus | tee "$RUNNER_TEMP/face-wasm.log"
[ "$(grep -c '^PASS ' "$RUNNER_TEMP/face-wasm.log")" = 3 ] || { echo "::error::not every check passed under wasm32"; exit 1; }
# The generated v2 vocabulary (wai/vocab/v2.*) is checked as a consumer uses it:
# sample manifests, typed and untyped, WAI1 and WAI2, are expanded through the
# JSON-LD context exactly as written on the wire and validated against the SHACL
# shapes, each with the result it must give (a candidate in any place is
# rejected; a media value no revision lists is accepted). One leg: RDF tooling,
# not arithmetic. The tool versions are pinned.
vocab-shapes:
needs: relevant
if: needs.relevant.outputs.run == 'true'
name: v2 vocabulary · manifests validate as stated
runs-on: linux-arm64
steps:
- uses: actions/checkout@v5
- uses: actions/setup-python@v5
with:
python-version: '3.11'
- name: Install the RDF tools
shell: bash
run: python -m pip install rdflib==7.6.0 PyLD==3.3.0 pyshacl==0.40.1
- name: Sample manifests against vocab/v2.shapes.ttl
shell: bash
run: python wai/vocab/check_shapes.py
# The corpora above are generated and verified by wai-rs, one implementation. These are
# the second implementations, written from the extension text in Python and sharing no
# code with wai-rs: claim_verify.py (every claim vector, the canonical fixture, and the
# bracket arithmetic of energy-measurement §6.2 recomputed with Python's integers),
# differential.py (both verifiers' verdicts on generated inputs the corpus does not hold,
# under a fixed seed, so a run is reproducible), jwp_verify.py (every JWP vector), and
# signer_verify.py (every key-discovery vector and the canonical fixture, with its
# verdicts required to equal wai_signer_vectors' line for line), and
# int_payload_verify.py (the integer payloads and their refusal fixtures), and
# staged_verify.py (the staged-delivery corpus), and http_verify.py (the HTTP delivery
# corpus), and quantum-conformance/tools/referee.py (both quantum-sim capabilities), and
# one verifier for each corpus under live-conformance/, which live-conformance/README.md
# lists beside its directory, extension and generator.
# Each exits non-zero on any failure or any difference, and the step fails with it.
# One platform: what they check is the reading of the text, not the architecture.
independent-verifiers:
needs: relevant
if: needs.relevant.outputs.run == 'true'
name: independent verifiers · claims, JWP, key discovery and integer payloads (Python)
runs-on: linux-arm64
env:
# No debuginfo, for the reason given at cargo-classes: this job ran out of the VM's disk
# mid-link beside two others (#550).
CARGO_PROFILE_DEV_DEBUG: '0'
WAI_FEATURES: key_discovery,http,video_manifest,stage_measure,live_events,live_room,capture_take,live_compose,live_record,timed_text,access_services,live_metering,energy_steering,live_moderation,dred_exact,live_ads,live_provenance,synthesis,synthesis_mark,neural_int,exact_upscale,robustness,ai_usage,contribution,settlement,browser_sink,receipt_claims,takedown,influence,direction,co_performance,age_assurance,bearer_receipts,exploration,co_watch,telemetry_aggregate,exact_tonemap,splat_exact,live_watermark,derive_edge,sink_energy,key_release,stitched_presentation,prior_wire,scene_map,avatar_face,receipt_ledger,stream_audit,fleet,native_sink,platform_encode,remote_desktop,stream_termination,live_world,format_probe,live_messaging,conform_result,revenue_share,opportunity_report,channel_lineup,route_record
WAI_PQ_FEATURES: synthesis,pq_signatures
WAI_RELEASE_FEATURES: dred_exact,synthesis_mark,robustness,avatar_face
steps:
- uses: actions/checkout@v5
- 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"
- uses: actions/setup-python@v5
with:
python-version: '3.11'
# The ad-presentation step runs the browser client's reference producer under Node, whose
# WebCrypto signs with Ed25519.
- uses: actions/setup-node@v4
with:
node-version: '22'
# The verifiers check Ed25519's equation with the `cryptography` package and make the
# rest of jwp-receipts §3.1 step 3 themselves.
- name: Install the Ed25519 library
shell: bash
run: python -m pip install cryptography
# Every wai-rs step below runs with one of the three feature lists this job declares,
# so cargo builds each target once and every later `cargo test` finds it fresh. A step
# selects its tests exactly as before (`--lib <module>::` or `--test <name>`, with its
# filters); only the feature list is shared. Each feature still compiles alone in the
# `features-alone` job.
#
# WAI_FEATURES the union of every step's features but the hybrid signatures'.
# WAI_PQ_FEATURES the hybrid signatures step. `pq_signatures` changes what a build
# without it refuses (pq-signatures §6.3: such a build reads a
# hybrid member as an unknown one), so it stays out of the union
# and every other step keeps testing a build without it.
# WAI_RELEASE_FEATURES the steps that run their tests optimised (`--release`).
#
# Builds of the library that differ in features, or in the dependencies' features,
# write the same file, so each switch between two of them rebuilds it. `cargo build`
# and `cargo test` are two such builds (the dev-dependencies turn on wai-ops' `oracle`
# and serde_json's `preserve_order`), and so are two feature lists. Hence the order:
# the corpus tools the steps run as programs first, as `cargo build` builds them,
# copied to $RUNNER_TEMP/wai-bins/union and $RUNNER_TEMP/wai-bins/pq (the steps run
# those copies); then the union's test build, last, which every step but the hybrid
# signatures' runs; the release build has a directory of its own. The hybrid
# signatures step builds its tests itself, the one other build of the test profile.
#
# The last step's differentials drive wai_claim_vectors' and wai_jwp_vectors'
# `verdicts` modes, and compare wai_signer_vectors' key-discovery verdicts with
# signer_verify.py's. Both builds of the three are copied and both are held to the
# Python verifiers: the union's, which has key_discovery and no pq_signatures, and the
# hybrid signatures', which reads the hybrid members the other refuses.
- name: Build wai-rs once for every step below, and the corpus verifiers it ships
working-directory: wai/wai-rs
shell: bash
run: |
set -euo pipefail
mkdir -p "$RUNNER_TEMP/wai-bins/union" "$RUNNER_TEMP/wai-bins/pq"
cargo build --no-default-features --features "$WAI_FEATURES" \
--bin wai_http_vectors --bin wai_stage_measure --bin wai_browser_sink_vectors \
--bin wai_claim_vectors --bin wai_jwp_vectors --bin wai_signer_vectors \
--bin wai_sink_energy_vectors --bin wai_stitched_presentation \
--bin wai_stream_termination_vectors --bin wai_format_probe --bin wai_conform_result_vectors \
--bin wai_channel_lineup_vectors
for b in wai_http_vectors wai_stage_measure wai_browser_sink_vectors \
wai_claim_vectors wai_jwp_vectors wai_signer_vectors \
wai_sink_energy_vectors wai_stitched_presentation \
wai_stream_termination_vectors wai_format_probe wai_conform_result_vectors \
wai_channel_lineup_vectors; do
cp "${CARGO_TARGET_DIR:-target}/debug/$b" "$RUNNER_TEMP/wai-bins/union/"
done
# Copied before this build replaces target/debug's copies of the three it shares.
cargo build --no-default-features --features "$WAI_PQ_FEATURES" \
--bin wai_pq_vectors --bin wai_claim_vectors --bin wai_jwp_vectors --bin wai_signer_vectors
for b in wai_pq_vectors wai_claim_vectors wai_jwp_vectors wai_signer_vectors; do
cp "${CARGO_TARGET_DIR:-target}/debug/$b" "$RUNNER_TEMP/wai-bins/pq/"
done
cargo test --no-run --no-default-features --features "$WAI_FEATURES" --lib \
--test live_events --test live_room --test capture_take --test live_compose --test live_record \
--test timed_text --test access_services --test live_metering --test energy_steering \
--test live_moderation --test live_ads --test ad_presentation --test live_provenance \
--test synthesis --test exact_upscale --test ai_usage --test contribution --test settlement \
--test browser_sink --test takedown --test influence --test direction --test co_performance \
--test age_assurance --test bearer_receipts --test exploration --test co_watch \
--test telemetry_aggregate --test exact_tonemap --test splat_exact --test live_watermark \
--test derive_edge --test det_cost_bin --test sink_energy --test key_release \
--test stitched_presentation --test prior_wire --test scene_map --test receipt_ledger \
--test stream_audit --test fleet --test native_sink --test platform_encode --test remote_desktop \
--test stream_termination --test live_world --test format_probe --test live_messaging \
--test conform_result --test revenue_share --test opportunity_report --test channel_lineup --test route_record
cargo test --release --no-run --no-default-features --features "$WAI_RELEASE_FEATURES" \
--test dred_exact --test dred_exact_measure --test synthesis_mark --test robustness \
--test avatar_face
# The integer payload corpus's second implementation (int-payload-conformance/README):
# it parses every payload with the extension's rules and check order, converts every
# JSON source independently and requires the committed bytes, decodes the WIV1
# keyframe-0 payloads in full to their sidecars' SHA-256, and checks every refusal
# fixture. Standard library only, so it needs nothing installed.
- name: int_payload_verify.py
working-directory: wai
shell: bash
run: python3 int-payload-conformance/int_payload_verify.py int-payload-conformance
# The determinism-cost record (research/determinism-cost.md): its summary recomputed
# from its readings by a second implementation that shares no code with the tool that
# wrote it (tools/wai_determinism_cost_verify.py, standard library only, run isolated),
# and every figure the research page and determinism-tiers §7 quote from it checked
# against it (each is followed by a `det` marker naming its place in the record). Then
# wai_det_cost, the decoder the record ran, held to the committed int_hyper vector and
# every WIH1 refusal fixture of int-payload-conformance/.
- name: determinism cost · the record, the text quoting it, and wai_det_cost
working-directory: wai
shell: bash
run: |
set -euo pipefail
python3 -I tools/wai_determinism_cost_verify.py research/determinism-cost/record.json \
research/determinism-cost.md extensions/determinism-tiers.md
(cd wai-rs && cargo test --no-default-features --features "$WAI_FEATURES" --test det_cost_bin)
# The staged-delivery corpus's second implementation (staged-conformance/README): it
# replays every case from its stage-0 buffers through its own reading of the
# extension (refines, WIR1, the sink's steps, holds, batches, conflicts, deadlines,
# tiers, stage hashes), decodes the WIV1 keyframe-0, PNG and FLAC bases, explodes the
# WAI2 files, and replays the schedule. Standard library only.
- name: staged_verify.py
working-directory: wai
shell: bash
run: python3 staged-conformance/staged_verify.py staged-conformance
# The HTTP delivery corpus's second implementation (http-conformance/README): the head,
# the head proof (every committed proof rebuilt from the text), response checks, plans,
# selection, the byte-range procedure and its fallback, the codecs union and floor, the
# playlists (read, rendered, held adjacent, the classical master unchanged), playlist
# receipts (WAI's strict Ed25519, _ed25519.py) and the live edge, and the adaptation policies,
# checked first against published BLAKE3 vectors, with the standard library alone;
# and the receipts, key logs, grants files and parameter sets of §8.1–§8.5, through
# http_receipts.py and the corpora's own verifiers of jwp-receipts, which need the
# `cryptography` package installed above (without it those cases fail, never skip).
# Its mutations and the differential against wai-rs run in wai-http.yml's falsify
# job.
- name: http_verify.py
working-directory: wai
shell: bash
run: python3 http-conformance/http_verify.py http-conformance
# Outside the corpus: wai_http_vectors fuzz writes seeded cases (Content-Range values,
# codecs values, #WAI-LAYER lines, manifests and their member types, encryption,
# refines, layers declared against their bases, layers over WAI2 components, objects
# past the first request through a tampering origin; playlists, adjacent pairs,
# published masters, renderings, adaptation states, the integer log and changed
# receipt files; receipt files, indexes, grants files and key logs of §8.1–§8.5,
# whose cases need the `cryptography` package installed above) with wai-rs's
# outcomes, and
# http_verify.py must give every one, a refusal by the same code. It prints each
# family's count of cases and of refusals. Two fixed seeds, so a run is reproducible.
- name: The HTTP differential outside the corpus (wai-rs against http_verify.py)
working-directory: wai
shell: bash
run: |
set -euo pipefail
for seed in 11 12; do
"$RUNNER_TEMP/wai-bins/union/wai_http_vectors" fuzz http-conformance --seed "$seed" --count 400 --out "$RUNNER_TEMP/http-fuzz-$seed.json"
python3 http-conformance/http_verify.py cases "$RUNNER_TEMP/http-fuzz-$seed.json" http-conformance
done
# The staged-measurement corpus's second implementation (staged-measure-conformance/README):
# it counts every object, applies every layer from its base's stage 0, computes the quality
# integers, the output tree, the prefixes, the overhead points and the dedup totals itself,
# and requires its decode to be the fixture tool's and its figures to be goldens.json's.
# Standard library only.
- name: measure_verify.py
working-directory: wai
shell: bash
run: python3 staged-measure-conformance/measure_verify.py staged-measure-conformance
# The delivery simulator's second implementation: Appendix B from the text, every case
# of staged-measure-conformance/sim/ reproduced and its claim checked, with a
# counter-case required for each part of the stall bound a schedule can lose.
- name: sim_verify.py
working-directory: wai
shell: bash
run: python3 staged-measure-conformance/sim_verify.py staged-measure-conformance
# The simulator differentially, outside the corpus: seeded random models (a refinement
# with its own delivery timeout among them) and plans, each simulated by
# wai_stage_measure sim and by sim_verify.py, the refusal or the whole result, the
# stall bound and the longest stall equal, and every stall within the bound where it
# applies. Two fixed seeds, so a run is reproducible.
- name: sim_diff.py, wai_stage_measure against sim_verify.py
working-directory: wai
shell: bash
run: |
set -euo pipefail
for seed in 1 2; do
python3 staged-measure-conformance/sim_diff.py "$RUNNER_TEMP/wai-bins/union/wai_stage_measure" "$seed" 1500
done
# wai.live.events (extensions/live-events.md): the reference module's unit tests and
# tests/live_events.rs (the committed corpus regenerates byte for byte from its fixed
# seeds, wai-rs gives every vector, policy case and binding case its stated outcome,
# the corpus covers every kind and reason, and §9 lists exactly the reference's
# codes); then the corpus's second implementation, live_events_verify.py, written
# from the extension's text and sharing no code with wai-rs, which verifies the same
# cases with WAI's strict Ed25519 (claim-conformance/_ed25519.py) and BLAKE3
# (claim-conformance/_blake3.py), standard library only, run isolated (-I).
- name: live events · wai-rs and live_events_verify.py
working-directory: wai
shell: bash
run: |
set -euo pipefail
(cd wai-rs && cargo test --no-default-features --features "$WAI_FEATURES" --lib live_events::)
(cd wai-rs && cargo test --no-default-features --features "$WAI_FEATURES" --test live_events)
python3 -I live-conformance/live_events_verify.py live-conformance/events
# wai.live.room (extensions/live-rooms.md): the reference module's unit tests and
# tests/live_room.rs (the committed corpus regenerates byte for byte from its fixed
# seeds, wai-rs gives every vector its stated outcome, every reason of §11 refuses a
# vector, and §11 lists exactly the reference's codes); then the corpus's second
# implementation, live_rooms_verify.py, written from the extension's text and sharing
# no code with wai-rs, which verifies every event with live_events_verify.py and every
# signature with WAI's strict Ed25519 (claim-conformance/_ed25519.py), standard
# library only, run isolated (-I).
- name: live rooms · wai-rs and live_rooms_verify.py
working-directory: wai
shell: bash
run: |
set -euo pipefail
(cd wai-rs && cargo test --no-default-features --features "$WAI_FEATURES" --lib live_room::)
(cd wai-rs && cargo test --no-default-features --features "$WAI_FEATURES" --test live_room)
python3 -I live-conformance/live_rooms_verify.py live-conformance/rooms
# wai.capture.take (extensions/capture-binding.md): the reference module's unit tests,
# the output tree's (whose RFC 6962 hash and RFC 9162 consistency proofs the take tree
# reuses), and tests/capture_take.rs (the committed corpus regenerates byte for byte
# from its fixed seeds, wai-rs gives every vector its stated outcome, every reason of
# §12 appears in it, and §12 lists exactly the reference's codes); then the corpus's
# second implementation, capture_take_verify.py, written from the extension's text and
# sharing no code with wai-rs, which verifies each room with live_rooms_verify.py and
# every signature with WAI's strict Ed25519 (claim-conformance/_ed25519.py), and
# requires every mutated copy of the corpus to fail; standard library only, run
# isolated (-I).
- name: capture take · wai-rs and capture_take_verify.py
working-directory: wai
shell: bash
run: |
set -euo pipefail
(cd wai-rs && cargo test --no-default-features --features "$WAI_FEATURES" --lib -- capture_take:: output_tree::)
(cd wai-rs && cargo test --no-default-features --features "$WAI_FEATURES" --test capture_take)
python3 -I live-conformance/capture_take_verify.py live-conformance/takes
# wai.live.compose (extensions/live-compose.md): the reference module's unit tests (the
# layout over every grid of 1 to 64 tiles stays on its canvas with no tile overlapping
# another, the fill modes, the attributes, the mixer) and tests/live_compose.rs (the
# committed corpus regenerates byte for byte from its fixed seeds, wai-rs gives every
# case its stated outcome, every reason of §10 refuses a case, and §10 lists exactly
# the reference's codes); then the corpus's second implementation,
# live_compose_verify.py, written from the extension's text and sharing no code with
# wai-rs, which verifies each room with live_rooms_verify.py, steps through its
# lifecycle replay to each instant itself, gives every layout, mix, descriptor,
# composition and receipt the same outcome rectangle for rectangle and sample for
# sample, and requires every mutated copy of the corpus to fail; standard library
# only, run isolated (-I).
- name: live compose · wai-rs and live_compose_verify.py
working-directory: wai
shell: bash
run: |
set -euo pipefail
(cd wai-rs && cargo test --no-default-features --features "$WAI_FEATURES" --lib live_compose::)
(cd wai-rs && cargo test --no-default-features --features "$WAI_FEATURES" --test live_compose)
python3 -I live-conformance/live_compose_verify.py live-conformance/compose
# wai.live.recording (extensions/live-recording.md): the reference module's unit tests,
# the output tree's (whose range proofs it adds, tested against RFC 9162 §2.1.3.2's
# check), and tests/live_record.rs (the committed corpus regenerates byte for byte from
# its fixed seeds, wai-rs gives every recording and clip its stated outcome, every reason
# of §9 appears in it, every take it says it reuses is capture binding's byte for byte,
# and §9 lists exactly the reference's codes); then the corpus's second implementation,
# live_record_verify.py, written from the extension's text and sharing no code with
# wai-rs, which checks range proofs by the extension's recursion and by RFC 9162
# §2.1.3.2's own algorithm, verifies each take with capture_take_verify.py and every
# signature with WAI's strict Ed25519 (claim-conformance/_ed25519.py), and requires every
# mutated copy of the corpus to fail; standard library only, run isolated (-I).
- name: live recording · wai-rs and live_record_verify.py
working-directory: wai
shell: bash
run: |
set -euo pipefail
(cd wai-rs && cargo test --no-default-features --features "$WAI_FEATURES" --lib -- live_record:: output_tree::)
(cd wai-rs && cargo test --no-default-features --features "$WAI_FEATURES" --test live_record)
python3 -I live-conformance/live_record_verify.py live-conformance/recordings
# wai.text.timed (extensions/timed-text.md): the reference module's unit tests (cue model,
# annotation, WebVTT, IMSC1 and its render-model bound, timelines, disclosure, and the
# 608 encoder and decoder) and tests/timed_text.rs (every file of the committed corpus,
# vectors.json and each expected .vtt, .ttml and .608.hex, regenerates byte for byte
# from its fixed seeds and no other file is there, wai-rs gives every case its stated
# outcome, the corpus covers every 608 code path, and §12 lists exactly the reference's
# codes); then the corpus's second implementation, timed_text_verify.py, written from
# the extension's text and sharing no code with wai-rs, which verifies every event with
# live_events_verify.py, writes every output byte for byte from the text, parses each
# IMSC1 document with xml.etree, and requires every mutated copy of the corpus to fail;
# standard library only, run isolated (-I).
- name: timed text · wai-rs and timed_text_verify.py
working-directory: wai
shell: bash
run: |
set -euo pipefail
(cd wai-rs && cargo test --no-default-features --features "$WAI_FEATURES" --lib timed_text::)
(cd wai-rs && cargo test --no-default-features --features "$WAI_FEATURES" --test timed_text)
python3 -I live-conformance/timed_text_verify.py live-conformance/captions
# wai.access.services (extensions/access-services.md): the reference module's unit tests
# (words, full and prefix alignment with their walk back, signed integers, gains) and
# tests/access_services.rs (vectors.json and each DAPT document regenerate byte for byte
# from their fixed seeds and no other file is there, wai-rs gives every vector and
# document its stated outcome and figures, every reason of §10 refuses a case, and §10
# lists exactly the reference's codes); then the corpus's second implementation,
# access_services_verify.py, written from the extension's text and sharing no code with
# wai-rs, which verifies events and captions with timed_text_verify.py and every record
# with WAI's strict Ed25519 rule, computes every figure and writes every DAPT document
# itself, parses each with xml.etree, reads the extension's reason table, and requires
# every mutated copy of the corpus to fail; standard library only, run isolated (-I).
- name: access services · wai-rs and access_services_verify.py
working-directory: wai
shell: bash
run: |
set -euo pipefail
(cd wai-rs && cargo test --no-default-features --features "$WAI_FEATURES" --lib access_services::)
(cd wai-rs && cargo test --no-default-features --features "$WAI_FEATURES" --test access_services)
python3 -I live-conformance/access_services_verify.py live-conformance/access
# conform-result/1 (extensions/conformance-results.md): the reference module's unit tests
# (a signed record accepted and every member covered, the strict rule's small-order forgery
# refused, the date form, a vector for every reason) and tests/conform_result.rs (the
# committed corpus regenerates byte for byte, wai-rs gives every vector its stated outcome,
# every reason of §5 refuses a vector, §5 lists exactly the reference's codes, and no leaf
# of a record survives a change after signing); then wai_conform_result_vectors verify, and
# the corpus's second implementation, conform_result_verify.py, written from the
# extension's text and sharing no code with wai-rs (WAI's strict Ed25519 rule from
# claim-conformance/_ed25519.py), which reads the extension's reason table; and with each
# check of §4 left out in turn (--skip), the corpus must fail it. Standard library only,
# run isolated (-I).
- name: conformance results · wai-rs and conform_result_verify.py
working-directory: wai
shell: bash
run: |
set -euo pipefail
(cd wai-rs && cargo test --no-default-features --features "$WAI_FEATURES" --lib conform_result::)
(cd wai-rs && cargo test --no-default-features --features "$WAI_FEATURES" --test conform_result)
"$RUNNER_TEMP/wai-bins/union/wai_conform_result_vectors" verify conform-result-conformance
python3 -I conform-result-conformance/conform_result_verify.py conform-result-conformance
for c in duplicates format members signature summary verdict; do
python3 -I conform-result-conformance/conform_result_verify.py --skip "$c" conform-result-conformance | tail -1
done
# wai.live.metering (extensions/live-metering.md): the reference module's unit tests
# (records and ledgers round-trip, the energy rules, the size bound at its limit, a
# total of two classes told from a wrong one, funds rounding, the CMCD event-timeline
# record and the application/cmcd batch, a ledger entry's audit path) and
# tests/live_metering.rs (the committed corpus regenerates byte for byte from its fixed
# seeds and the reference relay's recorded record, wai-rs gives every vector its stated
# outcome, every reason of §9 refuses a vector, the large audience's relay record is the
# lesson's size, and §9 lists exactly the reference's codes); then the corpus's second
# implementation, live_metering_verify.py, written from the extension's text and sharing
# no code with wai-rs, which verifies each room with live_rooms_verify.py, each take with
# capture_take_verify.py and each composition receipt with live_compose_verify.py,
# recomputes every unit, total and grant's consumption itself, and requires every
# mutated copy of the corpus to fail; standard library only, run isolated (-I).
- name: live metering · wai-rs and live_metering_verify.py
working-directory: wai
shell: bash
run: |
set -euo pipefail
(cd wai-rs && cargo test --no-default-features --features "$WAI_FEATURES" --lib live_metering::)
(cd wai-rs && cargo test --no-default-features --features "$WAI_FEATURES" --test live_metering)
python3 -I live-conformance/live_metering_verify.py live-conformance/metering
# wai.live.steering (extensions/energy-steering.md): the reference module's unit tests
# (policies and decisions round-trip and their rules refuse, the window, the request
# reader over HLS, DASH and CMCD, the RFC 9651 parser, exact products at their limits,
# the margin at its boundary, figures compared only within a class, and a pathway with
# no figure never placed first by its rank while one with a figure is within the
# limits) and tests/energy_steering.rs (the committed corpus regenerates byte for byte
# from its fixed seeds, wai-rs gives every request and vector its stated outcome, every
# reason of §10 refuses a vector, and §10 lists exactly the reference's codes); then the
# corpus's second implementation, energy_steering_verify.py, written from the
# extension's text and sharing no code with wai-rs, which reads the room with
# live_rooms_verify.py and the per-hop records with live_metering_verify.py, parses RFC
# 9651 itself, recomputes every report, figure, decision and manifest, and requires
# every mutated copy of the corpus to fail; standard library only, run isolated (-I).
- name: energy steering · wai-rs and energy_steering_verify.py
working-directory: wai
shell: bash
run: |
set -euo pipefail
(cd wai-rs && cargo test --no-default-features --features "$WAI_FEATURES" --lib energy_steering::)
(cd wai-rs && cargo test --no-default-features --features "$WAI_FEATURES" --test energy_steering)
python3 -I live-conformance/energy_steering_verify.py live-conformance/steering
# wai.sink.energy (extensions/sink-energy.md): the reference module's unit tests (a
# bracket summary is its intervals in integers, a round's figure and least declaration
# are energy-measurement §6.2's — checked against energy_report's reference — a round is
# refused by its first broken rule, a row seals its median and covers its spread, a
# segment's bounded window has no count term, the estimators and shares round half up,
# records sign and their identities cover the signature, §8 lists exactly the codes), the
# readers' unit tests (a counter is live only as a live rail advances, an advance crosses
# the wrap; on macOS, the per-process counter reads this process) and
# tests/sink_energy.rs (the committed corpus regenerates byte for byte from its fixed
# seeds, every case gets its stated outcome, every reason of §8 refuses a case, and every
# measured table under tables/ is accepted with its readings and procedure); then the
# corpus's second implementation, sink_energy_verify.py, written from the extension's text
# and sharing no code with wai-rs, which recomputes every round, row, segment and split in
# integers and requires every mutated copy of the corpus to fail; standard library only,
# run isolated (-I). These are the integer checks; the counters themselves are read by
# energy-hardware.yml's sink jobs, on the runners that have them.
- name: sink energy · wai-rs and sink_energy_verify.py
working-directory: wai
shell: bash
run: |
set -euo pipefail
(cd wai-rs && cargo test --no-default-features --features "$WAI_FEATURES" --lib sink_energy::)
(cd wai-rs && cargo test --no-default-features --features "$WAI_FEATURES" --lib sink_meter::)
(cd wai-rs && cargo test --no-default-features --features "$WAI_FEATURES" --test sink_energy)
(cd wai-rs && "$RUNNER_TEMP/wai-bins/union/wai_sink_energy_vectors" verify ../live-conformance/sink-energy)
python3 -I live-conformance/sink_energy_verify.py live-conformance/sink-energy
# wai.live.moderation (extensions/live-moderation.md): the reference module's unit tests
# (policies, statements and notices round-trip and their rules refuse, the export's
# strings and dates, the content types, the states that show an item) and
# tests/live_moderation.rs (every file of the committed corpus, vectors.json and each
# statement-of-reasons export, regenerates byte for byte from its fixed seeds and no
# other file is there, wai-rs gives every room, export and clip its stated outcome, and
# §10 lists exactly the reference's codes, each of which the corpus gives); then the
# corpus's second implementation, live_moderation_verify.py, written from the
# extension's text and sharing no code with wai-rs, which verifies each room with
# live_rooms_verify.py and each clip with live_record_verify.py, writes every export
# byte for byte, reads the extension's category, content-type and reason tables, and
# requires every mutated copy of the corpus to fail; standard library only, run
# isolated (-I).
- name: live moderation · wai-rs and live_moderation_verify.py
working-directory: wai
shell: bash
run: |
set -euo pipefail
(cd wai-rs && cargo test --no-default-features --features "$WAI_FEATURES" --lib live_moderation::)
(cd wai-rs && cargo test --no-default-features --features "$WAI_FEATURES" --test live_moderation)
python3 -I live-conformance/live_moderation_verify.py live-conformance/moderation
# wai.audio.opus.dred.int (extensions/opus-dred.md): first the draft's weights file and
# test vectors, which the corpus names by SHA-256 and does not hold, fetched from the
# draft's locations and checked against its digests (live-conformance/dred/fetch.sh).
# Then the reference module's unit tests (the range decoder against its encoder, the
# extension draft's worked examples, payloads round-trip, weights quantized from their
# bits, the activation tables, the driver on a synthetic set), tests/dred_exact.rs (the
# corpus regenerates byte for byte from its seeds and the weights and no other file is
# there, every payload and case reaches its outcome, §8 lists exactly the module's codes,
# §4 states its digests), and in release tests/dred_exact_measure.rs (every record of the
# draft's test vectors decoded through the profile and through the floating-point
# network: the profile passes the draft's feature test, and §6's table is what it
# measures). Then the corpus's second implementation, dred_verify.py, written from the
# extension's text and sharing no code with wai-rs, which recomputes every outcome,
# digest and row in its own integer arithmetic and requires every mutated copy of the
# corpus to fail; standard library only, run isolated (-I).
- name: opus deep redundancy · wai-rs and dred_verify.py
working-directory: wai
shell: bash
run: |
set -euo pipefail
d="${RUNNER_TEMP:-/tmp}/dred"
bash live-conformance/dred/fetch.sh "$d" vectors
w="$d/dred_unquantized_weights.bin"
(cd wai-rs && cargo test --no-default-features --features "$WAI_FEATURES" --lib dred_exact::)
(cd wai-rs && WAI_DRED_WEIGHTS="$w" cargo test --release --no-default-features --features "$WAI_RELEASE_FEATURES" --test dred_exact)
(cd wai-rs && WAI_DRED_WEIGHTS="$w" WAI_DRED_VECTORS="$d" cargo test --release --no-default-features --features "$WAI_RELEASE_FEATURES" --test dred_exact_measure)
python3 -I live-conformance/dred_verify.py live-conformance/dred "$w"
# wai.live.ads (extensions/live-ads.md): the reference module's unit tests (policies and
# annotations round-trip and their rules refuse, a break's identity, tags, events and
# asset lists written exactly), the break form of wai.video.ssai's receipt (its JSON
# carriage, each of its rules, its strict signature, the stitched form's legacy pin
# unchanged), and tests/live_ads.rs (every file of the committed corpus, vectors.json and
# each room's HLS tags, regenerates byte for byte from its fixed seeds and no other file
# is there, wai-rs gives every room its stated outcome, and §10 lists exactly the
# reference's codes, each of which the corpus gives); then the corpus's second
# implementation, live_ads_verify.py, written from the extension's text and sharing no
# code with wai-rs, which verifies each room with live_rooms_verify.py, writes every tag,
# event and asset list byte for byte, verifies every receipt with WAI's strict Ed25519
# rule and BLAKE3 from claim-conformance, reads the extension's reason table, and
# requires every mutated copy of the corpus to fail; standard library only, run isolated
# (-I).
- name: live ads · wai-rs and live_ads_verify.py
working-directory: wai
shell: bash
run: |
set -euo pipefail
(cd wai-rs && cargo test --no-default-features --features "$WAI_FEATURES" --lib live_ads::)
(cd wai-rs && cargo test --no-default-features --features "$WAI_FEATURES" --lib wai_video_ssai::)
(cd wai-rs && cargo test --no-default-features --features "$WAI_FEATURES" --test live_ads)
python3 -I live-conformance/live_ads_verify.py live-conformance/ads
# The proxy form of wai.video.keys (extensions/key-release.md): the reference module's unit
# tests (the commitment list, the entitlement and the ticket round-trip and their rules
# refuse, each check of the decision in its order, offline licences and renewals, each own
# rule of the receipt, its strict signature, the CPIX reader and the derivation of a list
# from a CPIX document), form 1's unit tests (its legacy pin unchanged), and
# tests/key_release.rs (every file of the committed corpus regenerates byte for byte from
# its fixed seeds and no other file is there, every log gets its stated outcome, and the
# extension's tables are the reference's codes); then the corpus's second implementation,
# key_release_verify.py, written from the extension's text and sharing no code with wai-rs,
# which reads the extension's tables, derives every list from its CPIX document with the
# standard library's XML parser, recomputes every decision of every log, verifies every
# signature with WAI's strict Ed25519 rule and BLAKE3 from claim-conformance, and requires
# every mutated copy of the corpus to fail; standard library only, run isolated (-I).
- name: key release · wai-rs and key_release_verify.py
working-directory: wai
shell: bash
run: |
set -euo pipefail
(cd wai-rs && cargo test --no-default-features --features "$WAI_FEATURES" --lib key_release::)
(cd wai-rs && cargo test --no-default-features --features "$WAI_FEATURES" --lib wai_video_keys::)
(cd wai-rs && cargo test --no-default-features --features "$WAI_FEATURES" --test key_release)
python3 -I live-conformance/key_release_verify.py live-conformance/keys
# wai.live.ad_presentation (extensions/ad-presentation.md): the reference module's unit
# tests (claims round-trip and their rules refuse, the quartile, the qualifying run, the
# touched objects, a policy's presentation fields, RFC 9577's TokenChallenge) and
# tests/ad_presentation.rs (every file of the committed corpus regenerates byte for byte
# from its fixed seeds and no other file is there, RFC 9578's own token verifies under its
# key, wai-rs gives every room its outcome and every claim its verdict, and §11 lists
# exactly the reference's codes); then the corpus's second implementation,
# ad_presentation_verify.py, written from the extension's text and sharing no code with
# wai-rs, which verifies each room with live_ads_verify.py, judges every claim and its
# RSASSA-PSS itself, requires every mutated copy of the corpus to fail and catches each of
# its own checks dropped; standard library only, run isolated (-I). Last, the browser
# client's reference producer (joule-moq-web/web/ads), which records observation
# sequences into spans and writes and signs the corpus's claims from them, byte for byte.
- name: ad presentation · wai-rs, ad_presentation_verify.py and the reference producer
working-directory: wai
shell: bash
run: |
set -euo pipefail
(cd wai-rs && cargo test --no-default-features --features "$WAI_FEATURES" --lib live_ads::presentation::)
(cd wai-rs && cargo test --no-default-features --features "$WAI_FEATURES" --test ad_presentation)
python3 -I live-conformance/ad_presentation_verify.py live-conformance/presentation
node --test ../joule-code/joule-code-rs/crates/joule-moq-web/web/ads/presentation.test.mjs
# wai.video.stitched_presentation (extensions/stitched-presentation.md): the reference
# module's unit tests (claims and pod-input records round-trip and their rules refuse,
# markers' bodies, a CPM price scaled to one impression, the XML subset) and the
# live-compose ad frames' (a squeeze's window and L tile the canvas, a double box's
# boxes), and tests/stitched_presentation.rs (every file of the committed corpus
# regenerates byte for byte from its fixed seeds and no other file is there, wai-rs gives
# every record, claim and ad its stated facts and every vector its spend by currency, and
# §9 lists exactly the codes the reference adds); then the tool's own check of the corpus
# through its binary; then the corpus's second implementation,
# stitched_presentation_verify.py, written from the extension's text and sharing no code
# with wai-rs, which reads every playlist, asset list, MPD, VAST document, form-1 receipt,
# record and claim itself, requires every mutated copy of the corpus to fail and catches
# each of its own checks dropped; standard library only, run isolated (-I). Last, the
# browser client's stitched producer (joule-moq-web/web/ads/stitched.js), which reads the
# markers from the corpus's manifests, measures an ad's region, and writes and signs the
# corpus's claims, byte for byte.
- name: stitched presentation · wai-rs, stitched_presentation_verify.py and the reference producer
working-directory: wai
shell: bash
run: |
set -euo pipefail
(cd wai-rs && cargo test --no-default-features --features "$WAI_FEATURES" --lib stitched_presentation::)
(cd wai-rs && cargo test --no-default-features --features "$WAI_FEATURES" --lib live_compose::layout::frame_tests)
(cd wai-rs && cargo test --no-default-features --features "$WAI_FEATURES" --test stitched_presentation)
(cd wai-rs && "$RUNNER_TEMP/wai-bins/union/wai_stitched_presentation" vectors verify ../live-conformance/stitched)
python3 -I live-conformance/stitched_presentation_verify.py live-conformance/stitched
node --test ../joule-code/joule-code-rs/crates/joule-moq-web/web/ads/stitched.test.mjs
# wai.video.lineup (extensions/channel-lineup.md): the reference module's unit tests (times,
# the document type declaration, the reasons) and tests/channel_lineup.rs (every file of the
# committed corpus regenerates byte for byte from its fixed seeds, and no other file is
# there; wai-rs gives every import and every verification its outcome; §10 lists exactly
# the reference's codes; §9's commands, run as the text writes them through `wai`, yield
# the corpus's receipt, lineup, cues and guides, and a refusal is its reason with exit 1);
# then the corpus's second implementation, channel_lineup_verify.py, written from the
# extension's text and sharing no code with wai-rs, which reimports every vector, requires
# every outcome and fact, and requires every mutated copy of the corpus to fail and every
# check it drops to be caught.
- name: channel lineup · wai-rs and channel_lineup_verify.py
working-directory: wai
shell: bash
run: |
set -euo pipefail
(cd wai-rs && cargo test --no-default-features --features "$WAI_FEATURES" --lib channel_lineup::)
(cd wai-rs && cargo test --no-default-features --features "$WAI_FEATURES" --test channel_lineup)
(cd wai-rs && "$RUNNER_TEMP/wai-bins/union/wai_channel_lineup_vectors" verify ../live-conformance/channels)
python3 -I live-conformance/channel_lineup_verify.py live-conformance/channels
# wai.live.provenance (extensions/live-provenance.md): the reference module's unit tests
# (boxes, chunks, emsg and the BMFF hash; the JUMBF store; COSE_Sign1 and the OKP key;
# certificates written and read, their profile and chain; identifiers, track renderings,
# dates and the compositor's source type) and tests/live_provenance.rs (every file of the
# committed corpus regenerates byte for byte from its fixed seeds and the packaging
# corpus's AV1 floor, and no other file is there; wai-rs gives every vector its stated
# outcome; every reason of §12 refuses a vector; §12 lists exactly the reference's codes
# with the two C2PA codes it reports); then the corpus's second implementation,
# c2pa_live_verify.py, written from the extension's text and sharing no code with
# wai-rs, which reads CBOR, ISO BMFF, JUMBF, COSE and X.509 DER itself, verifies every
# signature with WAI's strict Ed25519 rule and every receipt with BLAKE3 from
# claim-conformance, reads the extension's reason table, and requires every mutated copy
# of a good vector to be refused; standard library only, run isolated (-I).
- name: live provenance · wai-rs and c2pa_live_verify.py
working-directory: wai
shell: bash
run: |
set -euo pipefail
(cd wai-rs && cargo test --no-default-features --features "$WAI_FEATURES" --lib live_provenance::)
(cd wai-rs && cargo test --no-default-features --features "$WAI_FEATURES" --test live_provenance)
python3 -I live-conformance/c2pa_live_verify.py live-conformance/c2pa-live
# wai.media.synthesis (extensions/synthesis.md): the reference module's unit tests (the
# pinned derivations by their rules, the class lattice, a generator's envelope) and
# tests/synthesis.rs (the committed corpus regenerates byte for byte from its fixed seeds
# and no other file is there, wai-rs gives every case its stated outcome and statements,
# §12 lists exactly the reference's codes, each of which the corpus gives, and §10.2's
# table pins exactly the reference's icons); then the corpus's second implementation,
# synthesis_verify.py, written from the extension's text and sharing no code with wai-rs,
# which runs the pinned derivations and writes each digital source type and C2PA
# statement itself, verifies each room with live_rooms_verify.py and every record with
# WAI's strict Ed25519 rule and BLAKE3 from claim-conformance, reads the extension's icon
# and reason tables, and requires every mutated copy of the corpus to fail; standard
# library only, run isolated (-I).
- name: synthesis provenance · wai-rs and synthesis_verify.py
working-directory: wai
shell: bash
run: |
set -euo pipefail
(cd wai-rs && cargo test --no-default-features --features "$WAI_FEATURES" --lib synthesis::)
(cd wai-rs && cargo test --no-default-features --features "$WAI_FEATURES" --test synthesis)
python3 -I live-conformance/synthesis_verify.py live-conformance/synthesis
# The registered watermark schemes wai-mark:tent64 and wai-mark:tent64s
# (extensions/synthesis.md §7.4 to §7.9): the reference's unit tests (the code corrects 29
# errors and its generator is the definition's, the layouts, the embedding and the
# detector in every orientation, the tiled detector's exact autocorrelation and its
# recovery from a crop and a rotation, the battery's resampling, rotation and keyframe),
# then tests/synthesis_mark.rs in release, since it embeds and attacks every picture of
# the measurement sets under both schemes (every file of live-conformance/synthesis-mark/
# regenerates byte for byte, both measurements among them, and no other file is there;
# every embedding, detection and case gets what it states; the extension's definitions,
# generator polynomial and shuffles are the reference's; §7.5.8 and §7.9.7 claim only
# attacks the measurements show survived, and §7.5.6's and §7.9.5's figures are the
# measurements'); then the second implementation, synthesis_mark_verify.py with
# _wai_mark.py, written from the extension's text and sharing no code with wai-rs, which
# embeds, detects and decodes itself, both stages of the tiled detector among them, runs
# the battery's picture attacks, derives the frames the vectors name, verifies every case
# with synthesis_verify.py, mutates copies of the corpus and weakens its own verifier in
# turn; standard library only, run isolated (-I).
- name: synthesis watermark · wai-rs and synthesis_mark_verify.py
working-directory: wai
shell: bash
run: |
set -euo pipefail
(cd wai-rs && cargo test --no-default-features --features "$WAI_FEATURES" --lib -- synthesis::mark synthesis_mark::)
(cd wai-rs && cargo test --release --no-default-features --features "$WAI_RELEASE_FEATURES" --test synthesis_mark)
python3 -I live-conformance/synthesis_mark_verify.py live-conformance/synthesis-mark
# wai.media.upscale (extensions/exact-upscale.md): the integer super-resolution
# derivations' unit tests (the wai-ops/1 graph against the arithmetic of §3.2 written out
# loop by loop, on random priors and pictures; a prior with no detail is the pinned
# upscale; sr4 is sr2 twice; a prior that breaks §3.1 refused in its order; a picture past
# the caps refused), the module's unit tests (the pixel counts of §6.3, a residual within
# half its step), and tests/exact_upscale.rs (the committed corpus regenerates byte for
# byte from its fixed seeds and its two pinned trained priors, and no other file is there;
# wai-rs gives every case its stated outcome and statements; §8 lists exactly the
# reference's codes, each of which the corpus gives; sha256.json names every accepted
# output); then the corpus's second implementation, upscale_verify.py, written from the
# extension's text and sharing no code with wai-rs, which runs the derivations with
# _int_sr.py, verifies the claims with synthesis_verify.py and the residuals with
# staged_verify.py, and requires every mutated copy of the corpus to fail; standard
# library only, run isolated (-I).
- name: exact upscale · wai-rs and upscale_verify.py
working-directory: wai
shell: bash
run: |
set -euo pipefail
(cd wai-rs && cargo test --no-default-features --features "$WAI_FEATURES" --lib int_sr::)
(cd wai-rs && cargo test --no-default-features --features "$WAI_FEATURES" --lib exact_upscale::)
(cd wai-rs && cargo test --no-default-features --features "$WAI_FEATURES" --test exact_upscale)
python3 -I live-conformance/upscale_verify.py live-conformance/upscale
# Robustness evidence for soft bindings (extensions/robustness-evidence.md): the
# reference's unit tests (gamma is the rounded power, rates are exact and reduced, every
# attack of synthesis §7.5.7's battery is a transform that gives its bytes, parameters
# outside their ranges are refused), then tests/robustness.rs in release, since
# regenerating the corpus runs the harness over the measurement sets of synthesis §7.5.8
# (every file of live-conformance/robustness/ regenerates byte for byte and no other file
# is there; every case gets what it states; §12 lists exactly the reference's codes and
# the corpus refuses a case for each; §4 registers exactly the reference's transforms;
# the tent64 records' tables are the synthesis corpus's battery.json; the tent64 claim is
# synthesis §7.5.8's list; jwp-receipts §3.1 lists the span reasons); then the second
# implementation, robustness_verify.py with _wai_mark.py, written from the extension's
# text and sharing no code with wai-rs, which reruns the conformance record's battery end
# to end and requires the same table, checks the tent64 records against battery.json and
# the claim against synthesis §7.5.8, mutates copies of the corpus and weakens its own
# verifier in turn; standard library only, run isolated (-I).
- name: robustness evidence · wai-rs and robustness_verify.py
working-directory: wai
shell: bash
run: |
set -euo pipefail
(cd wai-rs && cargo test --no-default-features --features "$WAI_FEATURES" --lib robustness::)
(cd wai-rs && cargo test --release --no-default-features --features "$WAI_RELEASE_FEATURES" --test robustness)
python3 -I live-conformance/robustness_verify.py live-conformance/robustness
# Tensor files as prior forms (extensions/prior-carriage.md §9 to §14): the module's unit
# tests (each layout read strictly and written canonically, the arithmetic coder's integers
# round-tripping and a damaged payload caught, the profile's checks in their order, both
# bindings through every form) and tests/prior_wire.rs (the committed corpus regenerates
# byte for byte from its pinned native artifacts; §13 lists exactly the reference's codes;
# every corpus prior in every form loads to its native bytes, and the two trained WSR1
# priors give the same upscaled picture as their native files); then the corpus's second
# implementation, prior_forms_verify.py, written from the extension's text and sharing no
# code with wai-rs, which also requires every byte-flipped copy of an accepted file to be
# caught; standard library only, run isolated (-I).
- name: prior forms · wai-rs and prior_forms_verify.py
working-directory: wai
shell: bash
run: |
set -euo pipefail
(cd wai-rs && cargo test --no-default-features --features "$WAI_FEATURES" --lib -- prior_wire:: strict_json:: codecs::prior_form)
(cd wai-rs && cargo test --no-default-features --features "$WAI_FEATURES" --test prior_wire)
python3 -I live-conformance/prior_forms_verify.py live-conformance/prior-forms
# Scene carriage (extensions/scene-carriage.md): the module's unit tests (the conversions
# and spellings of §3 against fixed values, the containers an import builds equal to the
# ones wai-rs's world and audio-scene modules write, base64 and the USD subset's reader)
# and tests/scene_map.rs (the committed corpus regenerates byte for byte: every bundle
# written as glTF and USD and read back, every refusal reached; §8 lists exactly the
# reference's codes); then the corpus's second implementation, scene_verify.py, written
# from the extension's text and sharing no code with wai-rs, which also requires every
# byte-flipped copy of an exported document to be caught; standard library only, run
# isolated (-I).
- name: scene carriage · wai-rs and scene_verify.py
working-directory: wai
shell: bash
run: |
set -euo pipefail
(cd wai-rs && cargo test --no-default-features --features "$WAI_FEATURES" --lib -- scene_map:: strict_json::)
(cd wai-rs && cargo test --no-default-features --features "$WAI_FEATURES" --test scene_map)
python3 -I live-conformance/scene_verify.py live-conformance/scene
# wai.avatar.face (extensions/avatars.md §6 to §13): the module's unit tests (the
# generator's wai-ops/1 graph against §7.6's arithmetic written out loop by loop; the warp
# at rest is the reference; the mask's table; the files read and refused in their order),
# and tests/avatar_face.rs (the committed corpus regenerates byte for byte from its fixed
# seeds and its pinned inputs, and no other file is there; wai-rs gives every form, frame
# and case what it states; §10 lists exactly the reference's codes; §7.9's figures are
# training.json's; the registered generator meets acc64 and not acc32); then the corpus's
# second implementation, avatar_face_verify.py, written from the extension's text and
# sharing no code with wai-rs, which runs the driver and the generator's arithmetic in
# Python's integers, verifies the claims, the log and the label policy with
# synthesis_verify.py, and requires every mutated copy of the corpus to fail; standard
# library only, run isolated (-I).
- name: faces from keypoints · wai-rs and avatar_face_verify.py
working-directory: wai
shell: bash
run: |
set -euo pipefail
(cd wai-rs && cargo test --no-default-features --features "$WAI_FEATURES" --lib avatar_face::)
(cd wai-rs && cargo test --release --no-default-features --features "$WAI_RELEASE_FEATURES" --test avatar_face)
python3 -I live-conformance/avatar_face_verify.py live-conformance/avatar-face
# wai.ai.usage (extensions/ai-usage.md): the reference module's unit tests (RFC 9651's
# Dictionary parser against the vocabulary's examples and the RFC's edges, statements
# read and refused in their steps' order, the precedence rule, HTTP fields compared by
# meaning), the consumption class's body and terms in claim_receipt, and
# tests/ai_usage.rs (vectors.json regenerates byte for byte from its fixed seeds and no
# other file is there, wai-rs gives every statement, object, room, response, catalog,
# claim and gate its stated outcome, §9 lists exactly the reference's codes, each of which
# the corpus gives, and jwp-receipts §3.1 lists the class rules); then the corpus's second
# implementation, ai_usage_verify.py, written from the extension's text and sharing no
# code with wai-rs, which parses Structured Fields, canonical forms, receipts and claims
# itself, reads rooms with live_rooms_verify.py, checks signatures with WAI's strict
# Ed25519 rule and BLAKE3 from claim-conformance, reads the extension's reason table,
# requires every mutated copy of the corpus to fail, and drops each of its own checks in
# turn and requires the corpus to catch the weakened verifier; standard library only, run
# isolated (-I). Last, claim-conformance's own verifier reads every consumption claim of
# the corpus through jwp-receipts §3.1 steps 1 to 4 and requires the stated step and reason.
- name: AI usage · wai-rs and ai_usage_verify.py
working-directory: wai
shell: bash
run: |
set -euo pipefail
(cd wai-rs && cargo test --no-default-features --features "$WAI_FEATURES" --lib ai_usage::)
(cd wai-rs && cargo test --no-default-features --features "$WAI_FEATURES" --lib claim_receipt::consumption::)
(cd wai-rs && cargo test --no-default-features --features "$WAI_FEATURES" --test ai_usage)
python3 -I live-conformance/ai_usage_verify.py live-conformance/usage
python3 -I claim-conformance/claim_verify.py consumption live-conformance/usage/vectors.json
# wai.media.contribution (extensions/contribution.md): the reference module's unit tests
# (every proof of the steps' tree walks to its root, the copying operations follow their
# sample mappings, a map has one encoding) and tests/contribution.rs (the committed corpus
# regenerates byte for byte from its fixed seeds and no other file is there, wai-rs gives
# every case its stated outcome and statements, §11 lists exactly the reference's codes,
# each of which the corpus gives, and the corpus generates with the model file of
# wai.generate.spectral's conformance vector); then the corpus's second implementation,
# contribution_verify.py, written from the extension's text and sharing no code with
# wai-rs, which evaluates every pinned operation, runs the generator in its own arithmetic
# after checking it against the generator's conformance vector, computes every map, share
# and C2PA statement itself, reads origin claims with synthesis_verify.py and every record
# with WAI's strict Ed25519 rule and BLAKE3 from claim-conformance, requires every mutated
# copy of the corpus to fail, and drops each of its own checks in turn and requires the
# corpus to catch the weakened verifier; standard library only, run isolated (-I).
- name: contribution records · wai-rs and contribution_verify.py
working-directory: wai
shell: bash
run: |
set -euo pipefail
(cd wai-rs && cargo test --no-default-features --features "$WAI_FEATURES" --lib contribution::)
(cd wai-rs && cargo test --no-default-features --features "$WAI_FEATURES" --test contribution)
python3 -I live-conformance/contribution_verify.py live-conformance/contribution
# wai.live.contribution (extensions/live-contribution.md): the link records' corpus
# under live-conformance/links/, which joule-moq-ingest's reference generates and its
# own tests check (joule-code-conformance.yml); here its second implementation,
# live_contribution_verify.py, written from the extension's text and sharing no code
# with the reference, reads every part and series itself, checks every signature with
# WAI's strict Ed25519 rule from claim-conformance, requires each vector's stated outcome
# and reason and every reason of §7's last list, requires every mutated copy to be
# refused, and drops each of its own checks in turn and requires the corpus to catch the
# weakened verifier; standard library only, run isolated (-I).
- name: live contribution · live_contribution_verify.py
working-directory: wai
shell: bash
run: |
set -euo pipefail
python3 -I live-conformance/live_contribution_verify.py live-conformance/links
# wai.delivery.settlement (extensions/settlement.md): the reference module's unit tests
# (range proofs over every range around every chunk boundary of objects of many lengths
# against BLAKE3's own root, tampered proofs refused, the group tree of jwp-receipts §2.2,
# records and item lists read and refused, amounts rounded down per line) and
# tests/settlement.rs (vectors.json regenerates byte for byte from its fixed seeds and no
# other file is there, wai-rs gives every statement and range proof its stated outcome, §11
# lists exactly the reference's codes, each of which the corpus gives, beside every code it
# reuses); then the corpus's second implementation, settlement_verify.py, written from the
# extension's text and sharing no code with wai-rs, which verifies range proofs over
# BLAKE3's chunk tree with claim-conformance's BLAKE3, reads rooms, grants and proofs with
# live_rooms_verify.py and per-hop records with live_metering_verify.py, checks signatures
# with WAI's strict Ed25519 rule, recomputes every figure of every statement, reads the
# extension's reason table, requires every mutated copy of the corpus to fail, and drops
# each of its own checks in turn and requires the corpus to catch the weakened verifier;
# standard library only, run isolated (-I).
- name: delivery settlement · wai-rs and settlement_verify.py
working-directory: wai
shell: bash
run: |
set -euo pipefail
(cd wai-rs && cargo test --no-default-features --features "$WAI_FEATURES" --lib settlement::)
(cd wai-rs && cargo test --no-default-features --features "$WAI_FEATURES" --test settlement)
python3 -I live-conformance/settlement_verify.py live-conformance/settlement
# wai.delivery.ledger (extensions/receipt-ledger.md): the reference module's unit tests and
# tests/receipt_ledger.rs (vectors.json regenerates byte for byte from its fixed seeds and
# from the sources it takes from the metering, settlement, ads, presentation, stitched and
# routes corpora and the packs of pack-conformance, and no other file is there; wai-rs gives every vector its
# stated outcome; every reason of §10 and every reused code refuses a vector, and so does
# each source kind's own extension; §10 lists exactly the reference's codes; under a tariff
# of version 3, jobs priced per operation and a chain that bills a job's work once, its
# output's receipt cited again by a re-run, with version 2 billing as before); then the
# corpus's second implementation, receipt_ledger_verify.py, written from the extension's
# text and sharing no code with wai-rs, which verifies each source with that corpus's own
# second implementation (live_metering_verify.py, settlement_verify.py, live_ads_verify.py
# with ad_presentation_verify.py, stitched_presentation_verify.py, pack_verify.py, and for a
# media job route_record_verify.py and _int_motion_receipt.py) and
# reports a stitched stream's statement as that verifier gives it, checks signatures with
# WAI's strict Ed25519 rule, recomputes every line, citation, energy row and report,
# requires every mutated copy of the corpus to fail, and drops each of its own checks in turn and requires
# the corpus to catch the weakened verifier; run isolated (-I), with the `cryptography` package
# installed above for the OER/2 reference verifier that checks a job's hop receipts.
- name: receipt ledger · wai-rs and receipt_ledger_verify.py
working-directory: wai
shell: bash
run: |
set -euo pipefail
(cd wai-rs && cargo test --no-default-features --features "$WAI_FEATURES" --lib receipt_ledger::)
(cd wai-rs && cargo test --no-default-features --features "$WAI_FEATURES" --test receipt_ledger)
python3 -I live-conformance/receipt_ledger_verify.py live-conformance/ledger
# wai.delivery.revenue_share (extensions/revenue-share.md): the reference module's unit tests
# (the largest-remainder division and its ties, the date-time a marker states, the contract's
# and the statement's reading and rules, contracts that overlap) and the channel receipt's
# JSON carriage; tests/revenue_share.rs (vectors.json regenerates byte for byte from its fixed
# seeds and the ledger corpus, and no other file is there; wai-rs gives every vector its
# stated outcome; every reason of §11 and every reused code refuses a vector; §11 lists exactly
# the reference's codes; the worked example, three statements of one month computed and then
# recomputed from the public records alone; the four operations from the command line); then
# the corpus's second implementation, revenue_share_verify.py, written from the extension's
# text and sharing no code with wai-rs, which verifies each ledger document with
# receipt_ledger_verify.py, reads every contract, run, marker and statement itself,
# recomputes every attribution, line, division and citation, requires every mutated copy of
# the corpus to fail, and drops each of its own checks in turn and requires the corpus to
# catch the weakened verifier; standard library only, run isolated (-I).
- name: revenue share · wai-rs and revenue_share_verify.py
working-directory: wai
shell: bash
run: |
set -euo pipefail
(cd wai-rs && cargo test --no-default-features --features "$WAI_FEATURES" --lib revenue_share::)
(cd wai-rs && cargo test --no-default-features --features "$WAI_FEATURES" --lib wai_video_channel::)
(cd wai-rs && cargo test --no-default-features --features "$WAI_FEATURES" --test revenue_share)
python3 -I live-conformance/revenue_share_verify.py live-conformance/share
# wai.delivery.opportunity (extensions/opportunity-report.md): the reference module's unit
# tests (the SCTE 35 subset reader against the standard's sample and damaged sections, the
# reported statement's JSON and CSV forms and dates, the report's and the check's reading and
# rules, the ratios); tests/opportunity_report.rs (vectors.json regenerates byte for byte
# from its fixed seeds and no other file is there; wai-rs gives every vector its stated
# outcome; every reason of §13 and every reused code refuses a vector; §13 lists exactly the
# reference's codes; the worked example, a channel's day whose reported statement
# under-reports one owner's programme, and the check that shows it, recomputed from the
# public records alone); then the corpus's second implementation, opportunity_report_verify.py,
# written from the extension's text and sharing no code with wai-rs, which verifies rooms
# with live_ads_verify.py and contracts, runs and signed statements with
# revenue_share_verify.py, reads every report, check, section and reported statement itself,
# recomputes every break, attribution, line, citation and flag, requires every mutated copy
# of the corpus to fail, and drops each of its own checks in turn and requires the corpus to
# catch the weakened verifier; standard library only, run isolated (-I).
- name: opportunity report · wai-rs and opportunity_report_verify.py
working-directory: wai
shell: bash
run: |
set -euo pipefail
(cd wai-rs && cargo test --no-default-features --features "$WAI_FEATURES" --lib opportunity_report::)
(cd wai-rs && cargo test --no-default-features --features "$WAI_FEATURES" --test opportunity_report)
python3 -I live-conformance/opportunity_report_verify.py live-conformance/opportunity
# wai.delivery.audit (extensions/stream-audit.md): the reference module's unit tests (the
# acknowledgement windows, chains and repeats of §4.2, the origin rule, the report's bytes,
# channel names) and tests/stream_audit.rs (vectors.json regenerates byte for byte from its
# fixed seeds and no other file is there, wai-rs gives every session and report its stated
# outcome, §14 lists exactly the reference's codes, each of which the corpus gives, beside
# every code it borrows); then the corpus's second implementation, stream_audit_verify.py,
# written from the extension's text and sharing no code with wai-rs, which reads
# acknowledgements with settlement_verify.py, claims with ad_presentation_verify.py and logs
# and energy classes with live_metering_verify.py, checks every signature with WAI's strict
# Ed25519 rule, recomputes every report, requires every mutated copy of the corpus to fail,
# and drops each of its own checks in turn and requires the corpus to catch the weakened
# verifier; standard library only, run isolated (-I). The collector and the player
# integration run in wai-audit.yml.
- name: stream audit · wai-rs and stream_audit_verify.py
working-directory: wai
shell: bash
run: |
set -euo pipefail
(cd wai-rs && cargo test --no-default-features --features "$WAI_FEATURES" --lib stream_audit::)
(cd wai-rs && cargo test --no-default-features --features "$WAI_FEATURES" --test stream_audit)
python3 -I live-conformance/stream_audit_verify.py live-conformance/audit
# wai.delivery.fleet (extensions/fleet.md): the reference module's unit tests (the enrolment's
# rules, a summary line split only in the relay's form, a row summed across classes told from
# a wrong one, the four coverages) and tests/fleet.rs (vectors.json regenerates byte for byte
# from its seeds and the metering corpus and no other file is there; wai-rs gives every
# vector its stated outcome; every reason of §10 and every reused code refuses a vector; the
# accepted vectors state measured, unmetered and partial energy as §5.4 does; the week's
# records held as a service holds them sign the corpus's report byte for byte; §10 lists
# exactly the reference's codes); then the corpus's second implementation, fleet_verify.py,
# written from the extension's text and sharing no code with wai-rs, which reads per-hop
# records with live_metering_verify.py, checks every signature with WAI's strict Ed25519
# rule, recomputes every line, row, unmetered count and citation, requires every mutated
# copy of the corpus to fail, and drops each of its own checks in turn and requires the
# corpus to catch the weakened verifier; standard library only, run isolated (-I). The
# service and its smoke checks over HTTP run in wai-fleet.yml.
- name: fleet · wai-rs and fleet_verify.py
working-directory: wai
shell: bash
run: |
set -euo pipefail
(cd wai-rs && cargo test --no-default-features --features "$WAI_FEATURES" --lib fleet::)
(cd wai-rs && cargo test --no-default-features --features "$WAI_FEATURES" --test fleet)
python3 -I live-conformance/fleet_verify.py live-conformance/fleet
# wai.route.record (extensions/route-record.md): the reference module's unit tests (a
# document read strictly and held to the subset, §2's encodings, an estimate past the subset
# unknown, a null ranked last, the expected figures per successful job and when they are
# unknown, the outputs' commitment, §8 listing exactly the reference's codes) and
# tests/route_record.rs (vectors.json regenerates byte for byte from its seeds and no other
# file is there; wai-rs gives every vector its stated outcome; every reason of §8 and every
# reused code refuses a vector; the accepted vectors are §10's, of version 1 and of version 2,
# every limit removing a candidate; a record is bound to each of its documents; `wai route
# verify` prints the outcome and exits by it); then the corpus's second implementation,
# route_record_verify.py, written from the extension's text and sharing no code with wai-rs,
# which checks the router's signature with WAI's strict Ed25519 rule and the hop receipts
# with the OER/2 reference verifier (the `cryptography` package, installed above), computes
# the outputs' commitment with claim-conformance/_blake3.py, recomputes every candidate,
# removal, expected figure, rank, order, decision and attempt, requires every mutated copy
# of the corpus to fail, and drops each of its own checks in turn and requires the corpus to
# catch the weakened verifier; run isolated (-I).
- name: route record · wai-rs and route_record_verify.py
working-directory: wai
shell: bash
run: |
set -euo pipefail
(cd wai-rs && cargo test --no-default-features --features "$WAI_FEATURES" --lib route_record::)
(cd wai-rs && cargo test --no-default-features --features "$WAI_FEATURES" --test route_record)
python3 -I live-conformance/route_record_verify.py live-conformance/routes
# The native sink (extensions/native-sink.md): the reference module's unit tests (dates,
# durations and attribute lists read as a player reads them, origins serialized as RFC 6454
# does, names that state a content hash and names that do not, the acknowledgements
# rebuilt from hashes alone equal to stream-audit's reference, a bundle that verifies and
# one refused for another owner or channel) and tests/native_sink.rs (vectors.json
# regenerates byte for byte from its seeds and no other file is there, every call gets the
# answer it states, §8 lists exactly the reasons the corpus reaches, and every case run
# through the C interface's symbols gets the same answers); then the corpus's second
# implementation, native_sink_verify.py, written from the extension's text and sharing no
# code with wai-rs, which replays every case, reads playlist receipts and their chain with
# http_verify.py, holds every bundle to its own session field by field and verifies it with
# stream_audit_verify.py, requires every mutated copy of the corpus to fail, and drops each
# of its own checks in turn and requires the corpus to catch the weakened verifier;
# standard library only, run isolated (-I). The Swift package runs in wai-sink-swift.yml.
- name: native sink · wai-rs and native_sink_verify.py
working-directory: wai
shell: bash
run: |
set -euo pipefail
(cd wai-rs && cargo test --no-default-features --features "$WAI_FEATURES" --lib native_sink::)
(cd wai-rs && cargo test --no-default-features --features "$WAI_FEATURES" --test native_sink)
python3 -I live-conformance/native_sink_verify.py live-conformance/native-sink
# The browser sink (extensions/browser-sink.md): the reference module's unit tests (the
# registry gate's rows, registered tiers, integers as §5 reads them, a binding's
# canonical form, an answer for an unregistered codec string never read, powerEfficient
# never stated off the user agent's route, the side table's ambiguity) and
# tests/browser_sink.rs (both files of the committed corpus regenerate byte for byte and
# no other file is there, wai-rs gives every case its stated outcome, every reason of
# §11 appears in the corpus and §11 lists exactly the reference's codes, and the chain
# the generator signs by hand verifies under jwp_delivery); wai-live-web's browser
# functions held to the same corpus natively, and its wasm-route decoder verifying,
# decoding and binding every chain object to the published frame digests; then the
# corpus's second implementation, browser_sink_verify.py, written from the extension's
# text and sharing no code with wai-rs, which reads the registry export for each
# capability's class, recomputes every route, evaluation, energy entry, binding, chain
# signature, frame state and side table, changes the answers for unregistered codec
# strings every way and requires the corpus still to pass, and requires every mutated
# copy of the corpus to fail; standard library only, run isolated (-I). The browser's
# own run of it is joule-moq-web.yml's scenario binding.
- name: browser sink · wai-rs, wai-live-web and browser_sink_verify.py
working-directory: wai
shell: bash
run: |
set -euo pipefail
(cd wai-rs && cargo test --no-default-features --features "$WAI_FEATURES" --lib browser_sink::)
(cd wai-rs && cargo test --no-default-features --features "$WAI_FEATURES" --test browser_sink)
(cd wai-rs && "$RUNNER_TEMP/wai-bins/union/wai_browser_sink_vectors" verify ../live-conformance/browser)
(cd wai-live-web && cargo test --locked --features int_video --lib browser_tests)
python3 -I live-conformance/browser_sink_verify.py live-conformance/browser
# wai.media.takedown (extensions/takedown.md): the reference module's unit tests (times,
# clock identifiers, the published registry, the order of subjects, the lower median) and
# tests/takedown.rs (the committed corpus regenerates byte for byte from its fixed seeds
# and no other file is there, wai-rs gives every case its stated outcome and facts and
# every counts entry its rows, §11 lists exactly the reference's codes, each of which the
# corpus gives, and the registry the module carries is registry/takedown-clocks.json);
# then the corpus's second implementation, takedown_verify.py, written from the
# extension's text and sharing no code with wai-rs, which computes every closure, holder,
# purge time, clock verdict and counts row itself, reads derivation records and delivery
# receipts with edge_verify.py, origin claims with synthesis_verify.py, acknowledgements
# with settlement_verify.py and every record with WAI's strict Ed25519 rule and BLAKE3
# from claim-conformance, requires every mutated copy of the corpus to fail, and drops
# each of its own checks in turn and requires the corpus to catch the weakened verifier;
# run isolated (-I). The reference relay's DVR store honours takedowns (§10.1), tested by
# joule-moq-relay's tests/dvr.rs in joule-code-conformance.yml.
- name: takedown · wai-rs and takedown_verify.py
working-directory: wai
shell: bash
run: |
set -euo pipefail
(cd wai-rs && cargo test --no-default-features --features "$WAI_FEATURES" --lib takedown::)
(cd wai-rs && cargo test --no-default-features --features "$WAI_FEATURES" --test takedown)
python3 -I live-conformance/takedown_verify.py live-conformance/takedown
# wai.media.influence (extensions/influence.md): the reference module's unit tests (the
# blend keeps its base and its references by weight, the makers' split is whole, an
# estimate mixed into a share is told from another difference) and tests/influence.rs (the
# committed corpus regenerates byte for byte from its fixed seeds and no other file is
# there, wai-rs gives every case, statement and report its stated outcome, every reason of
# §9 and every code it reuses refuses a vector, and §9 lists exactly the reference's codes);
# then the corpus's second implementation, influence_verify.py, written from the
# extension's text and sharing no code with wai-rs, which verifies each session with
# contribution_verify.py, regenerates every conditioned step with that implementation's
# arithmetic of the generator, reads usage statements with ai_usage_verify.py and
# statements with settlement_verify.py, computes every step map, share, attribution line
# and report itself, requires every mutated copy of the corpus to fail, and drops each of
# its own checks in turn and requires the corpus to catch the weakened verifier; standard
# library only, run isolated (-I).
- name: influence attribution · wai-rs and influence_verify.py
working-directory: wai
shell: bash
run: |
set -euo pipefail
(cd wai-rs && cargo test --no-default-features --features "$WAI_FEATURES" --lib influence::)
(cd wai-rs && cargo test --no-default-features --features "$WAI_FEATURES" --test influence)
python3 -I live-conformance/influence_verify.py live-conformance/influence
# wai.media.direction (extensions/direction.md): the reference module's unit tests (the
# interpolations reach both keys and stay between them, the framing measure at its bounds,
# a signed integer's one spelling, the timeline's starts and overlaps, a frame set's one
# encoding) and tests/direction.rs (the committed corpus regenerates byte for byte from its
# fixed seeds and no other file is there, wai-rs gives every case its stated outcome and
# statements, §13 lists exactly the reference's codes, each of which the corpus gives, and
# the corpus generates with the model file of wai.generate.spectral's conformance vector);
# then the corpus's second implementation, direction_verify.py, written from the
# extension's text and sharing no code with wai-rs, which runs the generator in its own
# arithmetic after checking it against the generator's conformance vector, renders every
# frame, interpolates every track, measures every box and writes every statement and C2PA
# statement itself, reads records with synthesis_verify.py's strict JSON reader and every
# signature with WAI's strict Ed25519 rule and BLAKE3 from claim-conformance, requires every
# mutated copy of the corpus to fail, and drops each of its own checks in turn and requires
# the corpus to catch the weakened verifier; standard library only, run isolated (-I).
- name: direction records · wai-rs and direction_verify.py
working-directory: wai
shell: bash
run: |
set -euo pipefail
(cd wai-rs && cargo test --no-default-features --features "$WAI_FEATURES" --lib direction::)
(cd wai-rs && cargo test --no-default-features --features "$WAI_FEATURES" --test direction)
python3 -I live-conformance/direction_verify.py live-conformance/direction
# wai.live.coperformance (extensions/co-performance.md): the reference module's unit tests
# (the policy and every statement round-trip and their rules refuse, the attributes'
# decimal integers, a schedule's turns in bars and microseconds, the symbolic bodies read
# whole) and tests/co_performance.rs (vectors.json regenerates byte for byte from its fixed
# seeds and no other file is there, wai-rs gives every room its stated outcome, and §10
# lists exactly the reference's codes, each of which the corpus gives); then the corpus's
# second implementation, co_performance_verify.py, written from the extension's text and
# sharing no code with wai-rs, which verifies each room with live_rooms_verify.py and every
# signature with WAI's strict Ed25519 rule from claim-conformance, recomputes every intent,
# fidelity statement, turn, floor, commitment, selection and credit, reads the extension's
# reason table, requires every mutated copy of the corpus to fail, and drops each of its
# own checks in turn and requires the corpus to catch the weakened verifier; standard
# library only, run isolated (-I).
- name: co-performance · wai-rs and co_performance_verify.py
working-directory: wai
shell: bash
run: |
set -euo pipefail
(cd wai-rs && cargo test --no-default-features --features "$WAI_FEATURES" --lib co_performance::)
(cd wai-rs && cargo test --no-default-features --features "$WAI_FEATURES" --test co_performance)
python3 -I live-conformance/co_performance_verify.py live-conformance/coperformance
# wai.age.assurance (extensions/age-assurance.md): the reference module's unit tests (the
# pinned AlgorithmIdentifier and RFC 9578's first vector through this module, the
# TokenChallenge read exactly, the suppression floor, the grant attribute `age`, a span's
# coverage) and tests/age_assurance.rs (vectors.json regenerates byte for byte from its
# fixed seeds and no other file is there, wai-rs gives every case its stated outcome, and
# §11 lists exactly the reference's codes, each of which the corpus gives); then the
# corpus's second implementation, age_assurance_verify.py, written from the extension's
# text and sharing no code with wai-rs, which reads every record, writes JCS and verifies
# every token's RSASSA-PSS itself, reads rooms with live_rooms_verify.py, checks signatures
# with WAI's strict Ed25519 rule and BLAKE3 from claim-conformance, reads the extension's
# reason table, requires every mutated copy of the corpus to fail, and drops each of its
# own checks in turn and requires the corpus to catch the weakened verifier; standard
# library only, run isolated (-I).
- name: age assurance · wai-rs and age_assurance_verify.py
working-directory: wai
shell: bash
run: |
set -euo pipefail
(cd wai-rs && cargo test --no-default-features --features "$WAI_FEATURES" --lib age_assurance::)
(cd wai-rs && cargo test --no-default-features --features "$WAI_FEATURES" --test age_assurance)
python3 -I live-conformance/age_assurance_verify.py live-conformance/age
# wai.bearer.receipts (extensions/bearer-receipts.md): the reference module's unit tests
# (the bound, the bitmap rules, the bearer classes, and the corpus reaching every stated
# outcome and failing a changed one) and tests/bearer_receipts.rs (vectors.json
# regenerates byte for byte from its fixed seeds and no other file is there, wai-rs gives
# every case its stated outcome, the cases that carry one receipt on every bearer class
# carry the same bytes with the same object verdicts, §10 lists exactly the reference's
# codes, each of which the corpus gives, and jwp-receipts §3.1 lists the class codes at
# their steps); then the corpus's second implementation, bearer_verify.py, written from
# the extension's text and sharing no code with wai-rs, which verifies groups and objects
# with jwp_verify.py, claims through jwp-receipts §3.1 steps 1-5 with claim_verify.py and
# confirmations with signer_verify.py (each needs the `cryptography` package installed
# above), writes the context checks, the verdict, the bound and offline confirmation
# itself, reads the extension's reason table, requires every mutated copy of the corpus
# to fail, and drops each of its own checks in turn and requires the corpus to catch the
# weakened verifier; run isolated (-I). Last, claim-conformance's own verifier reads every
# transmission and reconciliation claim of the corpus through jwp-receipts §3.1 steps 1
# to 4 and requires the stated step and reason.
- name: bearer receipts · wai-rs and bearer_verify.py
working-directory: wai
shell: bash
run: |
set -euo pipefail
(cd wai-rs && cargo test --no-default-features --features "$WAI_FEATURES" --lib bearer)
(cd wai-rs && cargo test --no-default-features --features "$WAI_FEATURES" --test bearer_receipts)
python3 -I live-conformance/bearer_verify.py live-conformance/bearers
python3 -I claim-conformance/claim_verify.py bearer live-conformance/bearers/vectors.json
# wai.media.exploration (extensions/exploration.md): the reference module's unit tests (the
# descriptors of flat, single-row and checkerboard pictures, grid bins at both ends, the
# sample distance's zero, the taste score, derived prompts, and a schedule that replays and
# keeps the first comer without an objective) and tests/exploration.rs (vectors.json
# regenerates byte for byte from its fixed seeds and no other file is there, wai-rs gives
# every generation, descriptor vector and case its stated outcome, §13 lists exactly the
# reference's codes, each of which the corpus gives, and §3.2 names the reference's
# descriptors); then the corpus's second implementation, exploration_verify.py, written from
# the extension's text and sharing no code with wai-rs, which makes every picture with the
# generator as the extension's Appendix A restates it, computes the descriptors, replays
# every archive's schedule, reads usage statements with ai_usage_verify.py, verifies every
# record with WAI's strict Ed25519 rule and BLAKE3 from claim-conformance, reads the
# extension's reason table, requires every mutated copy of the corpus to fail, and drops each
# of its own checks in turn and requires the corpus to catch the weakened verifier; standard
# library only, run isolated (-I).
- name: exploration · wai-rs and exploration_verify.py
working-directory: wai
shell: bash
run: |
set -euo pipefail
(cd wai-rs && cargo test --no-default-features --features "$WAI_FEATURES" --lib exploration::)
(cd wai-rs && cargo test --no-default-features --features "$WAI_FEATURES" --test exploration)
python3 -I live-conformance/exploration_verify.py live-conformance/exploration
# wai.video.encode (extensions/platform-encode.md): the reference module's unit tests (the
# Exp-Golomb reader, emulation prevention, NAL splitting, length-prefixed samples, the
# resampler, the source reader, the strict JSON scan and the date-time) and
# tests/platform_encode.rs (the fixture streams are the pinned bytes, every generated file
# regenerates byte for byte, every case gets its outcome, every record reason has a case, and
# §12 lists exactly the reference's reasons); then the corpus's second implementation,
# encode_verify.py, written from the extension's text and sharing no code with wai-rs or
# wai-pack, which reads every Annex B stream, its access units and parameter sets itself,
# verifies every record with WAI's strict Ed25519 rule and every object with BLAKE3 from
# claim-conformance, checks the encoded renditions against the base packaging golden,
# requires every mutated copy of the corpus to fail, and drops each of its own checks in turn
# and requires the corpus or its mutations to catch the weakened verifier; standard library
# only, run isolated (-I). The encoders themselves run on the macOS leg (codec-wrappers).
- name: platform-encode · wai-rs and encode_verify.py
working-directory: wai
shell: bash
run: |
set -euo pipefail
(cd wai-rs && cargo test --locked --no-default-features --features "$WAI_FEATURES" --lib platform_encode::)
(cd wai-rs && cargo test --locked --no-default-features --features "$WAI_FEATURES" --test platform_encode)
python3 -I encode-conformance/encode_verify.py encode-conformance
# wai.live.cowatch (extensions/co-watch.md): the reference module's unit tests (the policy
# and its rules, statements read back and refused, the controlled position in the order of
# §5.4, each branch of the catch-up rule, percentiles by nearest rank, the control attribute)
# and tests/co_watch.rs (vectors.json regenerates byte for byte from its fixed seeds and no
# other file is there, wai-rs gives every room and catch-up case its stated outcome, and §12
# lists exactly the reference's codes, each of which the corpus gives); then the corpus's
# second implementation, co_watch_verify.py, written from the extension's text and sharing
# no code with wai-rs, which verifies each room with live_rooms_verify.py and every
# signature with WAI's strict Ed25519 rule, recomputes the controlled position, every
# sample, percentile and verdict, requires every mutated copy of the corpus to fail and
# drops each of its own checks in turn and requires the corpus to catch the weakened
# verifier; standard library only, run isolated (-I). Last, the browser client's co-watch
# module (joule-moq-web/web/room/cowatch.js), which gives every catch-up case its
# correction, recomputes each accepted room's controlled position, and writes the corpus's
# controls and presentation statements byte for byte.
- name: co-watch · wai-rs, co_watch_verify.py and the page's module
working-directory: wai
shell: bash
run: |
set -euo pipefail
(cd wai-rs && cargo test --no-default-features --features "$WAI_FEATURES" --lib co_watch::)
(cd wai-rs && cargo test --no-default-features --features "$WAI_FEATURES" --test co_watch)
python3 -I live-conformance/co_watch_verify.py live-conformance/cowatch
node --test ../joule-code/joule-code-rs/crates/joule-moq-web/web/room/cowatch.test.mjs
# wai.live.remote (extensions/remote-desktop.md): the reference module's unit tests (every
# statement read back and refused when a byte is short or over, the screen statement's
# field rules, the host's rules of §5.3 in their order, the grant attributes, a latency's
# legs, sealed actions: a seal with no plaintext in it that opens under the host's key
# alone, the commitment and what it binds, a seal that does not fit its actions, rules 8
# and 9 after the others) and the crate's HPKE against RFC 9180 A.1.1; tests/remote_desktop.rs
# (vectors.json regenerates byte for byte from its fixed seeds and no other file is there,
# wai-rs gives every room its stated outcome at the commitment level and at the opened
# level, and §12 lists exactly the reference's codes, host refusals, floor refusals and
# the reasons a seal is not opened, each of which the corpus gives);
# then the corpus's second implementation, remote_desktop_verify.py, written from the
# extension's text and sharing no code with wai-rs, which verifies each room with
# live_rooms_verify.py, every signature with WAI's strict Ed25519 rule and every seal with
# the aggregation verifier's HPKE, recomputes every outcome from the rules, the floor and
# every latency's legs at both levels, requires every mutated copy of the corpus to fail and
# drops each of its own checks in turn and requires the corpus to catch the weakened
# verifier; standard library only, run isolated (-I). Last, the browser viewer's module
# (joule-moq-web/web/room/remote.js), which writes the corpus's input statements, floor
# statements and latency records byte for byte, seals every sealed input that opens again
# byte for byte, and gives every input the outcome the corpus states.
- name: remote desktop · wai-rs, remote_desktop_verify.py and the page's module
working-directory: wai
shell: bash
run: |
set -euo pipefail
(cd wai-rs && cargo test --no-default-features --features "$WAI_FEATURES" --lib -- remote_desktop:: hpke::)
(cd wai-rs && cargo test --no-default-features --features "$WAI_FEATURES" --test remote_desktop)
python3 -I live-conformance/remote_desktop_verify.py live-conformance/remote
node --test ../joule-code/joule-code-rs/crates/joule-moq-web/web/room/remote.test.mjs
# wai.telemetry.aggregate (extensions/telemetry-aggregation.md): the reference module's unit
# tests (the fields against a wide-arithmetic-free product, the generators' orders,
# TurboSHAKE128 against RFC 9861, HPKE against RFC 9180 A.1.1, the FLP accepting a valid
# measurement and refusing an invalid one, delivery-telemetry's key classes) and
# tests/telemetry_aggregate.rs (vectors.json regenerates byte for byte from its fixed seeds and
# no other file is there, vdaf-22/ is the draft's test vectors as published and wai-rs passes
# every one, every receipt, cell and delivery-only report gets its stated outcome, every
# reason of §11 and every reused code refuses a vector, §11 lists exactly the reference's
# codes, delivery-telemetry §3.4 classes exactly the reference's keys); then the corpus's
# second implementation, telemetry_aggregate_verify.py, written from the extension's text and
# the drafts it cites and sharing no code with wai-rs, which evaluates Prio3 itself and passes
# the draft's vectors, opens every report with its own X25519, HKDF, AES-128-GCM and HPKE,
# re-runs every flow (both aggregators' verification, the aggregation job byte for byte, the
# batch buckets, every refusal, the collection), verifies every receipt and cell with WAI's
# strict Ed25519 rule from claim-conformance, reads the key classes and the reason table from
# the texts, requires every mutated copy of the corpus to fail, and drops each of its own
# checks in turn and requires the corpus to catch the weakened verifier; standard library
# only, run isolated (-I).
- name: QoE aggregation · wai-rs and telemetry_aggregate_verify.py
working-directory: wai
shell: bash
run: |
set -euo pipefail
(cd wai-rs && cargo test --no-default-features --features "$WAI_FEATURES" --lib -- telemetry_aggregate:: telemetry::)
(cd wai-rs && cargo test --no-default-features --features "$WAI_FEATURES" --test telemetry_aggregate)
python3 -I live-conformance/telemetry_aggregate_verify.py live-conformance/aggregate
# wai.media.tonemap, wai.meta.gainmap and wai.meta.st2094_50 (extensions/exact-tonemap.md):
# the reference module's unit tests (the fixed-point log2 and exp2 at known points, the
# table of K against its rule, the sRGB table, tan through its series, PCHIP slopes of a
# line, rounding of halves for both signs) and the PNG reader's, then tests/exact_tonemap.rs
# (the committed corpus regenerates byte for byte, no other file is there, every case and
# envelope gets its stated outcome, §9 lists exactly the reference's codes, §6 states the
# corpus's measurement against binary64, and frames.rgb8 is the int_video clip's decode
# whose digests its sidecar publishes); then the corpus's second implementation,
# tonemap_verify.py, written from the extension's text and sharing no code with wai-rs,
# which computes both derivations in integer arithmetic of its own, reads PNG, envelopes
# (with staged_verify.py) and both companions itself, recomputes §6's measurement, verifies
# every record with WAI's strict Ed25519 rule and BLAKE3 from claim-conformance, requires
# every mutated copy of the corpus to fail, and drops each of its own checks in turn and
# requires the corpus to catch the weakened verifier; standard library only, run isolated
# (-I).
- name: exact tone mapping · wai-rs and tonemap_verify.py
working-directory: wai
shell: bash
run: |
set -euo pipefail
(cd wai-rs && cargo test --no-default-features --features "$WAI_FEATURES" --lib -- exact_tonemap:: png_still::)
(cd wai-rs && cargo test --no-default-features --features "$WAI_FEATURES" --test exact_tonemap)
python3 -I live-conformance/tonemap_verify.py live-conformance/tonemap
# wai.splat.exact (extensions/splat-exact.md): the reference module's unit tests
# (exp_neg_q16 against the exponential, binary32 ranges rounded half up exactly, the
# signed integers' grammar, the identity set carrying every byte, and tiles that leave a
# frame unchanged) and tests/splat_exact.rs (live-conformance/splat/ regenerates byte for
# byte and no other file is there, every case gets its stated outcome, §10 lists exactly the
# reference's codes, the tiles leave every view of every scene unchanged, and the draft
# schema names §3.2's members); then the corpus's second implementation,
# splat_exact_verify.py, written from the extension's text and sharing no code with wai-rs:
# it reads each glTF asset, decodes each payload with int_payload_verify.py's parser and
# rANS decoder and tools/wai_ops_check.py's whm1/1 interpreter, renders every view with its
# own integer renderer, verifies every record with WAI's strict Ed25519 rule and BLAKE3
# from claim-conformance, reads the extension's reason table, requires every mutated copy
# of the corpus to fail, drops each of its own checks in turn and changes each rule of its
# renderer in turn, and requires the corpus to catch every one; standard library only, run
# isolated (-I).
- name: exact splats · wai-rs and splat_exact_verify.py
working-directory: wai
shell: bash
run: |
set -euo pipefail
(cd wai-rs && cargo test --no-default-features --features "$WAI_FEATURES" --lib splat_exact::)
(cd wai-rs && cargo test --no-default-features --features "$WAI_FEATURES" --test splat_exact)
python3 -I live-conformance/splat_exact_verify.py live-conformance/splat
# wai.live.termination (extensions/stream-termination.md) and the display match of
# capability-constraints §4: the reference module's unit tests (sides without orientation,
# each exceedance alone, the least rendition alone where none is within, a writer that
# refuses after its termination) and tests/stream_termination.rs (the committed corpus
# regenerates byte for byte from its fixed seeds, wai-rs gives every match and log its
# stated outcome and facts, every reason refuses a log, §7 lists exactly the reference's
# codes and capability-constraints §4.2 its match bits); wai-live-web's functions for a
# page held to the same corpus natively, a page's log written through them verified; then
# the corpus's second implementation, stream_termination_verify.py, written from the two
# extensions' text and sharing no code with wai-rs, which recomputes every match and every
# log's outcome and facts and requires every mutated copy of the corpus to fail; standard
# library only, run isolated (-I). The browser's own run is joule-moq-web.yml's scenario
# termination.
- name: stream termination · wai-rs, wai-live-web and stream_termination_verify.py
working-directory: wai
shell: bash
run: |
set -euo pipefail
(cd wai-rs && cargo test --no-default-features --features "$WAI_FEATURES" --lib stream_termination::)
(cd wai-rs && cargo test --no-default-features --features "$WAI_FEATURES" --test stream_termination)
(cd wai-rs && "$RUNNER_TEMP/wai-bins/union/wai_stream_termination_vectors" verify ../live-conformance/termination)
(cd wai-live-web && cargo test --locked --features int_video --lib termination_tests)
python3 -I live-conformance/stream_termination_verify.py live-conformance/termination
# wai.live.world (extensions/live-worlds.md): the reference module's unit tests (the
# statement and its rules, the grant attribute) and tests/live_world.rs (vectors.json
# regenerates byte for byte from its fixed seeds and no other file is there, wai-rs gives
# every world its stated outcome, and §11 lists exactly the reference's codes, each of which
# a verifier raises the corpus gives); then the corpus's second implementation,
# live_worlds_verify.py, written from the extension's text and the sections it cites and
# sharing no code with wai-rs: the statement, each grant's signature and attributes, each
# receipt in its binary form under the owner's chain, each op's signature, owner, kind,
# Lamport rule and equivocation, and the session hash. Standard library only, run isolated.
- name: live worlds · wai-rs and live_worlds_verify.py
working-directory: wai
shell: bash
run: |
set -euo pipefail
(cd wai-rs && cargo test --no-default-features --features "$WAI_FEATURES" --lib live_world::)
(cd wai-rs && cargo test --no-default-features --features "$WAI_FEATURES" --test live_world)
python3 -I live-conformance/live_worlds_verify.py live-conformance/worlds
# wai.live.e2ee (extensions/confidentiality.md): the corpus's second implementation,
# e2ee_verify.py, written from the extension's text and the documents it reads and
# sharing no code with the reference (joule-moq's secure_objects and joule-moq-mls,
# whose own checks run in joule-code-conformance.yml). Standard library only, run
# isolated (-I): AES, AES-GCM and RFC 9605's counter mode written from their
# specifications for test vectors only, HKDF and HMAC from the standard library,
# BLAKE3 and strict Ed25519 from claim-conformance. It checks every vector RFC 9605
# and draft-ietf-moq-secure-objects-01 publish, every record, key schedule, sealed
# object and room of vectors.json (taking each epoch's application secret as given,
# §14), and requires every mutated copy of the corpus to fail.
- name: end-to-end encrypted rooms · e2ee_verify.py
working-directory: wai
shell: bash
run: python3 -I live-conformance/e2ee_verify.py live-conformance/e2ee
# wai.live.message and wai.live.call (extensions/live-messaging.md): tests/live_messaging.rs
# (vectors.json regenerates byte for byte from its fixed seeds and no other file is there,
# wai-rs gives every conversation, history request, call and record its stated outcome, and
# §12 lists exactly the reference's codes, each of which the corpus gives); then the corpus's
# second implementation, live_messaging_verify.py, written from the extension's text and
# sharing no code with wai-rs, which reads descriptors with live_rooms_verify.py and Key IDs,
# keys, AES-GCM and plaintexts with e2ee_verify.py, implements the receipts' binary form and
# every rule of the extension itself, verifies every signature with WAI's strict Ed25519
# rule, requires every mutated copy of the corpus to fail, and drops each of its own checks
# in turn and requires the corpus to catch the weakened verifier; standard library only, run
# isolated (-I).
- name: live messaging · wai-rs and live_messaging_verify.py
working-directory: wai
shell: bash
run: |
set -euo pipefail
(cd wai-rs && cargo test --no-default-features --features "$WAI_FEATURES" --test live_messaging)
python3 -I live-conformance/live_messaging_verify.py live-conformance/messaging
# wai.live.watermark (extensions/forensic-watermark.md): the reference module's unit tests
# (the CBOR reader's deterministic-encoding rules, tokens of both COSE structures and
# every mode read and their rules refuse, a record's rules, big-endian bit addressing,
# the exact match and the binding) and tests/live_watermark.rs (vectors.json regenerates
# byte for byte from its fixed seeds and no other file is there, wai-rs gives every
# token, session list, match and disclosure its stated outcome, and §11 lists exactly the
# reference's codes, each of which the corpus gives); then the corpus's second
# implementation, live_watermark_verify.py, written from the extension's text and sharing
# no code with wai-rs, which reads rooms with live_rooms_verify.py and tokens with a CBOR
# reader of its own, requires every mutated copy of the corpus to fail, and drops each of
# its own checks in turn and requires the corpus to catch the weakened verifier; standard
# library only, run isolated (-I).
- name: forensic watermark sessions · wai-rs and live_watermark_verify.py
working-directory: wai
shell: bash
run: |
set -euo pipefail
(cd wai-rs && cargo test --no-default-features --features "$WAI_FEATURES" --lib live_watermark::)
(cd wai-rs && cargo test --no-default-features --features "$WAI_FEATURES" --test live_watermark)
python3 -I live-conformance/live_watermark_verify.py live-conformance/watermark
# wai.edge.derivation (extensions/deriving-edge.md): the reference module's unit tests
# (the operations pixel by pixel, which operations the registry's composition rule makes
# exact, the check each derivation takes, a record's reading rule by rule, its round trip
# and signature, the pinned output manifest, provenance items and AI-origin labels, the
# C2PA stores embedded in a still), the still writer and reader the module
# shares with wai-pack (png_still), and tests/derive_edge.rs (vectors.json regenerates
# byte for byte from its fixed seeds and no other file is there, wai-rs gives every vector
# its stated outcome, §9 lists exactly the reference's codes and §4 its derivations, and
# the reference edge wai_edge, run twice over a clip, makes a chain of two hops that
# verifies and is refused once a byte changes); then the corpus's second implementation,
# edge_verify.py, written from the extension's text and sharing no code with wai-rs,
# which reads receipts and writes stills itself, re-executes every replicate hop,
# requires every mutated copy of the corpus to fail, and drops each of its own checks in
# turn and requires the corpus to catch the weakened verifier; standard library only,
# run isolated (-I).
- name: deriving edge · wai-rs and edge_verify.py
working-directory: wai
shell: bash
run: |
set -euo pipefail
(cd wai-rs && cargo test --no-default-features --features "$WAI_FEATURES" --lib derive_edge::)
(cd wai-rs && cargo test --no-default-features --features "$WAI_FEATURES" --lib png_still::)
(cd wai-rs && cargo test --no-default-features --features "$WAI_FEATURES" --test derive_edge)
python3 -I edge-conformance/edge_verify.py edge-conformance
# wai.live.injection (extensions/cue-injection.md) and Enhanced RTMP ingest
# (extensions/live-ingest.md §12): both corpora are generated through joule-moq-ingest,
# whose tests/conformance_corpus.rs regenerates them byte for byte
# (joule-code-conformance.yml). Here their second implementations, written from the
# texts and sharing no code with the reference: injection_verify.py translates every
# SCTE 104 message to its SCTE 35 sections and cues (the standard's sample among them,
# byte for byte), requires every refusal's result code and reason, runs the injector's
# rules over every scenario, verifies every chain with WAI's strict Ed25519 and derives
# its breaks, and refuses every negative chain at its event; ertmp_verify.py reads every
# RTMP message of every session and requires every object of every room track and what
# was not carried. Each then requires every mutated copy of its corpus to fail
# (--self-test). Standard library only, run isolated (-I).
- name: cue injection and Enhanced RTMP · injection_verify.py and ertmp_verify.py
working-directory: wai
shell: bash
run: |
set -euo pipefail
python3 -I live-conformance/injection_verify.py --self-test live-conformance/injection
python3 -I live-conformance/ertmp_verify.py --self-test live-conformance/ertmp
# The quantum corpus's second implementation (quantum-sim extension), integers only:
# it derives the circuit/1 phase table by its recurrence and the circuit2 table by an
# interval-certified procedure, and requires both literal tables and their digests,
# and the extension's Appendix B to state the same;
# rebuilds every file of both vector trees byte for byte and recomputes every manifest
# entry with its own reader, simulator, sampler and BLAKE3; refuses every reject file
# with its listed class and by the rule its name states; and requires dyadic_ladder
# to see every ±1 change of every P(k) under both tables. Standard library only, run
# isolated (-I), so no module from the working directory, the environment or the
# user's site-packages is imported.
- name: quantum referee.py
shell: bash
run: python3 -I wai/quantum-conformance/tools/referee.py wai/quantum-conformance
# chain_differential.py signs receipt chains around jwp-receipts §3 step 3 and §6.1
# (two keys, two tracks, both payloads, replays, forks, gaps, the guard and the
# freshness bound), and chain_gap_differential.py genuine chains up to 90 groups
# delivered shuffled, withheld and walked back with rewritten links and forks; both
# require wai_jwp_vectors and jwp_verify.py to give every chain the same verdict. Two
# fixed seeds each, so a run is reproducible.
# Hybrid signatures (extensions/pq-signatures.md): the reference module's unit tests (its
# ML-DSA-65 against FIPS 204's ACVP vectors — keyGen, deterministic sigGen and sigVer —
# vendored in pq-conformance/acvp and pinned by SHA-256, and the composite against the
# draft's own vector, before anything is built on them), the synthesis reader's hybrid
# records, and tests/pq_signatures.rs (vectors.json regenerates byte for byte, every case
# reaches its verdict, §8 lists exactly the reference's codes, each given); then the
# corpus's second implementation, pq_verify.py, written from the extension's text and
# sharing no code with wai-rs, which verifies ML-DSA-65 from FIPS 204's text in pure
# Python (_mldsa.py), checks every ACVP verification vector and signature and the draft's
# vector, every case, the sizes §9 states and §8's table, requires every mutated case to be
# refused and the corpus to catch it with any one of its checks dropped; run isolated (-I).
# Last, the two give every case the same verdict.
- name: hybrid signatures · wai-rs and pq_verify.py
working-directory: wai
shell: bash
run: |
set -euo pipefail
(cd wai-rs && cargo test --no-default-features --features "$WAI_PQ_FEATURES" --lib pq_sig::)
(cd wai-rs && cargo test --no-default-features --features "$WAI_PQ_FEATURES" --lib synthesis::pq_tests)
(cd wai-rs && cargo test --no-default-features --features "$WAI_PQ_FEATURES" --test pq_signatures)
python3 -I pq-conformance/pq_verify.py pq-conformance
python3 -I pq-conformance/pq_verify.py verdicts pq-conformance/vectors.json > "$RUNNER_TEMP/pq-py.tsv"
(cd wai-rs && "$RUNNER_TEMP/wai-bins/pq/wai_pq_vectors" verdicts ../pq-conformance/vectors.json) > "$RUNNER_TEMP/pq-rs.tsv"
diff "$RUNNER_TEMP/pq-py.tsv" "$RUNNER_TEMP/pq-rs.tsv"
- name: claim_verify.py, differential.py, jwp_verify.py, chain_differential.py, chain_gap_differential.py, signer_verify.py
working-directory: wai
shell: bash
run: |
set -euo pipefail
python3 claim-conformance/claim_verify.py claim-conformance/vectors.json
python3 jwp-conformance/jwp_verify.py jwp-conformance/vectors.json
python3 signer-conformance/signer_verify.py signer-conformance/vectors.json
python3 signer-conformance/signer_verify.py verdicts signer-conformance/vectors.json > "$RUNNER_TEMP/signer-py.tsv"
# Each differential against both builds the first step copied (see its comment).
for build in union pq; do
bins="$RUNNER_TEMP/wai-bins/$build"
if [ "$build" = pq ]; then features=$WAI_PQ_FEATURES; else features=$WAI_FEATURES; fi
echo "::group::the differentials against the $build build (features $features)"
python3 claim-conformance/differential.py "$bins/wai_claim_vectors" --random 2000 --seed 1
for seed in 1 2; do
python3 jwp-conformance/chain_differential.py "$bins/wai_jwp_vectors" --n 3000 --seed "$seed"
python3 jwp-conformance/chain_gap_differential.py "$bins/wai_jwp_vectors" --n 400 --seed "$seed"
done
"$bins/wai_signer_vectors" verdicts signer-conformance/vectors.json > "$RUNNER_TEMP/signer-rs-$build.tsv"
diff "$RUNNER_TEMP/signer-py.tsv" "$RUNNER_TEMP/signer-rs-$build.tsv"
echo "the $build build: every differential agrees"
echo "::endgroup::"
done
# Header probes (extensions/format-probes.md, projection.md): the reference module's unit
# tests (bits, Exp-Golomb and emulation prevention, the codes) and tests/format_probe.rs (the
# committed corpus regenerates byte for byte from its external vectors and holds no other
# generated file, every vector, binding and fact gets its stated outcome, and the
# extensions' tables list exactly the reference's probes and codes); then the five LCEVC
# streams fetch.sh fetches and checks by SHA-256, each of which wai_format_probe and the
# second implementation require (a missing one is a failure); then
# format_probe_verify.py, written from the two texts and sharing no code with wai-rs,
# which probes every vector itself and requires every mutated copy of the corpus to fail.
# Standard library only, run isolated (-I).
- name: header probes · wai-rs, the fetched LCEVC streams and format_probe_verify.py
working-directory: wai
shell: bash
run: |
set -euo pipefail
(cd wai-rs && cargo test --no-default-features --features "$WAI_FEATURES" --lib format_probe::)
(cd wai-rs && cargo test --no-default-features --features "$WAI_FEATURES" --test format_probe)
fetched=$(mktemp -d)
bash format-probe-conformance/fetch.sh "$fetched"
(cd wai-rs && "$RUNNER_TEMP/wai-bins/union/wai_format_probe" verify ../format-probe-conformance --fetched "$fetched")
python3 -I format-probe-conformance/format_probe_verify.py format-probe-conformance --fetched "$fetched"
# CMSD reading (extensions/delivery-telemetry.md §6.6): the second implementation, written
# from that text and RFC 9651 with its own field parser, reads every field of
# telemetry-conformance/cmsd-read/ and every field expected/cmsd.json states, and requires
# every mutated copy to fail. wai-rs's reading is checked by wai_telemetry verify above.
- name: cmsd_read_verify.py
working-directory: wai
shell: bash
run: python3 -I telemetry-conformance/cmsd_read_verify.py telemetry-conformance
# LOC carriage (extensions/loc-carriage.md): the second implementation of joule-moq's loc
# module (whose tests/loc_vectors.rs runs in joule-code-conformance), written from the text,
# with its own MOQT -22 property decoder and BLAKE3 (claim-conformance/_blake3.py): it reads
# every object back to its envelope, writes it again byte for byte, gives every refused
# object and envelope its code, and requires every mutated copy, and the corpus under a
# copy of itself with a check dropped, to fail.
- name: loc_verify.py
working-directory: wai
shell: bash
run: python3 -I live-conformance/loc_verify.py live-conformance/loc
# Each feature list a step of the independent verifiers built alone, before those steps
# shared one build of the union, still compiles alone: a feature that compiles only beside
# another passes there and would fail a consumer that asks for it alone. A check, with no
# code generation, of every target the list enables (`--tests`: the library, as itself and
# as its unit tests see it, its binaries and its integration tests), for each list in turn;
# the tests themselves run in that job, under the union.
features-alone:
needs: relevant
if: needs.relevant.outputs.run == 'true'
name: each feature of the independent verifiers' steps compiles alone
# A check, so any architecture serves; linux-arm64 has the free slots.
runs-on: linux-arm64
steps:
- uses: actions/checkout@v5
- 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"
- name: wai-rs, each feature list alone
working-directory: wai/wai-rs
shell: bash
run: |
set -euo pipefail
for f in key_discovery http,video_manifest,key_discovery stage_measure live_events live_room \
capture_take live_compose live_record timed_text access_services live_metering energy_steering \
live_moderation dred_exact live_ads live_provenance synthesis synthesis_mark neural_int \
exact_upscale robustness ai_usage contribution settlement browser_sink browser_sink,receipt_claims \
takedown influence direction co_performance age_assurance bearer_receipts exploration co_watch \
telemetry_aggregate exact_tonemap splat_exact live_watermark derive_edge pq_signatures \
synthesis,pq_signatures sink_energy key_release stitched_presentation prior_wire \
prior_wire,neural_int scene_map avatar_face receipt_ledger stream_audit fleet native_sink \
platform_encode remote_desktop stream_termination live_world format_probe live_messaging \
conform_result revenue_share opportunity_report channel_lineup route_record; do
echo "::group::$f"
cargo check --no-default-features --features "$f" --tests
echo "::endgroup::"
done
# The browser sink step runs wai-live-web's tests with `int_video` only: they are a
# superset of the default build's, and the feature gates nothing off.
- name: wai-live-web without int_video
working-directory: wai/wai-live-web
run: cargo check --locked --tests
# Delivery telemetry's second implementation is an independent open-source CMCD and CMSD
# library at locked versions (telemetry-conformance/cml/package-lock.json). The
# differential builds each observation's report from the extension's tables, encodes it
# with the library, requires the bytes of expected/cmcd.json and expected/cmsd.json, reads
# the expected strings back as dictionary, query and header shards, and validates every
# report with no error. One platform: string encoding, not arithmetic.
telemetry-differential:
needs: relevant
if: needs.relevant.outputs.run == 'true'
name: delivery telemetry · CMCD and CMSD against an independent library
runs-on: linux-arm64
steps:
- uses: actions/checkout@v5
- uses: actions/setup-node@v4
with:
node-version: '22'
- name: npm ci, then the differential
working-directory: wai/telemetry-conformance/cml
shell: bash
run: |
set -euo pipefail
npm ci --no-audit --no-fund
node differential.mjs ..
byte-exact:
needs: relevant
if: needs.relevant.outputs.run == 'true'
name: cross-arch byte-equality · ${{ matrix.os }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
# Self-hosted fleet labels. Both architectures: x86_64 by linux, 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.
# Windows x86_64 leg removed 2026-09-30: runner offline. Restore by
# re-adding `windows` here once the runner is back online.
os: [linux, linux-arm64, macos]
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 codec wrappers are behind `codecs`, which binds C and C++ libraries that no
# container image of this fleet carries, so no other job compiles them. A feature no
# workflow enables has no CI coverage at all: without this job the wrappers' tests,
# and the limits on what a text payload may decode to (SPEC §2), pass by not running.
#
# One platform, the `macos` runner, whose host has the libraries. What the job proves
# is how the wrappers treat hostile bytes and where their limits fall, which is the
# same code on every host. A missing library fails the build step by name.
codec-wrappers:
needs: relevant
if: needs.relevant.outputs.run == 'true'
name: codec wrappers · fuzz smoke, text decode limits, C entry points, provenance, the semantic path
runs-on: macos
steps:
- uses: actions/checkout@v5
- name: Install Rust 1.98.0
shell: bash
run: |
export PATH="$HOME/.cargo/bin:$PATH"
rustup toolchain install 1.98.0 --profile minimal
rustup default 1.98.0
echo "$HOME/.cargo/bin" >> "$GITHUB_PATH"
# Every one of these test files is `#![cfg(feature = "codecs")]`: built without
# the feature each reports "0 passed" and exits 0. So the step names the feature,
# and then requires that each of the five binaries ran at least one test.
- name: Fuzz smoke, the text and media decode limits and the C entry points
working-directory: wai/wai-rs
shell: bash
run: |
set -o pipefail
cargo test --locked --features codecs \
--test fuzz_smoke --test text_decode_bounds --test text_decode_memory \
--test media_decode_bounds --test ffi_robustness \
2>&1 | tee "$RUNNER_TEMP/codec-wrappers.log"
ran=$(grep -cE '^test result: ok\. [1-9][0-9]* passed' "$RUNNER_TEMP/codec-wrappers.log" || true)
if [ "$ran" -ne 5 ]; then
echo "::error::expected five test binaries that each ran tests; $ran did"
exit 1
fi
# The platform's media framework encodes each codec through its hardware engine, the stream
# holds to platform-encode §4.3, its signed record verifies with the stream and the source
# held, and the platform's decoder gives one picture per frame. On this runner the test
# must run and pass: a host without the engine fails it rather than skipping it, so the
# step requires all five tests of the binary, the encode among them, to have run.
- name: platform-encode · the media framework's hardware encoder, end to end
working-directory: wai/wai-rs
shell: bash
run: |
set -o pipefail
cargo test --locked --no-default-features --features platform_encode --test platform_encode \
2>&1 | tee "$RUNNER_TEMP/platform-encode.log"
grep -q '^test the_platform_encoder_makes_a_stream_that_holds_and_decodes \.\.\. ok$' "$RUNNER_TEMP/platform-encode.log" \
|| { echo "::error::the platform encoder test did not run and pass"; exit 1; }
grep -qE '^test result: ok\. 5 passed' "$RUNNER_TEMP/platform-encode.log" \
|| { echo "::error::expected the five tests of tests/platform_encode.rs to pass"; exit 1; }
# wai_prov needs `codecs`, so no other job builds it. Its --carry path writes the
# provenance asset and receipt that wai-web's reach vectors commit: carried onto
# its own receipt, a run must write both again byte for byte. A receipt changed
# by one byte must be refused, which shows the comparison is not vacuous.
- name: wai_prov carries the committed provenance receipt, byte for byte
working-directory: wai/wai-rs
shell: bash
run: |
set -euo pipefail
cargo build --locked --features provenance,codecs,receipt_claims --bin wai_prov
bin="${CARGO_TARGET_DIR:-target}/debug/wai_prov"
v=../wai-web/reach/test/vectors/provenance
"$bin" "$RUNNER_TEMP/prov" --carry "$v/captured.receipt.json"
cmp "$RUNNER_TEMP/prov/captured.jpeg.wai" "$v/captured.jpeg.wai"
cmp "$RUNNER_TEMP/prov/captured.receipt.json" "$v/captured.receipt.json"
sed 's/"encode.jpeg"/"encode.jpeh"/' "$v/captured.receipt.json" > "$RUNNER_TEMP/changed.receipt.json"
if cmp -s "$RUNNER_TEMP/changed.receipt.json" "$v/captured.receipt.json"; then
echo "::error::the changed receipt is not changed"; exit 1
fi
if "$bin" "$RUNNER_TEMP/prov-changed" --carry "$RUNNER_TEMP/changed.receipt.json"; then
echo "::error::a changed receipt was carried"; exit 1
fi
# tests/semantic_path.rs needs `semantic`, which builds on `codecs` and binds the
# ONNX runtime, so this is the one job that can run it.
- name: The semantic path
working-directory: wai/wai-rs
shell: bash
run: |
set -o pipefail
cargo test --locked --features codecs,semantic --test semantic_path 2>&1 | tee "$RUNNER_TEMP/semantic-path.log"
ran=$(grep -cE '^test result: ok\. [1-9][0-9]* passed' "$RUNNER_TEMP/semantic-path.log" || true)
if [ "$ran" -ne 1 ]; then
echo "::error::the semantic path's test binary ran no test"
exit 1
fi
# 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:
needs: relevant
if: needs.relevant.outputs.run == 'true'
name: C2PA manifest emission · signed, read back, validated
runs-on: linux-arm64
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
# A room-session receipt (extensions/live-metering.md §7) in a real signed manifest:
# energy_kwh only where one class covers the session whole, the companion always.
- name: Emit a room-session receipt, sign, read back, validate
working-directory: wai/wai-rs
run: cargo test --lib --no-default-features --features c2pa_emit,live_metering c2pa_emit::tests::a_session
# 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"