Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MSC2674: Event Relationships #2674

Merged
merged 46 commits into from
Nov 23, 2021
Merged
Changes from 24 commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
9e8460f
initial version of event relationship MSC
uhoreg Jul 7, 2020
3415262
fix MSC numbers
uhoreg Jul 7, 2020
c00e4f4
clarifications
uhoreg Jun 2, 2021
e4c16fa
mention multiple relations per event might be useful, but postpone fo…
bwindels Jun 30, 2021
35fb00c
mention MSC 3051 for proposed multiple relations
bwindels Jun 30, 2021
db6213b
remove send_relation endpoint
bwindels Jun 30, 2021
2229975
move e2ee section under sending relations
bwindels Jun 30, 2021
d9ffb2c
mention limitation of leaving server-side aggregations out for now
bwindels Jul 1, 2021
bc1df59
remove mentions of m.reference, we'll sort that out in another MSC
bwindels Jul 1, 2021
18cac1a
whitespace
bwindels Jul 1, 2021
3e6e566
argument why m.relates_to should be preserved by redactions more general
bwindels Jul 1, 2021
62036f1
deal with this in the comments
bwindels Jul 1, 2021
c667a08
clarify the conditions to meet for a relation
bwindels Jul 1, 2021
e90f31e
mention specifically that this does not replace replies (yet)
bwindels Jul 1, 2021
fd13748
clarify how general rel_types should be
bwindels Jul 2, 2021
5eaf2de
clarify that gaps may cause clients to be unaware of some relations
bwindels Jul 2, 2021
157a097
Update proposals/2674-event-relationships.md
bwindels Jul 2, 2021
71d9668
Update proposals/2674-event-relationships.md
bwindels Jul 2, 2021
b590a4c
make wording clearer and move to bottom of section
bwindels Jul 5, 2021
0cd38d1
remove this as references are not defined here anymore
bwindels Jul 5, 2021
6665bc1
clearer wording
bwindels Jul 5, 2021
00ce39e
move edge cases to other relevant mscs
bwindels Jul 5, 2021
f41b78c
clarify that a goal of sticking to this format is backwards compat.
bwindels Jul 5, 2021
6c2e2e0
mention MSC 3267, to which m.reference has been extracted
bwindels Jul 5, 2021
5170cc1
Update proposals/2674-event-relationships.md
bwindels Aug 25, 2021
075ea46
Update proposals/2674-event-relationships.md
bwindels Aug 25, 2021
99a2729
Update proposals/2674-event-relationships.md
bwindels Aug 25, 2021
76a4116
Update proposals/2674-event-relationships.md
bwindels Aug 25, 2021
eb9033a
Update proposals/2674-event-relationships.md
bwindels Aug 25, 2021
4388dea
wrap lines
bwindels Aug 25, 2021
cd180b6
better wording
bwindels Aug 25, 2021
533b8e8
this is singular, really
bwindels Aug 25, 2021
138ca8c
add example of event shape
bwindels Aug 25, 2021
9c6d282
specify how invalid relations should be treated by the redaction algo…
bwindels Aug 25, 2021
e1309e1
fix typo
bwindels Sep 9, 2021
5ec656d
split up redactions changes in separate MSC
bwindels Sep 9, 2021
8cfda4d
also add new msc to introduction
bwindels Sep 9, 2021
f24945e
reword why not adopt m.in_reply_to
bwindels Sep 9, 2021
46d1bff
remove guidelines how to pick rel_type
bwindels Nov 17, 2021
8e12152
mention that the target event must exist in the same room
bwindels Nov 17, 2021
12fdf55
spell out the conscious (subject, object, verb) triple idea.
ara4n Nov 18, 2021
57cfb55
Spelling
turt2live Nov 22, 2021
e027133
remove paragraph saying what server should accept
bwindels Nov 23, 2021
7cca8ac
Revert "remove paragraph saying what server should accept"
bwindels Nov 23, 2021
12bdf05
further specify that a server should reject invalid relations through…
bwindels Nov 23, 2021
feb3377
linebreak
turt2live Nov 23, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
222 changes: 222 additions & 0 deletions proposals/2674-event-relationships.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,222 @@
# MSC2674: Event relationships

It's common to want to send events in Matrix which relate to existing events -
for instance, reactions, edits and even replies/threads.

