Change:
This initial effort tweaks the sections that talk about generating and processing Welcome messages. There might be other references to a single Welcome per Commit that should be amended for clarity. Someone should audit for those before we merge this PR.
From my reading, it looks like the creator of an epoch must send the exact same message to each new user. However, in some systems, it is more efficient to send a different message to each user, only containing the intended for them, rather than the for all new members. As far as I can tell, no changes are required on the recipient side. I'm running some performance testing, trying to add thousands of members at a time, and the messages are hundreds of kilobytes large. In a federated environment, this could be copied to multiple servers, with the vast majority of that being unnecessary data.
Good point NAME I filed . In the case, you would do something like send a Welcome per home server?
Thanks. With the way that Matrix currently works, it would probably be best to send a separate message per user, since the current endpoint for sending messages directly to devices requires specifying the message separately for each recipient, and implementations (AFAIK) currently don't do deduplication. In the future, it might be possible to do it differently.
NAME shouldn't ResumptionPSKUsage include (255)? enum { reserved(0), application(1), reinit(2), branch(3), (255) } ResumptionPSKUsage;
Fixed in

Discussion:
"init_secret" for the current epoch and the path secret (if present). <del> Construct a Welcome message from the encrypted GroupInfo object, the encrypted key packages, and any PSKs for which a proposal was included in the Commit.  The order of the "psks" MUST be the same as the order of PreSharedKey proposals in the "proposals" vector. </del> <ins> Construct one or more Welcome messages from the encrypted GroupInfo object, the encrypted key packages, and any PSKs for which a proposal was included in the Commit.  The order of the "psks" MUST be the same as the order of PreSharedKey proposals in the "proposals" vector.  As discussed on joining-via-welcome- message, the committer is free to choose how many Welcome messages to construct.  However, the set of Welcome messages produced in this step MUST cover every new member added in the Commit. </ins> If a ReInit proposal was part of the Commit, the committer MUST create a new group with the parameters specified in the ReInit

12.4.3.1. <del> The sender of a Commit message is responsible for sending a single Welcome message to all the new members added via Add proposals.  The Welcome message provides the new members with the current state of the group after the application of the Commit message.  The new </del> <ins> The sender of a Commit message is responsible for sending a Welcome message to each new member added via Add proposals.  The format of the Welcome message allows a single Welcome message to be encrypted for multiple new members.  It is up to the committer to decide how many Welcome messages to create for a given Commit.  The committer could create one Welcome that is encrypted for all new members, a different Welcome for each new member, or Welcome messages for batches of new members (according to some batching scheme that works well for the application).  The processes for creating and processing the Welcome are the same in all cases, aside from the set of new members for whom a given Welcome is encrypted. The Welcome message provides the new members with the current state of the group after the application of the Commit message.  The new </ins> members will not be able to decrypt or verify the Commit message, but will have the secrets they need to participate in the epoch initiated by the Commit message. <del> In order to allow the same Welcome message to be sent to all new </del> <ins> In order to allow the same Welcome message to be sent to multiple new </ins> members, information describing the group is encrypted with a symmetric key and nonce derived from the "joiner_secret" for the new epoch.  The "joiner_secret" is then encrypted to each new member