Groups implementation

For everybody attending the conference :

This thread got very long and is very active.
A Birds of Feather session would be nice !
But I am currently writing 2 proposals for “topics” and “ui things”, so:

Does any attendee maybe want to write a very short proposal “groups”, linking to this post ?
Just create a topic in this category …

1 Like

@Sebastian that APConf sub-category does not yet exist (or is restricted).

Hm, I can see six proposals by different people and other posts in the category.
So, @how : Is the category maybe restricted to a group?

Bumping… this discussion has unfinished biz   :slight_smile:

2 Likes

Re-using this topic as it is still open. I’m currently implementing FEP-400e from @grishka, in order to provide a complete project-agnostic groups implementation covering every known groups implementation and quirk (there are a fair number of these and I suspect we’ll have even more before all is said and done). Some questions came up.

If an actor has publicly-appendable collections, its server MAY include them as additional fields in its ActivityPub representation. For example, user actors may specify the link to their walls, or groups may specify the link to the collection of their photo albums.

Implementations MAY use the presence or absence of specific collection to determine whether the actor’s server supports features that depend on that collection and alter their UIs accordingly.

What is the proposal for indicating these writable collections in the actor record? It’s OK if this is just a hack. I just need to know what it is so we can use it and alter our behaviour accordingly. I’m more concerned at the moment with the “wall” than photo albums, but if there’s an example actor record that shows what is planned for both it would be sweet.

The next question is about using Create/Note/Collection (type, object,target). In the original AP/AS specifications, it was suggested that such activities should be Add/Note/Collection (not explicitly, but more or less inferred in the description of ‘Add’ and also the text in section 5.8.2 “Collection Management”). I intend to provide this as a general collection management interface and as recommended in the spec. Is there any chance that Smithereen could also do this, or should we also support Create/Note/Collection purely for Smithereen compatibility?

Third question. Regardless of the answer to the second question, there are different behaviours depending on the audience of the activity. If the activity is public, we don’t intend to add the Note to the wall (technically the outbox). This is more a published report of an activity that already happened - “Joe added a note to the Foobar group’s outbox”. Whereas if there is a single recipient (the owner of the wall) it can be taken as a directive to actually perform the activity rather than just report that it happened. Not sure how best to clarify this difference other than by looking at the audience and seeing if the collection belongs to the single recipient and ignore it if the activity is addressed more widely.

Fourth question (slightly related to the third): If the collection operation fails (lack of permission), is it even appropriate to notify anybody else besides the wall owner of the collection operation? I would say no, but I know there are a lot of people in this forum that would disagree and say the actor should be able to tell anybody anything at all, and the success or failure of the operation isn’t relevant. Because free speech. But if the activity is “Joe added a note to foobar group’s outbox” and it didn’t actually get added to foobar group’s outbox because Joe isn’t a member, such an activity is a lie and should not be sent.

I’m merely suggesting that any kind of activity with a collection target might require a bit of extra care to define the activity audience; which would let receivers know for certain whether this was a request to perform the operation or an activity reporting that it happened. Without looking at the activity audience, the desired action on receipt of the activity is ambiguous.

That’s a good question! Currently it’s up to the implementation. I suppose it’s best to take care of this particular thing as part of the capability negotiation/“compliance profiles”/privacy settings effort. Because, for example, an actor might have a wall, but whether you can post on it depends on who you are.

The problem I see with the approach in the spec is that the collection ID is only contained in the Add activity. It’s fine for straightforward cases like when your server hosts the collection and receives such an activity, but there are cases when this breaks down. For example, if you fetch the object using its ID (aka copy a link to a post and paste it into the search field on your instance), your instance has no way of knowing which collection the object belongs to because it doesn’t have its enclosing activity. So, it’s not self-contained. This would lead to buggy behavior like misrepresenting wall posts as something posted to one’s followers.

Example of an already existing similar behavior is replies. Each reply has a link to its parent in its inReplyTo, and each post that has replies lists them in its replies collection. This way you can traverse the thread in both directions, even when you start off with just a single post from the middle of it.

It depends. For wall posts, it doesn’t make much sense imo — you can’t move a post between walls. There’s also the question of semantics: Add implies that you add an existing object to a collection, so there should have been a Create at some point before it.

Right now I rely on LD-signed activity forwarding for this (the Create is sent to the collection owner only, and nothing is forwarded if it wasn’t added), but yes, I agree that it might use some improvement. There is currently no protection against some bad person sending a wall post to group members directly despite the group itself not allowing that post. You got me thinking about how there needs to be some (simple) way to prove that the collection owner approved someone adding an object to their collection. Maybe it should actually be an Add activity after all. So the flow would go like that:

  • Someone sends a Create{Note}, as in my FEP, to the instance that hosts the group.
  • If this is isn’t allowed, it returns a 403 or sends a Reject{Create{Note}} to that person.
  • If it is allowed, it adds the post to its wall, and then sends all group members an Add{Note}, as per spec, with the post as a link.

This way there will be a proof that the group has accepted the post, because there was an activity explicitly mentioning this post, signed by the group actor.

