open-standards/joule-code/joule-code-rs/crates/joule-contrib
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Transaction Science d1b4bd0c01
All checks were successful
joule-moq-room room service / joule-moq-room · does this change touch it (pull_request) Successful in 13s
joule-moq-web browser client / joule-moq-web · does this change touch it (pull_request) Successful in 14s
wai-quantum docs, course and locales / does this change touch it (pull_request) Successful in 6s
wai-quantum WebGPU member / does this change touch it (pull_request) Successful in 8s
WAI Studio / does this change touch it (pull_request) Successful in 7s
WAI energy receipts / does this change touch it (pull_request) Successful in 28s
WAI operation catalogue / does this change touch it (pull_request) Successful in 30s
wai-app and Create / wai-app · does this change touch it (pull_request) Successful in 32s
energy meters on real hardware / RAPL and NVML on jetson-hub (pull_request) Successful in 42s
joule-code conformance gate / joule-moq-relay, its own energy on a counter (macos) (pull_request) Successful in 45s
wai-quantum docs, course and locales / the Studio's words in every locale · linux (pull_request) Successful in 31s
joule-code conformance gate / Build + round-trip C1-C4 vectors (pull_request) Successful in 1m17s
jouleclaw public surface must stay documented / Public-surface audit (jouleclaw-rs) (pull_request) Successful in 1m31s
repository checks / lockfiles, advisories, tests in CI, workflow hygiene, spec and section references, public text (pull_request) Successful in 1m44s
energy meters on real hardware / sink decode table · per-task energy and the GPU rail on macOS (pull_request) Successful in 2m33s
wai-quantum docs, course and locales / the course and the command line's languages · linux (pull_request) Successful in 2m11s
wai-quantum WebGPU member / member · browser WebGPU (macos) (pull_request) Successful in 2m16s
wai-app and Create / wai-app · tests, clippy, the line language's verifier (linux) (pull_request) Successful in 26s
energy meters on real hardware / sink decode table · RAPL on jetson-hub (NVML surveyed) (pull_request) Successful in 3m11s
joule-code conformance gate / joule-moq-relay, every target (pull_request) Successful in 3m59s
WAI Studio / the catalogue's actions, the unit tests and the core · linux (pull_request) Successful in 2m58s
joule-moq-room room service / joule-moq-room, every target (pull_request) Successful in 4m9s
wai-quantum WebGPU member / member · Metal (macos) (pull_request) Successful in 4m19s
wai-quantum WebGPU member / member · software Vulkan (linux) (pull_request) Successful in 6m5s
joule-code conformance gate / joule-moq-ingest, every target (pull_request) Successful in 7m18s
WAI operation catalogue / the catalogue and every door · linux (pull_request) Successful in 4m51s
wai-quantum WebGPU member / shader checks · browser build · wasip2 inertness · MSRV (pull_request) Successful in 7m53s
WAI conformance / does this change touch it (pull_request) Successful in 10m3s
WAI breaking changes and the conformance runner / WAI breaking · does this change touch WAI (pull_request) Successful in 10m6s
WAI energy receipts / energy receipts · macos (pull_request) Successful in 7m40s
WAI examples / WAI examples · does this change touch them (pull_request) Successful in 10m11s
standards workspaces build + test / which workspaces this change touches (pull_request) Successful in 10m22s
WAI conformance / cross-arch byte-equality · macos (pull_request) Successful in 27s
wai-quantum WebGPU member / member · integrated GPU, Vulkan (framework-128gb) (pull_request) Successful in 10m14s
WAI conformance / v2 vocabulary · manifests validate as stated (pull_request) Successful in 49s
standards workspaces build + test / arl-rs (arl/arl-rs, arl-rs, linux) (pull_request) Successful in 55s
WAI conformance / cross-arch byte-equality · linux (pull_request) Successful in 1m24s
WAI breaking changes and the conformance runner / WAI breaking · wire, record and API against main · linux (pull_request) Successful in 1m25s
WAI conformance / codec wrappers · fuzz smoke, text decode limits, C entry points, provenance, the semantic path (pull_request) Successful in 1m4s
WAI conformance / faces from keypoints under wasm32-wasip2 (wasmtime) (pull_request) Successful in 1m43s
wai-quantum WebGPU member / member · DX12 and Vulkan (cbio-windows) (pull_request) Successful in 12m4s
WAI Studio / Studio in WebKit · linux (pull_request) Successful in 10m59s
standards workspaces build + test / joulehook-rs (joulehook/joulehook-rs, joulehook-rs, linux) (pull_request) Successful in 27s
standards workspaces build + test / pool-rs (pool/pool-rs, pool-rs, linux) (pull_request) Successful in 36s
standards workspaces build + test / joule-ui-rs (joule-ui/joule-ui-rs, joule-ui-rs, linux) (pull_request) Successful in 1m17s
standards workspaces build + test / jcp-rs (jcp-conformance, jcp/jcp-rs, -p jcp-energy --features nvml, jcp-rs, linux) (pull_request) Successful in 1m36s
wai-app and Create / wai-app · Create, browser end-to-end (macos) (pull_request) Successful in 10m23s
standards workspaces build + test / proof-rs (proof/conformance/v1/joulespec.toml, proof-conformance, proof/proof-rs, proof-rs, linux, true) (pull_request) Successful in 1m3s
standards workspaces build + test / eoc-rs (eoc/eoc-rs, -p eoc-meter --features cuda, eoc-rs, linux) (pull_request) Successful in 2m28s
WAI conformance / fast integer kernels, every x86_64 kernel set (AVX-512 silicon) (pull_request) Successful in 3m40s
standards workspaces build + test / sense-rs (sense/sense-rs, sense-rs, linux) (pull_request) Successful in 1m30s
standards workspaces build + test / joulespec-rs (true, joulespec/joulespec-rs, true, joulespec-rs, linux) (pull_request) Successful in 1m9s
standards workspaces build + test / sandbox-rs (sandbox-conformance, sandbox/sandbox-rs, -p sandbox-tee --features amd-kds,intel-pcs, sandbox-rs, linux) (pull_request) Successful in 2m10s
WAI Studio / Studio in Chromium and Firefox · macos (pull_request) Successful in 14m19s
joule-moq-web browser client / joule-moq-web · browser end-to-end (macos) (pull_request) Successful in 15m14s
WAI energy receipts / energy receipts · linux (pull_request) Successful in 14m8s
WAI energy receipts / energy receipts · linux-arm64 (pull_request) Successful in 14m16s
WAI conformance / delivery telemetry · CMCD and CMSD against an independent library (pull_request) Successful in 35s
standards workspaces build + test / joulespec-proofs (joulespec/joulespec-rs, joulespec-proofs, true, macos) (pull_request) Successful in 1m24s
WAI breaking changes and the conformance runner / WAI breaking and conform · their tests, and the independent verifiers through wai conform · linux (pull_request) Successful in 6m53s
WAI conformance / cross-arch byte-equality · linux-arm64 (pull_request) Successful in 49s
WAI conformance / quantum core and corpus under wasm32-wasip2 (wasmtime) (pull_request) Successful in 7m47s
WAI conformance / C2PA manifest emission · signed, read back, validated (pull_request) Successful in 2m18s
standards workspaces build + test / smart-byte-rs (smart-byte/smart-byte-rs, smart-byte-rs, linux) (pull_request) Successful in 7m17s
WAI examples / WAI examples · the archive, the readiness check, the browser and Apple · macos (pull_request) Successful in 10m8s
standards workspaces build + test / jouledesk-rs (jouledesk/jouledesk-rs, jouledesk-rs, macos) (pull_request) Successful in 8m32s
WAI examples / WAI examples · portable · linux (pull_request) Successful in 13m53s
wai-quantum WebGPU member / member · GPU, Vulkan (thor) (pull_request) Successful in 24m45s
WAI conformance / each feature of the independent verifiers' steps compiles alone (pull_request) Successful in 14m21s
wai-quantum docs, course and locales / every command and snippet in the docs · linux (pull_request) Successful in 26m3s
standards workspaces build + test / macOS energy backends (pull_request) Successful in 13m44s
WAI examples / WAI examples · android-app · linux-arm64 (pull_request) Successful in 7m1s
wai-quantum WebGPU member / member · GPU, Vulkan (jetson-hub) (pull_request) Successful in 23m54s
WAI conformance / cargo-class corpora · macos (pull_request) Successful in 18m31s
standards workspaces build + test / jouleclaw-rs (-nodebug, jouleclaw/jouleclaw-rs, -p jouleclaw-energy --features rapl,nvml, jouleclaw-rs, linux-arm64, -C target-feature=+fp16) (pull_request) Successful in 3m56s
WAI conformance / cargo-class corpora · linux-arm64 (pull_request) Successful in 20m12s
standards workspaces build + test / aac-rs (aac-conformance, aac/aac-rs, aac-rs, linux-arm64) (pull_request) Successful in 3m27s
WAI conformance / cargo-class corpora · linux (pull_request) Successful in 20m43s
standards workspaces build + test / joulecontract-rs (joulecontract/joulecontract-rs, joulecontract-rs, linux-arm64, true) (pull_request) Successful in 1m1s
standards workspaces build + test / map-rs (map-conformance, map/map-rs, map-rs, linux-arm64) (pull_request) Successful in 1m3s
standards workspaces build + test / mesh-rs (mesh/mesh-rs, -p mesh-engine-gguf -p mesh-openai --features mesh-engine-gguf/gguf,mesh-openai/server, mesh-rs, linux-arm64) (pull_request) Successful in 59s
standards workspaces build + test / openpay (openpay, openpay, linux-arm64) (pull_request) Successful in 3m30s
standards workspaces build + test / joule-code-rs (joule-code/joule-code-rs, joule-code-rs, linux-arm64, true) (pull_request) Successful in 6m32s
WAI conformance / independent verifiers · claims, JWP, key discovery and integer payloads (Python) (pull_request) Successful in 1h31m25s
joule-contrib: the SRT link tests again require every recovered packet taken before its delivery time; a recovery is pinned to when its gap was found, and a held packet keeps its margin at the link's end
The loss test's last assertion had become `margin_min <= window`, which the
receiver's clamp and the verifier's rule already guarantee: the end-to-end test
checked no timing at all. It again asserts `margin_min > 0`, the only check
across the real link (the sender's NAK handling, the connection's loop, the
proxy) that every recovered packet was taken before its own delivery time. The
ordering defect fixed in 066d82edf delivered a retransmission taken after its
drop point as recovered with a margin of 0, with nothing dropped and every
payload in order: exactly CI's failure at the old line 148. That failure fits
the defect, a busy runner's lag, or both (with the starved timer fixed in
76264fae6 lengthening the first window's recoveries); the part was not printed,
so it cannot be told which, and the earlier commit's "the bound measured the
host, not the protocol" says more than the evidence does. The window stays a
second, which absorbs the receiving task's lag seen under load. The recovery
time stays unbounded there: it counts from when the gap was found, not from the
packet's timestamp (live-contribution §6.3).

