Skip to content

Conversation

DonPrus
Copy link

@DonPrus DonPrus commented Sep 16, 2025

Summary

This MSC proposes "Live Messages": recipients see a message evolve in real time while it is being typed.
It leverages existing m.replace edits on m.room.message (no new event type), marked by an unstable
flag in content to denote a "live session". Non-supporting clients gracefully degrade to a normal edited
message; supporting clients render a smooth, streaming-like UX.

What this adds

  • Identification: initial message carries org.matrix.mscXXXX.live: {}; subsequent updates use m.replace
    with full m.new_content; the final update omits the live flag (session complete).
  • Control: optional state event m.room.live_messaging (enabled: boolean) to allow room-level opt-in/out.
  • Server: no new endpoints; existing relations/aggregation apply; admins may rate-limit high-frequency edits.

Backwards compatibility

Old clients see "a message with edits" and always end up with the final content.

Rendered Markdown
Rendered: proposals/4357-live-messages.md

Author

Author: @DonPrus

@DonPrus DonPrus changed the title MSC: Live Messages via Event Replacement (draft) MSC4357: Live Messages via Event Replacement (draft) Sep 16, 2025
@DonPrus DonPrus changed the title MSC4357: Live Messages via Event Replacement (draft) MSC4357: Live Messages via Event Replacement Sep 16, 2025
messages.
- **Storage**: Live sessions produce more events. Deployments can rely on retention policies and rate-limits.

## Alternatives
Copy link
Contributor

Choose a reason for hiding this comment

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

Conceptually this proposal sounds similar to #3489 (live location sharing). That one uses a state event and reference relations though. Replacements strike me as a more intuitive solution though.

Copy link
Author

@DonPrus DonPrus Sep 16, 2025

Choose a reason for hiding this comment

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

I agree the concept is similar to MSC3489 in that both stream incremental state. For live text, I believe m.replace on m.room.message is the most intuitive and compatibility‑friendly primitive: older clients already understand “edits” and will converge to the final content; supporting clients can render the intermediate states seamlessly. It also avoids adding a new event type purely for live typing and reuses the well‑understood edit aggregation path (per MSC2676 / spec).


### Semantics:

- If absent, default is enabled (unless server policy states otherwise).
Copy link
Contributor

Choose a reason for hiding this comment

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

IIUC the enforcement can only happen on the client side. This means clients would need a way to discover such global server policy?

Copy link
Author

Choose a reason for hiding this comment

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

In the draft I wrote “default is enabled (unless server policy states otherwise)”, which is ambiguous without a standard way to advertise that policy. I propose to clarify that the normative control here is room‑level via m.room.live_messaging; clients MUST honor it. Servers MAY reject live‑marked events in unencrypted rooms as a local policy, but there is no standardized discovery for a global ban, so it’s out of scope for this MSC. I’ll remove/adjust the “unless server policy states otherwise” wording to avoid implying a discovery mechanism that doesn’t exist


- If absent, default is enabled (unless server policy states otherwise).
- If `enabled: false`, clients **MUST NOT** offer live mode in this room.
- Servers **MAY** enforce rejection of events that carry live markers in rooms where it is disabled.
Copy link
Contributor

Choose a reason for hiding this comment

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

This is only possible in unencrypted rooms because org.matrix.msc4357.live is in content which is encrypted.

Copy link
Author

Choose a reason for hiding this comment

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

yep, feature still works end‑to‑end (supporting clients decrypt, detect the marker, and render progressively), but enforcement and special aggregation are client‑side only in E2EE. I’ll add an explicit “E2EE considerations” subsection stating that server‑side enforcement is only feasible in unencrypted rooms.

update replaces the entire content (`m.new_content` reflects the complete current text).
- **Completion**: on explicit send or mode exit, send a final update without the live marker. After this, do not send
further updates for this session.
- **Rate limiting**: clients **MUST** avoid flooding and respect server guidance; batching is encouraged.
Copy link
Contributor

Choose a reason for hiding this comment

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

Does batching mean combining several updates into a single event replacement?

Copy link
Author

Choose a reason for hiding this comment

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

By batching I mean coalescing local interim changes and emitting a single m.replace update at a bounded cadence (e.g. every ~2–3s or at natural boundaries like end‑of‑word), rather than sending an event per keystroke. Each update still contains the full current content in m.new_content; there’s no special “multi‑update container”. I’ll tighten the wording to make this explicit.

Comment on lines +38 to +39
- **Completion**: on explicit send or mode exit, send a final update without the live marker. After this, do not send
further updates for this session.
Copy link
Contributor

Choose a reason for hiding this comment

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

Is it allowed to transition back from completion into live mode?

Copy link
Author

Choose a reason for hiding this comment

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

I intend completion to be terminal for that message. Once the final update (without the live marker) is sent, the live session is over. Further changes are normal edits; resuming live mode should be done by starting a new live message. Allowing a message to re‑enter live mode risks confusing clients (especially non‑supporting ones) that have already treated it as finalized. I’ll add a normative MUST‑NOT to make this explicit.

@turt2live turt2live added proposal A matrix spec change proposal client-server Client-Server API kind:feature MSC for not-core and not-maintenance stuff needs-implementation This MSC does not have a qualifying implementation for the SCT to review. The MSC cannot enter FCP. labels Sep 16, 2025
Copy link
Member

Choose a reason for hiding this comment

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

Implementation requirements:

  • Client (sending)
  • Client (receiving)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

client-server Client-Server API kind:feature MSC for not-core and not-maintenance stuff needs-implementation This MSC does not have a qualifying implementation for the SCT to review. The MSC cannot enter FCP. proposal A matrix spec change proposal

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants