<?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.21 (Ruby 3.3.6) -->
<rfc xmlns:xi="http://www.w3.org/2001/XInclude" ipr="trust200902" docName="draft-lcurley-moq-transfork-03" category="info" submissionType="IETF" tocInclude="true" sortRefs="true" symRefs="true" version="3">
  <!-- xml2rfc v2v3 conversion 3.25.0 -->
  <front>
    <title abbrev="moqtf">Media over QUIC - Transfork</title>
    <seriesInfo name="Internet-Draft" value="draft-lcurley-moq-transfork-03"/>
    <author fullname="Luke Curley">
      <organization>Discord</organization>
      <address>
        <email>kixelated@gmail.com</email>
      </address>
    </author>
    <date year="2025" month="January" day="16"/>
    <area>wit</area>
    <workgroup>moq</workgroup>
    <abstract>
      <?line 25?>

<t>MoqTransfork is designed to serve live tracks over a CDN to viewers with varying latency and quality targets: the entire spectrum between real-time and VOD.
MoqTransfork itself is a media agnostic transport, allowing relays and CDNs to forward the most important content under degraded networks without knowledge of codecs, containers, or even if the content is fully encrypted.
Higher level protocols specify how to use MoqTransfork to encode and deliver video, audio, messages, or any form of live content.</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 31?>

<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="fork">
      <name>Fork</name>
      <t>This draft is based on moq-transport-03 <xref target="moqt"/>.
The concepts, motivations, and terminology are very similar on purpose.
When in doubt, refer to the upstream draft.</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.</t>
      <t>But there are practical and conceptual flaws with MoqTransport that need to be addressed.
However it's been difficult to design such an experimental protocol via committee.
Despite years of arguments in person and on GitHub, we've yet to align on even the most critical property of the transport... how to utilize QUIC.
The result is inevitably an unwieldy "compromise", consisting of a modes for each party that make everything more difficult to support or explain.</t>
      <t>In our RUSH to standardize a protocol, the QUICR solutions have led to WARP in ideals.</t>
      <t>This fork is meant to be a constructive, alternative vision.
I would like to lead by example, demonstrating that you can support real media use-cases while simplifying the protocol.
The working group will keep making progress and hopefully many of these ideas will be incorporated.</t>
      <t>The appendix contains a list of high level differences between MoqTransport and MoqTransfork.</t>
    </section>
    <section anchor="concepts">
      <name>Concepts</name>
      <t>MoqTransfork consists of:</t>
      <ul spacing="normal">
        <li>
          <t><strong>Session</strong>: An established connection between a client and server used to transmit any number of Tracks by path.</t>
        </li>
        <li>
          <t><strong>Track</strong>: An series of Groups, each of which is delivered and decoded <em>independently</em>.</t>
        </li>
        <li>
          <t><strong>Group</strong>: An series of Frames, each of which is delivered and decoded *in orde.</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 tracks, groups, and frames.
MoqTransfork is responsible for the caching and delivery by utilizing rules encoded in headers.
This provides robust and generic one-to-many transmission, 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 MoqTransfork handshakes.
The MoqTransfork handshake consists of version and extension negotiation.</t>
        <t>The intent is that sessions are 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 MoqTransfork session is hop-by-hop, but the application should be designed end-to-end.</t>
      </section>
      <section anchor="track">
        <name>Track</name>
        <t>A Track is a series of Groups identified by a unique path.
A MoqTransfork session is used to publish and subscribe to multiple, potentially unrelated, tracks.</t>
        <t>A Track path consists of string parts used to route subscriptions to the correct publisher.
The application determines the structure and encoding of the path.
A Track path <bcp14>MUST</bcp14> be unique within a Session and <bcp14>SHOULD</bcp14> contain entropy to avoid collisions with other sessions, for example timestamps or random values.</t>
        <t>A publisher can advertise available tracks via an ANNOUNCE message.
This allows a subscriber to dynamically discover available tracks based on a prefix.
For example: <tt>["meeting", "1234", "alice"]</tt> and <tt>["meeting", "1234", "bob"]</tt>
Alternatively, the application can discover tracks via an out-of-band mechanism.</t>
        <t>Each subscription is scoped to a single Track.