What pins where a recovery counts from is now the receivers' unit tests: they
find each gap at 20 ms rather than at the clock's origin, so a recovery counted
from 0, or from the last tick, fails them. The loss test also asserts what does
not depend on the host: every recovered packet came back as a retransmission
(the proxy neither delays nor reorders), and every NAK names a sequence number.

The caller that receives takes its time base from the listener's CONCLUSION
reply, wiring no unit test reaches. Its lossy test now checks its window, its
account (nothing dropped, a margin above 0), and a new test holds one packet
for the caller's window as the listener's test does.

A recovered packet still held when a link ends, SRT or RIST, was recorded with
a margin of 0, which reads as one taken after its delivery time; it now keeps
the time it arrived before that. A unit test for each.

A receiver unit test feeds ACKACKs through the connection's loop on a clock of
its own and pins the periodic NAK after the RTT is measured: every
(RTT + 4 x RTTVar) / 2, 30 ms at a 60 ms round trip, and the 20 ms floor at
1 ms, until the drop point. The comment on the timer test now says the periodic
NAK counts from the link's start; the NAK sent at once does not restart it.

live-contribution: §5.3 and §6.8 said a recovered packet arrives on time, which
under §6.1 does not hold for SRT: one taken after its own delivery time, before
the first packet after it that has arrived is due, is delivered late, counted
recovered with a margin of 0, and the record does not count how many. They now
say so, and §6.8 that the record does not say when a packet delivered at the
first try was taken. §4.1 and §6.1 name the drop point as the delivery time of
the first packet after it that has arrived, since the next one can itself be
missing. The CHANGELOG entry says the same.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-11-04 08:13:40 -05:00
..
src joule-contrib: the SRT link tests again require every recovered packet taken before its delivery time; a recovery is pinned to when its gap was found, and a held packet keeps its margin at the link's end 2026-11-04 08:13:40 -05:00
tests joule-contrib: the SRT link tests again require every recovered packet taken before its delivery time; a recovery is pinned to when its gap was found, and a held packet keeps its margin at the link's end 2026-11-04 08:13:40 -05:00
Cargo.toml joule-contrib: SRT and RIST contribution over UDP with retransmission 2026-10-25 22:31:09 -04:00
README.md live-contribution: registry, CI, READMEs, RIST's rate bound 2026-10-26 03:05:39 -04:00

