INVITE ONLY
OBSERVATORY

05 Security · Metadata

The envelope does not name you.

Content encryption is table stakes. The harder fight is the envelope — who, to whom, how much, when. Here is exactly how far we take it, and where it stops.

What the envelope actually says.

Sealed-sender v2 — rolling out

This is the wire struct, field for field. The sender is a blinded commitment the relay cannot reverse; only the recipient can. The commitments rotate every hour and on every key-transparency append.

SealedEnvelope — the wire schema, verbatim fields
  • delivery_token Per-conversation routing token. Rotates on KTS append — yesterday’s token maps to nothing today. Opaque
  • sender_blinded_pid Sender Profile ID committed under (token, window). Reversible only by the recipient. Opaque
  • recipient_blinded_pid Matched against commitments each device pre-registered for the current window — routing without a name. Opaque
  • time_window_id The hour the commitments were minted in. Visible — this is the envelope’s honest plaintext. Plaintext
  • ciphertext_hash + delivery_proof SHA-512/256 body commitment under an ML-DSA-87 signature — the relay cannot rewrite what it routes. Opaque
  • ciphertext The entangled frame, unchanged — Q-Ratchet keys, AEAD, and padding all live inside it. Ciphertext

Size stops being a fingerprint.

Every payload snaps up to a fixed bucket before sealing, so “yes” and a paragraph can leave the device the same size. These are the shipped constants, not an illustration.

Q-Pad ladder — shipped bucket constants
LadderBucketsRangeSized for
Text 9 64 B → 16 KiB chat: median under 128 B, p99 16 KiB
Voice 8 16 KiB → 2 MiB Opus VBR 24–48 kbps, ~0.5 s to ~64 s
Media 6 1 MiB → 1 GiB QSEAL-Stream totals after 256 KiB chunking

Padding hides length within a bucket; it does not hide that a message was sent, and timing correlation by a global passive observer remains an open problem for every store-and-forward messenger, including this one. QLEAP’s three-hop routing will raise the cost of linking endpoints; it is not in this build, and it would not make the problem vanish when it lands. Today the pad ladder and the sealed envelope above carry this alone.

The storage contract, present tense.

What the relay retains — today, then the roadmap
DataTodayRoadmap
Delivered messages erased on acknowledgment unchanged
Undelivered queue 30 days, hourly purge job tiered ladder: 24 h / 4 h / zero-storage
Delivery receipts zeroed on delivery unchanged
Envelope commitments expire with their hour window unchanged

The 30-day figure1 is the present-tense truth of the running relay. The tiered ladder is roadmap, and it will be written here in the present tense only when the purge code ships.

The hard questions.

Group names, subjects, avatars, and all content are end-to-end encrypted; the relay holds only opaque routing identifiers; sender identifiers are stripped from the stored message row (sealed-sender v2), though the relay still authenticates the sender at send time. Undelivered messages queue with routing metadata under a published retention ladder — that queue window is the honest exposure, stated above.

Because routing needs a freshness anchor: the relay must know which window’s pre-registered commitments to match an envelope against. One hour is the granularity — coarse enough to blunt timing precision, fine enough to keep delivery immediate.