How do we handle Groups (Reconciling FEP-400e and FEP-1b12)?

How the list of group members is represented (some property on a group actor I guess)?
Do you fetch announced activities from the server of origin when that server is different from the group actor’s server?

The list of group members is retrieved via the “followers” endpoint of the group with a signed request. Only if the signer is a member of the group can they retrieve the data. The permissions in the sender’s post are then set to all group members. The server makes a regular “announce” activity. The other servers then make a signed request to the sender’s server so that only members of the group can retrieve the post.

1 Like

The server makes a regular "announce" activity. The other servers then make a signed request to the sender's server so that only members of the group can retrieve the post.

I think this makes sense, even if it's not as explicitly segregated as @mikedev@fediversity.site's conversation containers. There is one concern in that an announce would still mean that the existence of the post would be known, even if not retrievable by members outside of the group.

Not necessarily a concern when you consider that the announce would only be addressed to group members, but when you use shared inboxes, then it gets a little more confusing... or does Friendica's implementation of private groups via 1b12 explicitly not target shared inboxes?

The announce is of course sent only to the members of the group. We always use the shared inboxes (if the system isn’t configured differently). But this is not an issue at all. The post does - of course - contain the appropriate headers (to or cc) to ensure that it is delivered only to the desired receivers.

By regular you mean Announce(Note)? Do you use FEP-1b12 activities such as Announce(Create|Update|Like|Delete), and if so, do you retrieve wrapped activities from the server or origin?

We can receive and process these “wrapped activities” but we don’t transmit them.

I’ve added an implementation spreadsheet and some prior discussions on this front for our June meeting.

@devnull By-the-by it strikes me that these implementation spreadsheets we’re making should be synthesised in some way at some point. My gut is that this would make a good masters or PhD thesis for someone, i.e. a knowledge graph or onotology or something like that of the actual Fediverse (i.e. how it’s actually implemented). We’d just need to find the right enthusiastic (and funded) academic…

@silverpill I was actually unclear on Mitra’s approach to 1b12 and 400e. Would you mind adding in a Yes in the right column (and any notes) to the spreadsheet?

3 Likes

Oh hi. I’m not very active on this forum lately but I received an email about this topic, only now.

My main idea with FEP-400e was to avoid posting group posts to one’s own profile at all costs. I see Announce-style groups as mostly a crutch for wider compatibility (there are even bots like this one that work on top of the Mastodon API, you mention it and it boosts). As I design things starting from the UX, I couldn’t use anything that uses Announce, because that would make my desired UX nearly impossible.

Now for some other implementations “not posting to profile” might not be a concern at all. Lemmy is modeled after Reddit, which does show your posts and comments on your profile front and center. And that’s fine. And it’s also fine to be incompatible; you can’t exactly imagine Mastodon and a phpBB forum interoperating in any meaningful capacity simply because their user experiences are so disparate.

My other idea was that it’s not just walls — it’s a generic mechanism of creating objects into someone else’s collections, while also relinquishing full control over them. My FEP explicitly says that the collection owner can delete someone else’s objects contained in the collection. I will soon start working on photo albums. Those will exist in groups too, and the way they will work is that everyone who has access to the group could upload new photos. So again, someone else’s collection into which others add things.

1 Like

Mitra can process incoming Announce(Delete) and Announce(Like) FEP-1b12 activities, but it can’t create any FEP-1b12 activities. I intend to fully support both FEP-1b12 and FEP-400e in the future.

Added “Yes (partial)” to FEP-1b12 column.

Also, Mitra fully supports standard Announce(Object) activities, but in my view they are not part of FEP-1b12, which only describes Announce(Activity) activities: fep/fep/1b12/fep-1b12.md at main - fediverse/fep - Codeberg.org

2 Likes

Great to see you here again!

True! Albeit, I think the general consensus here is that there isn’t an inherent incompatibility between 400e and 1b12. The question is more how an implementor approaches processing a Group actor’s activities. @trwnh helpfully lays out the possibilities above

The point of this topic and the spreadsheet I just shared is not to contrast the two standards. It’s more of an empirical reference of sorts for implmentors.

Well, I might slightly disagree with you there as Discourse, NodeBB and other forum-like implementations in the Threadiverse Working Group interoperate with Mastodon :slight_smile:

Thanks!

I think this is where the Discourse plugin will end up too.

Actually, now that I think of it, the Discourse plugin does partially support 400e as it will recognise a Collection in the target property. However it doesn’t process Additions to such a collection, so saying it supports 400e is premature.

2 Likes

Actually, now that I think of it, the Discourse plugin does partially support 400e as it will recognise a Collection in the target property. However it doesn't process Additions to such a collection, so saying it supports 400e is premature.

