jiebi/TextFlow huggingface dataset:
Original text:
Subscribe ID: Subscription Identifer as defined in message- subscribe-req. <del> Track Namespace: Identifies the namespace of the track as defined in (track-name). Track Name: Identifies the track name as defined in (track-name). </del> Expires: Time in milliseconds after which the subscription is no longer valid.  A value of 0 indicates that the subscription stays active until it is explicitly unsubscribed.  6.6. A publisher sends a SUBSCRIBE_ERROR control message in response to a

Reviewer comments:
This PR cleans up some nits to make all the places we use the RFC9000 encoding syntax valid, updates our extensions to it, and add a non normative summary of parts of the syntax we use. I don't think this is making any changes to anything on the wire or normative changes to spec other than the statement SHOULD use smallest number of bytes for variable length integers which RFC9000 only requires for some fields.
I am not in love with the ABNF idea, but this is non-controversial.

Revised text:
Subscribe ID: Subscription Identifer as defined in message- subscribe-req.  Expires: Time in milliseconds after which the subscription is no longer valid.  A value of 0 indicates that the subscription stays active until it is explicitly unsubscribed. <ins> ContentExists: 1 if an object has been published on this track, 0 if not. If 0, then the Largest Group ID and Largest Object ID fields will not be present. Largest Group ID: the largest Group ID available for this track. This Group ID corresponds to the Group that would be returned with a subscribe-locations RelativePrevious value of 0.  This field is only present if ContentExists has a value of 1. Largest Object ID: the largest Object ID available within the largest Group ID for this track.  This Object ID corresponds to the Object that would be returned with a subscribe-locations RelativePrevious value of 0. This field is only present if ContentExists has a value of 1. </ins> 6.6. A publisher sends a SUBSCRIBE_ERROR control message in response to a
Original text:
Subscribe ID: Subscription Identifer as defined in message- subscribe-req. <del> Track Namespace: Identifies the namespace of the track as defined in (track-name). Track Name: Identifies the track name as defined in (track-name). </del> Expires: Time in milliseconds after which the subscription is no longer valid.  A value of 0 indicates that the subscription stays active until it is explicitly unsubscribed.

Reviewer comments:
This PR
Track namespace and track name properties were removed from SUBSCRIBEOK message in draft 02. But they are still part of the text under "6.5. SUBSCRIBEOK" which is confusing.

Revised text:
Subscribe ID: Subscription Identifer as defined in message- subscribe-req.  Expires: Time in milliseconds after which the subscription is no longer valid.  A value of 0 indicates that the subscription stays active until it is explicitly unsubscribed.
Original text:
The basic data element of MOQT is an object.  An object is an addressable unit whose payload is a sequence of bytes.  All objects belong to a group, indicating ordering and potential dependencies. <del> model-group Objects are comprised of two parts: metadata and a payload.  The metadata is never encrypted and is always visible to relays.  The payload portion may be encrypted, in which case it is only visible to the producer and consumer.  The application is solely responsible for the content of the object payload.  This includes the underlying encoding, compression, any end-to-end encryption, or authentication.  A relay MUST NOT combine, split, or otherwise modify object payloads. </del>  2.2.

Reviewer comments:
Regardless of where they're retrieved from and over time.
I put a two very small nit comments but don't care either way. They do not change the substance of the PR and +1 on the overall thing this is saying.
This came as part of interim at Denver when discussing multiple announce for same track. There needs to text that mandates, if 2 objects comes with same name, they need to be bit identical. Also needs to clarify on how long the name needs to be unique

Revised text:
The basic data element of MOQT is an object.  An object is an addressable unit whose payload is a sequence of bytes.  All objects belong to a group, indicating ordering and potential dependencies.  <ins> model-group An object is uniquely identified by its track namespace, track name, group ID, and object ID, and must be an identical sequence of bytes regardless of how or where it is retrieved.  An Object can become unavailable, but it's contents MUST NOT change over time. Objects are comprised of two parts: metadata and a payload.  The metadata is never encrypted and is always visible to relays.  The payload portion may be encrypted, in which case it is only visible to the producer and consumer.  The application is solely responsible for the content of the object payload.  This includes the underlying encoding, compression, any end-to-end encryption, or authentication. A relay MUST NOT combine, split, or otherwise modify object payloads. </ins> 2.2.
Original text:
dependent on the congestion response.  A subscription remains active until it expires, until the publisher of the track terminates the track with a SUBSCRIBE_FIN (see message-subscribe-fin) or a <del> SUBSCRIBE_RST (see message-subscribe-rst). </del>  A relay MUST not reorder or drop objects received on a multi-object stream when forwarding to subscribers, unless it has application

