FEP Convergence (400e, 7888, 171b/Conversation Containers, 76ea)
-
Related to the ForumWG topic of resolvable context collections, there are four FEPs that are currently in consideration:
- FEP-7888: Demystifying the context property
- FEP-400e: Publicly-appendable ActivityPub collections
- Draft FEP-171b: Conversation Containers, an evolution of Conversation Containers
- FEP-76ea: Conversation Threads
@[email protected] made a suggestion last month to hopefully reduce the number of moving parts:
- Both FEP-400e and FEP-1b12 implementations: support FEP-7888 (context collection)
- FEP-400e implementations: upgrade to Conversation Containers
- FEP-1b12 implementations: add target property to Announce activity that points to context collection.
This takes FEP 400e out of the running (potentially). But the day after that last meeting, @[email protected] put together FEP 76ea, and now we're back to three.
My concern is that all three FEPs (7888, 171b, and 76ea) all share these distinct qualities:
- They establish a conversational context for a given object
- They federate out an
Add
on collection addition. (76ea also sendsRemove
) - They contain some concept of a context owner (
attributedTo
)
They differ on the following qualities:
- 7888/171b use
context
whereas 76ea uses a new propertythr:thread
- 171b specifies a new object type
Context
- Collection items:
- 7888 sends objects in chronological order
- 171b sends activities in chronological order
- 76ea sends objects in reverse chronological order
In the lead up to the November WG meeting I'd like to address those differences. All three FEPs are in pre-draft or draft stages, and so I am hoping we can find some common ground and compromise.
Pinging interested parties (who were not already mentioned above) for comment:
@[email protected] @[email protected] @[email protected] @[email protected]
-
@julian @silverpill @evan @trwnh @erincandescent @mikedev
I continue to feel that this general idea is in keeping with the as-written intent of the context property. Adding a new property is likely to make adoption slower and more complicated. Adding a new object type is also likely to make adoption slower and more complicated, but less so than the property. Either of those option only really makes sense to disambiguate from existing uses, of which there is very little. -
@julian @evan @jenniferplusplus @mikedev @erincandescent @evan @trwnh
>7888/171b use context whereas 76ea uses a new property thr:thread
I think
context
is good enough. Streams and NodeBB already provide this collection and Mitra will too.>171b specifies a new object type Context
It is for easier identification of conversation-Add activities. My server may receive many different kinds of Add activities, and it would be nice to have some indication of what collection is being modified.
This is just an idea though. Streams uses
Collection
type>Collection items:
My use case requires items to be activities, but I can support both variants of
context
collection. Conversation activities can be also put into a different collection. -
@[email protected] said in FEP Convergence (400e, 7888, 171b/Conversation Containers, 76ea):
It is for easier identification of conversation-Add activities. My server may receive many different kinds of Add activities, and it would be nice to have some indication of what collection is being modified.
In that case, are you trying to sidestep a potential future conflict? I think I can see your rationale that duck typing "resolved context is a Collection" may not be specific enough, but I am not currently aware of anybody outside of 400e/7888 that has a
context
that even resolves to anything. -
@silverpill @julian @evan @evan @mikedev @jenniferplusplus @trwnh
My plan is to bring Akkoma into conformance with FEP-7888.
Context
s (as they implicitly exist) containObject
s in Akkoma today, and my plan is to make that collection dereferencable.At the moment I have no plan to implement sending of
Add
activities though that could come in the future.Regarding FEP-171B’s use of the
Context
object type, I am ambivalent. We will likely expose an (Ordered?) collection at first.FEP-76EA’s definition of
thr:thread
doesn’t match how Akkoma maintains or interprets theContext
today. My opinion is that I would only invest time in implementing it if implemetations actually coalesced around it; it doesn’t suit our needs. In particular the requirement “The tree structure of the thread should be maintained; every object in the thread collection, except the root, should have an inReplyTo property that matches the id of another object in the collection.” does not match how Akkoma handles quote posts (it places them in the same Context). -
@[email protected] Future discussions of the ForumWG may turn to more forum-like handling of context collections like forking, moving of posts, locking, pinning, etc.
In the former two cases,
inReplyTo
would no longer necessarily point to an object that is in the self-defined context collection. This is a very good point.@[email protected] also made this point recently as well.
-
Conversation containers does send a 'Remove' if something is removed from a collection. But we typically don't waste resources on spammers, so we don't necessarily send a 'Remove' if we decided not to add it in the first place (perhaps due to comment controls, permissions, or blocks). You can send these as Remove activities if you want, but please don't force me to do so.
If you've fetched a conversation collection, it would be most common to do so in order to cache the conversation locally. In this case storing under local entities is going to be much more efficient if parents are stored before their children, so the InReplyTo can be pointed to an existing stored entity. If you do it backward, it's kind of awkward.
That said, our implementation of Collection objects has a flag to reverse the returned item order. So as long as the order is defined and isn't going to change, I don't actually care what it is; beyond the storage efficiency mentioned above. We need to sort it how we want after fetch anyway, because that's just basic input sanitisation.
It would seem most natural to me to send the collection in "thread" order - start from the root and recursively traverse every branch/leaf encountered. I'll mention this for consideration -- but again I really don't care. -
Jenniferplusplusreplied to Jenniferplusplus last edited by
@julian @silverpill @evan @trwnh @erincandescent @mikedev
As a side note, it's beyond frustrating that the original goal of this topic was to accomplish reply-limiting controls. But, a year and a half later, we're still bike shedding data types and haven't even gotten to the point of talking about an actual behavioral protocol for proposing, accepting, rejecting, and verifying the addition of an object to a relevant collection. -
No, that's for
target
property. Here's an example ofAdd.target
from Streams:"target": { "id": "https://streams.lndo.site/conversation/ed4775f8-18ee-46a5-821e-b2ed2dc546e8", "type": "Collection", "attributedTo": "https://streams.lndo.site/channel/red" },
In my code I have a handler for
Add
activity, which then sends activity to one of the other handlers:- Add{target: featured}
- Add{target: subscribers}
- Add{target: context}Currently I use heuristics to determine which one to use. But with
Add.target.type == <meaningful type name>
the code would be simpler and less fragile.Do you have something like that in NodeBB? I wonder how others solve this "routing" problem
-
@[email protected] said in FEP Convergence (400e, 7888, 171b/Conversation Containers, 76ea):
As a side note, it's beyond frustrating that the original goal of this topic was to accomplish reply-limiting controls.
I understand your frustrations, and for what it's worth, I feel like we need to get the more basic expectations out of the way first, that is: how do we meaningfully assign context to a set of individual posts, besides the already available but fragile
inReplyTo
traversal?At the same time, I do think that all four FEPs mentioned utilise the same mechanism for establishing basic reply-limiting... that there is a context owner that ultimately decides whether a reply is added to the collection or not.
-
@[email protected] said in FEP Convergence (400e, 7888, 171b/Conversation Containers, 76ea):
Do you have something like that in NodeBB? I wonder how others solve this "routing" problem
We do the same. We don't actually handle
Add
s right now, but ourUpdate
handler has aswitch..case
based ontype
.Adding a separate type would be easier, yes. Otherwise you're looking at additional logic to tease apart different variants that share the same base object type. For example, the logic for
Update(Note)
has further logic paths depending on whether the note is publicly addressed or not.So then yes, a
Add{target: Collectionish}
might be vague, but that's only the case if other implementations use the same. -
@julian This pattern can also be used in Accept and Undo activities:
{ "type": "Undo", "id": "https://social.example/activities/undo/1" "object": { "type": "Like", # or "Follow" "id": "https://social.example/activities/like/1" } }
-
@mikedev @julian you shouldn't have to send a Remove if you never Added it.
i also agree that the order should generally be forward-chrono because fetching the context in a linked data browser should render the context in the same way that the HTML view would render it by default. i don't know anyone who reads threads backwards.
in any case i recently submitted https://w3id.org/fep/1985 for explicitly declaring an `orderType` for OrderedCollection
-
infinite love ⴳreplied to infinite love ⴳ last edited by
@mikedev @julian i am also thinking about extended OrderedCollection to specifically represent *sorted* sets and not just *ordered* sets. that fep would define `sortedBy` pointing to a vocab term, as well as `sortType` being either `Ascending` or `Descending`. the only thing that gives me pause is that people can lie about the value of their object's sorting property, for example setting an as:published in the distant past to be pinned to the beginning of the SortedCollection.
-
@julian i replied from socialhub but it seems to not have made it across yet... again :x https://socialhub.activitypub.rocks/t/fep-convergence-400e-7888-171b-conversation-containers-76ea/4669/12
-
julian:
They establish a conversational context for a given object
from my understanding, only 7888 and 171b do this. 76ea instead tries to establish a central view of a reply tree, which is not the same as a conversation. there are several cases where replies and context diverge:
- replying to something in a different conversation (for example, when conversations get forked or posts get moved to a new conversation)
- participating in a conversation without replying
- replying without participating in a conversation
also, there is the consideration that
julian:context
is used for grouping, even if it's not resolvable. so it gracefully falls back to basic grouping behavior in the simplest case.thr:thread
doesn't do this.They federate out an
Add
on collection addition. (76ea also sendsRemove
)you can send a Remove in all three FEPs, it might just not be called out explicitly. the use of Add/Remove is a courtesy to anyone else following along, so they don't have to fetch the collection manually every single time. (although fetching the collection every single time is inefficient, it is the only way to have a guaranteed consistent state, so there are reasons why you may want to browse the collection "at the authoritative origin", so to speak.)
julian:171b specifies a new object type
Context
i am not strictly opposed to this, but neither do i support it. it might end up being useful to define a type that means "this specifically represents a collection whose items share the same
context
property" (as i thinkContext
is trying to do), but this should not be required.similarly, we could define a type that means "this specifically represents a collection whose items all have
content
" (we could call itConversation
orCollectionOfPosts
orCollectionOfContentfulObjects
or whatever) but this is similarly something that shouldn't be required.the reason that i think such types shouldn't be required is that not only are they not necessary for the basic mechanisms to work, they also might be misleading or incorrect, because ultimately the contents of any collection are solely decided by whoever owns the collection. i could declare that a collection is a
julian:Context
and then immediately after this i go and Add a bunch of objects that don't have thatcontext
, or anycontext
at all for that matter. this is something that is going to be very relevant in the interim where NodeBB and similar implementations continue to have behavior for traversing reply trees and attaching posts to topics that aren't explicitly declared ascontext
. (not that i think this behavior is necessarily always correct, either -- it's just something that could be done, and is probably useful to do, insofar as other implementations continue to remain unaware ofcontext
and its grouping properties. you could just as equally convert posts withinReplyTo
but nocontext
into NodeBB Chat Messages instead of NodeBB Topic Posts... but this is an implementation decision.)Collection items:
- 7888 sends objects in chronological order
- 171b sends activities in chronological order
- 76ea sends objects in reverse chronological order
7888 is agnostic as to what the exact contents are, aside from them ideally all sharing the same
context
-- you could have a 7888 collection contain any type in any order. however, with that said: i favor post objects (anything that hascontent
) in forward chronological order, because this is what is most useful to the casual browser. i don't know of any forum software that chooses to present threads in reverse order with the newest posts at the top. they usually do this for topics, but not for posts.also: these are "defaults", and ultimately we should probably move toward explicitly signaling how collections might be ordered or sorted, as well as providing a mechanism for requesting non-default presentations like "show me this thread in reverse chronological order" (
?reversed=true
or?sort=newest
or whatever) or "show me posts starting at index 69 and containing 7 items" (?startIndex=69&window=7
). to that end, i recently submitted https://w3id.org/fep/1985 for declaring anOrderedCollection
to have an explicitorderType
ofForwardChronological
orReverseChronological
. i also have a pre-draft of a FEP dealing with collections that are not just ordered sets, but specifically sorted sets. this would defineSortedCollection
as an extension ofOrderedCollection
, as well as defining asortedBy
property pointing to a vocab term, plus asortType
of eitherAscending
orDescending
. there's https://socialhub.activitypub.rocks/t/pre-fep-evolving-orderedcollection-to-be-more-useful/4608 as the thread exploring this.regarding the signaling of any given collection or actor following a specific protocol, i think we should define that explicit protocol before defining types. my old draft of FEP-9988 for "Federated Forums" was put on hold for exactly this reason -- there are simply too many protocol considerations that need to happen first. https://socialhub.activitypub.rocks/t/desired-ux-for-forums-and-accompanying-user-stories/4181 or https://community.nodebb.org/post/99491 exists as a thread to collect user stories for forum UX that should directly inform the development of such a protocol.
-
@[email protected] @[email protected] I think end of the day it's an implementation detail that is of minimal significance. When I fetch the collection pages I don't trust the order anyway, I reorder them all by date once I have them all anyways.
@[email protected] said that reverse chrono for activities is preferable, and that makes sense if you want to sync up. Just retrieve activities until you reach one you've seen and you're caught up.
-
@[email protected] said in FEP Convergence (400e, 7888, 171b/Conversation Containers, 76ea):
i don't know of any forum software that chooses to present threads in reverse order with the newest posts at the top.
I'll bite. NodeBB lets you choose how to sort the posts. Chrono, reverse, or by vote count. Q&A forums might elect to use the latter two. But that's neither here nor there, it's a frontend UX thing and shouldn't really have any bearing on an AP S2S implementation detail.
-
@julian @mikedev @silverpill i generally agree that seeing newest activities is usually preferable , but you could just as easily traverse as:last/as:prev* and stop when you reach something you've already seen, instead of traversing as:first/as:next* and likewise stopping when you reach something you've already seen. it's never made sense to me to mandate reversed order when it should just be the "recommended default". i think the real issue is that OrderedCollection doesn't imply any real order
-
julian:
that's neither here nor there, it's a frontend UX thing and shouldn't really have any bearing on an AP S2S implementation detail
It has bearing on anyone browsing the linked data, as brought up immediately after:
trwnh:also: these are “defaults”, and ultimately we should probably move toward explicitly signaling how collections might be ordered or sorted, as well as providing a mechanism for requesting non-default presentations like “show me this thread in reverse chronological order” (
?reversed=true
or?sort=newest
or whatever) or “show me posts starting at index 69 and containing 7 items” (?startIndex=69&window=7
). to that end, i recently submitted fep/fep/1985/fep-1985.md at main - fediverse/fep - Codeberg.org for declaring anOrderedCollection
to have an explicitorderType
ofForwardChronological
orReverseChronological
. i also have a pre-draft of a FEP dealing with collections that are not just ordered sets, but specifically sorted sets. this would defineSortedCollection
as an extension ofOrderedCollection
, as well as defining asortedBy
property pointing to a vocab term, plus asortType
of eitherAscending
orDescending
. there’s Pre-FEP: Evolving OrderedCollection to be more useful as the thread exploring this.Basically, imagine using https://browser.pub (or any other Web browser, really). The representation you serve in response to any GET request should be usable without requiring additional processing. You should be able to follow links normally like any other browser. This is the foundation of linked data.