You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The delivery_ack / DeliveryReceipt event surfaces are wired end-to-end
(libchat Rust → liblogoschat onDeliveryAck (Nim) → chat-module chatDeliveryAck
(Qt/C++)), but no acknowledgement is ever produced. A recipient that successfully
receives and decodes a PrivateV1 message does not send any receipt back, so the
sender never gets an ack and the callback chain is never triggered.
Evidence
Reproduced in the chat-module e2e (two clients + one Waku relay/filter/lightpush
service node in a shared docker network):
Saro opens a private conversation with Raya and calls sendMessage.
Raya receives the message over Waku relay (received relay message) and fires new_message upward. That is the last activity on Raya — no outbound publish,
no receipt frame.
Saro never receives a delivery_ack; the chat-module test waiting on chatDeliveryAck times out at 20s.
Reproduces unchanged with --filter=true --lightpush=true on the bootstrap
node: the bootstrap log shows the chat client's filter subscribe handled
cleanly (subscription added correctly, [200] OK) for content topic /chatsdk/test/proto (hardcoded FilterContentTopic in logos-messaging/logos-chat src/chat/delivery/waku_client.nim). The no subscribed peers found contentTopic=delivery_address warnings are benign:
same msg_hash correlates with a successful sent relay message. Transport
is not the blocker.
Root cause — three concrete pieces
Recipient has no code path that emits a receipt.
In logos-messaging/logos-chat, src/chat/client.nim defines notifyDeliveryAck (~line 129) and stores deliveryAckCallbacks, but notifyDeliveryAck has zero callers anywhere in the repo. parseMessage
(~lines 191-206) decodes inbound payloads into notifyNewConversation / notifyNewMessage only — no receipt branch. Even with the callback registered
(liblogoschat.nim builds newJsonDeliveryAckEvent, client_api.nim wires onDeliveryAck), the trigger is unreachable.
No Receipt frame variant in the core protocol. FrameType (matched in core/conversations/src/conversation/privatev1.rs:257-259)
is just Content | Placeholder. A repo-wide search for Receipt finds it
only in the ADR. There is no frame the sender could decode into a DeliveryReceipt, even if one were sent.
Documented as future work.
docs/adr/0001-client-event-system.md: DeliveryReceipt is emitted
"when decoding a PrivateV1Frame::Receipt (future protocol work)".
crates/client-ffi/src/delivery.rs: // TODO: (P1) CDelivery does not support delivery_address filtering.
Expected behaviour
When a recipient successfully decodes a PrivateV1 message that requested
acknowledgement, it produces a PrivateV1Frame::Receipt addressed to the
conversation's delivery_address. The original sender decodes the receipt frame
and emits DeliveryReceipt carrying the matching conversationId and messageId, which propagates up through liblogoschat (delivery_ack) and the
chat-module plugin (chatDeliveryAck).
Acceptance criteria
Add and handle a Receipt variant in FrameType (or equivalent
protocol-level mechanism) in libchat.
Recipient generates and sends a Receipt frame after successfully decoding
a message that requested acknowledgement.
Sender decodes the Receipt and triggers a DeliveryReceipt event with conversationId and messageId matching the original send.
Wire notifyDeliveryAck on the Nim side
(logos-messaging/logos-chat src/chat/client.nim) into the inbound
message-processing path so the registered onDeliveryAck callback
actually fires.
Resolve the delivery_address filtering TODO in crates/client-ffi/src/delivery.rs.
Either: works between two peers connected through a single Waku relay
node, OR: document that the receipt path requires the logos.dev delivery
fleet (or equivalent service infrastructure) and what that infrastructure
must provide.
Delivery Subscription Mechanism #83 (Delivery Subscription Mechanism, closed) — covers per-conversation delivery_address subscriptions; relevant to the filtering TODO above.
logos-messaging/logos-chat#9 (closed) — added the receipt event shape on the
Nim/proto side, but the frame type and the recipient-side trigger were not
implemented in libchat.
Notes
Surfacing layers already in place: liblogoschat onDeliveryAck
(logos-messaging/logos-chat) and chat-module chatDeliveryAck
(logos-co/logos-chat-module).
The chat-module e2e test_delivery_ack_received is currently pytest.mark.xfail(strict=True) referencing this issue; once implemented it
will XPASS and the marker should be removed.
Summary
The
delivery_ack/DeliveryReceiptevent surfaces are wired end-to-end(libchat Rust → liblogoschat
onDeliveryAck(Nim) → chat-modulechatDeliveryAck(Qt/C++)), but no acknowledgement is ever produced. A recipient that successfully
receives and decodes a PrivateV1 message does not send any receipt back, so the
sender never gets an ack and the callback chain is never triggered.
Evidence
Reproduced in the chat-module e2e (two clients + one Waku relay/filter/lightpush
service node in a shared docker network):
sendMessage.received relay message) and firesnew_messageupward. That is the last activity on Raya — no outbound publish,no receipt frame.
delivery_ack; the chat-module test waiting onchatDeliveryAcktimes out at 20s.--filter=true --lightpush=trueon the bootstrapnode: the bootstrap log shows the chat client's filter subscribe handled
cleanly (
subscription added correctly,[200] OK) for content topic/chatsdk/test/proto(hardcodedFilterContentTopicinlogos-messaging/logos-chat src/chat/delivery/waku_client.nim). Theno subscribed peers found contentTopic=delivery_addresswarnings are benign:same
msg_hashcorrelates with a successfulsent relay message. Transportis not the blocker.
Root cause — three concrete pieces
Recipient has no code path that emits a receipt.
In
logos-messaging/logos-chat,src/chat/client.nimdefinesnotifyDeliveryAck(~line 129) and storesdeliveryAckCallbacks, butnotifyDeliveryAckhas zero callers anywhere in the repo.parseMessage(~lines 191-206) decodes inbound payloads into
notifyNewConversation/notifyNewMessageonly — no receipt branch. Even with the callback registered(
liblogoschat.nimbuildsnewJsonDeliveryAckEvent,client_api.nimwiresonDeliveryAck), the trigger is unreachable.No
Receiptframe variant in the core protocol.FrameType(matched incore/conversations/src/conversation/privatev1.rs:257-259)is just
Content | Placeholder. A repo-wide search forReceiptfinds itonly in the ADR. There is no frame the sender could decode into a
DeliveryReceipt, even if one were sent.Documented as future work.
docs/adr/0001-client-event-system.md:DeliveryReceiptis emitted"when decoding a
PrivateV1Frame::Receipt(future protocol work)".crates/client-ffi/src/delivery.rs:// TODO: (P1) CDelivery does not support delivery_address filtering.Expected behaviour
When a recipient successfully decodes a PrivateV1 message that requested
acknowledgement, it produces a
PrivateV1Frame::Receiptaddressed to theconversation's
delivery_address. The original sender decodes the receipt frameand emits
DeliveryReceiptcarrying the matchingconversationIdandmessageId, which propagates up through liblogoschat (delivery_ack) and thechat-module plugin (
chatDeliveryAck).Acceptance criteria
Receiptvariant inFrameType(or equivalentprotocol-level mechanism) in libchat.
a message that requested acknowledgement.
DeliveryReceiptevent withconversationIdandmessageIdmatching the original send.notifyDeliveryAckon the Nim side(
logos-messaging/logos-chat src/chat/client.nim) into the inboundmessage-processing path so the registered
onDeliveryAckcallbackactually fires.
delivery_addressfiltering TODO incrates/client-ffi/src/delivery.rs.node, OR: document that the receipt path requires the logos.dev delivery
fleet (or equivalent service infrastructure) and what that infrastructure
must provide.
Related
names
DeliveryReceiptas future protocol work in the linked ADR.delivery_addresssubscriptions; relevant to the filtering TODO above.logos-messaging/logos-chat#9(closed) — added the receipt event shape on theNim/proto side, but the frame type and the recipient-side trigger were not
implemented in libchat.
Notes
onDeliveryAck(
logos-messaging/logos-chat) and chat-modulechatDeliveryAck(
logos-co/logos-chat-module).test_delivery_ack_receivedis currentlypytest.mark.xfail(strict=True)referencing this issue; once implemented itwill XPASS and the marker should be removed.