This proposal is one in a series of proposals that defines a mechanism for
events to relate to each other. Together, these proposals replace
[MSC1849](https://github.com/matrix-org/matrix-doc/pull/1849).

* This proposal defines a standard shape for indicating events which relate to
other events.
* [MSC2675](https://github.com/matrix-org/matrix-doc/pull/2675) defines APIs to
let the server calculate the aggregations on behalf of the client, and so
bundle the related events with the original event where appropriate.
* [MSC2676](https://github.com/matrix-org/matrix-doc/pull/2676) defines how
users can edit messages using this mechanism.
* [MSC2677](https://github.com/matrix-org/matrix-doc/pull/2677) defines how
users can annotate events, such as reacting to events with emoji, using this
mechanism.
* [MSC3267](https://github.com/matrix-org/matrix-doc/pull/3267) defines events
can make a reference to other events.

## Proposal

This proposal introduces the concept of relations, which can be used to
associate new information with an existing event.

A relationship is an object with a field `rel_type`, which is a string describing the type of relation,
and a field `event_id`, which is a string that represents the event_id of the target of this relation.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Someone mentioned to me that the target event must also be in the same room, but that doesn't seem to be captured in this MSC.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Clients don't always do that, i.e. when forwarding messages. It would make sense to require that without a room_id though.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can leave relating to events in other rooms up to another MSC, and for now say it must be the same room.
I don't think any client currently forwards an event? Replies, yes, and once those make use of relations as proposed here, the correct thing to do would probably be either define relating to events in other rooms in a new MSC or remove the reply relation. Wdyt?

Both of those fields are required. An event is said to contain a relationship if their `content` contains
turt2live marked this conversation as resolved.
Show resolved Hide resolved
a relationship with all the required fields under the `m.relates_to` key. If any of these conditions is not met,
clients and servers should treat the event as if it does not contain a relationship.
bwindels marked this conversation as resolved.
Show resolved Hide resolved
richvdh marked this conversation as resolved.
Show resolved Hide resolved

All the information about the relationship lives under the `m.relates_to` key.

If it helps, you can think of relations as a "subject verb object" triple,
where the subject is the relation event itself; the verb is the `rel_type`
field of the `m.relates_to` and the object is the `event_id` field.

We consciously do not support multiple different relations within a single event,
uhoreg marked this conversation as resolved.
Show resolved Hide resolved
in order to keep the API simple. Another MSC,
like [MSC 3051](https://github.com/matrix-org/matrix-doc/pull/3051),
can propose a change to add support for multiple relations if it turns out that
this would facilitate certain use cases.

Relations do not yet replace the
[reply mechanism currently defined in the spec](https://matrix.org/docs/spec/client_server/latest#rich-replies).
bwindels marked this conversation as resolved.
Show resolved Hide resolved
turt2live marked this conversation as resolved.
Show resolved Hide resolved

### Relation types

This MSC does not define any value for `rel_type`, but rather defines the generic
framework that different kinds of relations have in common and that other MSCs can
build on. Future definitions for values of `rel_type` should describe *how* the server
should aggregate relations on the target event
(as proposed in [MSC 2675](https://github.com/matrix-org/matrix-doc/pull/2675)).
The goals is to make each rel_type as broadly useful as possible,
and to keep the amount of types for a server implementation to support down to a minimum.
bwindels marked this conversation as resolved.
Show resolved Hide resolved

Multiple client use cases may be served by a single `rel_type` if they require aggregation
in a similar manner. To further specify how a relation should be displayed in the client,
MSCs may define additional fields in `m.relates_to` for specific values of `rel_type`.

Any values here should abide the
[general guidelines for identifiers](https://github.com/matrix-org/matrix-doc/pull/3171).

### Sending relations

Related events are normal Matrix events, and can be sent by the normal /send
bwindels marked this conversation as resolved.
Show resolved Hide resolved
API.

The server should postprocess relations if needed before sending them into a
room, as defined by the relationship type. For example, a relationship type
might only allow a user to send one related message to a given event.

### Receiving relations

Relations are received like other non-state events, with `/sync`,
`/messages` and `/context`, as normal discrete Matrix events. As explained
in the limitations, clients may be unaware of some relations using just these endpoints.

[MSC2675](https://github.com/matrix-org/matrix-doc/pull/2675) defines ways in
which the server may aid clients in processing relations by aggregating the
events.

### Redactions

Relations may be redacted like any other event.

The `m.relates_to`.`rel_type` and `m.relates_to`.`event_id` fields should
be preserved over redactions, so that clients can still distinguish
redacted relations from other redacted events of the same event type.
uhoreg marked this conversation as resolved.
Show resolved Hide resolved

One example is telling redacted edits (as proposed in
[MSC 2676](https://github.com/matrix-org/matrix-doc/pull/2676)) apart from
from normal redacted messages, and maintain reply ordering.

This modification to the redaction algorithm requires a new room version.
bwindels marked this conversation as resolved.
Show resolved Hide resolved
However, event relationships can still be used in existing room versions, but
the user experince may worse if redactions are performed.
bwindels marked this conversation as resolved.
Show resolved Hide resolved

## Potential issues

### Federation considerations

We have a problem with resynchronising relations after a gap in federation:
We have no way of knowing that an edit happened in the gap to one of the events
we already have. So, we'll show inconsistent data until we backfill the gap.
turt2live marked this conversation as resolved.
Show resolved Hide resolved
* We could write this off as a limitation.
* Or we could make *ALL* relations a DAG, so we can spot holes at the next
relation, and go walk the DAG to pull in the missing relations? Then, the
next relation for an event could pull in any of the missing relations.
Socially this probably doesn't work as reactions will likely drop off over
time, so by the time your server comes back there won't be any more reactions
pulling the missing ones in.
* Could we also ask the server, after a gap, to provide all the relations which
happened during the gap to events whose root preceeded the gap.
* "Give me all relations which happened between this set of
forward-extremities when I lost sync, and the point i've rejoined the DAG,
for events which preceeded the gap"?
* Would be hard to auth all the relations which this api coughed up.
* We could auth them based only the auth events of the relation, except we
lose the context of the nearby DAG which we'd have if it was a normal
backfilled event.
* As a result it would be easier for a server to retrospectively lie about
events on behalf of its users.
* This probably isn't the end of the world, plus it's more likely to be
consistent than if we leave a gap.
* i.e. it's better to consistent with a small chance of being maliciously
wrong, than inconsistent with a guaranteed chance of being innocently
wrong.
* We'd need to worry about pagination.
* This is probably the best solution, but can also be added as a v2.
* In practice this seems to not be an issue, which is worth complicating the s-s API over. Clients very rarely jump over the federation gap to an edit. In most cases they scroll up, which backfills the server and we have all the edits, when we reach the event before the gap.
bwindels marked this conversation as resolved.
Show resolved Hide resolved

## Limitations

Based solely on this MSC, relations are only received as discrete events in
the timeline, so clients may only have an incomplete image of all the relations
with an event if they do not fill gaps (syncs with a since token that have
`limited: true` set in the sync response for a room) in the timeline.

In practice, this has proven not to be too big of a problem, as reactions
(as proposed in [MSC 2677](https://github.com/matrix-org/matrix-doc/pull/2677))
tend to be posted close after the target event in the timeline.

A more complete solution to this has been deferred to
[MSC2675](https://github.com/matrix-org/matrix-doc/pull/2675).

bwindels marked this conversation as resolved.
Show resolved Hide resolved
## Tradeoffs

### Event shape

Shape of

```json
"content": {
"m.relates_to": {
"m.reference": {
"event_id": "$another:event.com"
}
}
}
```
versus

```json
"content": {
"m.relates_to": {
"rel_type": "m.reference",
"event_id": "$another:event.com"
}
}
```

The reasons to go with `rel_type` is:
* this format is now in use in the wider matrix ecosystem without a prefix, in spite of the original MSC 1849 not being merged. This situation is not ideal but we still don't want to break compatibility with several clients.
bwindels marked this conversation as resolved.
Show resolved Hide resolved
* we don't need the extra indirection to let multiple relations apply to a given pair of
events, as that should be expressed as separate relation events.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure I understand this - it's still a problem if you want multiple outgoing relations from an event? (Multiple incoming relations is obviously fine)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this is the case, i'd like to say that only being able to attach 1 relation to a message would be antithetical to future expansion and implementation in features, because now you cannot attach mutually occuring metadata with eachother (such as replies in a thread)

though maybe @deepbluev7 knows something about this

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The above sentence means that multiple relations are not a design goal. If you want multiple relations, you just send multiple events instead. I do disagree with that, which is why I made #3051 . Note that #3051 also uses rel_type, but it just puts the relations in a list, so you can even have multiple relations of the same type.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What @deepbluev7 said, does that make sense @dbkr?

* if we want 'adverbs' to apply to 'verbs' in the subject-verb-object triples which
relations form, then we apply it as mixins to the relation data itself rather than trying
to construct subject-verb-verb-object sentences.
* so, we should pick a simpler shape rather than inheriting the mistakes of m.in_reply_to
and we have to keep ugly backwards compatibility around for m.in_reply_to
but we can entirely separately worry about migrating replies to new-style-aggregations in future
perhaps at the same time as doing threads.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm confused here too: we're avoiding inheriting the mistakes but the first bullet justifies this approach because it's already in use? Are they talking about different things?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed this could be worded better, but yes, they are talking about different things.

The first point talks about MSC 1849 relations, and how they are already in widespread use, and we don't want to break compatibility with those.

This point talks about not inheriting the mistakes from the m.reply_to format, which is different from MSC 1849 relations.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have tried to clarify this in f24945e, lmk if you want further changes.


## Historical context

pik's MSC441 has:

Define the JSON schema for the aggregation event, so the server can work out
which fields should be aggregated.

```json
"type": "m.room._aggregation.emoticon",
"content": {
"emoticon": "::smile::",
"msgtype": "?",
"target_id": "$another:event.com"
}
```

These would then aggregated, based on target_id, and returned as annotations on
bwindels marked this conversation as resolved.
Show resolved Hide resolved
the source event in an `aggregation_data` field:

```json
"content": {
...
"aggregation_data": {
"m.room._aggregation.emoticon": {
"aggregation_data": [
{
"emoticon": "::smile::",
"event_id": "$14796538949JTYis:pik-test",
"sender": "@pik:pik-test"
}
],
"latest_event_id": "$14796538949JTYis:pik-test"
}
}
}
```