wai.live.watermark: forensic watermark session records, matched and disclosed one at a time (L14) #358

Merged
dcharlot merged 7 commits from wai/live-watermark into main 2026-10-20 13:05:39 -04:00
Owner

L14 of the live and interactive program: wai.live.watermark, a WAI record of forensic A/B watermark sessions (ETSI TS 104 002), bound to room grants, Lane A only.

What is in it

  • wai/extensions/forensic-watermark.md: the extension. It registers the record wai.live.watermark and has three records:

    • WWS1, the session record. The edge that chose the variants signs it when the session ends. It holds: the room; the content (owner and media kind); the span; the KIDs of the content keys; the token by its SHA-256; the token's wmvnd and wmpatlen; how the edge had the pattern (in the clear, decrypted, or derived); bitmaps of the positions it sequenced and the variant at each; counts of sequenced and unmarked segments; a salted binding to the session's grant and principal; the region where the record is kept; and expires.
    • WWQ1, the recovered sequence. The claimant signs it. It holds the known and bits bitmaps (positions left out are erasures), the span, the vendor, the copy's digest and the claimant's key.
    • WWD1, the disclosure. The room authority signs it. It opens one session's binding, for one sequence.

    The spec also covers: how a WAI verifier reads the TS's token (§4); retention and privacy (§6); the matching rule (§7); verification (§9); where the documents disagree (§10); 20 reason codes (§11).

  • wai-rs: the module live_watermark (feature live_watermark = ["live_room"], no new dependency). It has its own deterministic-CBOR reader (RFC 8949 §4.2.1) and reads the COSE_Mac0 and COSE_Sign1 structures of RFC 9052. It also adds:

    • the corpus generator live_watermark::corpus and the bin wai_live_watermark_vectors gen|verify;
    • the test tests/live_watermark.rs, which checks that the corpus regenerates byte for byte, that every case gets its outcome, and that §11 equals Reason::ALL;
    • 6 unit tests.
  • The corpus wai/live-conformance/watermark/vectors.json:

    • 3 rooms: broadcast with a key log, keyless, and an e2ee room with a WRE1 record;
    • 35 token vectors: 6 that read, 29 refused;
    • 31 session-list vectors: 3 accepted, 28 refused;
    • 10 match vectors: 1 matched, 1 ambiguous, 3 with no match, 5 sequences refused;
    • 14 disclosure vectors: 2 accepted, 12 refused.

    Every reason of §11 appears at least once.

  • wai/live-conformance/live_watermark_verify.py: the second implementation, written from the spec text. It shares no code with wai-rs. It reads rooms with live_rooms_verify.py, signatures with claim-conformance/_ed25519.py, and tokens with its own CBOR reader.

    • It runs 18 mutations of the corpus and requires each to fail.
    • It drops each of its own 17 checks in turn and requires the corpus to catch the weakened verifier.
  • Wiring:

    • a CI step in wai-conformance.yml, after the e2ee step, with a paths: entry for the extension;
    • REGISTRY.md: the record and the magics WWS1, WWQ1 and WWD1;
    • codecs/registry.rs and the regenerated export (registry/capabilities.json, vocab/v2.ttl);
    • SPEC §5 (the records list and a paragraph) and SPEC §6.5 (the Lane A records list);
    • a row and a bullet in jwp-receipts §7.5 for the key-log authority live/watermark;
    • CHANGELOG, the live-conformance README, and the corpus README.

Design decisions and why

  1. The capability is wai.live.watermark and the file is forensic-watermark.md. The record belongs to the live family: it is bound to room grants, the room clock, the region pin and the room authority's key log. It is registered the way wai.live.moderation is.
  2. The token is committed by digest, not carried.
    • A TS token can carry RFC 8392's sub. In indirect mode it carries a vendor wmid, which can be an account identifier.
    • Until its exp, a token can be presented again to get segments marked with its pattern.
    • So the record holds SHA-256(token) and restates only what matching needs: vendor, patlen, source and the embedded bits. The token travels beside the record only to the parties that check it.
    • Where the token is given, §5.7 checks four things: the digest; that it reads; that vendor, patlen and source agree with the record, and for a clear pattern that bits equals pattern AND served; and that the session's span is inside the token's window.
  3. ⚠️ The grant is committed to, not named in the clear. This departs from the brief's wording "the session's grant (by digest)".
    • Every participant holds a room's grants (live-rooms §10.5), and a grant names its principal (§13 there). So a grant digest in the clear names the viewer to anyone who holds the grants.
    • Instead, binding = SHA-256("wai:live-watermark-binding"‖0x01‖salt‖grant digest‖principal). The edge draws the salt per session and gives the opening (salt, grant digest, principal) to the room authority. The edge must not keep the opening once the authority holds it.
    • The grant stays bound: a disclosure opens the binding, and the verifier then checks the grant (grant_unknown, grant_wrong_principal, outside_grant_window).
  4. Detection does not invent statistics. TS 104 002 §5.8 leaves detection and its thresholds out of scope. So the rule is exact:
    • A record is a candidate when owner, media, vendor and patlen are equal and the spans meet.
    • It agrees when every stated position was sequenced with the stated variant. Positions not stated are erasures.
    • The outcome is matched (exactly one agrees), no_match or ambiguous_match, with each candidate's first disagreement (unserved or differs) and the number of positions stated.
    • There is no tolerance and no minimum, and the spec says so. Segments served unsequenced are never in served: position −1 and contingency (TS §5.7.5.1), sequencing disabled (§5.3), and positions at or beyond wmpatlen.
  5. Disclosure. The authority signs a WWD1 for one session and one signed sequence, only before expires.
    • A third party checks it against that one record, that sequence and the grant (§9.3), so it learns no other session.
    • Uniqueness of the match over all records is the authority's duty. The spec states that a third party cannot check it.
  6. Lane A only.
    • A record must name at least one content-key KID (not_protected). That ties the session to wai.video.keys release decisions without naming the licence or the viewer.
    • A room with a confidentiality record is refused e2ee_room, read in §9.1 step 2: magic, length, room and the authority's signature. The reason: the AEAD authenticates the full track name, group and object (confidentiality §4.1, §4.7), so an edge cannot serve a variant track's object as the viewer's track. One object per MOQT location means one track cannot carry per-subscriber objects. And the member's application holds the plaintext.
    • Plaintext rooms are out of this record's scope, by an explicit statement in §3.1.
  7. Who may sign. A record is signed by a key with the new key-log authority live/watermark, not live/relay, registered in jwp-receipts §7.5. With no origin, the signer must be a room key.
  8. Retention and privacy.
    • The record states its region, which must be inside the room's pin when the pin is non-empty (region_not_pinned). This extension extends the live-rooms §3.7 pin to session records.
    • expires must be at or after the session's end, and within the room's retention_days when that is non-zero (retention_exceeded).
    • A disclosure after expires is refused (disclosure_expired).
    • §6.3 says who reads what: the record goes to matching parties; the token to the authority and to a disclosure checker; the opening stays with the authority.
  9. One token is one session.
    • The edge binds a token to the grant it was first presented under, and refuses it under any other grant. A reconnect under the same grant continues the session.
    • Two records with one token are refused token_reused. This is the framing defence.
  10. Reading the documents together (§10).
    • The TS writes "kty number" for 5 and −7. These are RFC 9053 alg values: HMAC 256/256 is read as COSE_Mac0 and ES256 as COSE_Sign1.
    • RFC 8392 cites RFC 8152; the structures are read from RFC 9052.
    • Bit b selects variant b: A is 0, B is 1. The TS has two variants encoding '0' and '1' but does not spell out the mapping.
    • Positions at or beyond wmpatlen are served unsequenced.
    • A form the RFCs forbid is token_malformed. A form they allow that this revision does not read (a floating-point date, an untagged or nested CWT, another algorithm, an unknown header label) is token_unsupported.
  11. Token MACs and signatures are not checked by WAI verifiers (§4.4). The edge validates the token (TS §5.7.5.1), and the record is its signed statement that it did. The corpus tokens carry real HMAC-SHA-256 tags under the stated wmt_key.
  12. Sources read.
    • ETSI TS 104 002 V1.1.1 (2023-08). Its copyright notice refers reproduction to ETSI, so the spec cites clauses and reproduces none of its text. Curl was blocked by the ETSI WAF; the PDF was fetched with WebFetch.
    • RFC 8392, 8949 §4.2, 9052, 9053 and 4648.

