diff --git a/Scripts/verify.sh b/Scripts/verify.sh
index a058fc0..bf20eb7 100755
--- a/Scripts/verify.sh
+++ b/Scripts/verify.sh
@@ -429,6 +429,10 @@ if grep -q 'message.body = Self.readMarkerBody' Sources/Shared/XMPP/XMPPService.
echo "Read-marker service stanzas must not carry a plaintext body (it leaks into self-chat on other clients)"
exit 1
fi
+grep -q 'message.isMarkable = true' Sources/Shared/XMPP/XMPPService.swift || {
+ echo "Outgoing 1:1 messages must be or peers never answer with "
+ exit 1
+}
grep -q 'markersPublisher' Sources/Shared/XMPP/XMPPService.swift || {
echo "XEP-0333 displayed markers must mark messages as read"
exit 1
diff --git a/Sources/Shared/XMPP/XMPPService.swift b/Sources/Shared/XMPP/XMPPService.swift
index fe53fab..ac80d77 100644
--- a/Sources/Shared/XMPP/XMPPService.swift
+++ b/Sources/Shared/XMPP/XMPPService.swift
@@ -967,6 +967,13 @@ final class XMPPService {
let message = chat.createMessage(text: wireBody, id: messageID)
addOriginID(messageID, to: message)
+ // XEP-0333: peers only answer with `` when the outgoing
+ // stanza is marked ``. Martin adds `` (receipts)
+ // on its own but never markable, so 1:1 read state stayed stuck on
+ // "delivered". The element stays outside the OMEMO payload, which is
+ // exactly where Monal/Conversations look for it. MUC is exempt —
+ // XEP-0333 forbids markers in groupchats.
+ message.isMarkable = true
message.lastMessageCorrectionId = replacingMessageID
if chatStatesEnabled { message.chatState = .active }
addReply(replyTo, fallback: replyFallback, to: message)