From aa5b57b330c602ac5ff01e5b098f91d2ce7455aa Mon Sep 17 00:00:00 2001 From: Johannes Marbach Date: Thu, 12 Jun 2025 13:12:06 +0200 Subject: [PATCH 1/8] MSC4300: Processing status requests & responses Signed-off-by: Johannes Marbach --- proposals/4300-request-response.md | 130 +++++++++++++++++++++++++++++ 1 file changed, 130 insertions(+) create mode 100644 proposals/4300-request-response.md diff --git a/proposals/4300-request-response.md b/proposals/4300-request-response.md new file mode 100644 index 00000000000..c80546e0466 --- /dev/null +++ b/proposals/4300-request-response.md @@ -0,0 +1,130 @@ +# MSC4300: Requesting and reporting event processing status + +Matrix allows clients to exchange both built-in and custom events with other clients in rooms. There +is, however, no way for a client to understand if the events it sent were actually understood by +other clients or not. This is problematic as a compatibility mismatch means that the recipient user +might only be able to see a fallback representation of an event or, in the worst case, nothing at +all. At the same time, the sender is left wholly unaware of the recipient's experience. + +These problems are aggravated when one or both of the participating clients are an automated system +(a.k.a. bot) which cannot easily issue or respond to generic "Did you see my message?" questions. + +The present proposal partially addresses this problem by defining a generic scheme for clients to +request and receive an explicit processing status for events from other clients. + +## Proposal + +A new content block `m.request.status` is introduced to request a processing status from other +clients when sending events. It has the following properties in `content`: + +- `from_device` (required, string): The sending device's device ID. Allows recipients to optionally + submit their responses privately via to-device messages in the future. +- `lifetime` (integer): The duration in milliseconds during which the sender will consider responses + to this request. Prevents meaningless delayed responses when new or previously disconnected + devices encounter requests on older events. + +Clients MAY add `m.request.status` as a top-level property in `content` on any event they send. + +``` json5 +{ + "type": "m.pizza", + "event_id": "$1", + "content": { + "m.request.status": { + "from_device": "RJYKSTBOIE", + "lifetime": 90_000, // 90s + }, + // properties specific to m.pizza + } +} +``` + +Clients that receive events containing `m.request.status` content blocks MAY respond to them with a +new room event type `m.response.status`. The latter contains an `m.reference` relation pointing to +the original event as well as an `m.response.status` content block with the following properties: + +- `from_device` (required, string): The sending device's device ID. Helps clients identify the + remote echo of their own responses. +- `status` (required, string, one of `success`, `error`): Whether the sending device has understood + and successfully processed the event. +- `messages` (array): An optional array of messages to help recipients understand the `status`. + - `type`: (required, string, one of `info`, `warning`, `error`): The message category. + - `m.text`: (required, object): The message in one or more textual representations as per + [MSC1767]. + +The event `content` MAY contain further properties based on the type of the event that is being +responded to. + +``` json5 +{ + "type": "m.response.status", + "content": { + "m.response.status": { + "from_device": "EIOBTSKYJR", + "status": "error", + "messages": [{ + "type": "error", + "m.text": [{ "body": "Unknown event type m.pizza" }] + }] + }, + "m.relates_to": { + "event_id": "$1", + "rel_type": "m.reference", + }, + // optional properties specific to m.pizza + } +} +``` + +Clients can check whether a request has expired using `lifetime`, `origin_server_ts` and their local +clock. Once a request has expired, clients SHOULD refrain from sending `m.response` events +themselves and ignore any new `m.response` events received from other clients. + +## Potential issues + +This proposal doesn't strictly define what constitutes successful processing of an event. At a +minimum, the meaning of success will depend on the type of event sent and the receiving client. An +archival bot, for instance, may have to decrypt and export an event to consider it processed +successfully. An instant messaging client for end users, on the other hand, might have to render an +event in a way that allows the user to interact with it. The kind of rendering needed will be +specific to the type of event in this case. + +It is expected that the mechanism introduced in this proposal will be used as a basis for more +specialised features that clearly define the semantics of success. Therefore, this aspect is +consciously left unspecified here. + +## Alternatives + +Requests for processing statuses could be sent separately from the event being processed, for +instance, via to-device messages. This, however, introduces complexity because now both messages +have to be received and decrypted before responses can be sent. It is not clear what benefits, if +any, this alternative would have over the solution proposed in the present proposal. + +Instead of sending processing statuses per event, clients could statically advertise the types of +events that they are able to understand, for instance, via profiles or state events in a room. This +would allow senders to look up recipient capabilities ahead of time but would not allow recipients +to communicate back detailed information about their processing status of individual events. As a +result, the two mechanisms are not necessarily competing and could also play together. + +## Security considerations + +Communicating the processing status via room events leaks metadata by revealing client capabilities +to all room participants. This can be mitigated by transporting the status via to-device messages +instead. A future proposal may generalise the mechanism introduced here accordingly. Until then, +clients are not required to respond to status requests under this proposal and MAY simply ignore +them. + +Contrary to the above, persisting processing status responses in timeline events can be necessary in +scenarios that require auditability. + +## Unstable prefix + +While this MSC is not considered stable, `m.request.status` and `m.response.status` (the event type) +should be referred to as `de.gematik.msc4300.request.status` and +`de.gematik.msc4300.response.status`, respectively. + +## Dependencies + +None. + + [MSC1767]: https://github.com/matrix-org/matrix-spec-proposals/pull/1767 From f40374b74f9c6f2efe188eb1d8c928b0b32cb611 Mon Sep 17 00:00:00 2001 From: Johannes Marbach Date: Tue, 17 Jun 2025 11:18:04 +0200 Subject: [PATCH 2/8] Reference MSC4089 --- proposals/4300-request-response.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/proposals/4300-request-response.md b/proposals/4300-request-response.md index c80546e0466..da831aa3196 100644 --- a/proposals/4300-request-response.md +++ b/proposals/4300-request-response.md @@ -106,6 +106,12 @@ would allow senders to look up recipient capabilities ahead of time but would no to communicate back detailed information about their processing status of individual events. As a result, the two mechanisms are not necessarily competing and could also play together. +Delivery receipts as proposed in [MSC4089] are a partial alternative to this proposal. These +receipts only convey receipt and decryption status but not whether the decrypted event was actually +understood and processed successfully. Additionally, delivery receipts don't cover the case where an +event was received but failed to be processed. Lastly, receipts in their current form also don't +support including additional encrypted information about the processing result. + ## Security considerations Communicating the processing status via room events leaks metadata by revealing client capabilities @@ -128,3 +134,4 @@ should be referred to as `de.gematik.msc4300.request.status` and None. [MSC1767]: https://github.com/matrix-org/matrix-spec-proposals/pull/1767 + [MSC4089]: https://github.com/matrix-org/matrix-spec-proposals/pull/4089 From 511bfa2f294aa13e4495f9c974918b952e0c8656 Mon Sep 17 00:00:00 2001 From: Johannes Marbach Date: Mon, 1 Dec 2025 10:16:34 +0100 Subject: [PATCH 3/8] Use valid JSON number Signed-off-by: Johannes Marbach --- proposals/4300-request-response.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/4300-request-response.md b/proposals/4300-request-response.md index da831aa3196..17745a1952c 100644 --- a/proposals/4300-request-response.md +++ b/proposals/4300-request-response.md @@ -32,7 +32,7 @@ Clients MAY add `m.request.status` as a top-level property in `content` on any e "content": { "m.request.status": { "from_device": "RJYKSTBOIE", - "lifetime": 90_000, // 90s + "lifetime": 90000, // 90s }, // properties specific to m.pizza } From 13b35879a0ef60b094eb89cbe7ac459bff66349e Mon Sep 17 00:00:00 2001 From: Johannes Marbach Date: Mon, 1 Dec 2025 10:17:38 +0100 Subject: [PATCH 4/8] Use vendor prefix for everything that begins with m. Signed-off-by: Johannes Marbach --- proposals/4300-request-response.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/proposals/4300-request-response.md b/proposals/4300-request-response.md index 17745a1952c..c450f7b62dc 100644 --- a/proposals/4300-request-response.md +++ b/proposals/4300-request-response.md @@ -125,9 +125,9 @@ scenarios that require auditability. ## Unstable prefix -While this MSC is not considered stable, `m.request.status` and `m.response.status` (the event type) -should be referred to as `de.gematik.msc4300.request.status` and -`de.gematik.msc4300.response.status`, respectively. +While this MSC is not considered stable, `m.request.status` and `m.response.status` should be +referred to as `de.gematik.msc4300.request.status` and `de.gematik.msc4300.response.status`, +respectively. ## Dependencies From cda5d2cbeabd3c9cc27d784bd8529328241cc376 Mon Sep 17 00:00:00 2001 From: Johannes Marbach Date: Fri, 5 Dec 2025 15:16:46 +0100 Subject: [PATCH 5/8] Explain relation to MSC4301 Signed-off-by: Johannes Marbach --- proposals/4300-request-response.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/proposals/4300-request-response.md b/proposals/4300-request-response.md index c450f7b62dc..16e84bc57b8 100644 --- a/proposals/4300-request-response.md +++ b/proposals/4300-request-response.md @@ -82,6 +82,10 @@ themselves and ignore any new `m.response` events received from other clients. ## Potential issues +The mechanism introduced above doesn't enable clients to determine if other clients are able to +understand an event without actually sending it. [MSC4301] builds upon the present proposal and +introduces event capability queries to achieve this. + This proposal doesn't strictly define what constitutes successful processing of an event. At a minimum, the meaning of success will depend on the type of event sent and the receiving client. An archival bot, for instance, may have to decrypt and export an event to consider it processed @@ -134,4 +138,5 @@ respectively. None. [MSC1767]: https://github.com/matrix-org/matrix-spec-proposals/pull/1767 + [MSC4301]: https://github.com/matrix-org/matrix-spec-proposals/pull/4301 [MSC4089]: https://github.com/matrix-org/matrix-spec-proposals/pull/4089 From 061a7a5e5bc1acef0bc1e749075d55ff7690f491 Mon Sep 17 00:00:00 2001 From: gem-jn Date: Fri, 23 Jan 2026 13:56:38 +0100 Subject: [PATCH 6/8] Update request-response.md with 'to_device' field Added optional 'to_device' field for m.request.status to adress a specific receiver --- proposals/4300-request-response.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/proposals/4300-request-response.md b/proposals/4300-request-response.md index 16e84bc57b8..ff077160954 100644 --- a/proposals/4300-request-response.md +++ b/proposals/4300-request-response.md @@ -32,6 +32,7 @@ Clients MAY add `m.request.status` as a top-level property in `content` on any e "content": { "m.request.status": { "from_device": "RJYKSTBOIE", + "to_device": "EIOBTSKYJR", // optional the receiving device "lifetime": 90000, // 90s }, // properties specific to m.pizza @@ -45,6 +46,8 @@ the original event as well as an `m.response.status` content block with the foll - `from_device` (required, string): The sending device's device ID. Helps clients identify the remote echo of their own responses. +- `to_device`(optional, string): The receiving device's device ID. Should be set in case the sender + want to a adress a specific receiving client. - `status` (required, string, one of `success`, `error`): Whether the sending device has understood and successfully processed the event. - `messages` (array): An optional array of messages to help recipients understand the `status`. From 9f9c809d884830d9ad60ef2d0bee0eb215056a12 Mon Sep 17 00:00:00 2001 From: Johannes Marbach Date: Mon, 26 Jan 2026 10:48:22 +0100 Subject: [PATCH 7/8] Clarify new field to_device Signed-off-by: Johannes Marbach --- proposals/4300-request-response.md | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/proposals/4300-request-response.md b/proposals/4300-request-response.md index ff077160954..ff1083d4d5e 100644 --- a/proposals/4300-request-response.md +++ b/proposals/4300-request-response.md @@ -19,6 +19,8 @@ clients when sending events. It has the following properties in `content`: - `from_device` (required, string): The sending device's device ID. Allows recipients to optionally submit their responses privately via to-device messages in the future. +- `to_device`(optional, string): The receiving device's device ID. Should be set when the sender + wants to a adress a specific receiving device only. - `lifetime` (integer): The duration in milliseconds during which the sender will consider responses to this request. Prevents meaningless delayed responses when new or previously disconnected devices encounter requests on older events. @@ -40,14 +42,13 @@ Clients MAY add `m.request.status` as a top-level property in `content` on any e } ``` -Clients that receive events containing `m.request.status` content blocks MAY respond to them with a -new room event type `m.response.status`. The latter contains an `m.reference` relation pointing to -the original event as well as an `m.response.status` content block with the following properties: +Clients that receive events containing `m.request.status` content blocks where `to_device` is either +missing or identical to their own device ID, MAY respond to them with a new room event type +`m.response.status`. The latter contains an `m.reference` relation pointing to the original event as +well as an `m.response.status` content block with the following properties: - `from_device` (required, string): The sending device's device ID. Helps clients identify the remote echo of their own responses. -- `to_device`(optional, string): The receiving device's device ID. Should be set in case the sender - want to a adress a specific receiving client. - `status` (required, string, one of `success`, `error`): Whether the sending device has understood and successfully processed the event. - `messages` (array): An optional array of messages to help recipients understand the `status`. From cd12bb853c416cf655fa4fdb95abadfc168ef534 Mon Sep 17 00:00:00 2001 From: Johannes Marbach Date: Mon, 26 Jan 2026 10:49:42 +0100 Subject: [PATCH 8/8] Fix typo Signed-off-by: Johannes Marbach --- proposals/4300-request-response.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/4300-request-response.md b/proposals/4300-request-response.md index ff1083d4d5e..1028231df23 100644 --- a/proposals/4300-request-response.md +++ b/proposals/4300-request-response.md @@ -20,7 +20,7 @@ clients when sending events. It has the following properties in `content`: - `from_device` (required, string): The sending device's device ID. Allows recipients to optionally submit their responses privately via to-device messages in the future. - `to_device`(optional, string): The receiving device's device ID. Should be set when the sender - wants to a adress a specific receiving device only. + wants to a address a specific receiving device only. - `lifetime` (integer): The duration in milliseconds during which the sender will consider responses to this request. Prevents meaningless delayed responses when new or previously disconnected devices encounter requests on older events.