Checks run

Cargo was run on the build host through ~/kani-logs/remote/rb. The light checks were run locally. All of these are after merging origin/main (L7b #351 and others) into the branch.

check command result
module unit tests cargo test --locked --no-default-features --features live_watermark --lib live_watermark:: 6 passed
corpus test cargo test --locked --no-default-features --features live_watermark --test live_watermark 3 passed
bin verify wai_live_watermark_vectors verify ../live-conformance/watermark PASS regenerates byte for byte; PASS every case
registry tests cargo test --locked --no-default-features --lib codecs::registry 14 passed
registry CLI test cargo test --locked --no-default-features --test cli_registry 6 passed
registry export cargo run --no-default-features --bin wai -- registry export (with --pull), then --check up to date, rc 0
sidecar test (exclusion text edited) cargo test --locked --no-default-features --features neural_int,video_int,audio_int,world_int,splat_int --test int_kernels_vectors every_decoded_output_states_a_sha256 1 passed
clippy cargo clippy --locked --no-default-features --features live_watermark --all-targets 0 notes in live_watermark*, codecs/registry.rs and tests/int_kernels_vectors.rs. Two found earlier were fixed. The crate's other notes predate this branch.
second implementation python3 -I live-conformance/live_watermark_verify.py live-conformance/watermark rc 0: 130 PASS (every vector, 18 mutations, 17 dropped checks)
live-rooms verifier (it imports this) python3 -I live_rooms_verify.py rooms rc 0
repo checks check-tests-in-ci.py, check-workflow-concurrency.sh, check-spec-refs.py, check-wai-section-refs.py, check-no-vanity-metrics.sh, test-public-text-checks.sh, check-comparative-prose.sh, check-orphan-sources.py all rc 0
lockfiles every build ran with --locked; no dependency was added no lockfile change

Falsifications

Each was run after committing. Each was applied to the build host's copy and restored after.

  • F1. The region rule removed from check_session: tests/live_watermark.rs exits 101. The generator asserts sessions vector region_not_pinned, and every_case_gets_its_stated_outcome fails.
  • F2. One stated reason in the committed vectors.json changed: exits 101 (differ ["vectors.json"], and the case's outcome fails).
  • F3. The token_reused row dropped from §11: the_extension_lists_the_reasons exits 101.
  • F4. The opening check removed from verify_disclosure: exits 101.
  • Restored: 3 passed.
  • Python, corrupted copy. A copy of the corpus with one stated reason changed: live_watermark_verify.py exits 1. Every built-in mutation fails, and every dropped check is caught by a named vector.

What is NOT done

  • No reference edge. No relay signs WWS1 records. joule-moq-relay does not sequence variants.
  • Carriage not defined. WAI defines neither how a MOQT subscriber presents the WM token nor the names of the upstream variant tracks. The spec says so.
  • No real ES256 token. The ES256 / COSE_Sign1 path is covered by a Rust unit test whose signature is a placeholder. The corpus has no ES256 token, since the crate has no P-256.
  • The edge-to-authority channel is left to the deployment. That is how the opening reaches the authority.
  • Uniqueness of a match at disclosure is the authority's statement, by design.
  • The public-names check was not run locally. It needs the private WAI_NAME_DENYLIST; CI runs it. The text names no company; the TS is cited by identifier only.

🤖 Generated with Claude Code

L14 of the live and interactive program: `wai.live.watermark`, a WAI record of forensic A/B watermark sessions (ETSI TS 104 002), bound to room grants, Lane A only. ## What is in it - **`wai/extensions/forensic-watermark.md`**: the extension. It registers the record `wai.live.watermark` and has three records: - **`WWS1`, the session record.** The edge that chose the variants signs it when the session ends. It holds: the room; the content (owner and media kind); the span; the KIDs of the content keys; the token by its SHA-256; the token's `wmvnd` and `wmpatlen`; how the edge had the pattern (in the clear, decrypted, or derived); bitmaps of the positions it sequenced and the variant at each; counts of sequenced and unmarked segments; a salted **binding** to the session's grant and principal; the region where the record is kept; and `expires`. - **`WWQ1`, the recovered sequence.** The claimant signs it. It holds the `known` and `bits` bitmaps (positions left out are erasures), the span, the vendor, the copy's digest and the claimant's key. - **`WWD1`, the disclosure.** The room authority signs it. It opens one session's binding, for one sequence. The spec also covers: how a WAI verifier reads the TS's token (§4); retention and privacy (§6); the matching rule (§7); verification (§9); where the documents disagree (§10); 20 reason codes (§11). - **`wai-rs`**: the module `live_watermark` (feature `live_watermark = ["live_room"]`, no new dependency). It has its own deterministic-CBOR reader (RFC 8949 §4.2.1) and reads the COSE_Mac0 and COSE_Sign1 structures of RFC 9052. It also adds: - the corpus generator `live_watermark::corpus` and the bin `wai_live_watermark_vectors gen|verify`; - the test `tests/live_watermark.rs`, which checks that the corpus regenerates byte for byte, that every case gets its outcome, and that §11 equals `Reason::ALL`; - 6 unit tests. - **The corpus `wai/live-conformance/watermark/vectors.json`**: - 3 rooms: broadcast with a key log, keyless, and an e2ee room with a `WRE1` record; - 35 token vectors: 6 that read, 29 refused; - 31 session-list vectors: 3 accepted, 28 refused; - 10 match vectors: 1 matched, 1 ambiguous, 3 with no match, 5 sequences refused; - 14 disclosure vectors: 2 accepted, 12 refused. Every reason of §11 appears at least once. - **`wai/live-conformance/live_watermark_verify.py`**: the second implementation, written from the spec text. It shares no code with wai-rs. It reads rooms with `live_rooms_verify.py`, signatures with `claim-conformance/_ed25519.py`, and tokens with its own CBOR reader. - It runs 18 mutations of the corpus and requires each to fail. - It **drops each of its own 17 checks in turn** and requires the corpus to catch the weakened verifier. - **Wiring**: - a CI step in `wai-conformance.yml`, after the e2ee step, with a `paths:` entry for the extension; - `REGISTRY.md`: the record and the magics `WWS1`, `WWQ1` and `WWD1`; - `codecs/registry.rs` and the regenerated export (`registry/capabilities.json`, `vocab/v2.ttl`); - SPEC §5 (the records list and a paragraph) and SPEC §6.5 (the Lane A records list); - a row and a bullet in jwp-receipts §7.5 for the key-log authority `live/watermark`; - CHANGELOG, the live-conformance README, and the corpus README. ## Design decisions and why 1. **The capability is `wai.live.watermark` and the file is `forensic-watermark.md`.** The record belongs to the live family: it is bound to room grants, the room clock, the region pin and the room authority's key log. It is registered the way `wai.live.moderation` is. 2. **The token is committed by digest, not carried.** - A TS token can carry RFC 8392's `sub`. In indirect mode it carries a vendor `wmid`, which can be an account identifier. - Until its `exp`, a token can be presented again to get segments marked with its pattern. - So the record holds `SHA-256(token)` and restates only what matching needs: vendor, `patlen`, source and the embedded bits. The token travels beside the record only to the parties that check it. - Where the token is given, §5.7 checks four things: the digest; that it reads; that vendor, `patlen` and source agree with the record, and for a clear pattern that `bits` equals pattern AND `served`; and that the session's span is inside the token's window. 3. **⚠️ The grant is committed to, not named in the clear. This departs from the brief's wording "the session's grant (by digest)".** - Every participant holds a room's grants (live-rooms §10.5), and a grant names its principal (§13 there). So a grant digest in the clear names the viewer to anyone who holds the grants. - Instead, `binding = SHA-256("wai:live-watermark-binding"‖0x01‖salt‖grant digest‖principal)`. The edge draws the salt per session and gives the opening (salt, grant digest, principal) to the room authority. The edge must not keep the opening once the authority holds it. - The grant stays bound: a disclosure opens the binding, and the verifier then checks the grant (`grant_unknown`, `grant_wrong_principal`, `outside_grant_window`). 4. **Detection does not invent statistics.** TS 104 002 §5.8 leaves detection and its thresholds out of scope. So the rule is exact: - A record is a **candidate** when owner, media, vendor and `patlen` are equal and the spans meet. - It **agrees** when every stated position was sequenced with the stated variant. Positions not stated are erasures. - The outcome is `matched` (exactly one agrees), `no_match` or `ambiguous_match`, with each candidate's first disagreement (`unserved` or `differs`) and the number of positions stated. - There is no tolerance and no minimum, and the spec says so. Segments served unsequenced are never in `served`: position −1 and contingency (TS §5.7.5.1), sequencing disabled (§5.3), and positions at or beyond `wmpatlen`. 5. **Disclosure.** The authority signs a `WWD1` for one session and one signed sequence, only before `expires`. - A third party checks it against that one record, that sequence and the grant (§9.3), so it learns no other session. - Uniqueness of the match over all records is the authority's duty. The spec states that a third party cannot check it. 6. **Lane A only.** - A record must name at least one content-key KID (`not_protected`). That ties the session to `wai.video.keys` release decisions without naming the licence or the viewer. - A room with a confidentiality record is refused `e2ee_room`, read in §9.1 step 2: magic, length, room and the authority's signature. The reason: the AEAD authenticates the full track name, group and object (confidentiality §4.1, §4.7), so an edge cannot serve a variant track's object as the viewer's track. One object per MOQT location means one track cannot carry per-subscriber objects. And the member's application holds the plaintext. - Plaintext rooms are out of this record's scope, by an explicit statement in §3.1. 7. **Who may sign.** A record is signed by a key with the new key-log authority `live/watermark`, not `live/relay`, registered in jwp-receipts §7.5. With no origin, the signer must be a room key. 8. **Retention and privacy.** - The record states its `region`, which must be inside the room's pin when the pin is non-empty (`region_not_pinned`). This extension extends the live-rooms §3.7 pin to session records. - `expires` must be at or after the session's end, and within the room's `retention_days` when that is non-zero (`retention_exceeded`). - A disclosure after `expires` is refused (`disclosure_expired`). - §6.3 says who reads what: the record goes to matching parties; the token to the authority and to a disclosure checker; the opening stays with the authority. 9. **One token is one session.** - The edge binds a token to the grant it was first presented under, and refuses it under any other grant. A reconnect under the same grant continues the session. - Two records with one token are refused `token_reused`. This is the framing defence. 10. **Reading the documents together (§10).** - The TS writes "kty number" for 5 and −7. These are RFC 9053 `alg` values: HMAC 256/256 is read as COSE_Mac0 and ES256 as COSE_Sign1. - RFC 8392 cites RFC 8152; the structures are read from RFC 9052. - Bit *b* selects variant *b*: A is 0, B is 1. The TS has two variants encoding '0' and '1' but does not spell out the mapping. - Positions at or beyond `wmpatlen` are served unsequenced. - A form the RFCs forbid is `token_malformed`. A form they allow that this revision does not read (a floating-point date, an untagged or nested CWT, another algorithm, an unknown header label) is `token_unsupported`. 11. **Token MACs and signatures are not checked by WAI verifiers (§4.4).** The edge validates the token (TS §5.7.5.1), and the record is its signed statement that it did. The corpus tokens carry real HMAC-SHA-256 tags under the stated `wmt_key`. 12. **Sources read.** - ETSI TS 104 002 V1.1.1 (2023-08). Its copyright notice refers reproduction to ETSI, so the spec cites clauses and reproduces none of its text. Curl was blocked by the ETSI WAF; the PDF was fetched with WebFetch. - RFC 8392, 8949 §4.2, 9052, 9053 and 4648. ## Checks run Cargo was run on the build host through `~/kani-logs/remote/rb`. The light checks were run locally. All of these are after merging `origin/main` (L7b #351 and others) into the branch. | check | command | result | |---|---|---| | module unit tests | `cargo test --locked --no-default-features --features live_watermark --lib live_watermark::` | 6 passed | | corpus test | `cargo test --locked --no-default-features --features live_watermark --test live_watermark` | 3 passed | | bin verify | `wai_live_watermark_vectors verify ../live-conformance/watermark` | PASS regenerates byte for byte; PASS every case | | registry tests | `cargo test --locked --no-default-features --lib codecs::registry` | 14 passed | | registry CLI test | `cargo test --locked --no-default-features --test cli_registry` | 6 passed | | registry export | `cargo run --no-default-features --bin wai -- registry export` (with `--pull`), then `--check` | up to date, rc 0 | | sidecar test (exclusion text edited) | `cargo test --locked --no-default-features --features neural_int,video_int,audio_int,world_int,splat_int --test int_kernels_vectors every_decoded_output_states_a_sha256` | 1 passed | | clippy | `cargo clippy --locked --no-default-features --features live_watermark --all-targets` | 0 notes in `live_watermark*`, `codecs/registry.rs` and `tests/int_kernels_vectors.rs`. Two found earlier were fixed. The crate's other notes predate this branch. | | second implementation | `python3 -I live-conformance/live_watermark_verify.py live-conformance/watermark` | rc 0: 130 PASS (every vector, 18 mutations, 17 dropped checks) | | live-rooms verifier (it imports this) | `python3 -I live_rooms_verify.py rooms` | rc 0 | | repo checks | `check-tests-in-ci.py`, `check-workflow-concurrency.sh`, `check-spec-refs.py`, `check-wai-section-refs.py`, `check-no-vanity-metrics.sh`, `test-public-text-checks.sh`, `check-comparative-prose.sh`, `check-orphan-sources.py` | all rc 0 | | lockfiles | every build ran with `--locked`; no dependency was added | no lockfile change | ## Falsifications Each was run after committing. Each was applied to the build host's copy and restored after. - **F1.** The region rule removed from `check_session`: `tests/live_watermark.rs` exits 101. The generator asserts `sessions vector region_not_pinned`, and `every_case_gets_its_stated_outcome` fails. - **F2.** One stated reason in the committed `vectors.json` changed: exits 101 (`differ ["vectors.json"]`, and the case's outcome fails). - **F3.** The `token_reused` row dropped from §11: `the_extension_lists_the_reasons` exits 101. - **F4.** The opening check removed from `verify_disclosure`: exits 101. - **Restored:** 3 passed. - **Python, corrupted copy.** A copy of the corpus with one stated reason changed: `live_watermark_verify.py` exits 1. Every built-in mutation fails, and every dropped check is caught by a named vector. ## What is NOT done - **No reference edge.** No relay signs `WWS1` records. joule-moq-relay does not sequence variants. - **Carriage not defined.** WAI defines neither how a MOQT subscriber presents the WM token nor the names of the upstream variant tracks. The spec says so. - **No real ES256 token.** The ES256 / COSE_Sign1 path is covered by a Rust unit test whose signature is a placeholder. The corpus has no ES256 token, since the crate has no P-256. - **The edge-to-authority channel is left to the deployment.** That is how the opening reaches the authority. - **Uniqueness of a match at disclosure is the authority's statement, by design.** - **The public-names check was not run locally.** It needs the private `WAI_NAME_DENYLIST`; CI runs it. The text names no company; the TS is cited by identifier only. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
The extension text (extensions/forensic-watermark.md), the wai-rs module behind the
live_watermark feature, its corpus generator and test, and the registrations.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
live-conformance/watermark/vectors.json from wai_live_watermark_vectors, and
live_watermark_verify.py, written from the extension's text, which agrees on every
vector, fails every mutated copy and catches a verifier that leaves out any one of
its checks.

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]>
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Merge remote-tracking branch 'origin/main' into wai/live-watermark
All checks were successful
standards workspaces build + test / joule-code-rs (joule-code/joule-code-rs, joule-code-rs, linux-arm64, true) (pull_request) Successful in 3m38s
WAI conformance / delivery telemetry · CMCD and CMSD against an independent library (pull_request) Successful in 11s
WAI conformance / cross-arch byte-equality · linux-arm64 (pull_request) Successful in 27s
WAI conformance / C2PA manifest emission · signed, read back, validated (pull_request) Successful in 1m38s
WAI energy receipts / energy receipts · linux-arm64 (pull_request) Successful in 7m28s
wai-pack / wai-pack · linux-arm64 (pull_request) Successful in 1m12s
WAI conformance / cargo-class corpora · linux-arm64 (pull_request) Successful in 15m59s
wai-pack / wai-pack · the floor through a media prober (pull_request) Successful in 26s
wai-pack / wai-pack · dependency licences (pull_request) Successful in 1m20s
wai-pack / wai-pack · independent verifier (Python) (pull_request) Successful in 4m10s
WAI conformance / independent verifiers · claims, JWP, key discovery and integer payloads (Python) (pull_request) Successful in 21m55s
joule-moq-room room service / joule-moq-room · does this change touch it (pull_request) Successful in 5s
joule-moq-web browser client / joule-moq-web · does this change touch it (pull_request) Successful in 4s
wai-web reach builds / wai-web reach · does this change touch it (pull_request) Successful in 5s
standards workspaces build + test / macOS energy backends (pull_request) Successful in 7m12s
WAI conformance / cargo-class corpora · macos (pull_request) Successful in 13m25s
WAI conformance / cross-arch byte-equality · macos (pull_request) Successful in 19s
WAI conformance / quantum core and corpus under wasm32-wasip2 (wasmtime) (pull_request) Successful in 2m16s
WAI conformance / codec wrappers · fuzz smoke, text decode limits, C entry points, provenance, the semantic path (pull_request) Successful in 45s
WAI conformance / cross-arch byte-equality · linux (pull_request) Successful in 29s
WAI energy receipts / energy receipts · macos (pull_request) Successful in 3m50s
wai-pack / wai-pack · macos (pull_request) Successful in 1m1s
joule-moq-room room service / joule-moq-room, every target (pull_request) Successful in 1m12s
WAI energy receipts / energy receipts · linux (pull_request) Successful in 9m24s
wai-pack / wai-pack · linux (pull_request) Successful in 1m29s
wai-web wasm32 / wai-web wasm32 build · corpus, menu and writers (pull_request) Successful in 3m37s
WAI conformance / cargo-class corpora · linux (pull_request) Successful in 19m54s
joule-moq-web browser client / joule-moq-web · browser end-to-end (macos) (pull_request) Successful in 4m37s
wai-web reach builds / wai-web reach builds · the package of record, every output as recorded (pull_request) Successful in 2m44s
wai-web reach builds / wai-web reach builds · this tree's wai-web, every rung on its engine line (pull_request) Successful in 4m19s
01ac92191f
Co-Authored-By: Claude Opus 5.5 <[email protected]>
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!358
No description provided.