joule-contrib

Contribution over UDP with retransmission, for WAI's ingest gateway: SRT (draft-sharabayko-srt-01) and RIST (VSF TR-06-1:2020 Simple Profile, VSF TR-06-2:2024 Main Profile), the MPEG transport stream both carry, and an account of what became of every sequence number. WAI's extensions/live-contribution.md profiles them; joule-moq-ingest uses this crate to bring a contribution link into a room's tracks.

SRT

srt::Listener serves many callers on one UDP port, each connection found by the socket ID its packets name; srt::call calls a listener. Both run the caller-listener handshake of the draft's §4.3.1 (the SYN cookie, the HSv5 extensions, the stream ID, the key material), and live mode (§7.1): every message one packet, TSBPD over the negotiated latency, too-late drop, ACK/ACKACK with the RTT estimate, immediate and periodic NAKs, retransmission, AES-CTR with the key wrapped (RFC 3394) under PBKDF2-HMAC-SHA1. A listener decides each caller through an Admission, which sees the stream ID and gives the passphrase, the role (receive or send) and the latency, or a rejection code.

RIST (feature rist)

rist::RistListener receives one flow: the Simple Profile's RTP on an even port P and RTCP on P + 1, or the Main Profile's GRE-over-UDP tunnel on one port, in reduced overhead mode with the VSF EtherType or the legacy one, keep-alives, and PSK (PBKDF2-HMAC-SHA256 over the GRE nonce, AES-CTR on the GRE sequence number). It takes the first flow whose CNAME is the one it expects, and, under PSK, whose packets decrypt. It requests what is missing with range or bitmask requests, measures the RTT with the RTT echo, and delivers each packet a buffer after it was expected. rist::send is the sender of either profile.