Reviewer comments:
QUIC uses RESET, we should too.
Teeechnically, QUIC uses STOP for receiver-initiated closes. But RESET is better than RST.

Revised text:
dependent on the congestion response.  A subscription remains active until it expires, until the publisher of the track terminates the track with a SUBSCRIBE_FIN (see message-subscribe-fin) or a  <ins> SUBSCRIBE_RESET (see message-subscribe-reset). </ins> A relay MUST not reorder or drop objects received on a multi-object stream when forwarding to subscribers, unless it has application
Original text:
6.9. <del> A publisher issues a "SUBSCRIBE_RST" message to all subscribers </del>  indicating there was an error publishing to the given track and subscription is terminated. <del> The format of "SUBSCRIBE_RST" is as follows: </del>  Subscribe ID: Subscription Identifier as defined in message- subscribe-req.

Reviewer comments:
QUIC uses RESET, we should too.
Teeechnically, QUIC uses STOP for receiver-initiated closes. But RESET is better than RST.

Revised text:
6.9.  <ins> A publisher issues a "SUBSCRIBE_RESET" message to all subscribers </ins> indicating there was an error publishing to the given track and subscription is terminated.  <ins> The format of "SUBSCRIBE_RESET" is as follows: </ins> Subscribe ID: Subscription Identifier as defined in message- subscribe-req.
Original text:
track with a SUBSCRIBE_FIN (see message-subscribe-fin) or a SUBSCRIBE_RESET (see message-subscribe-reset).  A relay MUST not reorder or drop objects received on a multi-object stream when forwarding to subscribers, unless it has application specific information.

Reviewer comments:
Since they're on different streams, an object can arrive before its SUBSCRIBEOK. This is easy to process because the Subscribe ID and Track Alias must have been the ones that the subscriber chose. What if the publisher then sends a SUBSCRIBEERROR? Is this valid behavior or an error? (If it weren't for the Expires field, SUBSCRIBE_OK would be entirely redundant and we could get rid of it.)
Individual Comment: This is covered a bit in and Luke expressed a desire to document the full state machine in . My read is that you can't send objects before SUBSCRIBE OK (but they can arrive out of order). I don't think you can send SUBSCRIBEERROR after SUBSCRIBEOK (objects or no objects), instead, use SUBSCRIBE_RST?
I agree that SUBSCRIBEERROR cannot follow SUBSCRIBEOK. I think you're saying that if Objects are in flight, then SUBSCRIBEOK must be as well, so a SUBSCRIBEERROR would in itself be an error. That sounds reasonable to me.
We're clear that only one of SUBSCRIBEOK or SUBSCRIBEERROR can be sent: the subscription, via SUBSCRIBEOK ({{message-subscribe-ok}}) or the SUBSCRIBEERROR {{message-subscribe-error}} control message. The entity receiving the SUBSCRIBE MUST send only a single response to a given SUBSCRIBE of either SUBSCRIBEOK or SUBSCRIBEERROR. I wrote to clarify that you can't send objects and a SUBSCRIBE_ERROR.

Revised text:
track with a SUBSCRIBE_FIN (see message-subscribe-fin) or a SUBSCRIBE_RESET (see message-subscribe-reset). <ins> Objects MUST NOT be sent for unsuccessful subscriptions, and if a subscriber receives a SUBSCRIBE_ERROR after receiving objects, it MUST close the session with a 'Protocol Violation'. </ins> A relay MUST not reorder or drop objects received on a multi-object stream when forwarding to subscribers, unless it has application specific information.
Original text:
Subscribe ID: Subscription identifier as defined in message- subscribe-req.  Final Group: The largest Group ID sent by the publisher in an OBJECT message in this track.

