open-standards/joule-code/joule-code-rs/crates/joule-moq/src/lib.rs
Transaction Science 1b75ba80ff joule-moq: chains verify signatures, fill gaps in any order, hold within bounds in all; the trace recovers through for_moq (NEW 7, NEW 1, NEW 2, OPEN 1)
ReceiptChains, re-implemented from WAI jwp-receipts §3 step 3 as amended:

- NEW 7: admit verifies each group's key, signature and label first
  (ReceiptVerifier::verify_group, any key); a forged group is Unverified and never
  held, admitted or anchored, joined or re-anchored.
- NEW 1: each anchor leaves a gap; a group inside it linking to either end is
  history, so an ascending FETCH after a re-anchor and a joiner's ascending fill
  are admitted (the review's two sequences, as tests).
- NEW 2: held groups indexed by link and by parent; offered again only when a group
  they link to is admitted; each signature verified once; a history count per chain
  and a total across chains beside the live count; Chain.links capped at
  CHAIN_HELD_LINKS (65 536, as WAI's reference). Tests count held groups,
  verifications and re-offers, not time.
- OPEN 1: for_moq refuses a count above MAX_HELD_GROUPS; HoldBound::from_json
  refuses a statement without counts; admit_on and ObjectReceipt::check_moqt refuse
  a receipt off its track, group or object (MoqtMismatch) unheld.

tests/staged_moq_trace.rs drops its pending queue: each subscriber's chains are
for_moq under its stated bound; the joiner subscribes at its join and anchors; the
lossy subscriber's lost receipt is recovered by re-anchoring, its layers refused;
when each receipt is verified or refused, and each status's evidence, are the
trace's.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-06 12:08:54 -04:00

98 lines
4.1 KiB
Rust

//! **joule-moq** — MoQT (Media over QUIC Transport) wire protocol + JWP receipt
//! extension for the CommunicationOS broadcast surface.
//!
//! MoQT is the IETF-track pub/sub transport for live and broadcast media over
//! QUIC. Tracks fan out through relays to subscribers; objects within a track
//! are independently addressable, cacheable, and replayable. This crate
//! delivers the wire protocol *plus* a first-class JWP receipt extension so
//! every object carries verifiable provenance, joule cost, and (optionally)
//! MLS-wrapped end-to-end ciphertext.
//!
//! ## What this crate ships
//!
//! - Wire codec for the MoQT control + data planes ([`wire`], [`messages`])
//! - Track / Group / Object identifiers and metadata ([`track`])
//! - Session state machine for publisher / subscriber / relay roles ([`session`])
//! - Endpoint trait surface ([`endpoint`])
//! - **JWP receipt extension** — batched per-group signing with Merkle inclusion
//! proofs per object, identity-bound publication, joule attribution ([`receipt`])
//! - In-memory mock for testing without QUIC ([`mock`]), whose relay also forwards
//! staged tracks on a caller-driven clock: per-hop delivery timeouts, capping by
//! subscription, and the receipts of dropped objects forwarded all the same
//! - Staged tracks, one per layer of a WAI stage set ([`staged`]), and receipt chains
//! kept per publisher key and track ([`ReceiptChains`])
//!
//! ## What this crate intentionally does not ship (yet)
//!
//! - A production QUIC implementation (gated behind the `quic` feature; v0.1
//! exposes the trait surface only).
//! - Browser-native subscriber (will be a separate WASM crate).
//! - The relay binary (`joule-moq-relay`) and publisher SDK (`joule-moq-publisher`)
//! live in their own crates and depend on this one.
//!
//! ## Standards alignment
//!
//! Targets `draft-ietf-moq-transport` (working group draft, evolving). Wire
//! constants and message types are versioned per the draft revision implemented
//! by [`MOQT_DRAFT_VERSION`]. The JWP receipt extension is a non-normative
//! addition we plan to submit as `draft-charlot-moq-jwp-extensions`.
//!
//! ## Receipt-first design
//!
//! Every endpoint role in this crate produces or consumes JWP-signed receipts
//! by construction. There is no "raw" object path that bypasses receipt
//! generation.
pub mod endpoint;
pub mod error;
pub mod messages;
pub mod mock;
pub mod receipt;
pub mod session;
pub mod staged;
pub mod track;
pub mod wai_dispatch;
pub mod wire;
#[cfg(feature = "quic")]
pub mod transport_quic;
pub use endpoint::{
MoqEndpoint, Publisher, Relay, Subscriber, SubscriptionHandle,
};
pub use error::{MoqError, MoqResult};
pub use messages::{
AnnounceMessage, ControlMessage, ObjectHeader, SetupMessage,
SubscribeMessage, SubscribeOk,
};
pub use receipt::{
compose_group_class, Admission, Anchoring, BoundRefused, ChainEvent, ChainRefusal, GroupReceipt, HoldBound, ObjectReceipt,
ReceiptChains, ReceiptVerifier, ReceiptBuilder, ReceiptsTrack, MerkleProof, VerifiedGroup, CHAIN_HELD_LINKS, CHAIN_OPEN_GAPS,
MAX_HELD_GROUPS,
};
pub use session::{MoqSession, SessionRole, SessionState};
pub use track::{
GroupId, ObjectId, ObjectStatus, Track, TrackAlias, TrackName,
TrackNamespace,
};
pub use wai_dispatch::{
is_known_capability, is_mandatory_floor, is_neural, payload_has_wai_envelope,
KNOWN_CAPABILITIES, WAI1_MAGIC, WAI2_MAGIC,
};
pub use wire::{decode_varint, encode_varint, WireCodec};
/// MoQT draft revision targeted by this crate.
///
/// The IETF MoQ working group is iterating; bumping this constant signals
/// a wire-incompatible version of the protocol.
pub const MOQT_DRAFT_VERSION: u32 = 0xff00_0008; // matches draft-08-style version
/// JWP receipt extension version.
///
/// Independent of the MoQT draft version. Bumped when the receipt header
/// schema changes. 2: the labelled object leaf and the labelled group payload
/// (optional members; a receipt without them keeps its bytes).
pub const JWP_MOQ_EXTENSION_VERSION: u8 = 2;
/// Crate version, exposed for receipt-emitting tooling.
pub const VERSION: &str = env!("CARGO_PKG_VERSION");