wai: the native sink — its C interface (wai_sink_*), and the Swift package for the platform player (SDK-A) #480

Closed
dcharlot wants to merge 0 commits from wai/sdk-native-apple into main
Owner

What this is

SDK-A: the native sink core, its C interface, and the Swift package for the platform player on phones and tablets, televisions and desktops. A native host plays a stream through its platform's own player, which is unchanged and decodes on the platform's media engine. The sink sits on the path the player's requests take. For one playback session it:

  • verifies a media playlist against its playlist receipt and the chain of its live revisions (http-delivery §8.6). It holds every object whose URL states its content hash to that hash: a WAI object's cid, or a floor fragment's SHA-256 name under a signed playlist or by the owner's word. It tells the host, object by object, whether it may hand the bytes to the player. A refusal is withheld and the player gets a failed request (502).
  • signs stream-audit's records under a fresh key per session: settlement acknowledgements by plain SHA-256, presentation claims for marked ads, the WAS1 session record, and the bundle the owner's collector verifies.
  • keeps the observation log in order and closed at its end.
  • ends a session nobody can see, or whose viewer is idle, and stops the player's requests.
  • states the sink decode and the display as the unmetered marker. The platform's decoder runs in a platform process on its fixed-function decoder, which no counter an application can read covers.

One C interface (wai_sink_*, include/wai.h) serves every native platform. SDK-B binds it for the other mobile and television platforms.

Stacked on #474 (RI1, wai/audit-kit). The native sink signs exactly stream-audit's records, so a native session posts to the same collector as a page does. #474's commits are in this branch. Land #474 first, or land this PR and #474 together.

Contents