Reviewer comments:
by adding an explicit bool indicating whether any Objects were published for a subscription, similar to the explicit bool added to SUBSCRIBE_OK in .
and define: However, what happens if no objects were ever produced/sent?
Individual Comment: Oops. Two possible ways to handle this: 1) Flag indicating presence of these fields (Use Location now that is defined elsewhere?) 2) Change the semantics of the fields to be exclusive (eg: it is the first object NOT sent), so 0/0 means none.
I'm inclined towards 0/0, because optional fields are more complex to parse and I would expect the existing logic to work correctly with 0/0.
Let's say the last object delivered by the relay is . Does the relay send RESET or ? Is the subscriber able to infer the presence of future objects? What if either of those objects actually exist in the cache?
Individual Comment: If we use exclusive encoding then I'd say that the receiver shouldn't infer the existence of non-existence of the named object, and either 5/30 or 6/0 works, but 5/30 is preferable?
If you define there will be no objects greater than or equal to these, then 0/0 makes total sense. So 0/0 for null case and say the last group ID of the last object publish was 10 then the value in SUB_FIN would be 11.
In we went with an explicit flag, so I'm inclined to do the same here for consistency.

Revised text:
Subscribe ID: Subscription identifier as defined in message- subscribe-req. <ins> ContentExists: 1 if an object has been published for this subscription, 0 if not.  If 0, then the Final Group and Final Object fields will not be present. </ins> Final Group: The largest Group ID sent by the publisher in an OBJECT message in this track.
Original text:
Reason Phrase: Provides the reason for subscription error.  Final Group: The largest Group ID sent by the publisher in an OBJECT message in this track.

Reviewer comments:
by adding an explicit bool indicating whether any Objects were published for a subscription, similar to the explicit bool added to SUBSCRIBE_OK in .
and define: However, what happens if no objects were ever produced/sent?
Individual Comment: Oops. Two possible ways to handle this: 1) Flag indicating presence of these fields (Use Location now that is defined elsewhere?) 2) Change the semantics of the fields to be exclusive (eg: it is the first object NOT sent), so 0/0 means none.
I'm inclined towards 0/0, because optional fields are more complex to parse and I would expect the existing logic to work correctly with 0/0.
Let's say the last object delivered by the relay is . Does the relay send RESET or ? Is the subscriber able to infer the presence of future objects? What if either of those objects actually exist in the cache?
Individual Comment: If we use exclusive encoding then I'd say that the receiver shouldn't infer the existence of non-existence of the named object, and either 5/30 or 6/0 works, but 5/30 is preferable?
If you define there will be no objects greater than or equal to these, then 0/0 makes total sense. So 0/0 for null case and say the last group ID of the last object publish was 10 then the value in SUB_FIN would be 11.
In we went with an explicit flag, so I'm inclined to do the same here for consistency.

Revised text:
Reason Phrase: Provides the reason for subscription error. <ins> ContentExists: 1 if an object has been published for this subscription, 0 if not.  If 0, then the Final Group and Final Object fields will not be present. </ins> Final Group: The largest Group ID sent by the publisher in an OBJECT message in this track.
Original text:
No Error: The session is being terminated without an error. <del> Generic Error: An unclassified error occurred. </del>  Unauthorized: The endpoint breached an agreement, which MAY have been pre-negotiated by the application.

Reviewer comments:
To allow subscribers to indicate that no new subscriptions will be routed to the publisher for a given namespace. Happy to bikeshed on the name and whether we really need another frame for this.
The problem is not possible for the subscriber to reject an ANNOUNCE afterwards. This would be very useful, for example to inform a publisher that no more subscriptions will be routed to them for whatever reason. Examples: The auth parameter in ANNOUNCE has expired. Another publisher has sent an overriding ANNOUNCE (reconnect?) The broadcast has been closed remotely, ex. some moderation tool. Without this message, the only recourse for the subscriber is to close the connection. This won't work if multiple ANNOUNCE messages are pooled over the same connection, nor is it clean.
I propose two options: can be sent after . We add and to mirror . I personally hate 3 separate messages for a subscriber to close an announce, or a publisher to close a subscription. See
very trivial bikeshed comment ... I would prefer to call it something other RESET ( and also other places we use RESET ). I get the TCP analogy but I think that is the wrong way to think about this. I would prefer something like REVOKE.
how about ANNOUNCE_CANCEL to cancel an open announce ?
Conclusion is that we do need to add a new frame to end an ANNOUNCE. Additionally, there was a principle stated that we should not rely on closing the session as the typical or optimal way to close state and close either an ANNOUNCE or SUBSCRIBE.
On the call today, people tend to prefer ANNOUNCECLOSE over ANNOUNCECANCEL as a name. They also prefer merging SUBSCRIBERESET and SUBSCRIBEFIN into a single message, possibly SUBSCRIBE_CLOSE.
On an editorial note, it'd be nice to have subsections for publisher/subscriber to make it clearer to the reader.
If we're going to combine and , then we should just combine and now. My desire is to have four messages: publisher create: ANNOUNCE publisher close: UNANNOUNCE subscriber accept: ANNOUNCEOK subscriber close: ANNOUNCESTOP The same goes for subscriptions: subscriber create: SUBSCRIBE subscriber close: UNSUBSCRIBE publisher accept: SUBSCRIBEOK publisher close: SUBSCRIBESTOP