A subscription will always start at a Group boundary, either the latest group or a specified sequence number.
A subscriber chooses the ordering and priority of each subscription, hinting to the publisher which Track should arrive first during congestion.
This is critical for a decent user experience during network degradation and the core reason why QUIC can offer real-time latency.</t>
      </section>
      <section anchor="group">
        <name>Group</name>
        <t>A Group is an ordered stream of Frames within a Track.</t>
        <t>A group is served by a dedicated QUIC stream which may be closed on completion, reset by the publisher, or cancelled by the subscriber.
An active subscription involves delivering multiple potential concurrent groups.
The Frames within a Group will arrive reliably and in order thanks to the QUIC stream.
However, Groups within a Track can arrive in any order or not at all, and which the application should be prepared to handle.</t>
        <t>A subscriber may FETCH a specific group starting at a given byte offset.
This is similar to a HTTP request and may be used to recover from partial failures among other things.</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 anchor="liveliness">
        <name>Liveliness</name>
        <t>A media protocol can only be considered "live" if it can handle degraded network congestion.
MoqTransfork handles this by prioritizing the most important media while the remainder is starved.</t>
        <t>The importance of each track/group/frame is signaled by the subscriber and the publisher will attempt to obey it.
Subscribers signal importance using Track Priority and Group Order.
Any data that is excessively starved may be dropped (by either endpoint) rather than block the live stream.</t>
        <t>A publisher that serves multiple sessions, commonly a relay, should prioritize on a per-session basis.
Alice may want real-time latency with a preference for audio, while Bob may want reliable playback while audio is muted.
A relay <bcp14>MAY</bcp14> forward subscriber preferences upstream, but when there is a conflict (like the above example), the publisher's preference should be used as a tiebreaker.</t>
      </section>
    </section>
    <section anchor="workflow">
      <name>Workflow</name>
      <t>This section outlines the flow of messages within a MoqTransfork session.
See the section for Messages section for the specific encoding.</t>
      <section anchor="connection">
        <name>Connection</name>
        <t>MoqTransfork 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, MoqTransfork 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>MoqTransfork 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 MoqTransfork version and any extensions.
See the Extension section for more information.</t>
      </section>
    </section>
    <section anchor="streams">
      <name>Streams</name>
      <t>MoqTransfork involves many concurrent streams.</t>
      <t>Each transactional action, such as a SUBSCRIBE, is sent over it's own stream.
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 primarily 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">Announced</td>
              <td align="left">Subscriber</td>
            </tr>
            <tr>
              <td align="right">0x2</td>
              <td align="left">Subscribe</td>
              <td align="left">Subscriber</td>
            </tr>
            <tr>
              <td align="right">0x3</td>
              <td align="left">Fetch</td>
              <td align="left">Subscriber</td>
            </tr>
            <tr>
              <td align="right">0x4</td>
              <td align="left">Info</td>
              <td align="left">Subscriber</td>
            </tr>
          </tbody>
        </table>
        <section anchor="session-1">
          <name>Session</name>
          <t>The Session stream contains all messages that are session level.</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 MoqTransfork 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>0xff0bad00</tt>.
For example, moq-transfork-draft-03 is identified as <tt>0xff0bad03</tt>.</t>
        </section>
        <section anchor="announce">
          <name>Announce</name>
          <t>A subscriber can open a Announce Stream to discover tracks matching a prefix.
This is <bcp14>OPTIONAL</bcp14> and the application can determine track paths out-of-band.</t>
          <t>The subscriber starts the stream with a ANNOUNCE_PLEASE message.
The publisher replies with ANNOUNCE messages for any matching tracks.
Each ANNOUNCE message contains one of the following statuses:</t>
          <ul spacing="normal">
            <li>
              <t><tt>active</tt>: a matching track is available.</t>
            </li>
            <li>
              <t><tt>ended</tt>: a previously <tt>active</tt> track is no longer available.</t>
            </li>
            <li>
              <t><tt>live</tt>: all active tracks have been sent.</t>
            </li>
          </ul>
          <t>Each track starts as <tt>ended</tt> can transition to and from the <tt>active</tt>.
