Packets, the sender-signed mail.submit envelopes, are asynchronous signed
objects: relays and recipients reject only future-dated packets and apply no
live-write window or nonce maximum. Packet-ID tombstones and message
deduplication handle replays, so concurrent or late deliveries no longer fail
with nonce_not_greater, and retries reuse the same packet until it expires.
Relay snapshots drop the duplicated seen_nonces state.
Relay sender blocking is now SHOULD with no management endpoint; the SDK
relay setSenderBlocked/set_sender_blocked no longer takes an owner JWT, and
the host authenticates the owner. Recipients still apply sender policy before
decryption. MailInbox.accept verifies each packet once.
Drop the redundant header.protocol. Call the signed wire object the packet
and the plaintext the message across both specifications, schema definitions
(packetPayload, packetEvent, packetEnvelope), vectors, SDKs and the landing
page. Regenerate vectors, add relay vectors for a late lower-nonce packet and
a future-dated packet, and fix stale Mail client test fixtures.
Bump SDKs and the landing page SDK note to 0.11.1.
BREAKING CHANGE: packet headers no longer contain protocol; Mail schema
definitions and vector keys are renamed. MailSubmission/Submission and
MailLetter/Letter become MailPacket/Packet and MailMessagePayload/
MessagePayload; validateMailLetter, unframeMailLetter, mailSubmissionAad,
validate_letter, parse_letter, encrypt_letter and mail_submission_aad become
their message/packet forms; MailInbox.accept returns message instead of
letter; relay setSenderBlocked takes no JWT; deliver_with_nonce_store is
removed.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>