Revised text:
No Error: The session is being terminated without an error.  <ins> Internal Error: An implementation specific error occurred. </ins> Unauthorized: The endpoint breached an agreement, which MAY have been pre-negotiated by the application.
Original text:
dependent on the congestion response.  A subscription remains active until it expires, until the publisher of the track terminates the track with a SUBSCRIBE_FIN (see message-subscribe-fin) or a <del> SUBSCRIBE_RST (see message-subscribe-rst). </del>  A relay MUST not reorder or drop objects received on a multi-object stream when forwarding to subscribers, unless it has application

Reviewer comments:
To allow subscribers to indicate that no new subscriptions will be routed to the publisher for a given namespace. Happy to bikeshed on the name and whether we really need another frame for this.
The problem is not possible for the subscriber to reject an ANNOUNCE afterwards. This would be very useful, for example to inform a publisher that no more subscriptions will be routed to them for whatever reason. Examples: The auth parameter in ANNOUNCE has expired. Another publisher has sent an overriding ANNOUNCE (reconnect?) The broadcast has been closed remotely, ex. some moderation tool. Without this message, the only recourse for the subscriber is to close the connection. This won't work if multiple ANNOUNCE messages are pooled over the same connection, nor is it clean.
I propose two options: can be sent after . We add and to mirror . I personally hate 3 separate messages for a subscriber to close an announce, or a publisher to close a subscription. See
very trivial bikeshed comment ... I would prefer to call it something other RESET ( and also other places we use RESET ). I get the TCP analogy but I think that is the wrong way to think about this. I would prefer something like REVOKE.
how about ANNOUNCE_CANCEL to cancel an open announce ?
Conclusion is that we do need to add a new frame to end an ANNOUNCE. Additionally, there was a principle stated that we should not rely on closing the session as the typical or optimal way to close state and close either an ANNOUNCE or SUBSCRIBE.
On the call today, people tend to prefer ANNOUNCECLOSE over ANNOUNCECANCEL as a name. They also prefer merging SUBSCRIBERESET and SUBSCRIBEFIN into a single message, possibly SUBSCRIBE_CLOSE.
On an editorial note, it'd be nice to have subsections for publisher/subscriber to make it clearer to the reader.
If we're going to combine and , then we should just combine and now. My desire is to have four messages: publisher create: ANNOUNCE publisher close: UNANNOUNCE subscriber accept: ANNOUNCEOK subscriber close: ANNOUNCESTOP The same goes for subscriptions: subscriber create: SUBSCRIBE subscriber close: UNSUBSCRIBE publisher accept: SUBSCRIBEOK publisher close: SUBSCRIBESTOP

Revised text:
dependent on the congestion response.  A subscription remains active until it expires, until the publisher of the track terminates the track with a SUBSCRIBE_FIN (see message-subscribe-fin) or a  <ins> SUBSCRIBE_RESET (see message-subscribe-reset). Objects MUST NOT be sent for unsuccessful subscriptions, and if a subscriber receives a SUBSCRIBE_ERROR after receiving objects, it MUST close the session with a 'Protocol Violation'. </ins> A relay MUST not reorder or drop objects received on a multi-object stream when forwarding to subscribers, unless it has application
Original text:
Subscribe ID: Subscription identifier as defined in message- subscribe-req.  Final Group: The largest Group ID sent by the publisher in an OBJECT message in this track.