The subscriber <bcp14>SHOULD</bcp14> close 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>.</t>
          <t>The <tt>live</tt> status applies to the entire stream instead of a single track.
It <bcp14>SHOULD</bcp14> be sent by the publisher after all <tt>active</tt> ANNOUNCE messages have been sent.
The subscriber <bcp14>SHOULD</bcp14> use this as a signal that it has caught up, for example a track may not exist.</t>
          <t>Prefix matching is done on a part-by-part basis.
For example, a prefix of <tt>["meeting"]</tt> would match <tt>["meeting", "1234"]</tt> but not <tt>["meeting-1234"]</tt>.
The application is responsible for the encoding of the prefix, taking case to avoid any ambiguity such as multiple ways to encode the same value.</t>
          <t>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 Info Stream with a SUBSCRIBE message followed by any number SUBSCRIBE_UPDATE messages.
The publisher <bcp14>MUST</bcp14> reply with an INFO message followed by any number of SUBSCRIBE_GAP messages.
A publisher <bcp14>MAY</bcp14> reset the stream at any point if it is unable to serve the subscription.</t>
        <t>The publisher <bcp14>MUST</bcp14> transmit a complete Group Stream or a SUBSCRIBE_GAP message for each Group within the subscription range.
This means the publisher <bcp14>MUST</bcp14> transmit a SUBSCRIBE_GAP if a Group Stream is reset.
The subscriber <bcp14>SHOULD</bcp14> close the subscription when all GROUP and SUBSCRIBE_GAP messages have been received, and the publisher <bcp14>MAY</bcp14> close the subscription after all messages have been acknowledged.</t>
      </section>
      <section anchor="fetch">
        <name>Fetch</name>
        <t>A subscriber can open a Fetch Stream to receive a single Group at a specified offset.
This is primarily used to recover from an abrupt stream termination, causing the truncation of a Group.</t>
        <t>The subscriber <bcp14>MUST</bcp14> start a Fetch Stream with a FETCH message followed by any number of FETCH_UPDATE messages.
The publisher <bcp14>MUST</bcp14> reply with the contents of a Group Stream, except starting at the specified offset <em>after</em> the GROUP message.
Note that this includes any FRAME messages.</t>
        <t>The fetch is active until both endpoints close the stream, or either endpoint resets the stream.</t>
      </section>
      <section anchor="info">
        <name>Info</name>
        <t>A subscriber can open an Info Stream to request information about a track.
This is not often necessary as SUBSCRIBE will trigger an INFO reply.</t>
        <t>The subscriber <bcp14>MUST</bcp14> start the stream with a INFO_PLEASE message.
The publisher <bcp14>MUST</bcp14> reply with an INFO message or reset the stream.
Both endpoints <bcp14>MUST</bcp14> close the stream afterwards.</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.
When a Group stream is reset, the publisher <bcp14>MUST</bcp14> send a SUBSCRIBE_GAP message on the corresponding Subscribe stream.
A future version of this draft may utilize reliable reset instead.</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 any corresponding ANNOUNCE messages.</t>
        <artwork><![CDATA[
ANNOUNCE_PLEASE Message {
  Track Prefix Parts (i),
  [ Track Prefix Part (b) ]
}
]]></artwork>
        <t><strong>Track Prefix</strong>:
Indicate interest for any tracks that start with this prefix.
This uses byte-for-byte matching on each prefix part.</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 tracks.</t>
      </section>
      <section anchor="announce-1">
        <name>ANNOUNCE</name>
        <t>A publisher sends an ANNOUNCE message to advertise a track.
Only the suffix is encoded on the wire, the full path is constructed by prepending the prefix from the corresponding ANNOUNCE_INTEREST.</t>
        <artwork><![CDATA[
ANNOUNCE Message {
  Announce Status (i),
  [
    Track Suffix Parts (i),
    [ Track Suffix Part (b), ]
  ],
}
]]></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>
          <li>
            <t><tt>live</tt> (2): All active paths have been sent.</t>
          </li>
        </ul>
        <t><strong>Track Suffix</strong>:
