Original text:
process the Commit (i.e., not including any members being added or removed by the Commit). <del> The sender of a Commit SHOULD NOT include any Update proposals that the sender themselves generated.  If sender generated one or more Update proposals during an epoch, then it SHOULD instead update its leaf and direct path by sending "path" field in the Commit. </del> If there are multiple proposals that apply to the same leaf, the committer chooses one and includes only that one in the Commit, <del> 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 containing KeyPackages with the same tuple "(credential.identity, endpoint_id)" the committer again chooses one to include and considers the rest </del>  invalid.  Add proposals that contain KeyPackages with an "(credential.identity, endpoint_id)" tuple that matches that of an existing KeyPackage in the group MUST be considered invalid.  The

Reviewer comments:
When computing the tree hash, should there be an indicator bit for whether the value being hashed represents a leaf or parent node?
This doesn't seem like a terrible idea. You could either add a field to LeafNodeHashInput and ParentNodeHashInput, or define an enum and do the same, or make a . For example:
Any Update proposal for the sender is redundant if the Commit includes a .
This is true, but they're also harmless, since the information in the will overwrite all of their effects. Note that: A requirement to this effect would only be binding on a committer. The receiver of a Commit MUST process all of the referenced proposals, as prescribed in the Commit. A is required if a Commit covers Updates or Removes; if a Commit covers a self-Update, then it must have a . So there's no reasn to condition on "if a is included". This seems fine for some advisory text, but not an absolute prohibition.
The way I read Section 11.2 is that the receiver should verify that the committer has followed the rules, e.g. that the commit contains all valid proposals, etc., even if that is not explicit in the list of things the receiver of a commit should do. So any requirement on the committer would also affect the receiver. So if we mandate that a committer can't include self-updates if the path is populated, then it would be implicit that the receiver checks that the committer actually followed the rules when processing a commit. I'm not sure I understand your second point. My reasoning would be that if a committer wants to do an update, they would just include a path rather than an update proposal, which is redundant anyway.
Sorry NAME I missed that there was still conversation going on here before merging . On the latter point: All I'm saying is that there is no case where there is both (a) a self-update and (b) no . So you're always in the bad scenario :) In our Wire chat, you made a good point that repeated proposals for the same leaf are invalid, and self-Updates are effectively repeats of the . Reopening, will file a fresh PR to adjust the text.

Revised text:
process the Commit (i.e., not including any members being added or removed by the Commit).  If there are multiple proposals that apply to the same leaf, the committer chooses one and includes only that one in the Commit,  <ins> considering the rest invalid.  The committer MUST NOT include any Update proposals generated by the committer, since they would be duplicative with the "path" field in the Commit.  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 containing KeyPackages with the same tuple "(credential.identity, endpoint_id)" the committer again chooses one to include and considers the rest </ins> invalid.  Add proposals that contain KeyPackages with an "(credential.identity, endpoint_id)" tuple that matches that of an existing KeyPackage in the group MUST be considered invalid.  The