The account

stats::Account records what a receiver did with every sequence number, in order: delivered at the first try, recovered within the window, dropped when its time passed, or outstanding when the link ended; the loss runs, the requests sent and the numbers they named, the retransmissions, duplicates and late arrivals received, the round trips, how long each recovery took and its least margin. It is cut into parts, which the gateway signs as the link record.

The transport stream

ts::Demux reads the PAT and PMT (each section's CRC checked) and reassembles each stream's PES packets, with the PTS extended past 33 bits; a PES missing a packet is dropped whole and counted. ts::Mux writes a program of one video and one audio stream, and ts::Pacer times a stream's chunks by its PCR.

Tools

binary what
joule-contrib-send sends a transport stream file (paced by its PCR) or a synthetic program over SRT (calling or listening) or RIST
joule-contrib-recv receives over SRT or RIST into a file, and prints the link's account
joule-contrib-bench one link on loopback, both ends in the process: the payload rate, CPU time and energy, with a lossy path if asked

URLs: srt://HOST:PORT?streamid=…&passphrase=…&pbkeylen=16&latency=MS (calls; srt://:PORT listens), rist://HOST:PORT?profile=simple|main&cname=…&secret=…&aes-type=128|256&buffer=MS.

Tests

test what
unit tests RFC 3394, RFC 6070 and TR-06-2 Annex B vectors, SP 800-38A's CTR vector; the packet formats; the TR-06-1 Appendix A requests; the TS multiplexer against the demultiplexer, a lost packet, the PTS wrap; the account
srt_link SRT on loopback through a proxy that drops datagrams each way, every payload in order, the account of every sequence number; each key length, a wrong and a missing passphrase, the rejection codes; a packet held for the latency window; a listener that sends to a caller that receives
rist_link the Simple Profile with range and bitmask requests through lossy proxies; the Main Profile in the clear, under PSK of each length and in the legacy format; another CNAME and another passphrase refused
interop (ignored) against each transport's reference tools run locally, named by WAI_SRT_LIVE_TRANSMIT, WAI_RISTSENDER and WAI_RISTRECEIVER: their caller and senders into this crate and this crate into their listener and receivers, byte for byte, encrypted and through lossy paths. With --ignored, a tool not named fails the test

The lossy module's proxy drops, delays and reorders datagrams from a fixed seed.

Patents

VSF TR-06-1:2020 and TR-06-2:2024 each carry an intellectual property notice: a patent is claimed to read on their protocol sections, and its holder has assured the forum that it will license the claims to implementers. The RIST code is therefore built only with the feature rist, which no default build turns on; whether a distributed build carries it is a licensing decision for the distributor (extensions/live-contribution.md §10).

Dependencies

AES, CTR, HMAC, SHA-1 and SHA-256 from RustCrypto (MIT OR Apache-2.0); PBKDF2 (RFC 8018) and AES key wrap (RFC 3394) are written here over them. tokio, serde, serde_json, hex, tracing and rand_core: MIT or Apache-2.0. No C library is linked.

Licence

Apache-2.0.