Skip to content

Delivery acknowledgements never fire — recipient does not emit a Receipt frame #121

@at0m1x19

Description

@at0m1x19

Summary

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

  1. 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.

  2. 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.

  3. 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.

Related

  • Client Event System #97 (Client Event System) — this is a concrete sub-task of Client Event System #97, which already
    names DeliveryReceipt as future protocol work in the linked ADR.
  • 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions