osmaczko a94ba2a7e0
fix: deliver anonymous PrivateV1 messages to applications
A PrivateV1 conversation is an out-of-band X3DH intro that binds no sender
credential, so its messages carry an empty credential. The client's
`decode_sender` returns `Missing` for an empty credential, and the event
emitters dropped any message whose sender could not be decoded. A PrivateV1
conversation therefore surfaced `ConversationStarted` but never the message
content, for both the initial message and every reply.

Deliver these messages with no sender instead of dropping them:

- `Event::MessageReceived.sender` becomes `Option<MessageSender>`; `None` marks
  an anonymous PrivateV1 message.
- `ConvoOutcome` carries the conversation `class` (mirroring `InboxOutcome`), so
  the client can tell a legitimately credential-less PrivateV1 message from a
  group message that is missing one.
- A new `message_sender` helper gates the anonymous case on `class == Private`;
  a missing credential on any group class is still dropped, preserving the
  invariant that group messages must be attributable.

Covered by a new `private_v1_integration` test exercising both the inbox
(initial message) and convo (reply) receive paths.
2026-06-26 17:30:35 +02:00
..
2026-06-23 12:02:01 -07:00