The track path suffix.
This field is not present for status <tt>live</tt>, which is not elegant I know.</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)
  Track Path Parts (i)
  [ Track Path Part (b) ]
  Track Priority (i)
  Group Order (i)
  Group Expires (i)
  Group Min (i)
  Group Max (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>Track Path Parts</strong>:
The number of parts in the track path.</t>
        <t><strong>Track Path</strong>:
The unique path of the track.
The number of parts <bcp14>MUST</bcp14> be within the range of 1 to 32.
The entire path combined <bcp14>MUST</bcp14> be smaller than 1024 bytes.</t>
        <t><strong>Track 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.</t>
        <t><strong>Group Order</strong>:
The transmission order of the Groups within the subscription.
The publisher <bcp14>SHOULD</bcp14> transmit groups based on their sequence number in default (0), ascending (1), or descending (2) order.</t>
        <t><strong>Group Expires</strong>:
A duration in milliseconds that applies to all Groups within the subscription.
The group <bcp14>SHOULD</bcp14> be dropped if this duration has elapsed after group has finished, including any time spent cached.
The publisher's Group Expires value (via INFO) <bcp14>SHOULD</bcp14> be used instead when smaller.</t>
        <t><strong>Group Min</strong>:
The minimum group sequence number plus 1.
A value of 0 indicates the latest Group Sequence as determined by the publisher.</t>
        <t><strong>Group Max</strong>:
The maximum group sequence number plus 1.
A value of 0 indicates there is no maximum and the subscription continues indefinitely.</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 {
  Track Priority (i)
  Group Order (i)
  Group Expires (i)
  Group Min (i)
  Group Max (i)
}
]]></artwork>
        <t><strong>Track Priority</strong>:
The new track priority; see SUBSCRIBE.
The publisher <bcp14>SHOULD</bcp14> use the new priority for any blocked streams.</t>
        <t><strong>Group Order</strong>:
The new group order; see SUBSCRIBE.
The publisher <bcp14>SHOULD</bcp14> use the new order for any blocked streams.</t>
        <t><strong>Group Min</strong>:
The new minimum group sequence, or 0 if there is no update.
This value <bcp14>MUST NOT</bcp14> be smaller than prior SUBSCRIBE and SUBSCRIBE_UPDATE messages.</t>
        <t><strong>Group Max</strong>:
The new maximum group sequence, or 0 if there is no update.
This value <bcp14>MUST NOT</bcp14> be larger than prior SUBSCRIBE or SUBSCRIBE_UPDATE messages.</t>
        <t>If the Min and Max are updated, the publisher <bcp14>SHOULD</bcp14> reset any blocked streams that are outside the new range.</t>
      </section>
      <section anchor="subscribegap">
        <name>SUBSCRIBE_GAP</name>
        <t>A publisher transmits a SUBSCRIBE_GAP message when it is unable to serve a group for a SUBSCRIBE.</t>
        <artwork><![CDATA[
SUBSCRIBE_GAP {
  Group Start (i)
  Group Count (i)
  Group Error Code (i)
}
]]></artwork>
        <t><strong>Group Start</strong>:
The sequence number for the first group within the dropped range.</t>
        <t><strong>Group Count</strong>:
The number of additional groups after the first.
This value is 0 when only one group is dropped.</t>
        <t><strong>Error Code</strong>:
An error code indicated by the application.</t>
      </section>
      <section anchor="info-1">
        <name>INFO</name>
        <t>The INFO message contains the current information about a track.
This is sent in response to a SUBSCRIBE or INFO_PLEASE message.</t>
        <artwork><![CDATA[
INFO Message {
  Track Priority (i)
  Group Latest (i)
  Group Order (i)
  Group Expires (i)
}
]]></artwork>
        <t><strong>Track Priority</strong>:
The priority of this track within the session.
The publisher <bcp14>SHOULD</bcp14> transmit subscriptions with <em>higher</em> values first during congestion.</t>
        <t><strong>Group Latest</strong>:
The latest group as currently known by the publisher.
A relay without an active subscription <bcp14>SHOULD</bcp14> forward this request upstream</t>
        <t><strong>Group Order</strong>:
The publisher's intended order of the groups within the subscription: none (0), ascending (1), or descending (2).</t>
        <t><strong>Group Expires</strong>:
A duration in milliseconds.
The group <bcp14>SHOULD</bcp14> be dropped if this duration has elapsed after group has finished, including any time spent cached.
The Subscriber's Group Expires value <bcp14>SHOULD</bcp14> be used instead when smaller.</t>
      </section>
      <section anchor="infoplease">
        <name>INFO_PLEASE</name>
        <t>The INFO_PLEASE message is used to request an INFO response.</t>
        <artwork><![CDATA[
INFO_PLEASE Message {
  Track Path Parts (i)
  [ Track Path Part (b) ]
}
]]></artwork>
      </section>
      <section anchor="fetch-1">
        <name>FETCH</name>
        <t>A subscriber can request the transmission of a (partial) Group with a FETCH message.</t>
        <artwork><![CDATA[
FETCH Message {
  Track Path Parts (i)
  [ Track Path Part (b) ]
  Track Priority (i)
  Group Sequence (i)
  Frame Sequence (i)
}
]]></artwork>
        <t><strong>Track Priority</strong>:
The priority of the group relative to all other FETCH and SUBSCRIBE requests within the session.
The publisher should transmit <em>higher</em> values first during congestion.</t>
        <t><strong>Group Sequence</strong>:
The sequence number of the group.</t>
        <t><strong>Frame Sequence</strong>:
The starting frame number.
All frames from this point forward are transmitted.</t>
      </section>
      <section anchor="fetchupdate">
        <name>FETCH_UPDATE</name>
        <t>A subscriber can modify a FETCH request with a FETCH_UPDATE message.</t>
        <artwork><![CDATA[
FETCH_UPDATE Message {
  Track Priority (i)
}
]]></artwork>
        <t><strong>Track Priority</strong>:
The priority of the group relative to all other FETCH and SUBSCRIBE requests within the session.
The publisher should transmit <em>higher</em> values first during congestion.</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.</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-changelog">
      <name>Appendix: Changelog</name>
      <t>Notable changes between versions of this draft.</t>
      <section anchor="moq-transfork-03">
        <name>moq-transfork-03</name>
        <ul spacing="normal">
          <li>
            <t>Broadcast and Track have been merged.</t>
          </li>
          <li>
            <t>Tracks now have a variable length path instead of a (broadcast, name) tuple</t>
          </li>
          <li>
            <t>ANNOUNCE contains the suffix instead of the full path.</t>
          </li>
          <li>
            <t>ANNOUNCE contains a new status: active, ended, or live.</t>
          </li>
          <li>
            <t>GROUP_DROP has been renamed to SUBSCRIBE_GAP.</t>
          </li>
          <li>
            <t>FETCH is now at frame boundaries instead of byte offsets.</t>
          </li>
          <li>
            <t>The protocol is more polite: some messages have been renamed to *_PLEASE.</t>
          </li>
          <li>
            <t>Moved the use-cases appendix to a separate document.</t>
          </li>
        </ul>
      </section>
      <section anchor="moq-transfork-02">
        <name>moq-transfork-02</name>
        <ul spacing="normal">
          <li>
            <t>Document version numbers.</t>
          </li>
          <li>
            <t>Added ANNOUNCE_INTEREST to opt-into ANNOUNCE messages.</t>
          </li>
          <li>
            <t>Remove ROLE extension.</t>
          </li>
        </ul>
      </section>
      <section anchor="moq-transfork-01">
        <name>moq-transfork-01</name>
        <ul spacing="normal">
          <li>
            <t>Removed datagram support</t>
          </li>
          <li>
            <t>Removed native QUIC support</t>
          </li>
          <li>
            <t>Moved Expires from GROUP to SUBSCRIBE</t>
          </li>
          <li>
            <t>Added FETCH_UPDATE</t>
          </li>
          <li>
            <t>Added ROLE=Any</t>
          </li>
          <li>
            <t>Track Priority is now descending.</t>
          </li>
        </ul>
        <t>Datagram and native QUIC support may be re-added in a future draft.</t>
      </section>
      <section anchor="moq-transfork-00">
        <name>moq-transfork-00</name>
        <t>Based on moq-transport-03.
