FEP Convergence (400e, 7888, 171b/Conversation Containers, 76ea)
-
Hi @[email protected], thanks for your thoughts. I took the evening to think it over.
I agree that using
thr:thread
would be the most explicit way of signalling that NodeBB topics are threads, and if 76ea were to be adopted by a majority of implementors, then I would reconsider. Currently I am on the fence about whether or not I should implement it.I do want to point out that @[email protected]'s FEP 7888 doesn't expressly forbid multiple contexts, and I think upthread they even said that such a use case would not be contrary to the FEP:
based on this conversation i probably need to add examples to fep-7888 of how one might process multiple contexts.
~ trwnhMy opinion today is that when NodeBB uses
context
, it is doing so to signal that "hey, these posts are part of this collection", and exactly nothing more. It is up to the receiving end to decide how to implement it, and I think that this sort of variety is absolutely wonderful.If, for example, someone were to see my context and say "I'd like to map this context's objects out into a word cloud and do sentiment analysis on it", I think that's a perfectly cromulent use of the data. For me to say "this here is a thread, and you better treat it as a thread" is contrary to the spirit of ActivityPub and fedidevs in general.
It would be like the ForumWG saying to Eugen, @[email protected], et al. that "we've decided that YOU, Mastodon, need to support
as:Listen
and render inline players, and playlist support, etc.". That's ridiculous, wouldn't you agree? -
- (they/them btw)
- multiple contexts probably will end up like multiple inReplyTo; idk if most impls will support it. but "which one is the thread" as a question makes no sense bc most likely they are all "threads" in some way
- 76ea thr:thread is a reply tree, not a conversation
- reason i say "context likely == thread" is bc it's **more than just a collection**. it is WHY the object exists. what is a thread if not purposeful grouping? -
infinite love ⴳreplied to infinite love ⴳ on last edited by
@julian @scott in other words: for social media / network / "post" purposes, the context is almost always some thread. if it doesn't fit the shape of a thread, then don't treat it as a thread, but in most cases it will. otherwise it wouldn't be a "context", it'd just be some object/collection.
i'm defining "thread" as "when you reify a conversational context, specifically as a collection with an owner and canonical representation, instead of something you have to reconstruct for yourself".
-
infinite love ⴳreplied to infinite love ⴳ on last edited by
@julian @scott the problem with saying that a "thread" is different from a "conversational context reified as a collection" is that there is no criteria i am seeing by which a thread is different. the thread is a purposeful grouping (context), it has a canonical representation (collection items), and it is maintained by its owner (attributedTo). what more do you need? an explicit declaration that it is a 171b:ConversationContainer? what does that get you?
-
infinite love ⴳreplied to infinite love ⴳ on last edited by
@julian @scott at best, a dedicated type like ConversationContainer can hint that it was produced by some producer following the ConversationContainer spec/fep/whatever, but the problem is that a) anyone can claim that type without following the spec, and b) it's not actually needed for processing the context property, because you already know it is semantically the context -- the origin or purpose of that object. if it's an id, you group by that id, and if it's a collection then you fetch items
-
infinite love ⴳreplied to infinite love ⴳ on last edited by
@julian @scott basically if 171b wants to define a ConversationContainer type to signal that a producer is following that fep/spec/whatever then they can do that. i maintain that the use of `target` is still incorrect, invalid, and redundant, but it is what it is. if a similar/different fep defines some other type to signal basically the same thing except in details, then that can also be done. in the end, i would advise that the actual "protocol" doesn't require hardcoded type checking.
-
infinite love ⴳreplied to infinite love ⴳ on last edited by
@julian @scott in any case the algorithm for processing the post as a topic owner is:
1) loop over `context` for any ids you own
2) if the post is acceptable to you, add it to the relevant collectionthe algorithm for processing the post as a third-party observer is:
1) look at `context` to see if any of them are collections
2) pick a collection and navigate to it, discarding the post. if it's actually in the collection, you'll see it again. -
infinite love ⴳreplied to infinite love ⴳ on last edited by
@julian @scott that's basically what this all boils down to, really -- not a technical change, but a social one.
our softwares should stop trying to reconstruct shadow collections based on what they *think* should be in there, and they should just browse to the actual collections.
in general, more things should work like web browsers instead of blackboxes that gobble up data and mash it together based on their best guess of how they think it's connected.
-
@julian
If, for example, someone were to see my context and say "I'd like to map this context's objects out into a word cloud and do sentiment analysis on it", I think that's a perfectly cromulent use of the data. For me to say "this here is a thread, and you better treat it as a thread" is contrary to the spirit of ActivityPub and fedidevs in general.
Simply declaring a collection to be a thread does not force people to display it as a thread. But it does provide valuable information to people who do want to display it as a thread.
So you are not removing people's choice by simply stating that on your platform, this is considered a thread. -
Scott M. Stolzreplied to infinite love ⴳ on last edited by@infinite love ⴳ
our softwares should stop trying to reconstruct shadow collections based on what they *think* should be in there, and they should just browse to the actual collections.
That is my point. If you tell me what the thread is, I can download all of the posts within that thread. I don't even have to parse the reply tree at all. -
@[email protected] @[email protected] I'm at a loss as to why you seem to think this is not possible if the property is called
context
instead ofthread
. -
@julian @infinite love ⴳ As I said before, with platforms like yours, which only have one context, I can assume that one context is the thread.
Declaring which one is the thread is only necessary if you have multiple contexts.
But, I am thinking of other use cases where the context might not be a thread, or there are multiple contexts. In that case, additional clues would be very useful.
The reason why I think we should declare threads as threads is for two reasons:
1. It anticipates future use cases that are different from our own.
2. People tend to copy other people's implementations, and we have an opportunity to set the standard and be the example for others to follow.
So, no, you don't need to declare it a thread in your current implementation. But you may have to make changes later when projects start implementing multiple contexts and they don't conform to your assumptions about contexts.
It is always better to explicitly state something than to force people to guess. -
@julian @trwnh @evan @jenniferplusplus @mikedev @scott @erincandescent @trwnh What if we use
context
for activities andthread
for posts? -
@silverpill @scott @julian @evan @mikedev @jenniferplusplus @trwnh @trwnh the context property is in the objects, not the activities
-
@[email protected] said in FEP Convergence (400e, 7888, 171b/Conversation Containers, 76ea):
It is always better to explicitly state something than to force people to guess.
Partially agreed, but in this case I'd feel better about encouraging implementors to move toward a generic representation of object collections, with the potential for a more straightforward way of defining thread-like actions.
Let's take @[email protected]'s example of thread forking. You can already express this using existing activities:
as:Remove
the forked posts out of theas:context
,as:Add
them to a newas:context
. Maybe sprinkle in anas:Announce
or something (I read that somewhere...)Or perhaps a locked thread:
as:context
owner sendsas:Reject
and does not federate out anas:Add
to followers.We could definitely go down the road of designing a bespoke property with associated actions, but I feel like the ActivityStreams vocaulary is fairly expressive, if vague at times... that movement against vagueness is exactly what FEP 7888 is all about.
We don't know future use cases, and there may be cases in which these decisions look wrong in hindsight, but I'd wager that being too explicit is premature, and an approach that is generic enough to express more is better.
-
@[email protected] How to handle multiple contexts is indeed a topic that is well worth visiting. I hear you when you say that given multiple contexts, you don't know which one is the thread. I don't have the answers today, but I want to set the framework so that when we do find the answer, we won't be hamstrung by a past decision.
Right now my thinking is that if you have multiple contexts:
- You might not need to use multiple contexts (
as:context
for the thread,as:audience
for the collection one level higher) - We should recommend that contexts be ordered from narrowest scope to widest
That ought to handle practically all situations (ready to take my words back on this one hah!)
The one sticking point would be situations where an object is part of multiple contexts at the same scope, e.g. a software that lets you
inReplyTo
multiple context-independent objects. In that case, not even @[email protected]'sthr:thread
property would help because we'd want to set two threads there too! Now we're back at square one.So at least for today, we can probably safely declare that if multiple contexts are defined, and they both/all point to resolvable collections, you could treat them all like thread-like data structures, if that's your software's thing.
- You might not need to use multiple contexts (
-
@julian I see what you are saying, but you can't assume that collections are thread-like data structures.
In fact, one of the use cases I am looking at is creating a collections of threads, and each of those threads would have comments.
So you would have something like this:
- Project Collection
- - Thread
- - - Top Level Post in Thread
- - - Comment
- - - Comment
- - - Comment
- - Thread
- - - Top Level Post in Thread
- - - Comment
- - - Comment
If you displayed my collection of threads as a thread, it would look like a jumble of unrelated posts because it would be a jumble of unrelated posts. Each thread in the collection would need to be displayed as its own thread, not one giant thread with all posts in it.
To parse something like this, I think I would need to specify which collection is the thread, even if other platforms do not use that field.
Maybe there is another way to do it without parsing the reply tree, but I am not sure. After all, I want the moderated version of the thread, not the reply tree. -
infinite love ⴳreplied to Erin 💽✨ 🔜 38C3 on last edited by
@erincandescent @scott @julian @evan @mikedev @jenniferplusplus @silverpill @[email protected] it could be either and/or both. it’s really up to you what you declare, and what the collection owner decides to Add. i think there’s a missing piece for signaling the expected shape of what might get added — e.g., “object must have content, attributedTo must be in the audience, etc” but ultimately the collection owner reserves the right to add“unrelated” objects.
-
infinite love ⴳreplied to infinite love ⴳ on last edited by
@erincandescent @scott @julian @evan @mikedev @jenniferplusplus @silverpill @[email protected] for example, even a conversation/thread ostensibly bound by context, where every object is expected to share the same “context”, might not actually require this! for compatibility reasons, it may be enough to simply reply to a post with context, if that reply has no context. (if it sets a different context, that’s a clear signal it’s meant for a different thread.)
-
infinite love ⴳreplied to infinite love ⴳ on last edited by
@erincandescent @scott @julian @evan @mikedev @jenniferplusplus @silverpill @[email protected]
example 1: nodebb sets a context, mastodon is unaware and replies to nodebb. the reply has no context set. nodebb may want to Add this object anyway? this is an implementation decision based on missing information.
example 2: discourse Moves 6 posts into a new context. to keep anyone following old broken links in the loop, they Add the Move to the context.