From 7257e37f9211721941d65cb6461b81db5c7a4e2d Mon Sep 17 00:00:00 2001 From: Andy Balaam Date: Thu, 13 Jul 2023 16:43:08 +0100 Subject: [PATCH 01/18] Summary --- .../4037-thread-root-is-not-in-thread.md | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 proposals/4037-thread-root-is-not-in-thread.md diff --git a/proposals/4037-thread-root-is-not-in-thread.md b/proposals/4037-thread-root-is-not-in-thread.md new file mode 100644 index 0000000000..570090e721 --- /dev/null +++ b/proposals/4037-thread-root-is-not-in-thread.md @@ -0,0 +1,25 @@ +# MSC4037: Thread root is not in the thread + +The current spec implies that a thread root is considered within the thread, but +we argue that this does not make sense, and a thread root is not "in" it the +thread branching from it. + +## Proposal + + + +## Potential issues + + +## Alternatives + + +## Security considerations + + +## Unstable prefix + + +## Dependencies + + From 3a5f56d3f9c86f22c14462e13a873082c8606c16 Mon Sep 17 00:00:00 2001 From: Andy Balaam Date: Thu, 13 Jul 2023 17:02:56 +0100 Subject: [PATCH 02/18] First draft --- .../4037-thread-root-is-not-in-thread.md | 60 +++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/proposals/4037-thread-root-is-not-in-thread.md b/proposals/4037-thread-root-is-not-in-thread.md index 570090e721..e3f000f2f2 100644 --- a/proposals/4037-thread-root-is-not-in-thread.md +++ b/proposals/4037-thread-root-is-not-in-thread.md @@ -4,15 +4,75 @@ The current spec implies that a thread root is considered within the thread, but we argue that this does not make sense, and a thread root is not "in" it the thread branching from it. +This is important for creating and interpreting read receipts. + +## Motivation + +The current spec, in +[11.6.2.2 Threaded read receipts](https://spec.matrix.org/unstable/client-server-api/#threaded-read-receipts) +says: + +> An event is considered to be "in a thread" if it meets any of the following +> criteria: +> +> * It has a `rel_type` of `m.thread`. +> * It has child events with a `rel_type` of `m.thread` (in which case it’d be +> the thread root). +> * Following the event relationships, it has a parent event which qualifies for +> one of the above. Implementations should not recurse infinitely, though: a +> maximum of 3 hops is recommended to cover indirect relationships. +> +> Events not in a thread but still in the room are considered to be part of the +> "main timeline", or a special thread with an ID of `main`. + +This explicitly includes thread roots in the thread which branches off them, and +implicitly _excludes_ those messages from being in the `main` thread. + +This is problematic because: + +* It seems natural for messages that are displayed in the main timeline (as + thread roots are in most clients) to be considered read/unread when the user + reads them in the main timeline. + +* It normally does not make sense for a threaded read receipt to point at the + thread root, since the user has not really read anything in that thread if + they have only read the thread root. + +In practice, Synapse ignores any request to mark the thread root as read within +the thread, and accepts requests to mark it as read in the main timeline. + +In consequence, Element Web displayed bugs relating to unread rooms while its +underlying library used spec-compliant behaviour, many of which were fixed by +[reverting to the behaviour recommended by this proposal](https://github.com/matrix-org/matrix-js-sdk/pull/3600). + +It really does not make sense to treat thread roots as outside the main +timeline: any message can become a thread root at any time, when a user creates +a new threaded message pointing at it. + ## Proposal +We propose this definition: +> An event is considered to be "in a thread" if: +> +> * It has a `rel_type` of `m.thread`, or it has an ancestor event with this +> `rel_type`. +> +> Implementations should limit recursion to find ancestors: a maximum of 3 hops +> is recommended. +> +> Events not in a thread but still in the room are considered to be part of the +> "main timeline": a special thread with an ID of `main`. ## Potential issues ## Alternatives +We could treat thread roots as being in *both* their thread and the `main` +timeline, but it does not offer much benefit because a thread where only the +root message has been read is almost identical to one where the no messages have +been read. A thread cannot exist without at least one additional message. ## Security considerations From e1f61e8c0d06510c85a4edc85acb689538c944af Mon Sep 17 00:00:00 2001 From: Andy Balaam Date: Thu, 13 Jul 2023 18:15:23 +0100 Subject: [PATCH 03/18] Small wording improvements --- proposals/4037-thread-root-is-not-in-thread.md | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/proposals/4037-thread-root-is-not-in-thread.md b/proposals/4037-thread-root-is-not-in-thread.md index e3f000f2f2..d3c02f13c1 100644 --- a/proposals/4037-thread-root-is-not-in-thread.md +++ b/proposals/4037-thread-root-is-not-in-thread.md @@ -1,8 +1,8 @@ # MSC4037: Thread root is not in the thread The current spec implies that a thread root is considered within the thread, but -we argue that this does not make sense, and a thread root is not "in" it the -thread branching from it. +we argue that this does not make sense, and a thread root is not "in" the thread +branching from it. This is important for creating and interpreting read receipts. @@ -41,17 +41,18 @@ This is problematic because: In practice, Synapse ignores any request to mark the thread root as read within the thread, and accepts requests to mark it as read in the main timeline. -In consequence, Element Web displayed bugs relating to unread rooms while its +In consequence, Element Web exhibited bugs relating to unread rooms while its underlying library used spec-compliant behaviour, many of which were fixed by -[reverting to the behaviour recommended by this proposal](https://github.com/matrix-org/matrix-js-sdk/pull/3600). +[adoptingthe behaviour recommended by this proposal](https://github.com/matrix-org/matrix-js-sdk/pull/3600). It really does not make sense to treat thread roots as outside the main timeline: any message can become a thread root at any time, when a user creates -a new threaded message pointing at it. +a new threaded message pointing at it, so suddenly switching which receipts are +allowed to apply to it would not be sensible. ## Proposal -We propose this definition: +We propose that thread roots are in the main timeline, making the definition: > An event is considered to be "in a thread" if: > From ac05600b258cf1fd30fd91afeb10d7fb7ec34ca1 Mon Sep 17 00:00:00 2001 From: Andy Balaam Date: Thu, 13 Jul 2023 18:16:27 +0100 Subject: [PATCH 04/18] Fill in other sections --- proposals/4037-thread-root-is-not-in-thread.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/proposals/4037-thread-root-is-not-in-thread.md b/proposals/4037-thread-root-is-not-in-thread.md index d3c02f13c1..936de0c1ad 100644 --- a/proposals/4037-thread-root-is-not-in-thread.md +++ b/proposals/4037-thread-root-is-not-in-thread.md @@ -67,6 +67,7 @@ We propose that thread roots are in the main timeline, making the definition: ## Potential issues +None known. ## Alternatives @@ -77,10 +78,12 @@ been read. A thread cannot exist without at least one additional message. ## Security considerations +Unlikely to have any security impact. ## Unstable prefix +None needed. ## Dependencies - +No dependencies. From d9edaa4bf34c23e035b621f6dd9b8d723e409d95 Mon Sep 17 00:00:00 2001 From: Andy Balaam Date: Thu, 13 Jul 2023 18:18:43 +0100 Subject: [PATCH 05/18] Add additional explicit clarification --- proposals/4037-thread-root-is-not-in-thread.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/proposals/4037-thread-root-is-not-in-thread.md b/proposals/4037-thread-root-is-not-in-thread.md index 936de0c1ad..0b781fdb4d 100644 --- a/proposals/4037-thread-root-is-not-in-thread.md +++ b/proposals/4037-thread-root-is-not-in-thread.md @@ -64,6 +64,9 @@ We propose that thread roots are in the main timeline, making the definition: > > Events not in a thread but still in the room are considered to be part of the > "main timeline": a special thread with an ID of `main`. +> +> Note: thread roots (events that are referred to in a `m.thread` relationship) +> are in the main timeline. ## Potential issues From b82c82945dc2640d2c3c3f7f19795d8c52d36da0 Mon Sep 17 00:00:00 2001 From: Andy Balaam Date: Mon, 17 Jul 2023 09:49:15 +0100 Subject: [PATCH 06/18] Fix missing space Co-authored-by: Jonas Platte --- proposals/4037-thread-root-is-not-in-thread.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/4037-thread-root-is-not-in-thread.md b/proposals/4037-thread-root-is-not-in-thread.md index 0b781fdb4d..38ac5ab202 100644 --- a/proposals/4037-thread-root-is-not-in-thread.md +++ b/proposals/4037-thread-root-is-not-in-thread.md @@ -43,7 +43,7 @@ the thread, and accepts requests to mark it as read in the main timeline. In consequence, Element Web exhibited bugs relating to unread rooms while its underlying library used spec-compliant behaviour, many of which were fixed by -[adoptingthe behaviour recommended by this proposal](https://github.com/matrix-org/matrix-js-sdk/pull/3600). +[adopting the behaviour recommended by this proposal](https://github.com/matrix-org/matrix-js-sdk/pull/3600). It really does not make sense to treat thread roots as outside the main timeline: any message can become a thread root at any time, when a user creates From 651824f5b51d7e837468817d4fd997c1c6c9d38d Mon Sep 17 00:00:00 2001 From: Andy Balaam Date: Mon, 17 Jul 2023 13:38:03 +0100 Subject: [PATCH 07/18] Note that reactions to thread roots should be in the main timeline --- proposals/4037-thread-root-is-not-in-thread.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/proposals/4037-thread-root-is-not-in-thread.md b/proposals/4037-thread-root-is-not-in-thread.md index 38ac5ab202..7e55931ecd 100644 --- a/proposals/4037-thread-root-is-not-in-thread.md +++ b/proposals/4037-thread-root-is-not-in-thread.md @@ -50,6 +50,9 @@ timeline: any message can become a thread root at any time, when a user creates a new threaded message pointing at it, so suddenly switching which receipts are allowed to apply to it would not be sensible. +Similarly, it does not make sense for reactions to the thread root (or other +related events such as edits) to be outside the main timeline. + ## Proposal We propose that thread roots are in the main timeline, making the definition: From ccf00d3e5257695ed021ce0e5c3cd824dd82ac35 Mon Sep 17 00:00:00 2001 From: Andy Balaam Date: Tue, 18 Jul 2023 10:07:29 +0100 Subject: [PATCH 08/18] Link to a specific version of the spec --- proposals/4037-thread-root-is-not-in-thread.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/4037-thread-root-is-not-in-thread.md b/proposals/4037-thread-root-is-not-in-thread.md index 7e55931ecd..3e7d667336 100644 --- a/proposals/4037-thread-root-is-not-in-thread.md +++ b/proposals/4037-thread-root-is-not-in-thread.md @@ -9,7 +9,7 @@ This is important for creating and interpreting read receipts. ## Motivation The current spec, in -[11.6.2.2 Threaded read receipts](https://spec.matrix.org/unstable/client-server-api/#threaded-read-receipts) +[11.6.2.2 Threaded read receipts](https://spec.matrix.org/v1.7/client-server-api/#threaded-read-receipts) says: > An event is considered to be "in a thread" if it meets any of the following From 62d4f51c262728dbe2b26eb9f41d3c63063ab7e4 Mon Sep 17 00:00:00 2001 From: Andy Balaam Date: Tue, 18 Jul 2023 10:09:54 +0100 Subject: [PATCH 09/18] Link to Synapse code for deciding what thread an event is in --- proposals/4037-thread-root-is-not-in-thread.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/proposals/4037-thread-root-is-not-in-thread.md b/proposals/4037-thread-root-is-not-in-thread.md index 3e7d667336..5fa930657a 100644 --- a/proposals/4037-thread-root-is-not-in-thread.md +++ b/proposals/4037-thread-root-is-not-in-thread.md @@ -38,8 +38,9 @@ This is problematic because: thread root, since the user has not really read anything in that thread if they have only read the thread root. -In practice, Synapse ignores any request to mark the thread root as read within -the thread, and accepts requests to mark it as read in the main timeline. +In practice, Synapse +[ignores any request to mark the thread root as read](https://github.com/matrix-org/synapse/blob/v1.87.0/synapse/rest/client/receipts.py#L116-L154) +within the thread, and accepts requests to mark it as read in the main timeline. In consequence, Element Web exhibited bugs relating to unread rooms while its underlying library used spec-compliant behaviour, many of which were fixed by From cb06a85c8622fb7835a15bf5c4fcb4eb78aa8fc3 Mon Sep 17 00:00:00 2001 From: Andy Balaam Date: Tue, 18 Jul 2023 10:21:03 +0100 Subject: [PATCH 10/18] Explain why reactions to thread roots should be in the main timeline --- proposals/4037-thread-root-is-not-in-thread.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/proposals/4037-thread-root-is-not-in-thread.md b/proposals/4037-thread-root-is-not-in-thread.md index 5fa930657a..859f958c42 100644 --- a/proposals/4037-thread-root-is-not-in-thread.md +++ b/proposals/4037-thread-root-is-not-in-thread.md @@ -52,7 +52,13 @@ a new threaded message pointing at it, so suddenly switching which receipts are allowed to apply to it would not be sensible. Similarly, it does not make sense for reactions to the thread root (or other -related events such as edits) to be outside the main timeline. +related events such as edits) to be outside the main timeline, for similar +reasons: the message we are reacting to can become a thread root at any time, +making our previous receipt invalid retrospectively. (We could conceivably allow +receipts to exist both within a thread and the main timeline, but this does not +match the expected user mental model: I have either read a reaction/edit/reply, +or I have not - I don't want to have to read it twice just because it appears in +two places in the UI.) ## Proposal From 3421e3efbc5711ee524beb47e968b5c9e3c7d8fe Mon Sep 17 00:00:00 2001 From: Andy Balaam Date: Tue, 18 Jul 2023 11:06:17 +0100 Subject: [PATCH 11/18] Add a note about Synapse behaviour for edits of thread roots --- proposals/4037-thread-root-is-not-in-thread.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/proposals/4037-thread-root-is-not-in-thread.md b/proposals/4037-thread-root-is-not-in-thread.md index 859f958c42..e9116fe6d1 100644 --- a/proposals/4037-thread-root-is-not-in-thread.md +++ b/proposals/4037-thread-root-is-not-in-thread.md @@ -55,11 +55,17 @@ Similarly, it does not make sense for reactions to the thread root (or other related events such as edits) to be outside the main timeline, for similar reasons: the message we are reacting to can become a thread root at any time, making our previous receipt invalid retrospectively. (We could conceivably allow -receipts to exist both within a thread and the main timeline, but this does not +receipts to exist both within a thread and the main timeline[^1], but this does not match the expected user mental model: I have either read a reaction/edit/reply, or I have not - I don't want to have to read it twice just because it appears in two places in the UI.) +[^1]: In fact, observation of Synapse's behaviour shows that it does appear to + track two read/unread statuses for edits of thread roots, but not for thread + roots themselves. The code for this is in + [receipts.py](https://github.com/matrix-org/synapse/blob/v1.87.0/synapse/rest/client/receipts.py#L116-L154). + We still argue that this behaviour does not match the user's mental model. + ## Proposal We propose that thread roots are in the main timeline, making the definition: From 14ef925c6fd0955580224b86dc4867574397f536 Mon Sep 17 00:00:00 2001 From: Andy Balaam Date: Tue, 18 Jul 2023 11:52:17 +0100 Subject: [PATCH 12/18] Be more explicit that reactions/edits/etc to thread roots are in the main timeline --- proposals/4037-thread-root-is-not-in-thread.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/proposals/4037-thread-root-is-not-in-thread.md b/proposals/4037-thread-root-is-not-in-thread.md index e9116fe6d1..6ba1e388e8 100644 --- a/proposals/4037-thread-root-is-not-in-thread.md +++ b/proposals/4037-thread-root-is-not-in-thread.md @@ -82,7 +82,9 @@ We propose that thread roots are in the main timeline, making the definition: > "main timeline": a special thread with an ID of `main`. > > Note: thread roots (events that are referred to in a `m.thread` relationship) -> are in the main timeline. +> are in the main timeline. Similarly, reactions to thread roots, edits of +> thread root, and other events with non-thread relations to a thread root are +> in the main timline. ## Potential issues From 72af2a01b5f6016400b63ef8434893d00b577223 Mon Sep 17 00:00:00 2001 From: Andy Balaam Date: Tue, 18 Jul 2023 11:53:18 +0100 Subject: [PATCH 13/18] Add missing s --- proposals/4037-thread-root-is-not-in-thread.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/4037-thread-root-is-not-in-thread.md b/proposals/4037-thread-root-is-not-in-thread.md index 6ba1e388e8..27b67484b1 100644 --- a/proposals/4037-thread-root-is-not-in-thread.md +++ b/proposals/4037-thread-root-is-not-in-thread.md @@ -83,7 +83,7 @@ We propose that thread roots are in the main timeline, making the definition: > > Note: thread roots (events that are referred to in a `m.thread` relationship) > are in the main timeline. Similarly, reactions to thread roots, edits of -> thread root, and other events with non-thread relations to a thread root are +> thread roots, and other events with non-thread relations to a thread root are > in the main timline. ## Potential issues From 17c9942d974fb6ac31f1724c4818edf7ffc79e42 Mon Sep 17 00:00:00 2001 From: Andy Balaam Date: Tue, 18 Jul 2023 11:53:59 +0100 Subject: [PATCH 14/18] Add missing e --- proposals/4037-thread-root-is-not-in-thread.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/4037-thread-root-is-not-in-thread.md b/proposals/4037-thread-root-is-not-in-thread.md index 27b67484b1..c0e716530d 100644 --- a/proposals/4037-thread-root-is-not-in-thread.md +++ b/proposals/4037-thread-root-is-not-in-thread.md @@ -84,7 +84,7 @@ We propose that thread roots are in the main timeline, making the definition: > Note: thread roots (events that are referred to in a `m.thread` relationship) > are in the main timeline. Similarly, reactions to thread roots, edits of > thread roots, and other events with non-thread relations to a thread root are -> in the main timline. +> in the main timeline. ## Potential issues From f8a857e616a464c4e286435758f8a631676d14b8 Mon Sep 17 00:00:00 2001 From: Andy Balaam Date: Tue, 18 Jul 2023 12:30:38 +0100 Subject: [PATCH 15/18] Update to our new understanding of Synapse behaviour It basically follows this MSC already. --- proposals/4037-thread-root-is-not-in-thread.md | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/proposals/4037-thread-root-is-not-in-thread.md b/proposals/4037-thread-root-is-not-in-thread.md index c0e716530d..3396c97076 100644 --- a/proposals/4037-thread-root-is-not-in-thread.md +++ b/proposals/4037-thread-root-is-not-in-thread.md @@ -41,6 +41,9 @@ This is problematic because: In practice, Synapse [ignores any request to mark the thread root as read](https://github.com/matrix-org/synapse/blob/v1.87.0/synapse/rest/client/receipts.py#L116-L154) within the thread, and accepts requests to mark it as read in the main timeline. +When it reports thread notifications, it excludes thread roots (and e.g. edits +to thread roots) from the thread count, only showing them in the main timeline +count. In consequence, Element Web exhibited bugs relating to unread rooms while its underlying library used spec-compliant behaviour, many of which were fixed by @@ -55,17 +58,11 @@ Similarly, it does not make sense for reactions to the thread root (or other related events such as edits) to be outside the main timeline, for similar reasons: the message we are reacting to can become a thread root at any time, making our previous receipt invalid retrospectively. (We could conceivably allow -receipts to exist both within a thread and the main timeline[^1], but this does not +receipts to exist both within a thread and the main timeline, but this does not match the expected user mental model: I have either read a reaction/edit/reply, or I have not - I don't want to have to read it twice just because it appears in two places in the UI.) -[^1]: In fact, observation of Synapse's behaviour shows that it does appear to - track two read/unread statuses for edits of thread roots, but not for thread - roots themselves. The code for this is in - [receipts.py](https://github.com/matrix-org/synapse/blob/v1.87.0/synapse/rest/client/receipts.py#L116-L154). - We still argue that this behaviour does not match the user's mental model. - ## Proposal We propose that thread roots are in the main timeline, making the definition: From 7b5fb5b62f9102351ce201b216e0c042c7c8a5c5 Mon Sep 17 00:00:00 2001 From: Andy Balaam Date: Tue, 18 Jul 2023 12:35:58 +0100 Subject: [PATCH 16/18] Clarify that Synapse returns an error --- proposals/4037-thread-root-is-not-in-thread.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/4037-thread-root-is-not-in-thread.md b/proposals/4037-thread-root-is-not-in-thread.md index 3396c97076..6a7701c4f4 100644 --- a/proposals/4037-thread-root-is-not-in-thread.md +++ b/proposals/4037-thread-root-is-not-in-thread.md @@ -39,8 +39,8 @@ This is problematic because: they have only read the thread root. In practice, Synapse -[ignores any request to mark the thread root as read](https://github.com/matrix-org/synapse/blob/v1.87.0/synapse/rest/client/receipts.py#L116-L154) -within the thread, and accepts requests to mark it as read in the main timeline. +[returns an error for any request to mark the thread root as read within the thread](https://github.com/matrix-org/synapse/blob/v1.87.0/synapse/rest/client/receipts.py#L116-L154), +and accepts requests to mark it as read in the main timeline. When it reports thread notifications, it excludes thread roots (and e.g. edits to thread roots) from the thread count, only showing them in the main timeline count. From 6176516959fce7ac79d1ea1d78326ec76e68d9f8 Mon Sep 17 00:00:00 2001 From: Andy Balaam Date: Wed, 19 Jul 2023 15:17:15 +0100 Subject: [PATCH 17/18] Add a 'How we got here' section --- .../4037-thread-root-is-not-in-thread.md | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/proposals/4037-thread-root-is-not-in-thread.md b/proposals/4037-thread-root-is-not-in-thread.md index 6a7701c4f4..6cf7209fde 100644 --- a/proposals/4037-thread-root-is-not-in-thread.md +++ b/proposals/4037-thread-root-is-not-in-thread.md @@ -83,6 +83,26 @@ We propose that thread roots are in the main timeline, making the definition: > thread roots, and other events with non-thread relations to a thread root are > in the main timeline. +## How we got here + +The MSC that introduced read receipts for threads is +[MSC3771](https://github.com/matrix-org/matrix-spec-proposals/pull/3771). + +The relevant wording is in the +[Proposal](https://github.com/matrix-org/matrix-spec-proposals/blob/main/proposals/3771-read-receipts-for-threads.md#proposal) +section: + +> notifications generated from events with a thread relation matching the +> receipt’s thread ID prior to and including that event which are MUST be marked +> as read + +Notably it only mentions things "**with a thread relation**", so it appears to +match the wording of this proposal. + +It comes tantalisingly close to covering these issues in the example it uses, +but unfortunately does not cover what would happen if we received a receipt for +a thread root or for e.g. an edit of a thread root. + ## Potential issues None known. From 375e27f8d875146a7d23264318c793ada28498fa Mon Sep 17 00:00:00 2001 From: Andy Balaam Date: Wed, 19 Jul 2023 15:19:48 +0100 Subject: [PATCH 18/18] Add more words about children of thread roots --- proposals/4037-thread-root-is-not-in-thread.md | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/proposals/4037-thread-root-is-not-in-thread.md b/proposals/4037-thread-root-is-not-in-thread.md index 6cf7209fde..69037c3330 100644 --- a/proposals/4037-thread-root-is-not-in-thread.md +++ b/proposals/4037-thread-root-is-not-in-thread.md @@ -2,7 +2,7 @@ The current spec implies that a thread root is considered within the thread, but we argue that this does not make sense, and a thread root is not "in" the thread -branching from it. +branching from it, and neither are its non-thread children (e.g. edits). This is important for creating and interpreting read receipts. @@ -25,8 +25,9 @@ says: > Events not in a thread but still in the room are considered to be part of the > "main timeline", or a special thread with an ID of `main`. -This explicitly includes thread roots in the thread which branches off them, and -implicitly _excludes_ those messages from being in the `main` thread. +This explicitly includes thread roots (and their non-thread children) in the +thread which branches off them, and implicitly _excludes_ those messages from +being in the `main` thread. This is problematic because: @@ -65,7 +66,8 @@ two places in the UI.) ## Proposal -We propose that thread roots are in the main timeline, making the definition: +We propose that thread roots and their non-thread children are in the main +timeline, making the definition: > An event is considered to be "in a thread" if: >