path what
wai/extensions/native-sink.md the text. §3 the session and its configuration. §4 verification: reading a playlist as a player reads it, a playlist and its receipt (with the host fetching the parents the chain asks for), an object, and what a host does with the answer. §5 observations and the log. §6 the termination rule, and what a native host observes. §7 energy. §8 the reasons. §9 the C interface. §10 conformance. §11 security and privacy. No record of its own.
wai/wai-rs/src/native_sink.rs (+ corpus.rs, tests.rs) the core, feature native_sink: pure Rust, no codec library, built for every native target
wai/wai-rs/src/ffi_sink.rs, include/wai.h the C interface: an opaque wai_sink_t, JSON in, JSON or bytes out, thread-safe, WAI_SINK_ABI_VERSION 1, statuses 8/9 added; the header is regenerated and committed
wai/live-conformance/native-sink/ the corpus, 16 cases from fixed seeds over the reference package's floor fragments, plus refused configurations
wai/live-conformance/native_sink_verify.py the second implementation, from the text
wai/wai-audit/web/native-sink.test.mjs the page's integration of stream-audit replays one case call for call and signs the same bundle byte for byte
wai/wai-sink-swift/ the Swift package: WaiSink (the wrapper), WaiRelay (the loopback relay), WaiPlayerSession (the platform player through the relay), WaiViewAttention (the platform's visibility and input signals), WaiCollector, scripts/build-xcframework.sh, scripts/test-simulator.sh, and its tests
CI wai-conformance.yml: a native sink step. wai-audit.yml: the page replay. New wai-sink-swift.yml: every slice, desktop tests, simulator tests and device builds, on the macOS runner.
SPEC.md §5, CHANGELOG.md, live-conformance/README.md the paragraph, the entry, the listing

Design decisions

  • Stream-audit's records, not a record of our own. A native player and a page produce one bundle shape, for one collector. Termination is stream-audit's ended. A wai.live.termination log (#457) or a wai.sink.energy receipt (#460) can be attached (wai_sink_attach) once those land. This PR writes neither, because neither is on main.
  • Verification is the native sink's addition. Stream-audit reads nothing the delivering service signs. Here a stream that carries WAI's receipts is verified before its bytes reach the decoder. A stream another service delivers is never refused for what its names look like: SHA-256 names bind bytes only under a signed playlist, or when the owner says content_addressed.
  • Pull, not callbacks, at the C boundary. When a live chain needs a parent receipt, the verdict names it (need_parent). The host fetches it, hands it over, and gives the playlist again. Callbacks would have been awkward over JNI.
  • The log keeps itself valid. A player and its requests run on separate threads, so an object can arrive with a time before the last log entry. The sink logs it at the last entry's time and logs nothing after end/abandon (delivery-telemetry §7.1). This race refused a real bundle in testing before the rule existed.
  • A loopback relay, not the platform's loader hook. The relay sees every request of an HTTP presentation, segments included, and serves ranges from verified bytes. Every URI of a playlist is rewritten to the relay. Requests need a 128-bit path token, and the relay listens on loopback only.
  • Energy honesty. The decoder runs out of process on the media engine, so roles 3 and 4 are the unmetered marker by default. A host states a figure only from a counter that covers that role's work.
  • Codec licensing. No codec ships. The platform's player decodes with the platform's licensed codecs. The test presentation is made at run time with the platform's own encoder. The only new dependency is getrandom 0.3 (MIT OR Apache-2.0, already in the lock graph).

Checks

check where command result
core unit tests Framework box cargo test --locked --no-default-features --features native_sink --lib native_sink:: 8 passed
corpus, §8 table, C ABI over every case, fresh keys, bad inputs Framework box … --test native_sink 6 passed
corpus regenerates Framework box wai_native_sink_vectors verify ../live-conformance/native-sink PASS ×2
second implementation Framework box python3 -I live-conformance/native_sink_verify.py live-conformance/native-sink 16 cases pass; 17/17 mutations caught; 19/19 dropped checks caught
stream audit after the merges Framework box --features stream_audit --test stream_audit; stream_audit_verify.py; settlement_verify.py 4 passed; exit 0; exit 0
collector after the merges Framework box cd wai/wai-audit && cargo test --locked --release 4 passed
clippy, my files Framework box cargo clippy --no-default-features --features native_sink --all-targets 0 notes in native_sink*, ffi_sink, its test and bin
page parity Studio (node) node --test wai/wai-audit/web/native-sink.test.mjs pass 1
xcframework, every slice Studio scripts/build-xcframework.sh desktop arm64+x86_64, phone, phone simulator arm64+x86_64, television, television simulator: built
Swift package, desktop Studio swift test 8/8, three consecutive runs
device builds Studio xcodebuild build -scheme WaiSink -destination generic/platform={iOS,tvOS,macOS} BUILD SUCCEEDED ×3
simulator test bundles Studio scripts/test-simulator.sh ios, … tvos TEST BUILD SUCCEEDED ×2; not run (see below)
lockfiles Framework box cargo metadata --locked in all 11 workspaces containing wai all ok (wai-audit's refreshed: wai-quantum 0.6.14→0.6.15 from main)
registry export Framework box wai registry export --check up to date
repo checks local tests-in-ci, workflow-concurrency, spec-refs, wai-section-refs, vanity, comparative-prose, orphan-sources, public-text self-test all clean
workflows local wfsteps.py HEAD origin/main origin/wai/audit-kit …; YAML parse 0 problems; parse ok
names local check-public-names.sh on 65 changed files (Swift included); commit messages against the same patterns clean

The desktop player end to end runs as follows. The platform's own encoder makes three 1-second fragments (AVC, ISO/IEC 14496-10, fragmented MP4), each named by its SHA-256. A loopback origin serves them. The platform player plays them through the relay to their end. Every segment is presented, bound by its sha256 name, and the bundle is accepted. A fragment changed at the origin is refused object_digest_mismatch and answered 502 on each of the player's retries, never handed on. A session nobody can see ends hidden after its 1 s grace, with its player item removed.

Falsifications (the tree committed first; each one a mutation, its check's exit, then restored)

Rust, on the build host: 16 mutations of the core, the C interface and the text. Every one was caught, by tests/native_sink.rs, the lib test or the §8 test (exit 101):

  • the SHA-256 name check off;
  • the cid check off;
  • the playlist receipt unchecked;
  • the live chain not walked;
  • require-signed ignored;
  • keys acknowledged;
  • log order not kept;
  • the log not closed at the end;
  • the hidden rule off;
  • the idle rule off;
  • calls taken after the end;
  • energy accepted without a class;
  • the C ABI presenting every object;
  • the "fresh" key taken from a constant;
  • acknowledgement windows different from stream-audit's reference;
  • a reason left out of §8.

A Rust whose log differs from the page's, with its corpus regenerated, was caught by the page replay (exit 1) and by the second implementation (exit 1, Disagree('the log')). Restored: all pass.

Swift, on the Studio: four mutations, each caught (exit 1):

  • the relay hands refused bytes to the player: RelayTests and the tampered-fragment player test fail;
  • the relay fetches no receipt: RelayTests expects signed;
  • the player session ignores the termination rule: the hidden test fails;
  • the session never observes playback: presented_ms is 0.

Restored: 8/8.

Energy measured

The sink's own per-segment work: wai_sink_object on 1 MiB bodies named by their SHA-256, under the process's own energy counter (rusage v6 ri_energy_nj). On the M3 Ultra, under shared load:

  • energy: median 2.23 mJ per MiB (range 2.09–2.28 over 7 rounds of 64);
  • time: about 1.0 ms of CPU per MiB;
  • class: OnChipCounter, the task counter;
  • scope: this process's CPU only, a ctypes harness included, Partial.

This is the cost of verifying and acknowledging, not of decoding. No counter readable by an application covers the decode.

Not done

  • Simulator tests did not run. The build host's CoreSimulator (1051.55) is older than Xcode 27.1's (1174.9.2). xcodebuild refuses simulator destinations, and under simctl spawn the XCTest agent never starts. Both test bundles build. scripts/test-simulator.sh fails with that reason and never reports a pass, so wai-sink-swift.yml's simulator steps are red on today's host. The fix is Xcode's first-launch install as an administrator, which is an owner decision for a shared host.
  • No device runs. The phone and television device slices are built and linked only.
  • No #457 stream log and no #460 sink-energy receipt. Both PRs are off main. The C interface already attaches records by name.
  • No release distribution. The binary target is referenced by local path. The by-URL zip, its checksum, and a repository whose root is the package are described in the deploy note.

Owner decisions

  1. Run xcodebuild -runFirstLaunch with administrator rights on the build host, so the simulator tests run there and in CI.
  2. Decide whether the Swift package ships from a repository of its own, its binary target by URL and checksum.

🤖 Generated with Claude Code


Closed: Landed on main through merge train E (#499, merge bf39ec9a); verified by content: this PR's head is in main

## What this is **SDK-A: the native sink core, its C interface, and the Swift package for the platform player on phones and tablets, televisions and desktops.** A native host plays a stream through its platform's own player, which is unchanged and decodes on the platform's media engine. The sink sits on the path the player's requests take. For one playback session it: - **verifies** a media playlist against its playlist receipt and the chain of its live revisions (http-delivery §8.6). It holds every object whose URL states its content hash to that hash: a WAI object's cid, or a floor fragment's SHA-256 name under a signed playlist or by the owner's word. It tells the host, object by object, whether it may hand the bytes to the player. A refusal is withheld and the player gets a failed request (502). - **signs** stream-audit's records under a fresh key per session: settlement acknowledgements by plain SHA-256, presentation claims for marked ads, the `WAS1` session record, and the bundle the owner's collector verifies. - **keeps** the observation log in order and closed at its end. - **ends** a session nobody can see, or whose viewer is idle, and stops the player's requests. - **states** the sink decode and the display as the unmetered marker. The platform's decoder runs in a platform process on its fixed-function decoder, which no counter an application can read covers. One C interface (`wai_sink_*`, `include/wai.h`) serves every native platform. SDK-B binds it for the other mobile and television platforms. **Stacked on #474 (RI1, `wai/audit-kit`).** The native sink signs exactly stream-audit's records, so a native session posts to the same collector as a page does. #474's commits are in this branch. Land #474 first, or land this PR and #474 together. ### Contents | path | what | |---|---| | `wai/extensions/native-sink.md` | the text. §3 the session and its configuration. §4 verification: reading a playlist as a player reads it, a playlist and its receipt (with the host fetching the parents the chain asks for), an object, and what a host does with the answer. §5 observations and the log. §6 the termination rule, and what a native host observes. §7 energy. §8 the reasons. §9 the C interface. §10 conformance. §11 security and privacy. No record of its own. | | `wai/wai-rs/src/native_sink.rs` (+ `corpus.rs`, `tests.rs`) | the core, feature `native_sink`: pure Rust, no codec library, built for every native target | | `wai/wai-rs/src/ffi_sink.rs`, `include/wai.h` | the C interface: an opaque `wai_sink_t`, JSON in, JSON or bytes out, thread-safe, `WAI_SINK_ABI_VERSION` 1, statuses 8/9 added; the header is regenerated and committed | | `wai/live-conformance/native-sink/` | the corpus, 16 cases from fixed seeds over the reference package's floor fragments, plus refused configurations | | `wai/live-conformance/native_sink_verify.py` | the second implementation, from the text | | `wai/wai-audit/web/native-sink.test.mjs` | the page's integration of stream-audit replays one case call for call and signs the **same bundle byte for byte** | | `wai/wai-sink-swift/` | the Swift package: `WaiSink` (the wrapper), `WaiRelay` (the loopback relay), `WaiPlayerSession` (the platform player through the relay), `WaiViewAttention` (the platform's visibility and input signals), `WaiCollector`, `scripts/build-xcframework.sh`, `scripts/test-simulator.sh`, and its tests | | CI | `wai-conformance.yml`: a native sink step. `wai-audit.yml`: the page replay. New `wai-sink-swift.yml`: every slice, desktop tests, simulator tests and device builds, on the macOS runner. | | `SPEC.md` §5, `CHANGELOG.md`, `live-conformance/README.md` | the paragraph, the entry, the listing | ### Design decisions - **Stream-audit's records, not a record of our own.** A native player and a page produce one bundle shape, for one collector. Termination is stream-audit's `ended`. A `wai.live.termination` log (#457) or a `wai.sink.energy` receipt (#460) can be attached (`wai_sink_attach`) once those land. This PR writes neither, because neither is on main. - **Verification is the native sink's addition.** Stream-audit reads nothing the delivering service signs. Here a stream that carries WAI's receipts is verified before its bytes reach the decoder. A stream another service delivers is never refused for what its names look like: SHA-256 names bind bytes only under a signed playlist, or when the owner says `content_addressed`. - **Pull, not callbacks, at the C boundary.** When a live chain needs a parent receipt, the verdict names it (`need_parent`). The host fetches it, hands it over, and gives the playlist again. Callbacks would have been awkward over JNI. - **The log keeps itself valid.** A player and its requests run on separate threads, so an object can arrive with a time before the last log entry. The sink logs it at the last entry's time and logs nothing after `end`/`abandon` (delivery-telemetry §7.1). This race refused a real bundle in testing before the rule existed. - **A loopback relay, not the platform's loader hook.** The relay sees every request of an HTTP presentation, segments included, and serves ranges from verified bytes. Every URI of a playlist is rewritten to the relay. Requests need a 128-bit path token, and the relay listens on loopback only. - **Energy honesty.** The decoder runs out of process on the media engine, so roles 3 and 4 are the unmetered marker by default. A host states a figure only from a counter that covers that role's work. - **Codec licensing.** No codec ships. The platform's player decodes with the platform's licensed codecs. The test presentation is made at run time with the platform's own encoder. The only new dependency is `getrandom` 0.3 (MIT OR Apache-2.0, already in the lock graph). ## Checks | check | where | command | result | |---|---|---|---| | core unit tests | Framework box | `cargo test --locked --no-default-features --features native_sink --lib native_sink::` | 8 passed | | corpus, §8 table, C ABI over every case, fresh keys, bad inputs | Framework box | `… --test native_sink` | 6 passed | | corpus regenerates | Framework box | `wai_native_sink_vectors verify ../live-conformance/native-sink` | PASS ×2 | | second implementation | Framework box | `python3 -I live-conformance/native_sink_verify.py live-conformance/native-sink` | 16 cases pass; 17/17 mutations caught; 19/19 dropped checks caught | | stream audit after the merges | Framework box | `--features stream_audit --test stream_audit`; `stream_audit_verify.py`; `settlement_verify.py` | 4 passed; exit 0; exit 0 | | collector after the merges | Framework box | `cd wai/wai-audit && cargo test --locked --release` | 4 passed | | clippy, my files | Framework box | `cargo clippy --no-default-features --features native_sink --all-targets` | 0 notes in `native_sink*`, `ffi_sink`, its test and bin | | page parity | Studio (node) | `node --test wai/wai-audit/web/native-sink.test.mjs` | pass 1 | | xcframework, every slice | Studio | `scripts/build-xcframework.sh` | desktop arm64+x86_64, phone, phone simulator arm64+x86_64, television, television simulator: built | | Swift package, desktop | Studio | `swift test` | 8/8, three consecutive runs | | device builds | Studio | `xcodebuild build -scheme WaiSink -destination generic/platform={iOS,tvOS,macOS}` | BUILD SUCCEEDED ×3 | | simulator test bundles | Studio | `scripts/test-simulator.sh ios`, `… tvos` | TEST BUILD SUCCEEDED ×2; **not run** (see below) | | lockfiles | Framework box | `cargo metadata --locked` in all 11 workspaces containing `wai` | all ok (`wai-audit`'s refreshed: wai-quantum 0.6.14→0.6.15 from main) | | registry export | Framework box | `wai registry export --check` | up to date | | repo checks | local | tests-in-ci, workflow-concurrency, spec-refs, wai-section-refs, vanity, comparative-prose, orphan-sources, public-text self-test | all clean | | workflows | local | `wfsteps.py HEAD origin/main origin/wai/audit-kit …`; YAML parse | 0 problems; parse ok | | names | local | `check-public-names.sh` on 65 changed files (Swift included); commit messages against the same patterns | clean | The desktop player end to end runs as follows. The platform's own encoder makes three 1-second fragments (AVC, ISO/IEC 14496-10, fragmented MP4), each named by its SHA-256. A loopback origin serves them. The platform player plays them through the relay to their end. Every segment is presented, bound by its `sha256` name, and the bundle is accepted. A fragment changed at the origin is refused `object_digest_mismatch` and answered 502 on each of the player's retries, never handed on. A session nobody can see ends `hidden` after its 1 s grace, with its player item removed. ## Falsifications (the tree committed first; each one a mutation, its check's exit, then restored) Rust, on the build host: 16 mutations of the core, the C interface and the text. Every one was caught, by `tests/native_sink.rs`, the lib test or the §8 test (exit 101): - the SHA-256 name check off; - the cid check off; - the playlist receipt unchecked; - the live chain not walked; - require-signed ignored; - keys acknowledged; - log order not kept; - the log not closed at the end; - the hidden rule off; - the idle rule off; - calls taken after the end; - energy accepted without a class; - the C ABI presenting every object; - the "fresh" key taken from a constant; - acknowledgement windows different from stream-audit's reference; - a reason left out of §8. A Rust whose log differs from the page's, with its corpus regenerated, was caught by the page replay (exit 1) and by the second implementation (exit 1, `Disagree('the log')`). Restored: all pass. Swift, on the Studio: four mutations, each caught (exit 1): - the relay hands refused bytes to the player: RelayTests and the tampered-fragment player test fail; - the relay fetches no receipt: RelayTests expects `signed`; - the player session ignores the termination rule: the hidden test fails; - the session never observes playback: `presented_ms` is 0. Restored: 8/8. ## Energy measured The sink's own per-segment work: `wai_sink_object` on 1 MiB bodies named by their SHA-256, under the process's own energy counter (rusage v6 `ri_energy_nj`). On the M3 Ultra, under shared load: - energy: median **2.23 mJ per MiB** (range 2.09–2.28 over 7 rounds of 64); - time: about 1.0 ms of CPU per MiB; - class: `OnChipCounter`, the task counter; - scope: this process's CPU only, a ctypes harness included, `Partial`. This is the cost of verifying and acknowledging, not of decoding. No counter readable by an application covers the decode. ## Not done - **Simulator tests did not run.** The build host's CoreSimulator (1051.55) is older than Xcode 27.1's (1174.9.2). xcodebuild refuses simulator destinations, and under `simctl spawn` the XCTest agent never starts. Both test bundles build. `scripts/test-simulator.sh` fails with that reason and never reports a pass, so `wai-sink-swift.yml`'s simulator steps are red on today's host. The fix is Xcode's first-launch install as an administrator, which is an owner decision for a shared host. - **No device runs.** The phone and television device slices are built and linked only. - **No #457 stream log and no #460 sink-energy receipt.** Both PRs are off main. The C interface already attaches records by name. - **No release distribution.** The binary target is referenced by local path. The by-URL zip, its checksum, and a repository whose root is the package are described in the deploy note. ## Owner decisions 1. Run `xcodebuild -runFirstLaunch` with administrator rights on the build host, so the simulator tests run there and in CI. 2. Decide whether the Swift package ships from a repository of its own, its binary target by URL and checksum. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --- **Closed:** Landed on main through merge train E (#499, merge bf39ec9a); verified by content: this PR's head is in main
A content owner's evidence from the players of a stream another service
delivers over HTTP. settlement §14 acknowledges such objects by plain
SHA-256 from an upstream named by its origin. stream-audit defines the
session key and channel, the acknowledgement windows and chains, the
WAS1 session record (spans presented, start time and stalls recomputed
from the delivery-telemetry log, energy per role with its class, how the
session ended), WPC1 claims for marked ads under the channel, the bundle
a collector verifies, and the channel report it signs and any holder of
the bundles recomputes. No price, tariff or amount.

wai-rs module stream_audit (feature stream_audit), the generator
wai_stream_audit_vectors, tests/stream_audit.rs, and the corpus
live-conformance/audit/.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
live-conformance/stream_audit_verify.py, written from the extension's
text: it reads acknowledgements with settlement_verify.py, claims with
ad_presentation_verify.py and logs and energy classes with
live_metering_verify.py, recomputes every report, gives every vector the
corpus's outcome, requires 15 mutated copies to fail and catches each of
its 31 checks dropped. Dropping three of them first went uncaught (an
item that is not a whole object, a chain's first acknowledgement naming
a prev, notes that are not the bound ones); the corpus gains a control
for each.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
wai/wai-audit is the reference collector of stream-audit §12: it
verifies each bundle a player posts (wai-rs stream_audit), stores the
accepted ones one file per session (a different record of a stored
session is refused audit_session_duplicate), takes Event-mode CMCD
batches as advisory telemetry, and serves each channel's report signed
with its key. Limits per client (an IPv4 address or an IPv6 /64), per
route body limits, CORS for the configured page origins. The CLI also
verifies a bundle, recomputes a report from a data directory, and
checks a served report against its bundles. Its tests post every corpus
session and require the corpus's outcome, and require the stored
sessions to report exactly the corpus's served reports.

web/audit.js is the player integration: it hashes each object with
WebCrypto, signs the acknowledgements, claims and session record with
WebCrypto's Ed25519, computes the settlement tree root with a one-chunk
BLAKE3 of its own, records spans, ads, the log and its CMCD batch. Its
Node tests drive it with the corpus's inputs and require the corpus's
records byte for byte. adapter-tap.js wraps fetch and XMLHttpRequest for
any player; adapter-hlsjs.js wraps a player's loader class.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
e2e/run.sh builds the collector, installs the automation package and an
open-source web player from e2e/package-lock.json (npm ci, no install
scripts), runs the player integration's unit tests, then
e2e/audit.e2e.mjs: an HLS stream made with the host's media tool (H.264
and AAC in 2 s CMAF segments, a program time, a marked ad over two
segments) served from another origin with CMSD-Static exposed, played in
a real browser twice, once through the loader adapter and once through
the network tap, each session sent to a collector on loopback. It checks
the outcome, the acknowledged objects against the origin's own SHA-256
of what it served, the ad's claim, the CMSD notes, the unmetered energy,
the CMCD batches, the report, its recomputation by `wai-audit check`, a
replay stored once and a tampered record refused.

Three defects it found, fixed here:
- the player hands fragment buffers on (to a worker), emptying them
  after the loader's callback: the session now copies the bytes at once,
  and keeps each object in the order it was given;
- the tap read XMLHttpRequest responses after the player had moved them:
  it now listens from the request's construction, so it reads first;
- a stitched ad is entered between two observations, so its claim began
  past media time 0 and reached quartile 1: play that enters an ad
  continuously now starts its first span at 0 (stream-audit §6.3), as
  leaving it already ran the last span to the ad's end.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
The record wai.delivery.audit and the magic WAS1 in REGISTRY.md and the
code registry, the export regenerated; a SPEC §5 paragraph for the
audit, and a sentence on settlement §14 in settlement's; the changelog
entry; the corpus in live-conformance's index; a step in
wai-conformance.yml (the module's tests, tests/stream_audit.rs and
stream_audit_verify.py) with the extension in its paths; and
wai-audit.yml for the collector on Linux and macOS and the player
integration with the browser end to end on the macOS host; the
collector's README.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Of twelve rules of web/audit.js and its adapters broken one at a time,
two first went uncaught by the Node tests: an ad entered between two
observations (the corpus's observations fall on the ad's start, so only
the browser end to end caught it), and a stall begun before the first
presentation counted. A test for each; all twelve now fail the tests.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Co-Authored-By: Claude Opus 5.5 <[email protected]>
- The falsifications found the check that refuses an acknowledgement the
  record does not name guarded by no vector in either implementation:
  the corpus gains ack_not_named (audit_bundle_invalid), and the Python
  verifier can drop that check too, which the corpus now catches.
- The collector's default port moves to 9694: 9690 is the stitched
  presentation tool's.
- stream-audit §6.3 states that this revision claims every marked ad
  with WPC1, and that a stitched ad is claimed with the stitched
  presentation record where a deployment holds it, its bundle then
  carrying the manifests its claims name.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
native_sink (feature native_sink): what a native host's player integration runs for
one playback session. It verifies a media playlist against its playlist receipt and
the chain of its live revisions (http-delivery §8.6), holds a WAI object to the content
hash its name or fragment states and a fragment named by its SHA-256 to that name
(packaging §7.6), and answers per object whether the host may hand it to its decoder.
It signs what stream-audit has a player sign, under a fresh session key: settlement
acknowledgements by plain SHA-256, presentation claims for marked ads, the session
record, and the bundle. And it ends a session nobody can see, or whose viewer has gone
idle.

ffi_sink: the C ABI over it, an opaque wai_sink_t with JSON in and JSON or bytes out,
include/wai.h regenerated. The corpus live-conformance/native-sink/ is written from
fixed seeds over the reference package's floor fragments.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
extensions/native-sink.md: what a native host's sink does for a stream it plays through
its platform's player. Verification (§4): a media playlist against its playlist receipt
and the chain of its live revisions, an object against the content hash its URL states,
the host told per object whether it may hand the bytes to the player. Observations and
the log (§5), the rule that ends a session nobody can see or attends to (§6), the energy
a native host states (§7: the platform's decoder is outside every counter an application
reads, so the sink decode is the unmetered marker there), the reasons (§8), and the C
interface every native integration shares (§9).

The corpus gains a live revision that rebinds an alias, a parent served under another
name, and page-parity: wai-audit/web/native-sink.test.mjs replays it through the page's
integration of stream-audit, which signs the same bundle byte for byte.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
wai-audit e2e: the collector ends with the run, however it ends
Some checks failed
wai-ops-gpu integer operators on GPUs / does this change touch it (pull_request) Has been cancelled
wai-ops-gpu integer operators on GPUs / builds · no adapter is not a pass (linux) (pull_request) Has been cancelled
wai-ops-gpu integer operators on GPUs / Metal GPU and browser WebGPU (macos) (pull_request) Has been cancelled
WAI energy receipts / does this change touch it (pull_request) Has been cancelled
WAI energy receipts / energy receipts · linux (pull_request) Has been cancelled
WAI energy receipts / energy receipts · linux-arm64 (pull_request) Has been cancelled
WAI energy receipts / energy receipts · macos (pull_request) Has been cancelled
WAI conformance / does this change touch it (pull_request) Has been cancelled
WAI conformance / cargo-class corpora · linux (pull_request) Has been cancelled
WAI conformance / cargo-class corpora · linux-arm64 (pull_request) Has been cancelled
WAI conformance / cargo-class corpora · macos (pull_request) Has been cancelled
WAI conformance / quantum core and corpus under wasm32-wasip2 (wasmtime) (pull_request) Has been cancelled
WAI conformance / v2 vocabulary · manifests validate as stated (pull_request) Has been cancelled
WAI conformance / independent verifiers · claims, JWP, key discovery and integer payloads (Python) (pull_request) Has been cancelled
WAI conformance / delivery telemetry · CMCD and CMSD against an independent library (pull_request) Has been cancelled
WAI conformance / cross-arch byte-equality · linux (pull_request) Has been cancelled
WAI conformance / cross-arch byte-equality · linux-arm64 (pull_request) Has been cancelled
WAI conformance / cross-arch byte-equality · macos (pull_request) Has been cancelled
WAI conformance / codec wrappers · fuzz smoke, text decode limits, C entry points, provenance, the semantic path (pull_request) Has been cancelled
WAI conformance / C2PA manifest emission · signed, read back, validated (pull_request) Has been cancelled
wai-audit collector and player integration / does this change touch it (pull_request) Has been cancelled
wai-audit collector and player integration / collector · linux (pull_request) Has been cancelled
wai-audit collector and player integration / collector, player integration and the browser end to end · macos (pull_request) Has been cancelled
standards workspaces build + test / which workspaces this change touches (pull_request) Has been cancelled
standards workspaces build + test / macOS energy backends (pull_request) Has been cancelled
repository checks / lockfiles, advisories, tests in CI, workflow hygiene, spec and section references, public text (pull_request) Has been cancelled
joule-moq-web browser client / joule-moq-web · does this change touch it (pull_request) Has been cancelled
joule-moq-web browser client / joule-moq-web · browser end-to-end (macos) (pull_request) Has been cancelled
joule-moq-room room service / joule-moq-room · does this change touch it (pull_request) Has been cancelled
joule-moq-room room service / joule-moq-room, every target (pull_request) Has been cancelled
d56916dac5
A run that failed left the collector it started running, holding the
output of whatever started the script open (the falsification harness
waited on it). It is now killed on the process's exit.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
A second native sink, from the extension's text: it opens each case's session from its
configuration and seed (the session key derived as RFC 8032 §5.1.5 derives it), reaches
every call's answer by §3 to §7, and holds the bundle the corpus states to what its own
session holds, field by field (acknowledgements and their item lists, claims, the
record, the log and the notes byte for byte), and to the collector's outcome through
stream_audit_verify.py. Playlist receipts and their chain are http_verify.py's. It
catches every one of 17 mutations of the corpus and every one of 17 checks dropped.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
wai/wai-sink-swift: the native sink for the platforms whose native player is reached
from Swift. WaiSink wraps the C interface (every call JSON in, JSON out); WaiRelay is the
loopback server the player is given in place of the origin: it fetches each object,
gives the sink a playlist with its receipt and the chain's parents, and answers the
player only with bytes the sink presents (502 otherwise), every URI of a playlist
rewritten to it; WaiPlayerSession drives the platform's player through it, observes it
every 200 ms, logs its first frame, stalls and end, ends a session nobody can see, and
posts the bundle to the owner's collector; WaiViewAttention reads the platform's signals
of who can see the player. scripts/build-xcframework.sh builds WaiFFI.xcframework from
wai-rs. Tests: the corpus through the wrapper, the relay over the reference floor, and
the player end to end over a presentation made with the platform's own encoder.

A native host's player and its requests run on threads of their own, so an object can
reach the sink with a time before the log's last entry. delivery-telemetry §7.1 has a
log's times never decrease and nothing after end or abandon: the sink logs such an entry
at the last entry's time, and takes no entry after end or abandon, while an object
received then is still verified and acknowledged (native-sink §5.2). The corpus gains
log-order, and the second implementation checks both rules.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
wai-conformance.yml runs the native sink's module tests, tests/native_sink.rs and
native_sink_verify.py; wai-audit.yml has the page replay the native sink corpus's
page-parity case; wai-sink-swift.yml builds every slice of the package's binary target
and runs the package's tests on the desktop and in the phone and television simulators,
and builds the device slices. scripts/test-simulator.sh builds the test bundle for a
simulator and runs it there through simctl; on a host whose simulator service is older
than its Xcode's, it says so and fails, since a run that did not happen is not a pass.
The simulator slice of the phone SDK holds both architectures. packaging is cited by its
section heading. The corpus is listed in live-conformance/README.md.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Co-Authored-By: Claude Opus 5.5 <[email protected]>
CHANGELOG: the native sink's and stream audit's entries above main's new ones under v0.4.0.
Cargo.toml: getrandom beside main's new optional dependencies. Cargo.lock: main's, with wai's
getrandom added by cargo metadata.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Co-Authored-By: Claude Opus 5.5 <[email protected]>
wai-audit: its lockfile follows wai-quantum 0.6.15 from main
Some checks failed
WAI neural sink gates / model-free refusals of the neural sink (pull_request) Has been cancelled
WAI JPEG-AI whole decode (pinned inputs, required) / does this change touch it (pull_request) Has been cancelled
WAI JPEG-AI whole decode (pinned inputs, required) / fetch pinned JPEG-AI inputs → whole decode + pixel hash, required (pull_request) Has been cancelled
WAI energy receipts / does this change touch it (pull_request) Has been cancelled
WAI energy receipts / energy receipts · linux (pull_request) Has been cancelled
WAI energy receipts / energy receipts · linux-arm64 (pull_request) Has been cancelled
WAI energy receipts / energy receipts · macos (pull_request) Has been cancelled
WAI conformance / does this change touch it (pull_request) Has been cancelled
WAI conformance / cargo-class corpora · linux (pull_request) Has been cancelled
WAI conformance / cargo-class corpora · linux-arm64 (pull_request) Has been cancelled
WAI conformance / cargo-class corpora · macos (pull_request) Has been cancelled
WAI conformance / quantum core and corpus under wasm32-wasip2 (wasmtime) (pull_request) Has been cancelled
WAI conformance / v2 vocabulary · manifests validate as stated (pull_request) Has been cancelled
WAI conformance / independent verifiers · claims, JWP, key discovery and integer payloads (Python) (pull_request) Has been cancelled
WAI conformance / delivery telemetry · CMCD and CMSD against an independent library (pull_request) Has been cancelled
WAI conformance / cross-arch byte-equality · linux (pull_request) Has been cancelled
WAI conformance / cross-arch byte-equality · linux-arm64 (pull_request) Has been cancelled
WAI conformance / cross-arch byte-equality · macos (pull_request) Has been cancelled
WAI conformance / codec wrappers · fuzz smoke, text decode limits, C entry points, provenance, the semantic path (pull_request) Has been cancelled
WAI conformance / C2PA manifest emission · signed, read back, validated (pull_request) Has been cancelled
wai-audit collector and player integration / does this change touch it (pull_request) Has been cancelled
wai-audit collector and player integration / collector · linux (pull_request) Has been cancelled
wai-audit collector and player integration / collector, player integration and the browser end to end · macos (pull_request) Has been cancelled
standards workspaces build + test / which workspaces this change touches (pull_request) Has been cancelled
standards workspaces build + test / macOS energy backends (pull_request) Has been cancelled
repository checks / lockfiles, advisories, tests in CI, workflow hygiene, spec and section references, public text (pull_request) Has been cancelled
joule-moq-web browser client / joule-moq-web · does this change touch it (pull_request) Has been cancelled
joule-moq-web browser client / joule-moq-web · browser end-to-end (macos) (pull_request) Has been cancelled
joule-moq-room room service / joule-moq-room · does this change touch it (pull_request) Has been cancelled
joule-moq-room room service / joule-moq-room, every target (pull_request) Has been cancelled
05fb22cc17
Co-Authored-By: Claude Opus 5.5 <[email protected]>
The native sink corpus is staged into the test target's resources by
scripts/build-xcframework.sh (not committed), and the tests read it from Bundle.module,
else from the repository. Each test prints a summary line (WAI-SINK …): the corpus's cases
and calls through the C interface, the relay's verdicts per fragment, the refused
requests of a fragment changed at the origin and their statuses, and the end-to-end and
hidden sessions' outcomes.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
A device runs no tool-hosted test bundle, so the package's tests run on one hosted in
TestHost/: a minimal application (an empty window) and an Xcode project whose unit-test
target compiles the same test files against this package by its path, with the corpus in
its resources and local networking allowed for the loopback origin and relay. The package
itself is unchanged for consumers. The tests import WaiSink plainly (they use only its
public interface) and read the corpus from Bundle.module in the package, from their own
bundle in the host.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
wai-sink-swift TestHost: adopt the scene life cycle
Some checks failed
joule-moq-web browser client / joule-moq-web · does this change touch it (pull_request) Successful in 15s
WAI neural sink gates / does this change touch it (pull_request) Has been cancelled
WAI neural sink gates / model-free refusals of the neural sink (pull_request) Has been cancelled
WAI JPEG-AI whole decode (pinned inputs, required) / fetch pinned JPEG-AI inputs → whole decode + pixel hash, required (pull_request) Has been cancelled
wai-audit collector and player integration / does this change touch it (pull_request) Successful in 9s
WAI energy receipts / energy receipts · linux (pull_request) Has been cancelled
WAI energy receipts / energy receipts · linux-arm64 (pull_request) Has been cancelled
WAI energy receipts / energy receipts · macos (pull_request) Has been cancelled
WAI energy receipts / does this change touch it (pull_request) Has been cancelled
WAI conformance / cargo-class corpora · linux (pull_request) Has been cancelled
WAI conformance / cargo-class corpora · linux-arm64 (pull_request) Has been cancelled
wai-audit collector and player integration / collector · linux (pull_request) Has been cancelled
wai-quantum WebGPU member / member · DX12 and Vulkan (cbio-windows) (pull_request) Has been cancelled
standards workspaces build + test / macOS energy backends (pull_request) Has been cancelled
wai-audit collector and player integration / collector, player integration and the browser end to end · macos (pull_request) Has been cancelled
standards workspaces build + test / which workspaces this change touches (pull_request) Has been cancelled
WAI JPEG-AI whole decode (pinned inputs, required) / does this change touch it (pull_request) Has been cancelled
joule-moq-web browser client / joule-moq-web · browser end-to-end (macos) (pull_request) Has been cancelled
repository checks / lockfiles, advisories, tests in CI, workflow hygiene, spec and section references, public text (pull_request) Has been cancelled
joule-moq-room room service / joule-moq-room, every target (pull_request) Has been cancelled
WAI conformance / cargo-class corpora · macos (pull_request) Has been cancelled
WAI conformance / quantum core and corpus under wasm32-wasip2 (wasmtime) (pull_request) Has been cancelled
WAI conformance / v2 vocabulary · manifests validate as stated (pull_request) Has been cancelled
WAI conformance / independent verifiers · claims, JWP, key discovery and integer payloads (Python) (pull_request) Has been cancelled
WAI conformance / delivery telemetry · CMCD and CMSD against an independent library (pull_request) Has been cancelled
WAI conformance / cross-arch byte-equality · linux (pull_request) Has been cancelled
WAI conformance / cross-arch byte-equality · linux-arm64 (pull_request) Has been cancelled
WAI conformance / cross-arch byte-equality · macos (pull_request) Has been cancelled
WAI conformance / codec wrappers · fuzz smoke, text decode limits, C entry points, provenance, the semantic path (pull_request) Has been cancelled
WAI conformance / C2PA manifest emission · signed, read back, validated (pull_request) Has been cancelled
59bfbbfd9b
The platform now refuses to launch an application without the scene life cycle ("UIScene
life cycle is required"), so the test host quit before its tests connected. It is a
scene-based application now: an App with one WindowGroup, and the generated Info.plist
carries its scene manifest.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
wai-sink-swift: simulator tests hosted in TestHost, in a fresh simulator, every step bounded
Some checks failed
WAI neural sink gates / model-free refusals of the neural sink (pull_request) Has been cancelled
WAI JPEG-AI whole decode (pinned inputs, required) / does this change touch it (pull_request) Has been cancelled
WAI JPEG-AI whole decode (pinned inputs, required) / fetch pinned JPEG-AI inputs → whole decode + pixel hash, required (pull_request) Has been cancelled
WAI energy receipts / does this change touch it (pull_request) Has been cancelled
WAI energy receipts / energy receipts · linux (pull_request) Has been cancelled
WAI energy receipts / energy receipts · linux-arm64 (pull_request) Has been cancelled
WAI energy receipts / energy receipts · macos (pull_request) Has been cancelled
WAI conformance / does this change touch it (pull_request) Has been cancelled
WAI conformance / cargo-class corpora · linux (pull_request) Has been cancelled
WAI conformance / cargo-class corpora · linux-arm64 (pull_request) Has been cancelled
WAI conformance / cargo-class corpora · macos (pull_request) Has been cancelled
WAI conformance / quantum core and corpus under wasm32-wasip2 (wasmtime) (pull_request) Has been cancelled
WAI conformance / v2 vocabulary · manifests validate as stated (pull_request) Has been cancelled
WAI conformance / independent verifiers · claims, JWP, key discovery and integer payloads (Python) (pull_request) Has been cancelled
WAI conformance / delivery telemetry · CMCD and CMSD against an independent library (pull_request) Has been cancelled
WAI conformance / cross-arch byte-equality · linux (pull_request) Has been cancelled
WAI conformance / cross-arch byte-equality · linux-arm64 (pull_request) Has been cancelled
WAI conformance / cross-arch byte-equality · macos (pull_request) Has been cancelled
WAI conformance / codec wrappers · fuzz smoke, text decode limits, C entry points, provenance, the semantic path (pull_request) Has been cancelled
WAI conformance / C2PA manifest emission · signed, read back, validated (pull_request) Has been cancelled
wai-audit collector and player integration / collector · linux (pull_request) Has been cancelled
wai-audit collector and player integration / collector, player integration and the browser end to end · macos (pull_request) Has been cancelled
standards workspaces build + test / macOS energy backends (pull_request) Has been cancelled
joule-moq-web browser client / joule-moq-web · does this change touch it (pull_request) Has been cancelled
joule-moq-web browser client / joule-moq-web · browser end-to-end (macos) (pull_request) Has been cancelled
joule-moq-room room service / joule-moq-room · does this change touch it (pull_request) Has been cancelled
joule-moq-room room service / joule-moq-room, every target (pull_request) Has been cancelled
wai-audit collector and player integration / does this change touch it (pull_request) Has been cancelled
standards workspaces build + test / which workspaces this change touches (pull_request) Has been cancelled
repository checks / lockfiles, advisories, tests in CI, workflow hygiene, spec and section references, public text (pull_request) Has been cancelled
850eeefe64
scripts/test-simulator.sh no longer spawns the XCTest agent through simctl, which hangs
once the host's simulator service is current. It runs the tests the way a device does:
it creates a fresh simulator (the newest installed runtime of the platform, the first
device type of its family), boots it, builds the test host for it (build-for-testing)
and runs the tests hosted in it (test-without-building), then shuts the simulator down
and deletes it however the run ends. Each step has a hard limit (boot 300 s, build 900 s,
tests 600 s by default) and fails, naming the step, when it passes it. TestHost now
builds for phones, tablets and televisions, so the television simulator runs the same
tests. wai-sink-swift.yml bounds each step as well.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
dcharlot closed this pull request 2026-10-26 20:58:48 -04:00
Some checks failed
wai-web wasm32 / does this change touch it (pull_request) Has been cancelled
wai-web wasm32 / wai-web wasm32 build · corpus, menu and writers (pull_request) Has been cancelled
wai-web reach builds / wai-web reach · does this change touch it (pull_request) Has been cancelled
wai-web reach builds / wai-web reach builds · the package of record, every output as recorded (pull_request) Has been cancelled
wai-web reach builds / wai-web reach builds · this tree's wai-web, every rung on its engine line (pull_request) Has been cancelled
WAI mbt2018_mean integer decode (regenerated vectors) / does this change touch it (pull_request) Has been cancelled
WAI mbt2018_mean integer decode (regenerated vectors) / regenerate mbt2018_mean integer vectors → Rust decode, required (pull_request) Has been cancelled
wai-sink-swift native sink package / does this change touch it (pull_request) Has been cancelled
wai-sink-swift native sink package / libwai slices, desktop tests, simulator tests · macos (pull_request) Has been cancelled
wai-quantum WebGPU member / does this change touch it (pull_request) Has been cancelled
wai-quantum WebGPU member / shader checks · browser build · wasip2 inertness · MSRV (pull_request) Has been cancelled
wai-quantum WebGPU member / member · software Vulkan (linux) (pull_request) Has been cancelled
wai-quantum WebGPU member / member · Metal (macos) (pull_request) Has been cancelled
wai-quantum WebGPU member / member · discrete GPU, Vulkan (jetson-hub) (pull_request) Has been cancelled
wai-quantum WebGPU member / member · integrated GPU, Vulkan (framework-128gb) (pull_request) Has been cancelled
wai-quantum WebGPU member / member · browser WebGPU (macos) (pull_request) Has been cancelled
wai-quantum studio and desktop / does this change touch it (pull_request) Has been cancelled
wai-quantum studio and desktop / studio · browser (pull_request) Has been cancelled
wai-quantum studio and desktop / desktop app · macos (pull_request) Has been cancelled
wai-quantum WebGPU member / member · DX12 and Vulkan (cbio-windows) (pull_request) Has been cancelled
wai-pack / wai-pack · does this change touch it (pull_request) Has been cancelled
wai-pack / wai-pack · linux (pull_request) Has been cancelled
wai-pack / wai-pack · linux-arm64 (pull_request) Has been cancelled
wai-pack / wai-pack · macos (pull_request) Has been cancelled
wai-pack / wai-pack · independent verifier (Python) (pull_request) Has been cancelled
wai-pack / wai-pack · the floor through a media prober (pull_request) Has been cancelled
wai-pack / wai-pack · dependency licences (pull_request) Has been cancelled
wai-ops-gpu integer operators on GPUs / does this change touch it (pull_request) Has been cancelled
wai-ops-gpu integer operators on GPUs / builds · no adapter is not a pass (linux) (pull_request) Has been cancelled
wai-ops-gpu integer operators on GPUs / Metal GPU and browser WebGPU (macos) (pull_request) Has been cancelled
WAI neural sink gates / does this change touch it (pull_request) Has been cancelled
WAI neural sink gates / model-free refusals of the neural sink (pull_request) Has been cancelled
WAI JPEG-AI whole decode (pinned inputs, required) / does this change touch it (pull_request) Has been cancelled
WAI JPEG-AI whole decode (pinned inputs, required) / fetch pinned JPEG-AI inputs → whole decode + pixel hash, required (pull_request) Has been cancelled
WAI energy receipts / does this change touch it (pull_request) Has been cancelled
WAI energy receipts / energy receipts · linux (pull_request) Has been cancelled
WAI energy receipts / energy receipts · linux-arm64 (pull_request) Has been cancelled
WAI energy receipts / energy receipts · macos (pull_request) Has been cancelled
WAI conformance / does this change touch it (pull_request) Has been cancelled
WAI conformance / cargo-class corpora · linux (pull_request) Has been cancelled
WAI conformance / cargo-class corpora · linux-arm64 (pull_request) Has been cancelled
WAI conformance / cargo-class corpora · macos (pull_request) Has been cancelled
WAI conformance / quantum core and corpus under wasm32-wasip2 (wasmtime) (pull_request) Has been cancelled
WAI conformance / v2 vocabulary · manifests validate as stated (pull_request) Has been cancelled
WAI conformance / independent verifiers · claims, JWP, key discovery and integer payloads (Python) (pull_request) Has been cancelled
WAI conformance / delivery telemetry · CMCD and CMSD against an independent library (pull_request) Has been cancelled
WAI conformance / cross-arch byte-equality · linux (pull_request) Has been cancelled
WAI conformance / cross-arch byte-equality · linux-arm64 (pull_request) Has been cancelled
WAI conformance / cross-arch byte-equality · macos (pull_request) Has been cancelled
WAI conformance / codec wrappers · fuzz smoke, text decode limits, C entry points, provenance, the semantic path (pull_request) Has been cancelled
WAI conformance / C2PA manifest emission · signed, read back, validated (pull_request) Has been cancelled
wai-audit collector and player integration / collector · linux (pull_request) Has been cancelled
wai-audit collector and player integration / collector, player integration and the browser end to end · macos (pull_request) Has been cancelled
standards workspaces build + test / macOS energy backends (pull_request) Has been cancelled
joule-moq-web browser client / joule-moq-web · does this change touch it (pull_request) Has been cancelled
joule-moq-web browser client / joule-moq-web · browser end-to-end (macos) (pull_request) Has been cancelled
joule-moq-room room service / joule-moq-room · does this change touch it (pull_request) Has been cancelled
joule-moq-room room service / joule-moq-room, every target (pull_request) Has been cancelled
wai-audit collector and player integration / does this change touch it (pull_request) Has been cancelled
standards workspaces build + test / which workspaces this change touches (pull_request) Has been cancelled
repository checks / lockfiles, advisories, tests in CI, workflow hygiene, spec and section references, public text (pull_request) Has been cancelled

Pull request closed

Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
Transaction-Science/open-standards!480
No description provided.