All checks were successful
joule-moq-remote host agent / joule-moq-remote · does this change touch it (push) Successful in 14s
wai-key-proxy / does this change touch it (push) Successful in 14s
joule-moq-room room service / joule-moq-room · does this change touch it (push) Successful in 25s
wai-app and Create / wai-app · does this change touch it (push) Successful in 25s
wai-audit collector and player integration / does this change touch it (push) Successful in 32s
WAI Studio / does this change touch it (push) Successful in 19s
wai-quantum for JavaScript / does this change touch it (push) Successful in 1m42s
wai-quantum studio and desktop / does this change touch it (push) Successful in 1m51s
wai-sink-swift native sink package / does this change touch it (push) Successful in 2m14s
wai-fleet service / does this change touch it (push) Successful in 2m53s
wai-ledger service / does this change touch it (push) Successful in 3m11s
wai-sink-android native sink library / does this change touch it (push) Successful in 3m7s
WAI operation catalogue / does this change touch it (push) Successful in 3m24s
joule-moq-web browser client / joule-moq-web · does this change touch it (push) Successful in 3m26s
joule-moq-remote host agent / joule-moq-remote, every target (linux-arm64) (push) Successful in 3m38s
joule-code conformance gate / joule-moq-relay, every target (push) Successful in 5m27s
joule-code conformance gate / joule-moq-ingest, every target (push) Successful in 7m6s
repository checks / lockfiles, advisories, tests in CI, workflow hygiene, spec and section references, public text (push) Successful in 7m20s
joule-moq-room room service / joule-moq-room, every target (push) Successful in 7m8s
wai-sink-android native sink library / the JNI layer and the platform-free half on the host JVM · linux-arm64 (push) Successful in 4m34s
WAI breaking changes and the conformance runner / WAI breaking · does this change touch WAI (push) Successful in 12s
wai-quantum energy-landscape jobs / does this change touch it (push) Successful in 11s
wai-app and Create / wai-app · tests, clippy, the line language's verifier (linux) (push) Successful in 37s
joule-code conformance gate / Build + round-trip C1-C4 vectors (push) Successful in 2m41s
wai-key-proxy / proxy · linux (push) Successful in 1m49s
WAI Studio / the catalogue's actions, the unit tests and the core · linux (push) Successful in 1m22s
wai-audit collector and player integration / collector · linux (push) Successful in 2m18s
wai-quantum for JavaScript / javascript · linux (push) Successful in 5m2s
wai-quantum studio and desktop / studio · browser (push) Successful in 5m54s
wai-ledger service / service · linux (push) Successful in 2m11s
wai-fleet service / service · linux (push) Successful in 4m2s
wai-quantum studio and desktop / desktop app · linux (push) Successful in 9m50s
wai-quantum energy-landscape jobs / the same bits · linux-arm64 (push) Successful in 12m24s
WAI Studio / Studio in WebKit · linux (push) Successful in 13m19s
WAI operation catalogue / the catalogue and every door · linux (push) Successful in 11m24s
WAI breaking changes and the conformance runner / WAI breaking · wire, record and API against main · linux (push) Successful in 1m32s
WAI breaking changes and the conformance runner / WAI breaking and conform · their tests, and the independent verifiers through wai conform · linux (push) Successful in 6m4s
wai-quantum energy-landscape jobs / native against WebAssembly, over many seeds (push) Successful in 4m51s
wai-quantum energy-landscape jobs / reader, kernels, answers and the stated result · linux, release (push) Successful in 15m29s
wai-quantum energy-landscape jobs / the module under wasm32-wasip2 (wasmtime) (push) Successful in 19m19s
wai release binaries build on Windows / the seven release binaries · windows (push) Successful in 17m45s
wai-quantum studio and desktop / desktop app · windows (push) Successful in 10m5s
joule-code conformance gate / joule-moq-relay, its own energy on a counter (macos) (push) Successful in 56s
joule-moq-remote host agent / joule-moq-remote, every target (macos) (push) Successful in 1m6s
wai-audit collector and player integration / collector, player integration and the browser end to end · macos (push) Successful in 2m14s
wai-app and Create / wai-app · Create, browser end-to-end (macos) (push) Successful in 6m29s
wai-fleet service / service · macos (push) Successful in 39s
wai-quantum studio and desktop / desktop app · macos (push) Successful in 4m0s
wai-ledger service / service · macos (push) Successful in 1m3s
WAI Studio / Studio in Chromium and Firefox · macos (push) Successful in 10m25s
wai-sink-android native sink library / every ABI, the AAR, and the instrumented tests in a headless emulator · macos (push) Successful in 5m34s
wai-sink-swift native sink package / libwai slices, desktop tests, simulator tests · macos (push) Successful in 15m12s
joule-moq-web browser client / joule-moq-web · browser end-to-end (macos) (push) Successful in 15m51s
wai-quantum energy-landscape jobs / the same bits · macos (push) Successful in 6m17s
Each is a mapping with a reference module, a corpus and a second implementation written
from its text. None adds a record or changes a byte of an envelope, a receipt or a claim,
and none is wired into a relay, the room service or a page: each module is what a publisher
and a receiver call. Every draft was read at the latest revision in the IETF archive on 10
November 2026.
- Playout timing (draft-nandakumar-moq-tempo-00; co-watch §15, new). joule-moq-room's tempo
module reads and writes the draft's CaptureTimestamp, PlayoutDelay and HopTime, and holds
the instant they state to the room: it is the millisecond in which co-watch's controlled
position enters the object, and a delay above the track's stated bound is refused whatever
instant it gives. A change of delay the room decides is a pause and a play, or a seek, sent
as any control. The catalog member wai_tempo (moq-streaming-format §4.4) carries the bound
and the two catalog extensions the draft leaves to be defined. The draft's property types
are unassigned; the module uses placeholders in MOQT's application range.
- The MoQ FEC catalog binding (draft-ramadan-moq-fec-catalog-00, -fec-core-00,
-fec-block-codes-00; carousel §8.3, new). wai-rs's carousel::moq_fec binds a schedule's
raptorq entries to the FEC instances a catalog declares under moq-object-v1, and back:
an object a block, a pass a repair layer, symbols as symbol-track and repair objects. An
entry binds only where everything carousel §6 derives from it holds of the block sent (the
same symbols a pass, the same K'); a catalog is read failing closed; a rebuilt object is
delivered only at its entry's Location, length and content hash. tests/carousel_moq_fec.rs
writes the corpus and decodes every object with an independent implementation of RFC 6330,
whose symbols for the block-codes draft's Appendix B are that appendix's.
- Multicast endpoints (draft-ramadan-moq-multicast-02; bearer-receipts §9.7, which read -00).
At -02 an endpoint lists only mmtp tracks and their repair tracks, so no WAI track rides
one of the draft's endpoints, and §9.7 now says so. What is implemented is the reading of a
catalog's multicast member, each endpoint standing or ignored with a label; it joins nothing.
- MoQ files (draft-jennings-moq-file-05; live-recording §8.7, new). joule-moq's file module
writes a track's objects as the draft's .moq and .dat files and reads them back byte for
byte, properties and all, so a track and its receipts track verify from the files alone. A
reader opens nothing outside its directory and refuses a file cut short.
- V3C tracks (draft-yuyou-moq-v3c-00; moq-streaming-format §4.5, new). joule-moq's v3c
module splits a wai.pc.vpcc payload into the draft's component tracks and joins it back,
with the catalog member wai_v3c. ISO/IEC 23090-5 was not read: the unit header is RFC 10034
§4.3.1's copy, unit types 7 and above are refused, and the corpus holds opaque test bytes,
no bitstream an encoder wrote.
Planted faults, each caught by the reference and, but where noted, by the second
implementation: a symbol of another object (offered as itself, in place of a block's own
symbol, and, in the test alone, as a repair symbol under a rewritten header); a truncated data
file and a truncated .moq file; a timing claim outside its bound (a delay past the track's
bound, and an instant one millisecond off the controlled position's). Writing the tests
found two holes, both closed: a rebuilt object was not held to its entry's Location, and a
Group missing its last object on a track joins to another payload, which the text now states.
Corpora: wai/moqt-conformance/{moq-file,tempo,v3c}/ and
wai/live-conformance/carousel-moq-fec/, with moq_file_verify.py, tempo_verify.py,
v3c_verify.py and carousel_moq_fec_verify.py. The registry lists wai_tempo and wai_v3c
(export regenerated). wai/ietf/catalog_check.py holds them, fec and the packaging values
fec-repair, fec-source and v3c in three more writers' catalogs, with 31 more planted faults;
draft-charlot-moq-wai-packaging-01 is unchanged. joule-code-conformance.yml and
joule-moq-room.yml run the second implementations and trigger on the corpora and texts their
tests read; wai conform --independent runs four more verifiers.
Not done: no relay rewrites HopTime or reads the Sync Support parameter; nothing sends
stamped objects, FEC tracks or V3C tracks on a session; the drafts' MMTP packaging, FEC on
multicast paths and Reed-Solomon are not mapped.
Co-Authored-By: Claude <[email protected]>
199 lines
11 KiB
YAML
199 lines
11 KiB
YAML
name: joule-moq-room room service
|
|
|
|
# The room service (joule-code/joule-code-rs/crates/joule-moq-room), a workspace of its own
|
|
# with its own lock file: its keys file, the grants it signs checked against its
|
|
# descriptor and read by the relay's reader, the places and the limiter, and
|
|
# tests/room_service.rs, the service against a relay on loopback that trusts its authority:
|
|
# a grant and its proof open a session and the clock announces the publisher, the grant
|
|
# alone opens none, the room verifies (live-rooms §9), a publisher past the room's places
|
|
# is refused, clients are bounded, and a new room starts when the last publisher has left;
|
|
# an end-to-end encrypted room (WAI confidentiality), members keying through the
|
|
# service's log on a relay; admission by age (WAI age-assurance §5.6), the service a
|
|
# Privacy Pass origin whose tokens' thresholds its grants state and the relay serves by; and a
|
|
# watch room (WAI co-watch): viewers admitted by a proof of their key, their controls and
|
|
# statements carried when co-watch accepts them, the clock's skew statements and leaves, and the
|
|
# room the log carries verified by wai-rs; and a remote desktop room (WAI remote-desktop,
|
|
# tests/remote_room.rs): the host agent of joule-moq-remote enters by an invitation over https://
|
|
# and wss:// through TLS fronts, viewers make their keys, the host hands control over by a grant
|
|
# exchange it proves its key for, inputs are applied and refused by the rules, a controller's
|
|
# typing sealed to the host and absent from what a viewer receives, refused floor statements
|
|
# change nothing, a record out of its chain's order is cut and its author removed, the session's
|
|
# records are read under a grant of the room alone, and the session verified by wai-rs as the
|
|
# clock and the host hold it, at the commitment and the opened levels; a viewer flooding past its
|
|
# own record bound (max_records_per_principal), cut and removed while the session goes on and
|
|
# verifies; and a session the clock ends at its record bound on the whole session (max_records),
|
|
# whole and verified; a conversation (WAI live-messaging, tests/messaging_room.rs):
|
|
# members keying through real MLS groups, messaging across a restart of the service from its
|
|
# history store, a thread, reactions, an edit and a retraction, a removed member served nothing
|
|
# past its removal, every record verified offline; and a call (tests/call_room.rs) rung, accepted
|
|
# and carrying audio and video through the relay, and another missed. tests/openapi_contract.rs
|
|
# holds openapi.json to the service: every operationId is the operation's name in the toolchain's
|
|
# catalogue (wai/wai-rs/src/catalogue.rs, at the route it gives) and every operation the
|
|
# catalogue routes to the room service is described, the routes the routers match are exactly its
|
|
# operations, each status it lists is one its handlers return and each status they return is
|
|
# listed, and the service, run in each of its modes, answers every operation with a status it
|
|
# lists. tests/mcp_dev_room.rs builds `wai` with the feature `mcp` and the relay wai-relay (each a
|
|
# target directory of its own) and drives `wai mcp --toolset core,dev` with an MCP client: the tool
|
|
# room_grant and POST /grant named alike (room.grant), a stack whose room service is of another
|
|
# toolchain refused as stale, WAI's local stack (`wai dev --control`) started on loopback, grants
|
|
# for test principals, two joining and publishing with their receipts and one without, whose
|
|
# objects the relay drops, the session verified as live-rooms §9 verifies a room, a changed record
|
|
# refused, a synthetic publisher and viewer's test, and a grant from a service off the machine
|
|
# refused. tests/cli_dev_room.rs runs the same stack with `wai dev --control` in a project and
|
|
# drives it from the command line: wai room join (a grant, then the join through the stack's
|
|
# origin), wai session show verified as live-rooms §9 verifies a room, before and after wai room
|
|
# leave, wai room show --target local, wai log tail, wai session list (the summary of the session
|
|
# the relay closed) and wai room invite (an invitation the room's authority signed), and once the
|
|
# stack stops a door finds none. tests/participants.rs holds the synthetic participants (`wai-room participant`) to a
|
|
# relay with doors: a participant without receipts dropped there and served where there is none,
|
|
# impairment on the QUIC binding changing the loss QUIC measures, and a load delivered in full.
|
|
# tests/ports.rs holds the local stack's ports in one place: room.example.toml's relay_url is
|
|
# relay.example.toml's WebSocket endpoint and path, gateway.example.toml, read by the gateway's
|
|
# own reader (joule-moq-ingest, a dev-dependency), has the relay's QUIC endpoint and each listener
|
|
# it names a row (off until set when commented out, and read at the row's port once set), the relay's
|
|
# example is `wai-relay --dev`, wai dev's origin is the one the remote desktop template's host
|
|
# reaches, and the defaults of wai-audit, wai-ledger, wai-fleet, wai-quantum-service, the worlds'
|
|
# relay, the stitched presentation verifier and `wai http origin` are their sources', every one
|
|
# of them a row of wai/quickstart/README.md's port table and no port twice; the room service
|
|
# started from its example opens its clock's session on the relay started from its; and the
|
|
# gateway started from its example (ports moved to free ones, its files made) opens HTTP and
|
|
# RTMP and none of the listeners its example leaves off.
|
|
#
|
|
# It builds on wai-rs's room, event, composition, co-watch and remote desktop records, on the
|
|
# relay, on joule-moq-mls, on the remote desktop host agent and on wai-metrics, so a change to any
|
|
# of them runs it. Push filters match the push's delta, so every path the job reads is listed.
|
|
# After the tests, clippy holds the service's own code, every target, to no warnings.
|
|
|
|
concurrency:
|
|
group: ${{ github.workflow }}-${{ github.event_name == 'push' && github.sha || github.ref }}
|
|
cancel-in-progress: true
|
|
|
|
on:
|
|
# A push to main runs it too: work lands as direct commits to main, and this workflow has
|
|
# no schedule, so without this a direct commit would build and test none of it.
|
|
push:
|
|
branches: [main]
|
|
paths:
|
|
- 'joule-code/joule-code-rs/crates/joule-moq-room/**'
|
|
- 'joule-code/joule-code-rs/crates/joule-moq-remote/**'
|
|
- 'joule-code/joule-code-rs/crates/joule-moq/**'
|
|
- 'joule-code/joule-code-rs/crates/joule-moq-mls/**'
|
|
- 'joule-code/joule-code-rs/crates/joule-moq-relay/**'
|
|
- 'joule-code/joule-code-rs/crates/jwp/**'
|
|
- 'joule-code/joule-code-rs/vendor/**'
|
|
- 'wai/wai-rs/**'
|
|
- 'wai/wai-ops/**'
|
|
- 'wai/wai-metrics/**'
|
|
# tests/tempo_vectors.rs regenerates and checks the playout timing corpus and requires
|
|
# co-watch §15.6's table; the step after the tests reads it with its second implementation.
|
|
- 'wai/moqt-conformance/tempo/**'
|
|
- 'wai/moqt-conformance/tempo_verify.py'
|
|
- 'wai/extensions/co-watch.md'
|
|
# Read and started by tests/ports.rs: the ingest gateway and what it builds on.
|
|
- 'joule-code/joule-code-rs/crates/joule-moq-ingest/**'
|
|
- 'joule-code/joule-code-rs/crates/joule-contrib/**'
|
|
# Read by tests/ports.rs.
|
|
- 'wai/quickstart/README.md'
|
|
- 'wai/examples/remote-desktop/host.sh'
|
|
- 'wai/wai-audit/src/main.rs'
|
|
- 'wai/wai-ledger/src/main.rs'
|
|
- 'wai/wai-fleet/src/main.rs'
|
|
- 'wai/wai-quantum-service/src/main.rs'
|
|
- 'wai/wai-relay/src/main.rs'
|
|
- '.github/workflows/joule-moq-room.yml'
|
|
pull_request:
|
|
paths:
|
|
- 'joule-code/joule-code-rs/crates/joule-moq-room/**'
|
|
- 'joule-code/joule-code-rs/crates/joule-moq-remote/**'
|
|
- 'joule-code/joule-code-rs/crates/joule-moq/**'
|
|
- 'joule-code/joule-code-rs/crates/joule-moq-mls/**'
|
|
- 'joule-code/joule-code-rs/crates/joule-moq-relay/**'
|
|
- 'joule-code/joule-code-rs/crates/jwp/**'
|
|
- 'joule-code/joule-code-rs/vendor/**'
|
|
- 'wai/wai-rs/**'
|
|
- 'wai/wai-ops/**'
|
|
- 'wai/wai-metrics/**'
|
|
# tests/tempo_vectors.rs regenerates and checks the playout timing corpus and requires
|
|
# co-watch §15.6's table; the step after the tests reads it with its second implementation.
|
|
- 'wai/moqt-conformance/tempo/**'
|
|
- 'wai/moqt-conformance/tempo_verify.py'
|
|
- 'wai/extensions/co-watch.md'
|
|
# Read and started by tests/ports.rs: the ingest gateway and what it builds on.
|
|
- 'joule-code/joule-code-rs/crates/joule-moq-ingest/**'
|
|
- 'joule-code/joule-code-rs/crates/joule-contrib/**'
|
|
# Read by tests/ports.rs.
|
|
- 'wai/quickstart/README.md'
|
|
- 'wai/examples/remote-desktop/host.sh'
|
|
- 'wai/wai-audit/src/main.rs'
|
|
- 'wai/wai-ledger/src/main.rs'
|
|
- 'wai/wai-fleet/src/main.rs'
|
|
- 'wai/wai-quantum-service/src/main.rs'
|
|
- 'wai/wai-relay/src/main.rs'
|
|
- '.github/workflows/joule-moq-room.yml'
|
|
|
|
jobs:
|
|
# Forgejo matches `paths:` against the push delta, so a rebase fires this workflow
|
|
# whatever the pull request changes. This job reads the pull request's own diff against
|
|
# the paths above (scripts/pr-touches-paths.py, which fails open).
|
|
relevant:
|
|
name: joule-moq-room · does this change touch it
|
|
runs-on: gate
|
|
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/joule-moq-room.yml \
|
|
"${{ github.event.pull_request.base.sha }}" \
|
|
"${{ github.event.pull_request.head.sha }}")
|
|
echo "this change touches the room service: $r"
|
|
echo "run=$r" >> "$GITHUB_OUTPUT"
|
|
|
|
test:
|
|
name: joule-moq-room, every target
|
|
needs: relevant
|
|
if: needs.relevant.outputs.run == 'true'
|
|
runs-on: linux-arm64
|
|
timeout-minutes: 45
|
|
steps:
|
|
- name: Checkout
|
|
uses: actions/checkout@v4
|
|
|
|
- name: Install Rust 1.99.1
|
|
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.99.1
|
|
rustup toolchain install 1.99.1 --profile minimal --component clippy
|
|
rustup default 1.99.1
|
|
echo "$HOME/.cargo/bin" >> "$GITHUB_PATH"
|
|
|
|
- name: joule-moq-room, every target
|
|
working-directory: joule-code/joule-code-rs/crates/joule-moq-room
|
|
shell: bash
|
|
run: cargo test --locked --all-targets
|
|
|
|
# Playout timing (draft-nandakumar-moq-tempo-00; WAI co-watch §15): the corpus read by
|
|
# a second implementation written from the text, which computes the controlled position
|
|
# itself (tests/tempo_vectors.rs holds the crate to the corpus in the step above).
|
|
- name: playout timing, second implementation
|
|
shell: bash
|
|
run: |
|
|
if ! command -v python3 >/dev/null 2>&1; then
|
|
SUDO=""; [ "$(id -u)" = 0 ] || SUDO="sudo"
|
|
$SUDO apt-get update -qq
|
|
$SUDO apt-get install -y -qq python3
|
|
fi
|
|
python3 -I wai/moqt-conformance/tempo_verify.py
|
|
|
|
# Its own code only (`--no-deps`), every target, warnings as errors: a lint in a crate it
|
|
# builds on through a path dependency is that crate's to fix.
|
|
- name: joule-moq-room, clippy
|
|
working-directory: joule-code/joule-code-rs/crates/joule-moq-room
|
|
shell: bash
|
|
run: cargo clippy --locked --all-targets --no-deps -- -D warnings
|