Reviewer comments:
To allow subscribers to indicate that no new subscriptions will be routed to the publisher for a given namespace. Happy to bikeshed on the name and whether we really need another frame for this.
The problem is not possible for the subscriber to reject an ANNOUNCE afterwards. This would be very useful, for example to inform a publisher that no more subscriptions will be routed to them for whatever reason. Examples: The auth parameter in ANNOUNCE has expired. Another publisher has sent an overriding ANNOUNCE (reconnect?) The broadcast has been closed remotely, ex. some moderation tool. Without this message, the only recourse for the subscriber is to close the connection. This won't work if multiple ANNOUNCE messages are pooled over the same connection, nor is it clean.
I propose two options: can be sent after . We add and to mirror . I personally hate 3 separate messages for a subscriber to close an announce, or a publisher to close a subscription. See
very trivial bikeshed comment ... I would prefer to call it something other RESET ( and also other places we use RESET ). I get the TCP analogy but I think that is the wrong way to think about this. I would prefer something like REVOKE.
how about ANNOUNCE_CANCEL to cancel an open announce ?
Conclusion is that we do need to add a new frame to end an ANNOUNCE. Additionally, there was a principle stated that we should not rely on closing the session as the typical or optimal way to close state and close either an ANNOUNCE or SUBSCRIBE.
On the call today, people tend to prefer ANNOUNCECLOSE over ANNOUNCECANCEL as a name. They also prefer merging SUBSCRIBERESET and SUBSCRIBEFIN into a single message, possibly SUBSCRIBE_CLOSE.
On an editorial note, it'd be nice to have subsections for publisher/subscriber to make it clearer to the reader.
If we're going to combine and , then we should just combine and now. My desire is to have four messages: publisher create: ANNOUNCE publisher close: UNANNOUNCE subscriber accept: ANNOUNCEOK subscriber close: ANNOUNCESTOP The same goes for subscriptions: subscriber create: SUBSCRIBE subscriber close: UNSUBSCRIBE publisher accept: SUBSCRIBEOK publisher close: SUBSCRIBESTOP

Revised text:
Subscribe ID: Subscription identifier as defined in message- subscribe-req. <ins> ContentExists: 1 if an object has been published for this subscription, 0 if not.  If 0, then the Final Group and Final Object fields will not be present. </ins> Final Group: The largest Group ID sent by the publisher in an OBJECT message in this track.
Original text:
6.9. <del> A publisher issues a "SUBSCRIBE_RST" message to all subscribers </del>  indicating there was an error publishing to the given track and subscription is terminated. <del> The format of "SUBSCRIBE_RST" is as follows: </del>  Subscribe ID: Subscription Identifier as defined in message- subscribe-req.

Reviewer comments:
To allow subscribers to indicate that no new subscriptions will be routed to the publisher for a given namespace. Happy to bikeshed on the name and whether we really need another frame for this.
The problem is not possible for the subscriber to reject an ANNOUNCE afterwards. This would be very useful, for example to inform a publisher that no more subscriptions will be routed to them for whatever reason. Examples: The auth parameter in ANNOUNCE has expired. Another publisher has sent an overriding ANNOUNCE (reconnect?) The broadcast has been closed remotely, ex. some moderation tool. Without this message, the only recourse for the subscriber is to close the connection. This won't work if multiple ANNOUNCE messages are pooled over the same connection, nor is it clean.
I propose two options: can be sent after . We add and to mirror . I personally hate 3 separate messages for a subscriber to close an announce, or a publisher to close a subscription. See
very trivial bikeshed comment ... I would prefer to call it something other RESET ( and also other places we use RESET ). I get the TCP analogy but I think that is the wrong way to think about this. I would prefer something like REVOKE.
how about ANNOUNCE_CANCEL to cancel an open announce ?
Conclusion is that we do need to add a new frame to end an ANNOUNCE. Additionally, there was a principle stated that we should not rely on closing the session as the typical or optimal way to close state and close either an ANNOUNCE or SUBSCRIBE.
On the call today, people tend to prefer ANNOUNCECLOSE over ANNOUNCECANCEL as a name. They also prefer merging SUBSCRIBERESET and SUBSCRIBEFIN into a single message, possibly SUBSCRIBE_CLOSE.
On an editorial note, it'd be nice to have subsections for publisher/subscriber to make it clearer to the reader.
If we're going to combine and , then we should just combine and now. My desire is to have four messages: publisher create: ANNOUNCE publisher close: UNANNOUNCE subscriber accept: ANNOUNCEOK subscriber close: ANNOUNCESTOP The same goes for subscriptions: subscriber create: SUBSCRIBE subscriber close: UNSUBSCRIBE publisher accept: SUBSCRIBEOK publisher close: SUBSCRIBESTOP

Revised text:
6.9.  <ins> A publisher issues a "SUBSCRIBE_RESET" message to all subscribers </ins> indicating there was an error publishing to the given track and subscription is terminated.  <ins> The format of "SUBSCRIBE_RESET" is as follows: </ins> Subscribe ID: Subscription Identifier as defined in message- subscribe-req.