Original text:
representation of the state of the group by applying the proposals and advancing the key schedule. <del> A group member that has observed one or more Proposal messages within an epoch MUST send a Commit message before sending application data. This ensures, for example, that any members whose removal was proposed during the epoch are actually removed before any application information is transmitted. The sender of a Commit message MUST include in it all valid Proposals that the sender has received during the current epoch.  Invalid Proposals include, for example, Proposals with an invalid signature or Proposals that are semantically inconsistent, such as a Remove proposal for an unoccupied leaf.  The Commit MUST NOT combine Proposals sent within different epochs.  Despite these requirements, it is still possible for a valid Proposal not to be covered by a Commit, for example, because the sender of the Commit did not receive the Proposal.  In such cases, the sender of the proposal can retransmit the Proposal in the new epoch.  In the case where a committer is processing Proposals where an Update proposal or a Remove proposal exists for herself, this proposal MUST be ignored and added to the list of discarded proposals in the Commit. </del> Each proposal covered by the Commit is identified by a ProposalID value, which contains the hash of the MLSPlaintext in which the <del> Proposal was sent, using the hash function for the group's </del>  ciphersuite. <del> The sender of a Commit message MUST include in it all proposals that it has received during the current epoch.  Proposals that recipients should implement are placed in the "updates", "removes", and "adds" vector, according to their type.  Proposals that should not be implemented are placed in the "ignored" vector.  For example, if two Update proposals are issued for the same leaf, then one of them (presumably the earlier one) should be ignored and the other (presumably the later) should be added to the "updates" vector. </del>  [[ OPEN ISSUE: This structure loses the welcome_info_hash, because new participants are no longer expected to have access to the Commit A member of the group creates a Commit message and the corresponding Welcome message at the same time, by taking the following steps: <del> Construct an initial Commit object with "updates", "removes", "adds", and "ignored" fields populated from Proposals received during the current epoch, and an empty "path" field. </del>  Generate a provisional GroupContext object by applying the proposals referenced in the initial Commit object in the order Regardless of how messages are kept in sequence, implementations MUST only update their cryptographic state when valid Commit messages are <del> received.  Generation of handshake messages MUST be stateless, since the endpoint cannot know at that time whether the change implied by the handshake message will succeed or not. </del>  11.1. With this approach, the delivery service ensures that incoming messages are added to an ordered queue and outgoing messages are <del> dispatched in the same order.  The server is trusted to resolve conflicts during race-conditions (when two members send a message at the same time), as the server doesn't have any additional knowledge thanks to the confidentiality of the messages. </del>  Messages should have a counter field sent in clear-text that can be checked by the server and used for tie-breaking.  The counter starts

Reviewer comments:
Ignored proposals don't make sense to me. How can they possibly add value? Also, re-structured section on Commits some. !
I'm afraid the flow chart might not quite be that simple. It is possible for there to be proposals that (1) don't appear in the Commit and (2) don't need to be re-sent. The simplest case is when a member sends two Update messages within an epoch. On the one hand, there's no practical need for them both to be included in the Commit, since one will overwrite the other. On the other hand, at the same time, the new member shouldn't re-send the stale Update. The idea of the array was to provide a slot for these to be included in the Commit, but without the need for recipients to act on them.
On a separate note, it would be helpful if you could base your different PRs on master, to make the specific changes clearer.
In that specific example, the member is aware of all the Updates they've sent and can know to only expect one to be included. In fact, the member can try to enforce a lot of things: Re-send if no Update was included. Re-send if the included Update isn't "recent enough." Re-send if the included Update isn't the most recent. The member's own sense of what should/shouldn't be included is what matters here, not the comitter's.
I can agree that the difference between "Proposal got dropped somewhere in the ether" and "Proposal was consciously ignored by the Committer" is not really salient. I'll post to the list to see if anyone else objects.
NAME raised some concerns with this on the mailing list. I proposed a compromise there, of the form: Specify that if a Committer receives two Updates proposals for the same leaf in the same epoch, then it MUST commit the latest one it received. State explicitly that the only Proposals that may be omitted from a Commit are: Invalid proposals (e.g., because of a bad signature, parsing error, reference to a non-existent leaf) Proposals whose effect on the tree is overwritten by another proposal, which at this point includes only: Updates for a leaf prior to the latest Update received by the committer Updates for a leaf for which there is a Remove in the epoch
NAME - How does that strike you?
Isn't that what's currently in the PR? The only difference is "SHOULD prefer the most recent Update" because it's not enforceable anyway
Here's the Weekly Digest for : - - Last week 5 issues were created. Of these, 1 issues have been closed and 4 issues are still open. :greenheart: , by :greenheart: , by :greenheart: , by :greenheart: , by :heart: , by :speaker: , by It received 3 comments. - - Last week, 8 pull requests were created, updated or merged. Last week, 7 pull requests were updated. :yellowheart: , by :yellowheart: , by :yellowheart: , by :yellowheart: , by :yellowheart: , by :yellowheart: , by :yellowheart: , by Last week, 1 pull request was merged. :purpleheart: , by - - Last week there were 3 commits. :hammerandwrench: by :hammerandwrench: by :hammerandwrench: by - - Last week there were 2 contributors. :bustinsilhouette: :bustinsilhouette: - - Last week there were no stargazers. - - Last week there were no releases. - - That's all for last week, please :eyes: Watch and :star: Star the repository to receive next weekly updates. :smiley: You can also .

Revised text:
representation of the state of the group by applying the proposals and advancing the key schedule.  Each proposal covered by the Commit is identified by a ProposalID value, which contains the hash of the MLSPlaintext in which the  <ins> Proposal was sent, using the hash function from the group's </ins> ciphersuite.  <ins> A group member that has observed one or more proposals within an epoch MUST send a Commit message before sending application data. This ensures, for example, that any members whose removal was proposed during the epoch are actually removed before any application data is transmitted. The sender of a Commit MUST include all valid proposals that it has received during the current epoch.  Invalid proposals include, for example, proposals with an invalid signature or proposals that are semantically invalid, such as an Add when the sender does not have the application-level permission to add new users.  If there are multiple proposals that apply to the same leaf, the committer chooses one and includes only that one in the Commit, considering the rest invalid.  The committer MUST prefer any Remove received, or the most recent Update for the leaf if there are no Removes.  If there are multiple Add proposals for the same client, the committer again chooses one to include and considers the rest invalid. The Commit MUST NOT combine proposals sent within different epochs. In the event that a valid proposal is omitted from the next Commit, the sender of the proposal SHOULD retransmit it in the new epoch. </ins> [[ OPEN ISSUE: This structure loses the welcome_info_hash, because new participants are no longer expected to have access to the Commit A member of the group creates a Commit message and the corresponding Welcome message at the same time, by taking the following steps:  <ins> Construct an initial Commit object with "updates", "removes", and "adds" fields populated from Proposals received during the current epoch, and an empty "path" field. </ins> Generate a provisional GroupContext object by applying the proposals referenced in the initial Commit object in the order Regardless of how messages are kept in sequence, implementations MUST only update their cryptographic state when valid Commit messages are  <ins> received.  Generation of Commit messages MUST NOT modify a client's state, since the endpoint doesn't know at that time whether the changes implied by the Commit message will succeed or not. </ins> 11.1. With this approach, the delivery service ensures that incoming messages are added to an ordered queue and outgoing messages are  <ins> dispatched in the same order.  The server is trusted to break ties when two members send a Commit message at the same time. </ins> Messages should have a counter field sent in clear-text that can be checked by the server and used for tie-breaking.  The counter starts