jiebi/TextFlow huggingface dataset:
Original text:
by setting the "Safely Replayable" send parameter to true when sending the data.  In general, 0-RTT data may be replayed (for example, if a TCP SYN contains data, and the SYN is retransmitted, <del> the data will be retransmitted as well), but racing means that different leaf nodes have the opportunity to send the same data independently.  If data is truly safely replayable, this should be permissible. </del>  Once the application has provided its 0-RTT data, an implementation should keep a copy of this data and provide it to each new leaf node distributed pre-shared keys (PSKs).  Implementations should be aware of security concerns around using these tokens across multiple addresses or paths when racing.  In the case of TLS, any given ticket <del> or PSK should only be used on one leaf node.  If implementations have multiple tickets available from a previous connection, each leaf node attempt must use a different ticket.  In effect, each leaf node will send the same early application data, yet encoded (encrypted) differently on the wire. </del>  6.

Reviewer comments:
I would further recommend to move this section into 4 somewhere as this section is more about connection establishment than sending messages
LGTM

Revised text:
by setting the "Safely Replayable" send parameter to true when sending the data.  In general, 0-RTT data may be replayed (for example, if a TCP SYN contains data, and the SYN is retransmitted,  <ins> the data will be retransmitted as well but may be considered as a new connection instead of a retransmission).  Also, when racing connections, different leaf nodes have the opportunity to send the same data independently.  If data is truly safely replayable, this should be permissible. </ins> Once the application has provided its 0-RTT data, an implementation should keep a copy of this data and provide it to each new leaf node distributed pre-shared keys (PSKs).  Implementations should be aware of security concerns around using these tokens across multiple addresses or paths when racing.  In the case of TLS, any given ticket  <ins> or PSK should only be used on one leaf node, since servers will likely reject duplicate tickets in order to prevent replays (see section-8.1 RFC8446).  If implementations have multiple tickets available from a previous connection, each leaf node attempt can use a different ticket.  In effect, each leaf node will send the same early application data, yet encoded (encrypted) differently on the wire. </ins> 6.
Original text:
Message lengths can be defined, and Messages can be partially reliable. <del> Below, primitives in the style of "CATEGORY.[SUBCATEGORY].PRIMITIVENAME.PROTOCOL" (e.g., "CONNECT.SCTP") refer to the primitives with the same name in section 4 of RFC8303.  For further implementation details, the description of these primitives in RFC8303 points to section 3, which refers back to the specifications for each protocol.  This back-tracking method applies to all elements of I-D.ietf-taps-minset (see appendix D of I- D.ietf-taps-interface): they are listed in appendix A of I-D.ietf- taps-minset with an implementation hint in the same style, pointing back to section 4 of RFC8303. </del>  10.1.

Reviewer comments:
Section 10 of impl draft: "Below, primitives in the style of "CATEGORY.[SUBCATEGORY].PRIMITIVENAME.PROTOCOL" (e.g., "CONNECT.SCTP") refer to the primitives with the same name in section 4 of [RFC8303]." I know it's specified like this in RFC8303 but PRIMITIVENAME does not seem to be explained or used. Maybe I didn't look careful enough but to be honest I also didn't find the use of this nomenclature from RFC8303 very helpful...
Just to answer the comment of usefulness of this nomenclature: this allows back-tracking to the relevant spec., which (I believe) is valuable for people implementing a TAPS system. In the example of CONNECT.SCTP, RFC 8303 describes this as consisting of: Interleaving' (optional), followed by 'Associate' Initialize and Associate are obvious; naturally, they come from RFC 4960. Considering to use 'Enable/Disable Interleaving' (which is very important for a TAPS system - to implement priorities between streams) is perhaps less obvious, and the text points back at RFC 8260.

Revised text:
Message lengths can be defined, and Messages can be partially reliable.  <ins> Below, terms in capitals with a dot (e.g., "CONNECT.SCTP") refer to the primitives with the same name in section 4 of RFC8303.  For further implementation details, the description of these primitives in RFC8303 points to section 3 of RFC8303 and section 3 of RFC8304, which refers back to the relevant specifications for each protocol. This back-tracking method applies to all elements of I-D.ietf-taps- minset (see appendix D of I-D.ietf-taps-interface): they are listed in appendix A of I-D.ietf-taps-minset with an implementation hint in the same style, pointing back to section 4 of RFC8303. </ins> 10.1.
Original text:
Preference: can take one of five values (Prohibit, Avoid, Ignore, Prefer, Require) for the level of preference of a given property <del> during protocol selection; see selection-props. </del>  For types Integer and Numeric, special values can be defined per property; it is up to implementations how these special values are Selection Properties are listed in the subsections below.  Note that many properties are only considered during establishment, and can not be changed after a Connection is established; however, they can be <del> queried.  Querying a Selection Property after establishment yields the value "Require" for properties of the selected protocol and path, Avoid for properties avoided during selection, and Ignore for all other properties. </del>  An implementation of this interface must provide sensible defaults for Selection Properties.  The defaults given for each property below

