Standardizing on ActivityPub Groups

re: definition, most of it makes sense.

This is an implementation detail. For Mastodon, it probably should be.

*yet? I imagine this should be possible in the future, especially if Add is used instead of Create.


re: initial implementation, this also makes sense, bearing in mind that it is initial implementation.


re: ActivityPub:

  • Group type is fine, but perhaps some extra extension properties or types should be used to signal how the Group works on the backend. There are some existing projects that already use Group actors for mailing-list-like use cases. Some thought will be necessary to differentiate those “groups” from Mastodon-compatible “groups”. The use of @type = as:Group is not enough.

    • There needs to be a way to signal that a Group is a “joinable” Group and not a “forwarding” Group. Or it may be both. Perhaps an extension type like toot:Group instead of as:Group? Perhaps an extension property like toot:joinable?

      • I somewhat favor the first of these two options, as it makes clear the distinction between the typical ActivityPub delivery model (Follow, inbox forwarding, get from outbox) and the proposed mechanism here (Join, distribute an Add, get from wall). Projects that support both models may declare a type array like @type = [as:Group, toot:Group]. This would signal that the Group may be both Followed and Joined.

      • The downside to using a property like toot:joinable instead is that any implementation that does not understand this property may attempt to send a Follow rather than a Join, which may not be understood. But on the other hand, it is more generic, and could be used to signal (for example) that an as:Organization follows the same Join-based semantics.

      • It may actually be a good idea to use both.

  • Join, Accept/Reject Join, Leave, that’s all fine too.

  • Sending posts and replies to the group for redistribution is fine too and probably necessary for the proper UX. But there should be some way to signal that a post is authoritatively owned by the Group, maybe? FEP-400e (or similar) is certainly one way to do this, as a group “wall” is assumed to be managed by the Group actor, and Add/Remove into that “wall” simplifies both distribution of activities and also avoids semantic issues about what it means to Delete someone else’s object. My only concern with FEP-400e as currently written/finalized is in its use of “abbreviated objects”, which doesn’t seem JSON-LD compliant to me.


re: open questions:

as:audience can contain either the Group IRI or an array of Group and as:Public. There is a slight pitfall in that some implementations may copy audience into to/cc and therefore copy as:Public, causing a group post to “leak” into the regular timeline for Mastodon 3.5 and below, but this is why I favor using an extension type as described above. Non-group-aware implementations will probably ignore the existence of toot:Group entirely, no?

Implementation detail: drop all interactions from non-members (inside the group context). If a post leaks out of the group context, then those interactions may be delivered to the inbox of a regular Person actor, but this is not much different than the issue presented by blocked actors/domains, or by non-reply-control-aware implementations in a FEP-5624 world. There is always the chance that a separate conversation may be taking place outside your control, and all you can do is ignore it or filter it out.

Inbox forwarding? Although I’m not sure how to “guarantee” that inbox forwarding was performed or took place. I guess maybe Accept/Reject can be used to signal processing side effects?

  • Sending a GET to the group wall with an HTTP Signature should return at minimum any posts authored by the owner of the signature. If the signer is also a member, the GET should return all group posts as well. This should allow prior members to view their old posts and delete them if they wish.

    • Alternatively, you could say it is the responsibility of the individual actor to keep track of which of their posts are in which groups.
  • Replies should be visible if they are publicly dereferenceable via the replies collection?

Add/Remove to the members collection, if it matters (and group membership is publicly visible). The members collection should maybe use the same HTTP-Sig mechanism as the wall, so that anyone can check if they are a member by whether they are included in the partial Collection returned. Or you could rely entirely on keeping track of the history of Join / Accept Join. There’s also your follower collection synchronization FEP that could help in shared server scenarios.

Actor tokens could work, bearcaps could work if fetching the wall is the primary method of interfacing with a group. And one other option is, if you implicitly trust the group to verify everything and not commit forgeries, then it can forward activities without a signature. But for verification it would probably be a good idea to use bearcaps. I’m not sure what that implies for scaling.

Either with Offer Remove, or as an implementation detail you could have the Group send out a new Remove attributed to itself if it was received from a member with the appropriate permissions.

2 Likes