diff options
Diffstat (limited to 'doc/edit-proposal.md')
| -rw-r--r-- | doc/edit-proposal.md | 201 |
1 files changed, 201 insertions, 0 deletions
diff --git a/doc/edit-proposal.md b/doc/edit-proposal.md new file mode 100644 index 0000000..806e674 --- /dev/null +++ b/doc/edit-proposal.md @@ -0,0 +1,201 @@ +--- +title: Message editing +layout: spec +work-in-progress: true +copyrights: + - + name: "Andre Hora" + period: "2026" +--- + +## Notes for implementing work-in-progress version + +This is a work-in-progress specification. + +Software implementing this work-in-progress specification MUST NOT use the +unprefixed `message-editing` capability name. +Instead, implementations SHOULD use the `draft/message-editing` capability +name to be interoperable with other software implementing a compatible +work-in-progress version. + +The final version of the specification will use an unprefixed capability name. + +This proposal is adapted from the direction of +[IRCv3 PR #425](https://github.com/ircv3/ircv3-specifications/pull/425) +and mirrors the structure of [`draft/message-redaction`][]. + +## Introduction + +This specification enables messages to be edited after they are sent. +Use cases include correcting typos, updating information, and amending +accidentally sent content. These are cosmetic use cases and do not provide any +operational security guarantees. The original message content remains visible to +clients that do not support this capability, and servers MAY retain the original +content in history. + +## Architecture + +### Dependencies + +Clients wishing to use this capability MUST negotiate the [`message-tags`][] +capability with the server. +Clients SHOULD negotiate the [`echo-message`][] capability in order to receive +message IDs for their own messages, so they can be edited. + +### Capability + +This specification adds the `draft/message-editing` capability. +Clients MUST ignore this capability's value, if any. + +Implementations that negotiate this capability indicate that they are +capable of handling the command described below. + +### Command + +To edit a message, a client MUST negotiate the `draft/message-editing` +capability and send an `EDIT` command to a target nickname or channel. +The command is defined as follows: + + EDIT <target> <msgid> :<new content> + +Where `<msgid>` is the id of the message to be edited, which MUST be a +`PRIVMSG` or `NOTICE`. + +The `<new content>` parameter is required and contains the full replacement text. +As the last parameter, it MAY contain spaces. + +If the client is authorised to edit the message, the server: + +* SHOULD forward this `EDIT`, with an appropriate prefix, to the target + recipients that have negotiated the `draft/message-editing` capability, in the + same way as PRIVMSG messages. +* MUST NOT forward this `EDIT` to target recipients that have not negotiated + this capability (see "Fallback" below). +* SHOULD assign a new `msgid` to the EDIT event itself, distinct from the + original message's `msgid`. + +### Chat history + +After a message is edited, [`chathistory`][] responses SHOULD include the +`EDIT` message after the original message. The original message's content +SHOULD be preserved as-is, with the `EDIT` indicating the replacement. + +Clients reconstructing a conversation from history SHOULD display only the +most recent edit for each original message. + +### Errors + +This specification defines `FAIL` messages using the [standard replies][] +framework for notifying clients of errors with message editing. +The following codes are defined, with sample plain text descriptions. + +* `FAIL EDIT INVALID_TARGET <target> :You cannot edit messages in <target>` +* `FAIL EDIT EDIT_FORBIDDEN <target> <target-msgid> :You are not authorised to edit this message` +* `FAIL EDIT EDIT_WINDOW_EXPIRED <target> <target-msgid> <window> :You can no longer edit this message` +* `FAIL EDIT UNKNOWN_MSGID <target> <target-msgid> :This message does not exist or is too old` + +## Client implementation considerations + +It is strongly RECOMMENDED that clients provide visible edit history to users. +This helps ensure accountability and mitigates abuse through surreptitious +editing. This could be done via a tooltip showing the original text, an +"(edited)" indicator, or a separate log. + +Clients SHOULD display the edited content as the primary message text, with +an indication that the message was modified. + +For the purposes of user interface, clients MAY assume that their own messages +are editable. However, this will not always be the case. Pending a mechanism +for discovering edit permissions, clients SHOULD allow users to attempt to edit +their own messages via some mechanism. + +When an `EDIT` command's `msgid` parameter references a known message not in +the `target`'s history, clients MUST ignore it. + +## Server implementation considerations + +This section is non-normative. + +Servers SHOULD restrict editing to the original message author by default. +Channel operators or server administrators MAY be granted edit permissions +at the server's discretion, though this is less common than for redaction. + +Servers MAY impose a time window after which edits are no longer permitted. +The `EDIT_WINDOW_EXPIRED` error code is provided for this purpose. + +Servers MAY choose to store the full edit history (all versions of a message) +or only the latest version. Datomic-backed implementations naturally retain +full history via immutable datoms. + +### Message validation + +To implement validation, servers require a mechanism for determining whether +a particular edit action is permitted. The same considerations as +[`draft/message-redaction`][] apply: servers can look up message properties +from the ID, or encode required properties within the message ID itself. + +### Fallback + +Server implementations might choose to inform clients that haven't negotiated +the capability that an edit has taken place. The fallback method used (if any) +is left up to server implementations, but could take the form of a standard +NOTICE or PRIVMSG with information about the action. For example: + + :irc.example.com NOTICE #channel :nickname edited a message from 5 seconds ago + +Alternatively, servers could re-send the message as a new PRIVMSG with an +indication that it replaces a prior message, though this risks confusion +with standard clients. + +## Security considerations + +The ability to edit messages does not offer any information or operational +security guarantees. Once a message has been sent, assume that the original +content will remain visible to any recipients or servers, whether or not it +is subsequently edited. Above all else, clients that do not support this +specification will not see any changes to the original message. + +Servers SHOULD retain the original message content in their history backend, +even after an edit, to support audit and accountability use cases. + +## Examples + +Editing a PRIVMSG: + + C: PRIVMSG #channel :an exmple with a tpyo + S: @msgid=123 :nick!u@h PRIVMSG #channel :an exmple with a tpyo + C: EDIT #channel 123 :an example with no typos + S: @msgid=456 :nick!u@h EDIT #channel 123 :an example with no typos + +Editing a message in a DM: + + C: PRIVMSG friend :meet me at 3pm + S: @msgid=789 :nick!u@h PRIVMSG friend :meet me at 3pm + C: EDIT friend 789 :meet me at 4pm actually + S: @msgid=790 :nick!u@h EDIT friend 789 :meet me at 4pm actually + +Failed edit (not authorised): + + C: EDIT #channel 123 :trying to edit someone else's message + S: FAIL EDIT EDIT_FORBIDDEN #channel 123 :You are not authorised to edit this message + +Failed edit (window expired): + + C: EDIT #channel 123 :too late + S: FAIL EDIT EDIT_WINDOW_EXPIRED #channel 123 300 :You can no longer edit this message + +Interaction with chat history: + + C: CHATHISTORY LATEST #channel * 50 + S: BATCH +abc chathistory #channel + S: @batch=abc;msgid=123;time=2026-04-22T10:00:00.000Z :nick!u@h PRIVMSG #channel :an exmple with a tpyo + S: @batch=abc;msgid=456;time=2026-04-22T10:00:05.000Z :nick!u@h EDIT #channel 123 :an example with no typos + S: BATCH -abc + + +[`echo-message`]: ../extensions/echo-message.html +[standard replies]: ../extensions/standard-replies.html +[`message-tags`]: ../extensions/message-tags.html +[`msgid`]: ../extensions/message-ids.html +[`chathistory`]: ../extensions/chathistory.html +[`draft/message-redaction`]: ../extensions/message-redaction.html |
