<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE rfc [
  <!ENTITY nbsp    "&#160;">
  <!ENTITY zwsp   "&#8203;">
  <!ENTITY nbhy   "&#8209;">
  <!ENTITY wj     "&#8288;">
]>
<?xml-stylesheet type="text/xsl" href="rfc2629.xslt" ?>
<!-- generated by https://github.com/cabo/kramdown-rfc version 1.7.29 (Ruby 3.4.4) -->
<rfc xmlns:xi="http://www.w3.org/2001/XInclude" ipr="trust200902" docName="draft-lcurley-moq-lite-00" category="info" submissionType="IETF" tocInclude="true" sortRefs="true" symRefs="true" version="3">
  <!-- xml2rfc v2v3 conversion 3.30.0 -->
  <front>
    <title abbrev="moql">Media over QUIC - Lite</title>
    <seriesInfo name="Internet-Draft" value="draft-lcurley-moq-lite-00"/>
    <author fullname="Luke Curley">
      <organization/>
      <address>
        <email>kixelated@gmail.com</email>
      </address>
    </author>
    <date year="2025" month="July" day="22"/>
    <area>wit</area>
    <workgroup>moq</workgroup>
    <abstract>
      <?line 24?>

<t>Moq-Lite is designed to fanout live content from publishers to any number of subscribers across the internet.
Liveliness is achieved by using QUIC to prioritize the most important content, potentially starving or dropping other content, to avoid head-of-line blocking while respecting encoding dependencies.
While designed for media, it is an agnostic transport, allowing relays and CDNs to forward content without knowledge of codecs, containers, or encryption keys.</t>
    </abstract>
    <note removeInRFC="true">
      <name>Discussion Venues</name>
      <t>Discussion of this document takes place on the
    Media Over QUIC Working Group mailing list (moq@ietf.org),
    which is archived at <eref target="https://mailarchive.ietf.org/arch/browse/moq/"/>.</t>
      <t>Source for this draft and an issue tracker can be found at
    <eref target="https://github.com/kixelated/moq-drafts"/>.</t>
    </note>
  </front>
  <middle>
    <?line 30?>

<section anchor="conventions-and-definitions">
      <name>Conventions and Definitions</name>
      <t>The key words "<bcp14>MUST</bcp14>", "<bcp14>MUST NOT</bcp14>", "<bcp14>REQUIRED</bcp14>", "<bcp14>SHALL</bcp14>", "<bcp14>SHALL
NOT</bcp14>", "<bcp14>SHOULD</bcp14>", "<bcp14>SHOULD NOT</bcp14>", "<bcp14>RECOMMENDED</bcp14>", "<bcp14>NOT RECOMMENDED</bcp14>",
"<bcp14>MAY</bcp14>", and "<bcp14>OPTIONAL</bcp14>" in this document are to be interpreted as
described in BCP 14 <xref target="RFC2119"/> <xref target="RFC8174"/> when, and only when, they
appear in all capitals, as shown here.</t>
      <?line -18?>

</section>
    <section anchor="rationale">
      <name>Rationale</name>
      <t>This draft is based on MoqTransport <xref target="moqt"/>.
