decrypt
Decrypts and processes envelope (docs/message-reliability.md, docs/application-delivery.md).
A new application message is stored as pending, sealed at rest, in the same transaction as its ratchet step, and returned as ReceiveResult.Delivery. It is not acknowledged: call commitReceivedMessage once the application has applied it.
A message whose logical ID is pending (a retry before the commit) is returned again as the same ReceiveResult.Delivery, not acknowledged, and not stored twice.
A message whose logical ID was committed is returned as ReceiveResult.AlreadyCommitted without its plaintext and acknowledged again; one that was discarded likewise as ReceiveResult.AlreadyDiscarded.
An acknowledgement removes the matching pending message sent to this sender (ReceiveResult.Acknowledgement). It is never acknowledged.
A logical ID that arrives again with another body fails with SecureMessageClientException.LogicalMessageConflict and changes nothing and is not acknowledged, also after a discard. For IDs committed before milestone 20 no digest is stored, so such a mismatch is not detected; they count as committed.
A failed acknowledgement does not fail this call: the result says ackSent = false and the sender's next retry triggers a new one.
Failures change nothing, except that a SecureMessageClientException.SessionCollision retires the losing initiation; its message is not acknowledged, so its sender keeps it pending and can send it again on the winning session. A decrypted plaintext that is not a reliability frame (for example from a peer before milestone 8) fails with ProtocolException.MalformedSecurePayload or ProtocolException.UnsupportedSecurePayloadVersion.
Envelopes from one sender must be decrypted one at a time, in the order the transport delivered them (docs/transport-ordering.md).