Reviewer comments:
I chose boolean, because, when querying, it only matters whether a Selection Property was chosen or not (I believe).
From Kyle Rose: NAME says: I think this isn't very controversial, I believe we should just do this as he suggested. This issue is just a reminder for myself to do this.
Thanks

Revised text:
Preference: can take one of five values (Prohibit, Avoid, Ignore, Prefer, Require) for the level of preference of a given property  <ins> during protocol selection; see selection-props.  When querying, a Preference is of type Boolean, with "true" indicating that the Selection Property has been applied. </ins> For types Integer and Numeric, special values can be defined per property; it is up to implementations how these special values are Selection Properties are listed in the subsections below.  Note that many properties are only considered during establishment, and can not be changed after a Connection is established; however, they can be  <ins> queried.  The return type of a queried Selection Property is Boolean, where "true" means that the Selection Property has been applied and "false" means that the Selection Property has not been applied.  Note that "true" does not mean that a request has been honored.  For example, if "Congestion control" was requested with preference level "Prefer", but congestion control could not be supported, querying the "congestionControl" property yields the value "false".  If preference level "Avoid" was used for "Congestion control", and, as requested, the Connection is not congestion controlled, querying the "congestionControl" property also yields the value "false". </ins> An implementation of this interface must provide sensible defaults for Selection Properties.  The defaults given for each property below
Original text:
Transport Services architecture.  The Transport Services Application Programming Interface (API) is based on an asynchronous, event-driven interaction pattern.  It uses messages for representing data transfer <del> to applications, and it assumes an implementation that can use </del>  multiple IP addresses, multiple protocols, and multiple paths, and provide multiple application streams.  This document further defines common terminology and concepts to be used in definitions of There are key differences between the architecture of the Transport Services system and the architecture of the Socket API: the Transport Services API is asynchronous and event-driven; it uses messages for <del> representing data transfer to applications; and it assumes an implementation that can use multiple IP addresses, multiple protocols, multiple paths, and provide multiple application streams. </del>  2.1.

Reviewer comments:
Address
I think the word /assumes/ is not a good choice of word in the arch draft. OLD: and it assumes an implementation that can use multiple IP addresses, multiple protocols, multiple paths, and provide multiple application streams NEW: and it can provide benefit when an implementation can use multiple IP addresses, multiple protocols, multiple paths, and provide multiple application streams.
Done
Exactly what I expected to see!

Revised text:
Transport Services architecture.  The Transport Services Application Programming Interface (API) is based on an asynchronous, event-driven interaction pattern.  It uses messages for representing data transfer  <ins> to applications, and it describes how implementations can use </ins> multiple IP addresses, multiple protocols, and multiple paths, and provide multiple application streams.  This document further defines common terminology and concepts to be used in definitions of There are key differences between the architecture of the Transport Services system and the architecture of the Socket API: the Transport Services API is asynchronous and event-driven; it uses messages for  <ins> representing data transfer to applications; and it describes how implementations can use multiple IP addresses, multiple protocols, multiple paths, and provide multiple application streams. </ins> 2.1.
Original text:
application.  This requires the implementation to understand where messages end, either via a supplied deframer or because the top-level protocol in the established Protocol Stack preserves message <del> boundaries; if, on the other hand, the top-level protocol only supports a byte-stream and no deframers were supported, the application must specify the minimum number of bytes of Message content it wants to receive (which may be just a single byte) to control the flow of received data. </del>  If a Connection becomes finished before a requested Receive action can be satisfied, the implementation should deliver any partial

Reviewer comments:
As described in , I removed the condition that requires the application to specify the length upon receiving from this example.
Impl draft section 5.2 Receiving Messages: "if, on the other hand, the top-level protocol only supports a byte-stream and no deframers were supported, the application must specify the minimum number of bytes of Message content it wants to receive (which may be just a single byte) to control the flow of received data." This text says the application MUST specify minIncompleteLength, however, the API draft says that this values is optional. This should be further clarified and more guidance given in case the value is not set.
Having looked at this and the API carefully, my suggestion would be to turn the semicolon preceding this statement into a full stop and remove all of this "if, on the other hand, ...." text in the implementation draft.
WFM.
This was a long text block - I had a few editorial NiTs you may like to address.