The concepts, motivations, and terminology are very similar and when in doubt, refer to the upstream draft.
However, a few things have been renamed because I think they make the concepts clearer (and I couldn't help myself).</t>
      <t>I absolutely believe in the motivation and potential of Media over QUIC.
The layering is phenomenal and addresses many of the problems with current live media protocols.
I fully support the goals of the working group and the IETF process.
But it's been difficult to design such an experimental protocol via committee.</t>
      <t>MoqTransport has become too complicated.
There are too many messages, optional modes, and half-baked features.
Too many hypotheses, too many potential use-cases, too many diametrically opposed opinions.
This is expected (and even desired) as compromise gives birth to a standard.</t>
      <t>But the specification has become a distraction and I think it impedes progress.
I believe that MoQ is an experiment that needs to be proven before it can be cemented.
We should spend more time building an <em>actual</em> application and less time arguing about a hypothetical one.
I can't waste any more time on FETCH and other fringe functionality.</t>
      <t>moq-lite is the bare minimum needed for a real-time conferencing application <em>only</em>.
Every feature from MoqTransport that is not necessary (or has not been implemented yet) has been removed for simplicity.
This includes many great ideas (ex. group order) that are just not worth implementing at the moment.
This draft is the current state, not the end state.</t>
    </section>
    <section anchor="concepts">
      <name>Concepts</name>
      <t>moq-lite consists of:</t>
      <ul spacing="normal">
        <li>
          <t><strong>Session</strong>: An established QUIC connection between a client and server.</t>
        </li>
        <li>
          <t><strong>Broadcast</strong>: A collection of Tracks from a single publisher.</t>
        </li>
        <li>
          <t><strong>Track</strong>: An series of Groups, each of which can be delivered and decoded <em>out-of-order</em>.</t>
        </li>
        <li>
          <t><strong>Group</strong>: An series of Frames, each of which must be delivered and decoded <em>in-order</em>.</t>
        </li>
        <li>
          <t><strong>Frame</strong>: A sized payload of bytes representing a single moment in time.</t>
        </li>
      </ul>
      <t>The application determines how to split data into broadcast, tracks, groups, and frames.
The moq-lite layer provides fanout, prioritization, and caching even for latency sensitive applications.</t>
      <section anchor="session">
        <name>Session</name>
        <t>A Session consists of a connection between a QUIC client and server.</t>
        <t>A session is established after the necessary QUIC, WebTransport, and moq-lite handshakes.
The moq-lite handshake consists of version and extension negotiation.</t>
        <t>The intent is that sessions are transparently chained together via relays.
A broadcaster could establish a session with an CDN ingest edge while the viewers establish separate sessions to CDN distribution edges.
A moq-lite session is hop-by-hop, but the application should be designed end-to-end.</t>
      </section>
      <section anchor="broadcast">
        <name>Broadcast</name>
        <t>A Broadcast is a collection of Tracks from a single publisher.
This cooresponds to a MoqTransport "track namespace".</t>
        <t>A publisher may produce multiple broadcasts.
The available broadcasts are advertised via an ANNOUNCE message and a subscriber can discover available broadcasts via an ANNOUNCE_PLEASE message.
These announcements are live and can change over time, allowing for dynamic origin discovery.</t>
        <t>A broadcast consists of any number of Tracks.
These tracks are related by name only and there's no requirement that they have the same content.
Tracks are not advertised as part of a broadcast; they must be discovered via an out-of-band mechanism.
For example, a "catalog" file or track that describes the broadcast.</t>
      </section>
      <section anchor="track">
        <name>Track</name>
        <t>A Track is a series of Groups identified by a unique name within a Broadcast.</t>
        <t>A track consists of a single active Group at any moment.
When a new Group is started, the previous Group is closed and any unconsumed content may be dropped.</t>
        <t>Each subscription is scoped to a single Track.
A subscription will always start at the latest Group and continues until either the publisher or subscriber cancels the subscription.
The publisher closes a Group when a new Group is started.</t>
        <t>A subscriber chooses the priority of each subscription, hinting to the publisher which Track should arrive first during congestion.
This enables the most important content to arrive during network degradation while still respecting encoding dependencies.</t>
      </section>
      <section anchor="group">
        <name>Group</name>
        <t>A Group is an ordered stream of Frames within a Track.</t>
        <t>Each group consists of a sequence number and an appendable set of Frames.
The sequence number is an increasing integer for each new group in the same Track.
Different tracks may use the same group sequence number for alignment purposes; it's up to the application to handle this.</t>
        <t>A Group is served by a dedicated QUIC stream which is closed on completion, reset by the publisher, or cancelled by the subscriber.
The Frames within a Group will arrive reliably and in order thanks to the QUIC stream.
In contrast, Groups may temporarily arrive out of order due to network congestion and the application should be prepared to handle this.</t>
      </section>
      <section anchor="frame">
        <name>Frame</name>
        <t>A Frame is a payload of bytes within a Group.</t>
        <t>A frame is used to represent a chunk of data with a known size.
A frame should represent a single moment in time and avoid any buffering that would increase latency.</t>
      </section>
    </section>
    <section anchor="flow">
      <name>Flow</name>
      <t>This section outlines the flow of messages within a moq-lite session.
See the section for Messages section for the specific encoding.</t>
      <section anchor="connection">
        <name>Connection</name>
        <t>moq-lite runs on top of WebTransport.
WebTransport is a layer on top of QUIC and HTTP/3, required for web support.
The API is nearly identical to QUIC, however notably lacks stream IDs and has fewer available error codes.</t>
        <t>How the WebTransport connection is established is out-of-scope for this draft.
For example, a service <bcp14>MAY</bcp14> use the WebTransport handshake to perform authentication via the URL.</t>
      </section>
      <section anchor="termination">
        <name>Termination</name>
        <t>QUIC bidirectional streams have an independent send and receive direction.
Rather than deal with half-open states, moq-lite combines both sides.
If an endpoint closes the send direction of a stream, the peer <bcp14>MUST</bcp14> also close the send direction.</t>
        <t>moq-lite contains many long-lived transactions, such as subscriptions and announcements.
These are terminated when the underlying QUIC stream is terminated.</t>
        <t>To terminate a stream, an endpoint may:
- close the send direction (STREAM with FIN) to gracefully terminate (all messages are flushed).
- reset the send direction (RESET_STREAM) to immediately terminate.</t>
        <t>After resetting the send direction, an endpoint <bcp14>MAY</bcp14> close the recv direction (STOP_SENDING).
However, it is ultimately the other peer's responsibility to close their send direction.</t>
      </section>
      <section anchor="handshake">
        <name>Handshake</name>
        <t>After a connection is established, the client opens a Session Stream and sends a SESSION_CLIENT message, to which the server replies with a SESSION_SERVER message.
The session is active until either endpoint closes or resets the Session Stream.</t>
        <t>This session handshake is used to negotiate the moq-lite version and any extensions.
See the Extension section for more information.</t>
      </section>
    </section>
    <section anchor="streams">
      <name>Streams</name>
      <t>moq-lite uses a bidirectional stream for each transaction.
If the stream is closed, potentially with an error, the transaction is terminated.</t>
      <section anchor="bidirectional-streams">
        <name>Bidirectional Streams</name>
        <t>Bidirectional streams are used for control streams.
There's a 1-byte STREAM_TYPE at the beginning of each stream.</t>
        <table>
          <thead>
            <tr>
              <th align="right">ID</th>
              <th align="left">Stream</th>
              <th align="left">Creator</th>
            </tr>
          </thead>
          <tbody>
            <tr>
              <td align="right">0x0</td>
              <td align="left">Session</td>
              <td align="left">Client</td>
            </tr>
            <tr>
              <td align="right">0x1</td>
              <td align="left">Announce</td>
              <td align="left">Subscriber</td>
            </tr>
            <tr>
              <td align="right">0x2</td>
              <td align="left">Subscribe</td>
              <td align="left">Subscriber</td>
            </tr>
          </tbody>
        </table>
        <section anchor="session-1">
          <name>Session</name>
          <t>There is a single Session Stream per WebTransport session.</t>
          <t>The client <bcp14>MUST</bcp14> open a single Session Stream immediately
After establishing the QUIC/WebTransport session, the client opens a Session Stream.
There <bcp14>MUST</bcp14> be only one Session Stream per WebTransport session and its closure by either endpoint indicates the moq-lite session is closed.</t>
          <t>The client sends a SESSION_CLIENT message indicating the supported versions and extensions.
If the server does not support any of the client's versions, it <bcp14>MUST</bcp14> close the stream with an error code and <bcp14>MAY</bcp14> close the connection.
Otherwise, the server replies with a SESSION_SERVER message to complete the handshake.</t>
          <t>Afterwards, both endpoints <bcp14>SHOULD</bcp14> send SESSION_UPDATE messages, such as after a significant change in the session bitrate.</t>
          <t>This draft's version is combined with the constant <tt>0xff0dad00</tt>.
For example, moq-lite-draft-03 is identified as <tt>0xff0dad03</tt>.</t>
        </section>
        <section anchor="announce">
          <name>Announce</name>
          <t>A subscriber can open a Announce Stream to discover broadcasts matching a prefix.
This is <bcp14>OPTIONAL</bcp14> and the application can determine track paths out-of-band.</t>
          <t>The subscriber creates the stream with a ANNOUNCE_PLEASE message.
The publisher replies with ANNOUNCE messages for any matching broadcasts.
Each ANNOUNCE message contains one of the following statuses:</t>
          <ul spacing="normal">
            <li>
              <t><tt>active</tt>: a matching broadcast is available.</t>
            </li>
            <li>
              <t><tt>ended</tt>: a previously <tt>active</tt> broadcast is no longer available.</t>
            </li>
          </ul>
          <t>Each broadcast starts as <tt>ended</tt> and <bcp14>MUST</bcp14> alternate between <tt>active</tt> and <tt>ended</tt>.
The subscriber <bcp14>MUST</bcp14> reset the stream if it receives a duplicate status, such as two <tt>active</tt> statuses in a row or an <tt>ended</tt> without <tt>active</tt>.
When the stream is closed, the subscriber <bcp14>MUST</bcp14> assume that all broadcasts are now <tt>ended</tt>.</t>
          <t>Path prefix matching and equality is done on a byte-by-byte basis.
There <bcp14>MAY</bcp14> be multiple Announce Streams, potentially containing overlapping prefixes, that get their own copy of each ANNOUNCE.</t>
        </section>
      </section>
      <section anchor="subscribe">
        <name>Subscribe</name>
        <t>A subscriber can open a Subscribe Stream to request a Track.</t>
        <t>The subscriber <bcp14>MUST</bcp14> start a Subscribe Stream with a SUBSCRIBE message followed by any number of SUBSCRIBE_UPDATE messages.
The publisher <bcp14>MUST</bcp14> reply with an SUBSCRIBE_OK message.</t>
        <t>The publisher <bcp14>SHOULD</bcp14> close the stream after the track has ended.
Either endpoint <bcp14>MAY</bcp14> reset/cancel the stream at any time.</t>
      </section>
      <section anchor="unidirectional-streams">
        <name>Unidirectional Streams</name>
        <t>Unidirectional streams are used for data transmission.</t>
        <table>
          <thead>
            <tr>
              <th align="right">ID</th>
              <th align="left">Stream</th>
              <th align="left">Creator</th>
            </tr>
          </thead>
          <tbody>
            <tr>
              <td align="right">0x0</td>
              <td align="left">Group</td>
              <td align="left">Publisher</td>
            </tr>
          </tbody>
        </table>
        <section anchor="group-1">
          <name>Group</name>
          <t>A publisher creates Group Streams in response to a Subscribe Stream.</t>
          <t>A Group Stream <bcp14>MUST</bcp14> start with a GROUP message and <bcp14>MAY</bcp14> be followed by any number of FRAME messages.
A Group <bcp14>MAY</bcp14> contain zero FRAME messages, potentially indicating a gap in the track.
A frame <bcp14>MAY</bcp14> contain an empty payload, potentially indicating a gap in the group.</t>
          <t>Both the publisher and subscriber <bcp14>MAY</bcp14> reset the stream at any time.</t>
        </section>
      </section>
    </section>
    <section anchor="encoding">
      <name>Encoding</name>
      <t>This section covers the encoding of each message.</t>
      <section anchor="streamtype">
        <name>STREAM_TYPE</name>
        <t>All streams start with a short header indicating the stream type.</t>
        <artwork><![CDATA[
STREAM_TYPE {
  Stream Type (i)
}
]]></artwork>
        <t>The stream ID depends on if it's a bidirectional or unidirectional stream, as indicated in the Streams section.
A reciever <bcp14>MUST</bcp14> close the session if it receives an unknown stream type.</t>
      </section>
      <section anchor="sessionclient">
        <name>SESSION_CLIENT</name>
        <t>The client initiates the session by sending a SESSION_CLIENT message.</t>
        <artwork><![CDATA[
SESSION_CLIENT Message {
  Supported Versions Count (i)
  Supported Version (i)
  Extension Count (i)
  [
    Extension ID (i)
    Extension Payload (b)
  ]...
}
]]></artwork>
      </section>
      <section anchor="sessionserver">
        <name>SESSION_SERVER</name>
        <t>The server responds with the selected version and any extensions.</t>
        <artwork><![CDATA[
SESSION_SERVER Message {
  Selected Version (i)
  Extension Count (i)
  [
    Extension ID (i)
    Extension Payload (b)
  ]...
}
]]></artwork>
      </section>
      <section anchor="sessionupdate">
        <name>SESSION_UPDATE</name>
        <artwork><![CDATA[
SESSION_UPDATE Message {
  Session Bitrate (i)
}
]]></artwork>
        <t><strong>Session Bitrate</strong>:
The estimated bitrate of the QUIC connection in bits per second.
This <bcp14>SHOULD</bcp14> be sourced directly from the QUIC congestion controller.
A value of 0 indicates that this information is not available.</t>
      </section>
      <section anchor="announceplease">
        <name>ANNOUNCE_PLEASE</name>
        <t>A subscriber sends an ANNOUNCE_PLEASE message to indicate it wants to receive an ANNOUNCE message for any broadcasts with a path that starts with the requested prefix.</t>
        <artwork><![CDATA[
ANNOUNCE_PLEASE Message {
  Broadcast Path Prefix (s),
}
]]></artwork>
        <t><strong>Broadcast Path Prefix</strong>:
Indicate interest for any broadcasts with a path that starts with this prefix.</t>
        <t>The publisher <bcp14>MAY</bcp14> close the stream with an error code if the prefix is too expansive.
Otherwise, the publisher <bcp14>SHOULD</bcp14> respond with an ANNOUNCE message for any matching broadcasts.</t>
      </section>
      <section anchor="announce-1">
        <name>ANNOUNCE</name>
        <t>A publisher sends an ANNOUNCE message to advertise a broadcast in response to an ANNOUNCE_PLEASE.
Only the suffix is encoded on the wire, the full path is constructed by prepending the requested prefix.</t>
        <artwork><![CDATA[
ANNOUNCE Message {
  Announce Status (i),
  Broadcast Path Suffix (s),
}
]]></artwork>
        <t><strong>Announce Status</strong>:
A flag indicating the announce status.</t>
        <ul spacing="normal">
          <li>
            <t><tt>ended</tt> (0): A path is no longer available.</t>
          </li>
          <li>
            <t><tt>active</tt> (1): A path is now available.</t>
          </li>
        </ul>
        <t><strong>Broadcast Path Suffix</strong>:
This is combined with the broadcast path prefix to form the full broadcast path.</t>
      </section>
      <section anchor="subscribe-1">
        <name>SUBSCRIBE</name>
        <t>SUBSCRIBE is sent by a subscriber to start a subscription.</t>
        <artwork><![CDATA[
SUBSCRIBE Message {
  Subscribe ID (i)
  Broadcast Path (s)
  Track Name (s)
  Subscriber Priority (i)
}
]]></artwork>
        <t><strong>Subscribe ID</strong>:
A unique idenfier chosen by the subscriber.
A Subscribe ID <bcp14>MUST NOT</bcp14> be reused within the same session, even if the prior subscription has been closed.</t>
        <t><strong>Subscriber Priority</strong>:
The transmission priority of the subscription relative to all other active subscriptions within the session.
The publisher <bcp14>SHOULD</bcp14> transmit <em>higher</em> values first during congestion.
If there is a tie, a publisher <bcp14>MAY</bcp14> use the Publisher Priority as a tiebreaker.</t>
      </section>
      <section anchor="subscribeupdate">
        <name>SUBSCRIBE_UPDATE</name>
        <t>A subscriber can modify a subscription with a SUBSCRIBE_UPDATE message.</t>
        <artwork><![CDATA[
SUBSCRIBE_UPDATE Message {
  Subscriber Priority (i)
}
]]></artwork>
        <t><strong>Subscriber Priority</strong>:
The new subscriber priority; see SUBSCRIBE.</t>
      </section>
      <section anchor="subscribeok">
        <name>SUBSCRIBE_OK</name>
        <t>The SUBSCRIBE_OK is sent in response to a SUBSCRIBE.
It contains information about the subscription</t>
        <artwork><![CDATA[
SUBSCRIBE_OK Message {
  Publisher Priority (i)
}
]]></artwork>
        <t><strong>Publisher Priority</strong>:
The priority of the subscription as indicated by the publisher.
This <bcp14>SHOULD</bcp14> be used as a tiebreaker when the Subscriber Priority is the same.</t>
        <t><strong>Meta</strong>: This field isn't super useful and could have been removed, but we should encode <em>something</em> to acknowledge the subscription.</t>
      </section>
      <section anchor="group-2">
        <name>GROUP</name>
        <t>The GROUP message contains information about a Group, as well as a reference to the subscription being served.</t>
        <artwork><![CDATA[
GROUP Message {
  Subscribe ID (i)
  Group Sequence (i)
}
]]></artwork>
        <t><strong>Subscribe ID</strong>:
The corresponding Subscribe ID.
This ID is used to distinguish between multiple subscriptions for the same track.</t>
        <t><strong>Group Sequence</strong>:
The sequence number of the group.
This <bcp14>SHOULD</bcp14> increase by 1 for each new group.</t>
      </section>
      <section anchor="frame-1">
        <name>FRAME</name>
        <t>The FRAME message is a payload at a specific point of time.</t>
        <artwork><![CDATA[
FRAME Message {
  Payload (b)
}
]]></artwork>
        <t><strong>Payload</strong>:
An application specific payload.
A generic library or relay <bcp14>MUST NOT</bcp14> inspect or modify the contents unless otherwise negotiated.</t>
      </section>
    </section>
    <section anchor="appendix-a-changelog">
      <name>Appendix A: Changelog</name>
      <t>A quick comparison of moq-lite and moq-transport-10:</t>
      <section anchor="deleted-messages">
        <name>Deleted Messages</name>
        <ul spacing="normal">
          <li>
            <t>GOAWAY</t>
          </li>
          <li>
            <t>MAX_SUBSCRIBE_ID</t>
          </li>
          <li>
            <t>SUBSCRIBES_BLOCKED</t>
          </li>
          <li>
            <t>SUBSCRIBE_ERROR</t>
          </li>
          <li>
            <t>UNSUBSCRIBE</t>
          </li>
          <li>
            <t>SUBSCRIBE_DONE</t>
          </li>
          <li>
            <t>FETCH</t>
          </li>
          <li>
            <t>FETCH_OK</t>
          </li>
          <li>
            <t>FETCH_ERROR</t>
          </li>
          <li>
            <t>FETCH_CANCEL</t>
          </li>
          <li>
            <t>TRACK_STATUS_REQUEST</t>
          </li>
          <li>
            <t>TRACK_STATUS</t>
          </li>
          <li>
            <t>ANNOUNCE_OK</t>
          </li>
          <li>
            <t>ANNOUNCE_ERROR</t>
          </li>
          <li>
            <t>ANNOUNCE_CANCEL</t>
          </li>
          <li>
            <t>SUBSCRIBE_ANNOUNCES_OK</t>
          </li>
          <li>
            <t>SUBSCRIBE_ANNOUNCES_ERROR</t>
          </li>
          <li>
            <t>UNSUBSCRIBE_ANNOUNCES</t>
          </li>
          <li>
            <t>FETCH_HEADER</t>
          </li>
          <li>
            <t>OBJECT_DATAGRAM</t>
          </li>
          <li>
            <t>OBJECT_DATAGRAM_STATUS</t>
          </li>
        </ul>
      </section>
      <section anchor="deleted-fields">
        <name>Deleted Fields</name>
        <t>Some of these fields occur in multiple messages.</t>
        <ul spacing="normal">
          <li>
            <t>Track Alias</t>
          </li>
          <li>
            <t>Group Order</t>
          </li>
          <li>
            <t>Filter Type</t>
          </li>
          <li>
            <t>StartGroup</t>
          </li>
          <li>
            <t>StartObject</t>
          </li>
          <li>
            <t>EndGroup</t>
          </li>
          <li>
            <t>Expires</t>
          </li>
          <li>
            <t>ContentExists</t>
          </li>
          <li>
            <t>Largest Group ID</t>
          </li>
          <li>
            <t>Largest Object ID</t>
          </li>
          <li>
            <t>Subscribe Parameters</t>
          </li>
          <li>
            <t>Announce Parameters</t>
          </li>
          <li>
            <t>Subgroup ID</t>
          </li>
          <li>
            <t>Object ID</t>
          </li>
          <li>
            <t>Object Status</t>
          </li>
          <li>
            <t>Extension Headers</t>
          </li>
        </ul>
      </section>
      <section anchor="misc-changes">
        <name>Misc Changes</name>
        <ul spacing="normal">
          <li>
            <t>Messages don't have an encoded length.</t>
          </li>
          <li>
            <t>Track Namespace (renamed to Broadcast Path) is a string, not an array of bytes.</t>
          </li>
          <li>
            <t>Track Name is a string, not bytes.</t>
          </li>
        </ul>
      </section>
    </section>
    <section anchor="security-considerations">
      <name>Security Considerations</name>
      <t>TODO Security</t>
    </section>
    <section anchor="iana-considerations">
      <name>IANA Considerations</name>
      <t>This document has no IANA actions.</t>
    </section>
  </middle>
  <back>
    <references anchor="sec-normative-references">
      <name>Normative References</name>
      <reference anchor="moqt">
        <front>
          <title>Media over QUIC Transport</title>
          <author fullname="Suhas Nandakumar" initials="S." surname="Nandakumar">
            <organization>Cisco</organization>
          </author>
          <author fullname="Victor Vasiliev" initials="V." surname="Vasiliev">
            <organization>Google</organization>
          </author>
          <author fullname="Ian Swett" initials="I." surname="Swett">
            <organization>Google</organization>
          </author>
          <author fullname="Alan Frindell" initials="A." surname="Frindell">
            <organization>Meta</organization>
          </author>
          <date day="7" month="July" year="2025"/>
          <abstract>
            <t>   This document defines the core behavior for Media over QUIC Transport
   (MOQT), a media transport protocol designed to operate over QUIC and
   WebTransport, which have similar functionality.  MOQT allows a
   producer of media to publish data and have it consumed via
   subscription by a multiplicity of endpoints.  It supports
   intermediate content distribution networks and is designed for high
   scale and low latency distribution.

            </t>
          </abstract>
        </front>
        <seriesInfo name="Internet-Draft" value="draft-ietf-moq-transport-13"/>
      </reference>
      <reference anchor="RFC2119">
        <front>
          <title>Key words for use in RFCs to Indicate Requirement Levels</title>
          <author fullname="S. Bradner" initials="S." surname="Bradner"/>
          <date month="March" year="1997"/>
          <abstract>
            <t>In many standards track documents several words are used to signify the requirements in the specification. These words are often capitalized. This document defines these words as they should be interpreted in IETF documents. This document specifies an Internet Best Current Practices for the Internet Community, and requests discussion and suggestions for improvements.</t>
          </abstract>
        </front>
        <seriesInfo name="BCP" value="14"/>
        <seriesInfo name="RFC" value="2119"/>
        <seriesInfo name="DOI" value="10.17487/RFC2119"/>
      </reference>
      <reference anchor="RFC8174">
        <front>
          <title>Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words</title>
          <author fullname="B. Leiba" initials="B." surname="Leiba"/>
          <date month="May" year="2017"/>
          <abstract>
            <t>RFC 2119 specifies common key words that may be used in protocol specifications. This document aims to reduce the ambiguity by clarifying that only UPPERCASE usage of the key words have the defined special meanings.</t>
          </abstract>
        </front>
        <seriesInfo name="BCP" value="14"/>
        <seriesInfo name="RFC" value="8174"/>
        <seriesInfo name="DOI" value="10.17487/RFC8174"/>
      </reference>
    </references>
    <?line 508?>

<section numbered="false" anchor="acknowledgments">
      <name>Acknowledgments</name>
      <t>TODO acknowledge.</t>
    </section>
  </back>
  <!-- ##markdown-source:
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
4lGePE3+B1C+prv0QwAA

-->

</rfc>