The significant changes have been broken into sections.</t>
        <ul spacing="normal">
          <li>
            <t>Bikeshedding
            </t>
            <ul spacing="normal">
              <li>
                <t>Renamed Track Namespace to Broadcast</t>
              </li>
              <li>
                <t>Renamed Object to Frame</t>
              </li>
            </ul>
          </li>
          <li>
            <t>Each unidirectional stream contains a single group.
            </t>
            <ul spacing="normal">
              <li>
                <t>Removed stream per track.</t>
              </li>
              <li>
                <t>Removed stream per object.</t>
              </li>
            </ul>
          </li>
          <li>
            <t>Subscriber chooses track priority and group order.</t>
          </li>
          <li>
            <t>Bidirectional control stream per ANNOUNCE/SUBSCRIBE/FETCH/INFO.
            </t>
            <ul spacing="normal">
              <li>
                <t>Removed ANNOUNCE_ERROR</t>
              </li>
              <li>
                <t>Removed ANNOUNCE_DONE</t>
              </li>
              <li>
                <t>Removed UNANNOUNCE</t>
              </li>
              <li>
                <t>Removed SUBSCRIBE_OK</t>
              </li>
              <li>
                <t>Removed SUBSCRIBE_ERROR</t>
              </li>
              <li>
                <t>Removed SUBSCRIBE_DONE</t>
              </li>
              <li>
                <t>Removed UNSUBSCRIBE</t>
              </li>
            </ul>
          </li>
          <li>
            <t>Groups IDs are sequential.</t>
          </li>
          <li>
            <t>All sequences are explicitly delivered.
            </t>
            <ul spacing="normal">
              <li>
                <t>(unreliable) GROUP for each sequence.</t>
              </li>
              <li>
                <t>Or (reliable) SUBSCRIBE_GAP when a stream is reset.</t>
              </li>
            </ul>
          </li>
          <li>
            <t>Fetch Group via offset</t>
          </li>
          <li>
            <t>Added INFO_PLEASE and INFO</t>
          </li>
          <li>
            <t>Replaced SUBSCRIBE_OK with INFO</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="Luke Curley" initials="L." surname="Curley">
            <organization>Discord</organization>
          </author>
          <author fullname="Kirill Pugin" initials="K." surname="Pugin">
            <organization>Meta</organization>
          </author>
          <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>
          <date day="21" month="October" year="2024"/>
          <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-07"/>
      </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 694?>

<section numbered="false" anchor="acknowledgments">
      <name>Acknowledgments</name>
      <t>TODO acknowledge.</t>
    </section>
  </back>
  <!-- ##markdown-source:
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
mehtfS84WxSc9+VKfHdUbc4GKyKsDZ84Rv149pRfFPxfzg9J303frtcJBlXe
qnZ89PQb3ogdUiiyDuzAVbXROYtd6A/PMlFLpiQ4jDcf9WzvryOx6BbM2z43
75DCwxV9luJQjvvsP58xkEObrJ+9q5C9+byEeEP/Lo76cbL42IE/9KN7qaJT
LHT43y4SPDMNng6rgbm4e/BkhPnglyD00tMnTGGwFrEstg9YdKIZ1zrD01OU
belmA98NIvzzM5bHZwd8mqZ7pTMt93RCtAoQ8qZ2ByD5VdotCmUFbwRjbIyP
5nD9ikgbdo8hebBph6Vf1R3vwcneY9y8iUjPk4AwMmntaBHEK/ocsAocjgp9
DSSt27WejegIZZODtz7+SHrpTioJkKHvJ7Xv7qY7PbOQlMRFk3Xy8IdI4c3V
EBd1IIWoIwvErDkrWuonpvyVFJtvu+FGq4Ud6HANVfhi2wkxO82UDjjbDUF9
dcf/fBTp912FvVc3LHf+GXhv/Vr2mLfuOMb3ncvThJIOCLhDVvU+j4Pv6hE3
uPzlE7OX+vSsgcLja/1KT07mSAKeU6Z2k9K+DUpsWPXCGBoFCw6SPtOIWyo7
gH2fERB5vYbwu8jL8fNNe6grP9rUG+geoDcZl/moTwTo0ozp/prDNn3S8Nu8
yrbBndxOiNIO6xjgy8lVfJ5Ewkm9F7EjZ9ff+kuEl4u4ebdjlzjcz86Cbiib
DG0qRCbEEqlcO8VyLTA2J1kaQmXbdWna6eY4rd+9cEFIQ4zyR8ckInYTqyRN
M0HUJOL68/c0Q6Qk8I8j5pjbyeZOO8rENKVfHwXWuD51aJ04+KCrr/0XiE5E
Z9SQcPtmqHKT3bif0XWp5VRaB1gPNbq3XUJCIQo+0+O+5qD2+U74E042zgmx
kqfHvjzF200Rf0fWx6tT2qKjxrjHhOUBSsGo6W7w1mNQuvMm6T+gKrT7T7cR
GM8tNj0etScwhJkPfbGB4IIwJV1+NGc7AdcIGv1ZieSXppD/d/mg35a7JyH8
vCxQ7VJxPjXPLqIXnS/Vg6/ayGQDDEzrI8Dd55bSAShNLe7d7EvpaHbKFWxo
P5Zzt0+C/RfdtrpQzNf+AK0fdR8uDeaLfLo3uvhF/kK1rb94lGPOYaqhfPqc
IlIOE/6BIlIXti/MhWug12J+uNd05wH3Ft3HDWCh/P0dBfsQjqWmv3oWOkkl
9PNpCadCn87jmX2qWKHK9Cfx0a1PhJP/D1Km7yhgG5pGjBvSLo73xW5SDurq
3VvEF2s66qtnWGUjZhQwZpa2zVo5cI284/k+gdj1GN1e6Oz2Iz3d8zNJNWDk
wPml/CG4Fj9ao59D8ieao4DsTr+iBkvy8nvthHQYe/T8vYawWx9/KSDc5jQX
08Cx+AtYpLP0csjFsGPmeCUXJdGLPr3gRudHMAfQb1Ll2azC7S+0y4ROR2v9
AZqBX4o1dFyLzC3ahNQWOX7PrdQuhj8oJtvAzES+1nZiTmlTfV4ucZMR5fa8
zd5/ns0dZYga8Nzn3fmw8Mg81485kU2xfXrUe20r2ow20k+pIXzOJ17xa7nc
xs9tsWxWgrCHW4gfuy9FDQ1+N/iJaVrQFRjN9R+iDFg7I36MqBky7n0xodqJ
AfUTyb+GhjIlSnJyahGN2GLfnV1fXnnAFkwQyCLljmoffJ4djXYMGvHG8pGa
jGATR2bw2YyamLXyH/WjY/N4SG9T5lljT0xdrm3/lkJHzKEkETjWm5JO2K5s
8BlB9/U+/uSOfjVLPyLbK+ynMNaZfmVW29ZscUTzJMXccqdhRB9i2DQj+iZc
T9NyZK7tGk/sX1++nvr2dy8Jx+7plHZBLYGlepQmuCUfY+RDv+4u80HzPAqB
7BRD4bl1REFPLyKJf5kUW1VnH6REzD4hBvrPlEI0jB6a9GsRlR0lqXzBLtFd
MPuN7mjwfN/XZGXf6s4ZmlBLwKQ+0Cdiqaaf68fswJCzDxZzaNo9Ywyyk/WJ
l3qBmcMm4YjjjD568HL27+il4D5/jmVk6FxE7y6V0P5kr6n4ax6RJVn7s2AS
BPbcLWlq1KbgyJ37glOEyvF3AD1YNqa1hxTGhztpfFXcr52mfE0a8jVm7DFV
zgKm19eX1/23zi4vptGdtxeuRxxe9k7l8l/33Nidxd/rmSbUdIHr6TMMlYZR
zPvJnHH3kwRWvo/fXM3mGRa07tOTvPTH9G05cuZPxKjcDm4dg5+8hMrfPxrj
RbyNurvhjFwpbW/l4I9QPXtKZ5Zh1YTCJawEF73Jk3mHi5yY0hN0ztlClY5K
cSofzknkU9+XZ5fuJj15PrmYdJ+SI2jqFDEsFCU/mTjLog+M47dQKBC7Ldr0
CYPBzyfsQW36l4NFktf24NcBTx5s5h4P/gueG7asMWAAAA==

-->

</rfc>