The one small problem that then remains is that if you fetch that post using a direct URL, it would still be considered to be on the group’s wall even though it’s actually not. This could be abused by making such a post and then a comment (reply) to it mentioning someone. Their instance would receive the post with the mention, and will fetch the thread to show its context, and would thus end up with that fake post on a group wall.

The problem then becomes: given an object that claims to belong to a collection on another instance, how do I prove that this instance that owns the collection has sanctioned the addition of this object to its collection? Since I’m treating ActivityPub like an API, I want something resembling an API call that would accept a collection ID and an object ID and return a yes/no answer whether the object is in the collection. I’m open to suggestions on this one.

Thanks. I’ve got something that may work with what you have today (needs testing but shouldn’t be too far off). If you do change anything just say something so we can adjust and re-test if necessary.

I’m not ignoring the other points raised, but they aren’t really issues in our implementation – for various reasons; so I wouldn’t be the best person to offer any advice on them or debate their merit.

In Lemmy we solve this by having the Group wrap all user activities in Announce, before sending it to followers (with original, unchanged activity as object). This makes verification pretty easy. It also scales much better than your idea of rewriting activities (Create to Add). We have a dozen activities that can be sent in a group, so wrapping works much better, eg Announce/Create/Note, Announce/Vote, even Announce/Undo/Delete.

We specify the group in cc, which works fine. But it sounds cleaner to move it into a separate field, so I think its a good idea.

In most current implementations, Announce means repost (and a many-to-one relation, as many actors could Announce a single object). I chose Add specifically to emphasize the creation of an object into someone else’s collection as a semantically different action.

The important distinction here is that you delegate the authority over your object to the collection owner.

I really don’t like the idea of wrapping someone else’s activities or objects like that. My internal representation can’t fully correspond to whatever JSON some other software might generate, so for example Smithereen would definitely not serialize back again any of the fields it doesn’t recognize. And I don’t store the original JSON either. This is one reason why I advocate for always using links for objects from other servers.

1 Like

Yes, Announce means that the group reposts that activity to its followers. That uses the outbox, which is also a collection. And we dont really want to delegate authority over the object (though mods can delete the page/note from the group).

Your proposal might work if the only activity being sent inside of groups is Create, which can then be turned into Add. But in Lemmy groups we also use Update, Delete, Like, Undo/Delete and more. It just wouldnt make sense to turn all of those into Add activities.

I think your FEP essentially tries to standardize the groups implementation of Smithereeen, but doesnt take into account how other activitypub projects implement similar functionality. To make a general standard of “groups in activitypub”, it is probably necessary to do more work making our projects compatible with each other.

Announcing activities doesn’t match how any other implementation works. (except maybe when boosting polls?) Activities from members have no need to “belong” to the group, they just need to be forwarded.

I also still do not believe that posting to a group should grant the group any permissions to modify the object.

I use forwarding for this (and all my activities have LD-signatures).

Yes and no. There are different group models. The one the FEP is about, and the one Smithereen implements, is the same way groups work in VKontakte and Facebook.

But I do think that this model of creating objects into collections is universal enough that Lemmy could possibly use it as well. Reddit and other similar link aggregation services work on the same model my FEP proposes: you submit a link to a subreddit, and the subreddit either accepts it or not. It also has a complete authority over it: the moderators can delete it, put a flare on it, mark it as NSFW, and you could be blocked from submitting it in the first place. Your link can’t exist on its own. It can only be considered in the context of the subreddit, it’s not a self-contained object.

Announce is when you take someone’s self-contained, pre-existing object and put a reference to it into your outbox. An object can be Announced many times by different actors. Add is when you accept someone’s request to create an object into a collection you own. An object can only belong to a single collection at any given time. It’s its creator’s outbox by default, but this FEP allows this to be something else.

I will admit, I think it’s a little confusing to me to even think about what “federation” means between a SNS/microblogging service like Smithereen or Mastodon and a link-aggregator service like Lemmy. What does it it mean for a subreddit to be “compatible with” a Facebook group? What is the expected UX on either side?

How does this forwarding work? You just have the community sign and send the same json that was sent by the user? I guess this could work for Lemmy together with the target field. On the other hand, that would probably break compatibility with Mastodon/Pleroma completely, and I dont see a good reason for such a break.

Yes. I actually do the same for all posts. If you post a comment for example, that only goes to the top-level post and the immediately parent comment authors, and any mentioned users. The server of the top-level post author is then responsible for forwarding that comment to anyone else who might be interested in it. Same for any other activities relating to the post, like likes and comment deletions.

It actually doesn’t break compatibility. Mastodon works fine with relayed group posts. Pleroma doesn’t; but only because they haven’t found anybody to write a JSON-LD normaliser in Elixir. You sort of need this component for third-party verification. Actually you don’t need it at all, but that’s another battle for another day.

@grishka @macgirvin Okay that sounds like it should work for us then. But i dont want to make another rewrite with breaking changes of our federation code at this time. Better to wait until the FEP makes more progress, and more projects give their input on it. I also have some comments on it btw, where do you prefer I post them?

Maybe in the FEP topic?

1 Like