This is where there is some potential to trailblaze as the other half of the equation might be implementing 7888, aka a resolvable context.

I have a feeling that context and target would work well to point to the same thing.

@angus@socialhub.activitypub.rocks said in How do we handle Groups (Reconciling FEP-400e and FEP-1b12)?:

By-the-by it strikes me that these implementation spreadsheets we're making should be synthesised in some way at some point.

My assumption was that the surveys and spreadsheets would be helpful to guide discussion at WG meetings, but eventually lead to a SocialCG report of non-normative findings, followed by a recommendation for new implementors.

3 Likes

Agreed! The Discourse plugin treats them as equivalents, with a preference for context over target.

def create_collection(post)
   # See https://codeberg.org/fediverse/fep/src/branch/main/fep/400e/fep-400e.md
   # See https://socialhub.activitypub.rocks/t/standardizing-on-activitypub-groups/1984
   raw_collection = object.context || object.target
   ...

Also agreed, that is my thinking too. I just meant that when I was making the spreadsheet it occurred to me that it could also be the basis for an academic project. Perhaps I’m also just being lazy and thinking of who would be enthusiastic about and have the time to do this kind of thing comprehensively.

2 Likes

You can’t prevent this, because there’s no such thing as an explicit “profile” that you add posts into. I don’t really understand why Smithereen and Mastodon are so strongly concerned with this point that it leads to some frankly very strange decisions. There are two “correct” paths forward:

Really, my concern is that the use of target is not only spec-incompliant, it’s also not a guarantee of the thing you’re trying to guarantee. If you really want to make sure posts don’t get displayed “at all costs” then why not stop using to/cc for such posts? As far as I can tell, Mastodon at least will ignore the audience property and should discard your “group” post as having no recipients.

This also strikes me as unnecessary. There’s no need to delete other people’s objects, you can just not include them; they effectively become orphaned references that can be garbage collected (or added back later!)

2 Likes

I don’t address them to any followers and don’t put them into the outbox. This should be enough, in theory.

How would you prevent that from leaking into the UX? How would you explain that to users? It’s generally expected that group moderators can delete any content from the group. And again, the semantics of you not owning the post, not having a complete authority over it, are important.

Is there a practical difference between “deleting from the group” or “removing from the group”? In both cases the end result is that the post is not visible anymore. Semantically it’s a red herring, you should own the collection, not other people’s posts.

The most basic of examples: I make a static HTML page that I claim is in response to one of your static HTML pages. You have the option to acknowledge my page as a response, or otherwise not acknowledge it. But you can’t stop my page from existing. The problem is entirely conventional and third-party observers should view only your page and its acknowledged responses if they care about your authority to decide what gets acknowledged. In other words, “moderation” is in what you choose to include or exclude, not in preventing the existence of something.

The way I’d explain it to users is very simple: “Your post has been removed from the group”. UX-wise, you can invalidate the stale cache for the orphaned object. I don’t see why anything has to “leak” anywhere.

I agree that group actors should not be able to Delete posts, only Remove them from a “wall” or a context. It should be always clear who owns what. Without that, authentication and authorization are difficult and that leads to numerous security issues.

@grishka I’m writing a FEP on this very topic: feps/c7d3/fep-c7d3.md at main - silverpill/feps - Codeberg.org

1 Like

Well then for me, Remove{Note} would simply be a fancier way for moderators to do the same thing that Delete{Note} would do.

It is clear — the group owns its wall collection but each post author also owns each individual post they made, to a degree. The group can’t edit posts, but it can delete them. The author can both edit and delete their own posts.

I also have a mechanism for checking that the object is truly in a collection, but that isn’t documented as a FEP (yet?). It is documented in my federation document.

But how recipients are expected to know that?

In a regular Delete{Note} activity, authorization check is straightforward: Delete.actor == Note.attributedTo.
But if Delete.actor is a different actor (a group actor), then I wouldn’t be able to process it without 1) knowing the type of application I’m federating with 2) discovering the members collection.

Remove{Note}, in comparison, doesn’t require any special knowledge. It updates the target collection (according to ActivityPub spec), so I just need to verify that Remove.actor == Remove.target.attributedTo.

It’s specified like that in FEP-400e ¯\_(ツ)_/¯

You don’t need to discover the members of the collection to make this work. Remember, I treat ActivityPub like an API.

If you already have this post in your local database, you know which wall it’s on, so you check that, in AP terms, Delete.actor == post.target.attributedTo || Delete.actor == post.attributedTo (my actual DB schema is different, I have owner_id and author_id in my posts table so I just check if it’s either the one or the other).

If you don’t have that post in your local database, it’s a no-op because it’s asking you to delete something you’ve never seen to begin with. Deletes already work like that.

This is exactly what Lemmy does. Delete for your own posts, Remove for mod actions.