Revised text:
application.  This requires the implementation to understand where messages end, either via a supplied deframer or because the top-level protocol in the established Protocol Stack preserves message  <ins> boundaries.  If the top-level protocol only supports a byte-stream and no framers were supported, the application can control the flow of received data by specifying the minimum number of bytes of Message content it wants to receive at one time. </ins> If a Connection becomes finished before a requested Receive action can be satisfied, the implementation should deliver any partial
Original text:
1. <del> This document specifies a modern abstract programming interface (API) atop the high-level architecture for transport services defined in I- D.ietf-taps-arch.  It supports the asynchronous, atomic transmission of messages over transport protocols and network paths dynamically selected at runtime.  It is intended to replace the traditional BSD sockets API as the common interface to the transport layer, in environments where endpoints select from multiple interfaces and potential transport protocols. </del>  As applications adopt this interface, they will benefit from a wide set of transport features that can evolve over time, and ensure that

Reviewer comments:
Resolving Editorial NiTs in section 1
Section 1: This section contains a RFC2119 keyword that precedes the definition! We use the words /abstract programming interface/ and the acronym /API/ but never tie these together. NiTs: /provide applications a way to/provide a way for applications to/ /as it comes at the cost of reduced portability/because it can reduce the portability./ /How these abstract concepts/The way these abstract concepts/ /is largely dependent on/mostly depends on/
A PR for this issue has already been merged.
Looks good to me, thanks for doing this!

Revised text:
1.  <ins> This document specifies a modern abstract application programming interface (API) atop the high-level architecture for transport services defined in I-D.ietf-taps-arch.  It supports the asynchronous, atomic transmission of messages over transport protocols and network paths dynamically selected at runtime.  It is intended to replace the traditional BSD sockets API as the common interface to the transport layer, in environments where endpoints select from multiple interfaces and potential transport protocols. </ins> As applications adopt this interface, they will benefit from a wide set of transport features that can evolve over time, and ensure that
Original text:
The most basic form of sending on a connection involves enqueuing a single Data block as a complete Message, with default Message <del> Properties.  Message data is transferred as an array of bytes, and the resulting object contains both the byte array and the length of the array. </del>  The interpretation of a Message to be sent is dependent on the implementation, and on the constraints on the Protocol Stacks implied

Reviewer comments:
Looks fine to me. I wonder if we want to add some text and given some implementation hints. Not sure if that is needed but it could be useful...?
Looks good.
In section 7.1 of API it says: messageData := "hello".bytes() Connection.Send(messageData) For some languages that are dynamic typed (i.e. python) this limits the usability of the API as it adds an unnecessary extra step to each send. To me this seems like it should be an implementation detail and not specified in the API.
What are the options other than raw bytes?
In python you could just pass any type that gets automatically converted inside the API. For example, in our implementation you could just pass a string or integer that gets converted to bytes inside the implementation before sending. Also, if there is a TLV framer, you could just pass a [type,value] tuple without having to go through the message context.
We generally consider this a case for framers. However, I think it's reasonable to assume that any of the objects used in a TAPS implementation should provide some way for the app to get at the underlying bytes (and therefore, at least implicitly, the length). I don't read this text as prohibiting the use of some object that is able.
I agree that this is an implementation detail that's irrelevant to the abstract API. Can we close this issue?
Requiring the data be accessible as a byte array is overly restrictive. Can we just remove "Message data is transferred as an array of bytes, and the resulting object contains both the byte array and the length of the array." and the call?

Revised text:
The most basic form of sending on a connection involves enqueuing a single Data block as a complete Message, with default Message  <ins> Properties. </ins> The interpretation of a Message to be sent is dependent on the implementation, and on the constraints on the Protocol Stacks implied
Original text:
that Message are outstanding, there will be two Expired events delivered.  7.3.1. The Sent Event occurs when a previous Send Action has completed, provide backpressure to the transport stack when it is temporarily not ready to receive messages.  8.2.1. A Received event indicates the delivery of a complete Message.  It

Reviewer comments:
Apple does this: URL URL it may be more convenient than what we currently have (or do we have it unspecified? My interpretation of our text would have been to use only one receive handler associated to the Connection). E.g., if an application expects 3 different types of messages to be received in sequence, it can hand over three different receive handlers in Apple's case, and that seems useful. Apple also has a "completion" handler per sent event, handed over as a parameter to "send". Is this necessary? Who needs 3 different "Sent" handlers for 3 different messages - shouldn't the "sent" handler rather be a singular per-Connection thing?
I think this gets into an implementation-specific area. If the language has an easy way to provide a unique completion/closure for a given invocation of Receive(), then I think it is preferable to do this to having a single function. If anything, it may be nice to make a not for Received() and Sent() that they should, if supported by the language, provide this kind of linking between calls and events.
I agree, and I assign this to Tommy since he offered (in an email) to write text. Thanks a lot!

