How do we handle Groups (Reconciling FEP-400e and FEP-1b12)?
-
angus: Navigating that thicket in a consistent way across the various implementations in #meeting:threadiverse-wg is the goal here. We definitely don’t want to create another standard silverpill: I don’t know how widely these features are implemented today (perhaps this is something the working group could include in the report?). devnull: we should conduct surveys to make sure we know what the implementation landscape looks like at current before attempting to write any guidelines. So I have to raise a tangential point here, which @devnull will probably be interested in as well: this is kind of what I set out to do in the WIP FEP i set out to start writing a week or two ago; at first it was 9988 "Federated Forums" to try to develop UX guidelines and map them to protocol affordances, but this eventually morphed into 8007 "A conformance profile for social networking services" (both titles pending of course). The general idea is that we all do certain things, and they map onto certain concepts, so we should map those common abstractions and primitives and try to concisely bound behavior of implementations such that you can actually know what to expect. I talk about this in 7888 a bit more, but there isn't actually a difference between the various spins of fediverse software. They're all just specific presentations of generic data. Or at least, on a protocol level, the abstractions of one specific presentation shouldn't leak in. What you have is objects or links, activities, collections. Those building blocks are then transformed into local entities, sure, but the primary focus should be on the protocol level building blocks and not on what any one platform assumes at a UX level. This is how you build commonalities. Practically speaking, a Note can be presented as a social media status or microblog entry or chat message or forum post or comment or whatever. And a Collection of Notes can be presented as a profile, thread, timeline, category, chat room, topic, et cetera. If the grouping is done with an explicit purpose, it ought to be declared as the context. With that said, there isn't really anything to "reconcile" about contextual grouping and distribution of activities. They're mostly orthogonal. The one point of intersection is whether any given actor will send out an Add or an Announce. And given that this is a working group for threaded conversations, it makes sense to me that the working group ought to describe how conversations are constructed. My personal opinion is that these conversations should be explicit based on context rather than implicit based on inReplyTo. Case in point: Consider the common forum use-case of "splitting a thread", which involves moving a post to another thread. That post may be a reply to a post from the original thread. It's important to be able to specify the intended grouping as a separate thing from who you're responding to.
-
-
@[email protected] said:
My personal opinion is that these conversations should be explicit based on context rather than implicit based on inReplyTo.
Yes, that makes a lot of sense. The building of a context via
inReplyTo
is decently reliable but suffers from scaling issues. Given a superior method of deriving context (that is, having one provided by the object) would make things simpler, and more complete, if combined with a good backfill method. -
@trwnh Thanks, this is very helpful. I agree with pretty much everything you've said. So from a practical perspective, for the purposes of implementation, this topic (i.e. reconciling FEP-400e and FEP-1b12) essentially boils down to trwnh: The one point of intersection is whether any given actor will send out an Add or an Announce I think it would be helpful to work through an example of where this particular point of intersection may become an issue. trwnh: Consider the common forum use-case of “splitting a thread”, which involves moving a post to another thread. That post may be a reply to a post from the original thread. It’s important to be able to specify the intended grouping as a separate thing from who you’re responding to. So, this would result in something like: You receive Note 2 (with context A, a collection) which is inReplyTo Note 1 (with context A) You receive an Update to Note 2 and it now has context B (a collection)? OR perhaps you receive an Add of Note 2 to context B? In both 2 and 3, the inReplyTo would still be to Note 1, which would still have context A. @trwnh something like that?
-
Yeah, pretty much. angus: I think it would be helpful to work through an example of where this particular point of intersection may become an issue. Say you encounter an actor of type Group. You Follow the actor. You can't expect it to behave in any one particular way, but it will generally behave in one of these ways: It is a "normal" publishing actor. You will receive Create Object, Announce Object, Like Object, and so on. It is a boost bot. You will receive Announce Object for any object sent to it, mentioning it, etc. It is a 1b12 actor. You will receive Announce Activity, and other activities described in 1b12. It is a Smithereen-style actor. There will be a wall property, and it will send out Add activities where the target is that wall. The Add.object will also have a target, and this will match the Add.target as per 400e. Bonus: It is a context moderator. You will receive Add activities where the target is the object.context. It may also additionally be a "normal" publishing actor. So for any given "post", it might be a Create/Add/Announce/Announce-Create. This isn't limited to Group actors, but it is most prevalent in Group actors because of the popular (erroneous) interpretation of Group as equivalent to Facebook Groups. One final thing to note is that "normal" publishing actors and context moderators may be any type, not just Group -- there is no specific type dependency for these mechanisms, as they are the intended mechanisms. angus: So, this would result in something like: You receive Note 2 (with context A, a collection) which is inReplyTo Note 1 (with context A) You receive an Update to Note 2 and it now has context B (a collection)? OR perhaps you receive an Add of Note 2 to context B? In both 2 and 3, the inReplyTo would still be to Note 1, which would still have context A. @trwnh something like that? Yup. id: type: Note attributedTo: context: content: "I'm posting in a thread" --- id: type: Note attributedTo: inReplyTo: context: content: "This post is in a different thread but still replying to the first" --- id: type: Article attributedTo: inReplyTo: name: "Some Article" summary: "In which I reply to a forum post with an entire blog post. This is not part of any context." content: "
Lorem ipsum dolor sit amet...
" -
silverpill:
My question was specifically about private groups. Implementations based on FEP-400e already exist in the Fediverse. As far as I can tell, private groups based on FEP-1b12 exist only in a form of an RFC.
Friendica, which follows FEP-1b12, does support private groups as well. We implemented them just like the public groups. The only addition is that the author system fetches the list of the group members, so that the access can be controlled.
-
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.
-
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 @[email protected]'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
orcc
) to ensure that it is delivered only to the desired receivers. -
heluecht:
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.
By regular you mean
Announce(Note)
? Do you use FEP-1b12 activities such asAnnounce(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.
-
Angus McLeodreplied to Angus McLeod on last edited by [email protected]angus:
Implementations
https://docs.google.com/spreadsheets/d/159_K48ICn53IYOIr0KT39luVJCqBBmmpLeL6Puc7XLE/edit?usp=sharing
I've added an implementation spreadsheet and some prior discussions on this front for our June meeting.
June Meeting (6 June 2024)
Agenda preparation for the June ForumWG¹ meeting can be found at this public link (anyone can make comments for review.) Monthly meetings are held on the first Thursday of each month, at 1700 to 1800 UTC. You can find t…
SocialHub (socialhub.activitypub.rocks)
@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?
-
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 usesAnnounce
, 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.
-
[email protected]replied to Angus McLeod on last edited byangus:
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?
Mitra can process incoming
Announce(Delete)
andAnnounce(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 describesAnnounce(Activity)
activities: https://codeberg.org/fediverse/fep/src/branch/main/fep/1b12/fep-1b12.md#the-announce-activity -
Angus McLeodreplied to Gregory on last edited by [email protected]
Great to see you here again!
grishka:And it’s also fine to be incompatible
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.
grishka:you can’t exactly imagine Mastodon and a phpBB forum interoperating in any meaningful capacity simply because their user experiences are so disparate.
Well, I might slightly disagree with you there as Discourse, NodeBB and other forum-like implementations in the #activitypub:threadiverse-wg interoperate with Mastodon
silverpill:Added “Yes (partial)” to FEP-1b12 column.
Thanks!
silverpill:I intend to fully support both FEP-1b12 and FEP-400e in the future.
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 processAdd
itions to such a collection, so saying it supports 400e is premature. -
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.
@[email protected] 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.
-
Angus McLeodreplied to julian on last edited by [email protected]julian:
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.
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 ...
julian: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.
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.
-
grishka:
My main idea with FEP-400e was to avoid posting group posts to one’s own profile at all costs.
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:
- Explicit manage your "profile" stream as a Collection
- Use something like
audience
to hint which "streams" the activity should be displayed in (see https://socialhub.activitypub.rocks/t/overlapping-taxonomies-and-the-audience-property/4229/8 and https://socialhub.activitypub.rocks/t/overlapping-taxonomies-and-the-audience-property/4229/11 for more details)
Really, my concern is that the use of
grishka: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 theaudience
property and should discard your "group" post as having no recipients.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.
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!)
-
trwnh:
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?
I don't address them to any followers and don't put them into the outbox. This should be enough, in theory.
trwnh: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!)
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.