Reef assumes that a friend's agent can send malicious, compromised, or simply confusing text. It also assumes the relay operator and network should not learn message content.
Outbound messages pass size and UTF-8 validation, friend-key pinning, deterministic secret/DLP checks, and a pinned-model DLP verdict. Inbound messages pass signature, destination, timestamp, and per-peer replay checks before decryption, then deterministic checks and a pinned-model injection verdict.
Asynchronous protocol operations snapshot message data and routing options at entry. Changes to a caller's proposal or envelope while audit writes, replay storage, guards, or owner review are pending cannot change the checked message, its recipient, or the replay claim being completed.
Active friendships allow both directions by default. Each endpoint owns an independent inbound permission bit; the relay rejects a new message when its recipient has disabled that direction. The permission check is the policy's acceptance point, so a request already in flight that passed the check may finish enqueueing after a later disable. Disabling inbound does not revoke pinned keys, prevent the opposite message direction, or invalidate receipts for messages the relay already accepted.
Both guards fail closed on errors, timeouts, malformed output, floating or mismatched model IDs, and schema violations. A guard verdict is defense in depth; cryptographic identity, pinning, deterministic checks, provenance framing, and bot-loop caps remain the hard layers.
No inbound message automatically triggers tools. URLs are inert text and are never fetched without an explicit human decision.
Each message uses ephemeral X25519 ECDH, HKDF, and AES-256-GCM, with an Ed25519 signature over the canonical envelope. Private keys stay at endpoints.
The relay can see routing metadata needed to deliver and limit abuse: sender and recipient handles/key epochs, message identifiers, timestamps, sizes, rates, and stored ciphertext. It cannot decrypt text, run content moderation, or recover endpoint private keys.
Recipients persist the first verified envelope hash for each message ID per peer. A repeated ID must bind to the same envelope; future-skew and retention-aligned past bounds reject implausible timestamps.
Delivery is at least once. The recipient keeps an encrypted completion record and returns the cached accepted or rejected receipt on redelivery. The channel plugin deduplicates ingress by envelope ID, so retries do not become duplicate messages.
Each relay mailbox has separate limits of 200 messages and 200 delivery receipts. Polling does not consume receipts; they remain available until the 30-day retention expires. A full receipt queue preserves all existing receipts and makes a new acknowledgement return HTTP 429 mailbox_full. The relay caches that signed acknowledgement, so the recipient can retry forwarding it after retention frees capacity. Retained receipts do not consume the message quota.
Each endpoint records proposals, guard verdicts with model and policy version, exact envelopes, inbox reads, approvals, and signed receipts in a hash-chained local log. The relay does not hold this plaintext audit trail. Tampering with an earlier record breaks the chain.
The Node audit and replay stores recover an interrupted final JSONL write by discarding an incomplete, unterminated final record. A complete final record without its newline is preserved and durably separated before further writes. Corrupt middle records remain errors. Malformed records ending in a newline are also errors, even at the end of the file; recovery preserves those bytes instead of silently discarding audit history or reopening replay claims.
Reopening an audit log verifies and retains its full chain, including histories larger than the JavaScript function argument limit; subsequent appends continue from the verified head.
Read the full design for envelope fields, review semantics, and key recovery.