Revised text:
that Message are outstanding, there will be two Expired events delivered. <ins> The interface should allow the application to correlate which Send Action resulted in a particular Send Event.  The manner in which this correlation is indicated is implementation-specific. </ins> 7.3.1. The Sent Event occurs when a previous Send Action has completed, provide backpressure to the transport stack when it is temporarily not ready to receive messages. <ins> The interface should allow the application to correlate which call to Receive resulted in a particular Receive Event.  The manner in which this correlation is indicated is implementation-specific. </ins> 8.2.1. A Received event indicates the delivery of a complete Message.  It
Original text:
7.7. To reduce the overhead of sending multiple small Messages on a <del> Connection, the application may want to batch several Send actions </del>  together.  This provides a hint to the system that the sending of these Messages should be coalesced when possible, and that sending any of the batched Messages may be delayed until the last Message in the batch is enqueued.  7.8. For application-layer protocols where the Connection initiator also

Reviewer comments:
batch sending, as currently specified, means that you already have to have all messages ready in the application because you can declare a patch. That means you have to potentially "buffer" some message in the application. Wouldn't it may be better/easier to have a message property that indicates that a certain message should wait (probably up until a maximum time) for the next message and then buffer it in the transport instead?
We can just clarify the text that the batch may be an arbitrarily long-running block of code, and not require knowing up front all of the data.
Could also allow begin batch/end batch. Explain use case around optimizing send performance.

Revised text:
7.7. To reduce the overhead of sending multiple small Messages on a  <ins> Connection, the application may want to batch several Send Actions </ins> together.  This provides a hint to the system that the sending of these Messages should be coalesced when possible, and that sending any of the batched Messages may be delayed until the last Message in the batch is enqueued. <ins> The semantics for starting and ending a batch can be implementation- specific, but need to allow multiple Send Actions to be enqueued. </ins> 7.8. For application-layer protocols where the Connection initiator also
Original text:
4.2.1. Transport Properties are referred to by property names.  These names <del> are lower-case strings whereby words are separated by hyphens.  These names serve two purposes: </del>  <del> Allow different components of a TAPS implementation to pass </del>  Transport Properties, e.g., between a language frontend and a policy manager, or as a representation of properties retrieved from a file or other storage. <del> Make code of different TAPS implementations look similar. </del>  Transport Property Names are hierarchically organized in the form [<Namespace>.]<PropertyName>. <del> The Namespace part MUST be empty for well-known, generic </del>  properties, i.e., for properties that are not specific to a protocol and are defined in an RFC. Vendor or implementation specific properties MUST use a string identifying the vendor or implementation as Namespace. <del> Namespaces for the keywords provided in the IANA protocol numbers registry (see https://www.iana.org/assignments/protocol-numbers/ protocol-numbers.xhtml) are reserved for Protocol Specific Properties and MUST not be used for vendor or implementation specific properties. </del>  4.2.2.

Reviewer comments:
Clarify how the IANA protocol numbers registry keywords (largely upper-case) textually relate to Transport Property Names. Refine some of the surrounding text.

Revised text:
4.2.1. Transport Properties are referred to by property names.  These names  <ins> are lower-case alphanumeric strings in which words may be separated by hyphens.  These names serve two purposes: </ins>  <ins> Allowing different components of a TAPS implementation to pass </ins> Transport Properties, e.g., between a language frontend and a policy manager, or as a representation of properties retrieved from a file or other storage.  <ins> Making code of different TAPS implementations look similar. </ins> Transport Property Names are hierarchically organized in the form [<Namespace>.]<PropertyName>.  <ins> The Namespace component MUST be empty for well-known, generic </ins> properties, i.e., for properties that are not specific to a protocol and are defined in an RFC. Vendor or implementation specific properties MUST use a string identifying the vendor or implementation as Namespace.  <ins> Namespaces for each of the keywords provided in the IANA protocol numbers registry (see https://www.iana.org/assignments/protocol- numbers/protocol-numbers.xhtml), translated to lower-case and with characters other than letters, numbers, and hyphens deleted, are reserved for Protocol Specific Properties and MUST not be used for vendor or implementation-specific properties. </ins> 4.2.2.