WAI already references MoQ for confidentiality (MLS + SFrame), and that binding treats MoQ as a pipe. MoQ is not a pipe — it is a two-layer design, and the upper layer has an open slot exactly where a container of capability-dispatched objects belongs. MOQT moves objects in groups on tracks and does not know what an object means. MSF (draft-ietf-moq-msf) says what objects mean: it fragments a stream into objects, declares what a publisher emits in a catalog, and sets prioritisation. The alignment with WAI is structural rather than aspirational — MSF's unit is an object in a group, WAI envelopes are already objects, and jwp-receipts already commits per object and signs per group. Neither layer has to change to agree. THE SLOT IS OPEN, AND CHEAPLY. MSF's `packaging` field has a fixed value set and no central registry, which reads closed. draft-ietf-moq-cmsf shows it is not: a sibling I-D that declares packaging value `cmaf`, says it extends the allowed values defined in MSF, inherits MSF wholesale, adds two track-level catalog fields, and registers nothing — "this document has no IANA actions". LOCMAF is a second instance. A sibling draft, no registry action, no permission sought. What CMSF did NOT take is the per-object slot. MSF §12 defines properties at Track AND Object scope with an IANA type registry holding essentially one entry (MSF_COMPRESSION); CMSF defines no per-object property. §5 takes that slot with WAI_RECEIPT — content hash, joules, acquisition class, group-receipt hash — which is the shape jwp-receipts already has. `acquisition` MUST accompany `joules_micro`, because a joule figure without its acquisition class is what energy-measurement §2 forbids, and putting it on a wire does not make it acceptable. The load-bearing rule is §3: the object boundary MUST be the envelope boundary. That is what makes MOQT's object identity and the receipt's per-object commitment the same unit. If they diverge, every guarantee that composes them is void. §4 makes the catalog do work rather than decorate: `wai_capabilities` MUST be exhaustive, a sink MUST NOT subscribe assuming an undeclared capability will not appear, and `wai_determinism` is the WEAKEST tier on the track — declaring the strongest would let a track advertise a guarantee most of its objects do not meet. §6 states what this does not do, so it is not re-argued: no MOQT wire encoding, no replacement for CMSF or LOC, no making MoQ WAI's transport, and no pinning of a draft revision. MOQT is pre-Last-Call; where it and this text disagree, MOQT wins and this text is what changes. Ingest queue item 13b from the landscape survey (#80 §4.4). Sourced from direct reads of draft-ietf-moq-msf and draft-ietf-moq-cmsf-00. Co-Authored-By: Claude Opus 5 <[email protected]>
7.2 KiB
WAI Extension: MoQ Streaming Format
Status: Draft, and deliberately tracking rather than pinning — MOQT is pre-Working-Group-Last-Call and its text still moves. Declares WAI as a streaming format over Media over QUIC Transport, so a WAI envelope is a first-class MOQT object rather than an opaque payload inside someone else's container. No new transport: WAI defines none by charter, and this extension does not change that. Field semantics and rules over them only — never MOQT's byte encoding. Keywords MUST, MUST NOT, SHOULD, MAY are RFC 2119/8174.
1. Why a streaming format
MoQ separates two things that other stacks fuse:
- MOQT (
draft-ietf-moq-transport) moves objects, in groups, on tracks. It does not know what an object means. - MSF (
draft-ietf-moq-msf) says what objects mean: it fragments a stream into objects, declares what a publisher emits in a catalog, and sets prioritisation.
WAI already references MoQ for confidentiality (MLS + SFrame; see confidentiality). That binding treats MoQ as a pipe. This one treats it as what it is — a two-layer design with an open slot at the upper layer, which is precisely where a container that carries capability-dispatched objects belongs.
The alignment is structural, not aspirational. MSF fragments a stream into objects in groups; WAI envelopes are already objects, and jwp-receipts already commits per object and signs per group. The two layers agree on the unit without either being changed.
2. Precedent: the slot is open, and cheaply
MSF's catalog names a format in its packaging field, over a value set MSF's own
text fixes (loc, mediatimeline, eventtimeline, moqlog, moqmetrics,
catalog). There is no central streaming-format registry. Read alone, that is
closed.
draft-ietf-moq-cmsf shows it is not. CMSF is a sibling Internet-Draft that
declares packaging value cmaf, stating that it extends the allowed packaging
values defined in MSF; inherits MSF wholesale — all of the specifications,
requirements and terminology defined in MSF apply to implementations of this
extension; adds two track-level catalog fields; and registers nothing: this
document has no IANA actions. LOCMAF is a second instance of the same move.
So the path is a sibling draft with no registry action and no permission sought. This extension is the WAI-side statement of what such a draft would say.
3. The packaging value
A track carrying WAI envelopes MUST declare packaging value "wai".
- Every object on such a track MUST be exactly one WAI envelope (
WAI1magic + manifest + payload), whole. An object carrying a fragment of an envelope, or more than one, is not this packaging. - The object boundary MUST be the envelope boundary. This is what makes the
receipt's per-object commitment (
jwp-receipts§2.1) and MOQT's object identity the same unit; if they diverge, every guarantee that composes them is void. - A sink that does not recognise
"wai"MUST NOT attempt to interpret the objects. MSF's tolerant-parser rule covers unknown fields; it does not license guessing at unknown packaging.
4. Catalog declaration
A WAI track's catalog entry MUST declare, in addition to MSF's required fields, the capabilities a sink needs to dispatch what the track carries:
| field | type | meaning |
|---|---|---|
wai_capabilities |
array of string | Capability strings (WAI SPEC.md §4) that objects on this track may dispatch to. |
wai_determinism |
string | The weakest tier any object on the track claims — see determinism-tiers. Absent means no tier is claimed. |
wai_receipts |
boolean | Whether objects carry receipts per §5. |
wai_capabilitiesMUST be exhaustive for the track. A publisher that dispatches to a capability it did not declare has broken the catalog's purpose, which is letting a sink decide before subscribing whether it can play what it is about to receive.- A sink MUST NOT subscribe on the assumption that an undeclared capability will not appear, and MUST treat an undeclared capability at dispatch as a protocol error rather than falling back silently.
wai_determinismis the weakest tier on the track, not the strongest. Declaring the strongest would let a track advertise a guarantee most of its objects do not meet.
These are custom catalog fields under MSF's extension rule; they are namespaced
by their wai_ prefix and MUST NOT collide with MSF-defined names.
5. The per-object property
MSF §12 defines MSF Properties at Track and Object scope, with an
IANA registry of property types that today holds essentially one entry
(MSF_COMPRESSION). CMSF adds track-level catalog fields and defines no
per-object property. The object-scope slot is empty.
A WAI receipt is already per-object. This extension therefore defines one
object-scope property, WAI_RECEIPT, whose value is the object's receipt
commitment:
| field | type | meaning |
|---|---|---|
content_hash |
32 B | jwp-receipts §2.1 BLAKE3 over the envelope bytes. |
joules_micro |
u64 | Microjoules producing this object. |
acquisition |
string | Acquisition class per energy-measurement §2. |
group_receipt |
32 B | BLAKE3 of the group receipt covering this object. |
acquisitionMUST accompanyjoules_micro. A joule figure without its acquisition class is exactly whatenergy-measurement.md§2 forbids, and putting it on the wire does not make it acceptable.- A relay MUST preserve this property unchanged, per
jwp-receipts§4.1. A relay that recomputes it is asserting something it did not measure. - Absence of the property is not evidence of absence of a receipt; receipts MAY
ride elsewhere (§1 of
jwp-receiptslists sidecar and trailer carriage). A sink MUST NOT infer that an object without the property is unattested.
6. What this extension does not do
Stated so it is not re-argued:
- It does not define, profile, or restate MOQT's wire encoding — not the object header, not the extension-header byte layout, not the control messages. Those are MOQT's, and the property that makes this binding cheap is that WAI rides a transport instead of defining one.
- It does not replace CMSF or LOC. A publisher with CMAF-packaged media should use CMSF; this packaging is for tracks whose objects are WAI envelopes.
- It does not make MoQ WAI's transport. WAI remains carrier-agnostic; this
is one binding among the several
jwp-receipts§1 anticipates. - It does not pin a MOQT draft revision. MOQT is pre-Last-Call; an extension that pinned a moving target would be wrong within a meeting cycle. Where MOQT and this text disagree, MOQT wins and this text is the thing that must change.
7. Framing
The delivery industry is converging on MoQ, and the layer above it is where formats declare themselves. A container that carries instructions, dispatches by capability, and commits per object has a natural home there — not because it competes with the transport, but because the transport deliberately left the question of meaning to someone else.