Skip to content

Commit 9654bf1

Browse files
uhoregbwindelsdeepbluev7ara4nturt2live
committed
MSC2674: Event Relationships (#2674)
* initial version of event relationship MSC * fix MSC numbers * clarifications * mention multiple relations per event might be useful, but postpone for a future MSC * mention MSC 3051 for proposed multiple relations * remove send_relation endpoint * move e2ee section under sending relations * mention limitation of leaving server-side aggregations out for now * remove mentions of m.reference, we'll sort that out in another MSC * whitespace * argument why m.relates_to should be preserved by redactions more general but still give example of redacted edits * deal with this in the comments * clarify the conditions to meet for a relation * mention specifically that this does not replace replies (yet) * clarify how general rel_types should be * clarify that gaps may cause clients to be unaware of some relations * Update proposals/2674-event-relationships.md Co-authored-by: DeepBlueV7.X <[email protected]> * Update proposals/2674-event-relationships.md Co-authored-by: DeepBlueV7.X <[email protected]> * make wording clearer and move to bottom of section * remove this as references are not defined here anymore * clearer wording * move edge cases to other relevant mscs * clarify that a goal of sticking to this format is backwards compat. * mention MSC 3267, to which m.reference has been extracted * Update proposals/2674-event-relationships.md Co-authored-by: Hubert Chathi <[email protected]> * Update proposals/2674-event-relationships.md Co-authored-by: Hubert Chathi <[email protected]> * Update proposals/2674-event-relationships.md Co-authored-by: Matthew Hodgson <[email protected]> * Update proposals/2674-event-relationships.md Co-authored-by: Matthew Hodgson <[email protected]> * Update proposals/2674-event-relationships.md Co-authored-by: Travis Ralston <[email protected]> * wrap lines * better wording * this is singular, really * add example of event shape * specify how invalid relations should be treated by the redaction algorithm * fix typo * split up redactions changes in separate MSC * also add new msc to introduction * reword why not adopt m.in_reply_to * remove guidelines how to pick rel_type * mention that the target event must exist in the same room * spell out the conscious (subject, object, verb) triple idea. * Spelling Co-authored-by: Richard van der Hoff <[email protected]> * remove paragraph saying what server should accept * Revert "remove paragraph saying what server should accept" This reverts commit e027133. * further specify that a server should reject invalid relations through the cs api * linebreak Co-authored-by: Richard van der Hoff <[email protected]> Co-authored-by: Bruno Windels <[email protected]> Co-authored-by: DeepBlueV7.X <[email protected]> Co-authored-by: Matthew Hodgson <[email protected]> Co-authored-by: Travis Ralston <[email protected]> Co-authored-by: Richard van der Hoff <[email protected]>
1 parent ac98c8c commit 9654bf1

File tree

1 file changed

+250
-0
lines changed

1 file changed

+250
-0
lines changed
Lines changed: 250 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,250 @@
1+
# MSC2674: Event relationships
2+
3+
It's common to want to send events in Matrix which relate to existing events -
4+
for instance, reactions, edits and even replies/threads.
5+
6+
This proposal is one in a series of proposals that defines a mechanism for
7+
events to relate to each other. Together, these proposals replace
8+
[MSC1849](https://github.com/matrix-org/matrix-doc/pull/1849).
9+
10+
* This proposal defines a standard shape for indicating events which relate to
11+
other events.
12+
* [MSC2675](https://github.com/matrix-org/matrix-doc/pull/2675) defines APIs to
13+
let the server calculate the aggregations on behalf of the client, and so
14+
bundle the related events with the original event where appropriate.
15+
* [MSC2676](https://github.com/matrix-org/matrix-doc/pull/2676) defines how
16+
users can edit messages using this mechanism.
17+
* [MSC2677](https://github.com/matrix-org/matrix-doc/pull/2677) defines how
18+
users can annotate events, such as reacting to events with emoji, using this
19+
mechanism.
20+
* [MSC3267](https://github.com/matrix-org/matrix-doc/pull/3267) defines how events
21+
can make a reference to other events.
22+
* [MSC3389](https://github.com/matrix-org/matrix-doc/pull/3389) defines changes to
23+
the redaction algorithm, to preserve the type and target id of a relation.
24+
25+
26+
## Proposal
27+
28+
This proposal introduces the concept of relations, which can be used to
29+
associate new information with an existing event.
30+
31+
A relationship is an object with a field `rel_type`, which is a string describing the type of relation,
32+
and a field `event_id`, which is a string that represents the event_id of the target event of this relation.
33+
The target event must exist in the same room as the relating event is sent.
34+
Both of those fields are required. An event is said to contain a relationship if its `content` contains
35+
a relationship with all the required fields under the `m.relates_to` key. If any of these conditions is not met,
36+
clients and servers should treat the event as if it does not contain a relationship.
37+
Servers should reject events not meeting these conditions with an HTTP 400 error when
38+
they are received via the client-server API.
39+
40+
Here's a (partial) example of an event relating to another event:
41+
42+
```json
43+
{
44+
"content": {
45+
"m.relates_to": {
46+
"rel_type": "m.replace",
47+
"event_id": "$abc:server.tld"
48+
}
49+
}
50+
}
51+
```
52+
53+
All the information about the relationship lives under the `m.relates_to` key.
54+
55+
If it helps, you can think of relations as a "subject verb object" triple,
56+
where the subject is the relation event itself; the verb is the `rel_type`
57+
field of the `m.relates_to` and the object is the `event_id` field.
58+
59+
We consciously do not support multiple different relations within a single event,
60+
in order to keep the API simple. This means that if event A relates to event B
61+
in two different ways you would send two events to describe the two relations,
62+
rather than bundling them into a single event. Another MSC,
63+
like [MSC 3051](https://github.com/matrix-org/matrix-doc/pull/3051),
64+
can propose a change to add support for multiple relations if it turns out that
65+
this would facilitate certain use cases.
66+
67+
Relations do not yet replace the
68+
[reply mechanism currently defined in the spec](https://matrix.org/docs/spec/client_server/r0.6.1#rich-replies).
69+
70+
### Relation types
71+
72+
Any values for `rel_type` should abide the
73+
[general guidelines for identifiers](https://github.com/matrix-org/matrix-doc/pull/3171).
74+
75+
The `rel_type` property determines how an event relates to another and can be used
76+
by clients to determine how and in what context a relation should be displayed.
77+
78+
[MSC 2675](https://github.com/matrix-org/matrix-doc/pull/2675) proposes to also interpret the `rel_type` server-side.
79+
80+
It is left up to the discretion of other MSCs building on this one whether they introduce
81+
`rel_type`s that are specific to their use case or that can serve a broad range
82+
of use cases. MSCs may define additional properties on the relation object for a given `rel_type`.
83+
84+
Currently, a few `rel_type`s are already proposed. Here's a non-exhaustive list:
85+
86+
- `m.replace` in [MSC 2676](https://github.com/matrix-org/matrix-doc/pull/2676).
87+
- `m.annotation` in [MSC 2677](https://github.com/matrix-org/matrix-doc/pull/2677).
88+
- `m.reference` in [MSC 3267](https://github.com/matrix-org/matrix-doc/pull/3267).
89+
- `m.thread` in [MSC 3440](https://github.com/matrix-org/matrix-doc/pull/3440).
90+
91+
92+
### Sending relations
93+
94+
Related events are normal Matrix events, and can be sent by the normal `/send`
95+
API.
96+
97+
The server should postprocess relations if needed before sending them into a
98+
room, as defined by the relationship type. For example, a relationship type
99+
might only allow a user to send one related message to a given event.
100+
101+
### Receiving relations
102+
103+
Relations are received like other non-state events, with `/sync`,
104+
`/messages` and `/context`, as normal discrete Matrix events. As explained
105+
in the limitations, clients may be unaware of some relations using just these endpoints.
106+
107+
[MSC2675](https://github.com/matrix-org/matrix-doc/pull/2675) defines ways in
108+
which the server may aid clients in processing relations by aggregating the
109+
events.
110+
111+
### Redactions
112+
113+
Events with a relation may be redacted like any other event.
114+
115+
[MSC3389](https://github.com/matrix-org/matrix-doc/pull/3389) proposes that
116+
the redaction algorithm should preserve the type and target id of a relation.
117+
118+
However, event relationships can still be used in existing room versions, but
119+
the user experience may be worse if redactions are performed.
120+
121+
## Potential issues
122+
123+
### Federation considerations
124+
125+
We have a problem with resynchronising relations after a gap in federation:
126+
We have no way of knowing that an edit happened in the gap to one of the events
127+
we already have. So, we'll show inconsistent data until we backfill the gap.
128+
* We could write this off as a limitation.
129+
* Or we could make *ALL* relations a DAG, so we can spot holes at the next
130+
relation, and go walk the DAG to pull in the missing relations? Then, the
131+
next relation for an event could pull in any of the missing relations.
132+
Socially this probably doesn't work as reactions will likely drop off over
133+
time, so by the time your server comes back there won't be any more reactions
134+
pulling the missing ones in.
135+
* Could we also ask the server, after a gap, to provide all the relations which
136+
happened during the gap to events whose root preceeded the gap.
137+
* "Give me all relations which happened between this set of
138+
forward-extremities when I lost sync, and the point i've rejoined the DAG,
139+
for events which preceeded the gap"?
140+
* Would be hard to auth all the relations which this api coughed up.
141+
* We could auth them based only the auth events of the relation, except we
142+
lose the context of the nearby DAG which we'd have if it was a normal
143+
backfilled event.
144+
* As a result it would be easier for a server to retrospectively lie about
145+
events on behalf of its users.
146+
* This probably isn't the end of the world, plus it's more likely to be
147+
consistent than if we leave a gap.
148+
* i.e. it's better to consistent with a small chance of being maliciously
149+
wrong, than inconsistent with a guaranteed chance of being innocently
150+
wrong.
151+
* We'd need to worry about pagination.
152+
* This is probably the best solution, but can also be added as a v2.
153+
* In practice this seems to not be an issue, which is worth complicating
154+
the s-s API over. Clients very rarely jump over the federation gap to an edit.
155+
In most cases they scroll up, which backfills the server and we have all the
156+
edits, when we reach the event before the gap.
157+
158+
## Limitations
159+
160+
Based solely on this MSC, relations are only received as discrete events in
161+
the timeline, so clients may only have an incomplete image of all the relations
162+
with an event if they do not fill gaps (syncs with a since token that have
163+
`limited: true` set in the sync response for a room) in the timeline.
164+
165+
In practice, this has proven not to be too big of a problem, as reactions
166+
(as proposed in [MSC 2677](https://github.com/matrix-org/matrix-doc/pull/2677))
167+
tend to be posted close after the target event in the timeline.
168+
169+
A more complete solution to this has been deferred to
170+
[MSC2675](https://github.com/matrix-org/matrix-doc/pull/2675).
171+
172+
## Tradeoffs
173+
174+
### Event shape
175+
176+
Shape of
177+
178+
```json
179+
"content": {
180+
"m.relates_to": {
181+
"m.reference": {
182+
"event_id": "$another:event.com"
183+
}
184+
}
185+
}
186+
```
187+
versus
188+
189+
```json
190+
"content": {
191+
"m.relates_to": {
192+
"rel_type": "m.reference",
193+
"event_id": "$another:event.com"
194+
}
195+
}
196+
```
197+
198+
The reasons to go with `rel_type` is:
199+
* This format is now in use in the wider matrix ecosystem without a prefix,
200+
in spite of the original MSC 1849 not being merged. This situation is not ideal
201+
but we still don't want to break compatibility with several clients.
202+
* We don't need the extra indirection to let multiple relations apply to a given pair of
203+
events, as that should be expressed as separate relation events.
204+
* If we want 'adverbs' to apply to 'verbs' in the subject-verb-object triples which
205+
relations form, then we apply it as mixins to the relation data itself rather than trying
206+
to construct subject-verb-verb-object sentences.
207+
* We decided to not adopt the format used by `m.in_reply_to` as it allows for multiple relations
208+
and is hence overly flexible. Also, the relation type of `m.in_reply_to` is also overly specific
209+
judged by the guidelines for `rel_type`s laid out in this MSC. Having replies use the same
210+
format as relations is postponed to a later MSC, but it would likely involve replies
211+
adopting the relation format with a more broadly useful `rel_type` (possibly the `m.reference`
212+
type proposed in [MSC3267](https://github.com/matrix-org/matrix-doc/pull/3267)),
213+
rather than relations adopting the replies format.
214+
215+
## Historical context
216+
217+
pik's MSC441 has:
218+
219+
Define the JSON schema for the aggregation event, so the server can work out
220+
which fields should be aggregated.
221+
222+
```json
223+
"type": "m.room._aggregation.emoticon",
224+
"content": {
225+
"emoticon": "::smile::",
226+
"msgtype": "?",
227+
"target_id": "$another:event.com"
228+
}
229+
```
230+
231+
These would then be aggregated, based on target_id, and returned as annotations on
232+
the source event in an `aggregation_data` field:
233+
234+
```json
235+
"content": {
236+
...
237+
"aggregation_data": {
238+
"m.room._aggregation.emoticon": {
239+
"aggregation_data": [
240+
{
241+
"emoticon": "::smile::",
242+
"event_id": "$14796538949JTYis:pik-test",
243+
"sender": "@pik:pik-test"
244+
}
245+
],
246+
"latest_event_id": "$14796538949JTYis:pik-test"
247+
}
248+
}
249+
}
250+
```

0 commit comments

Comments
 (0)