The message transport is an interface (SHARING-SPEC §3): it moves a signed, sealed envelope from one archive's outbox to another's inbox. The interface covers nothing else. This page compares five transport options — one built, four researched and judged — against the same three-question test. Companion doc: COURIER-CONCEPT-v0.1.md. Existing code and specification filenames retain the earlier courier name until the software is migrated. The plain-words version is for everyone else.
Every candidate below is asked the same three questions, in the same order. These three are the entire evaluation:
Nothing about a candidate's popularity, feature richness, or engineering elegance enters the evaluation. A road either answers these three questions in a way that lets it carry the envelope, or it doesn't.
Q1 — moves bytes? Yes, and extremely well: forward secrecy, post-compromise security, a relay that sees ciphertext + routing metadata only.
Q2 — operator trust? N/A as evaluated here. The question this catalog actually answers is whether to run Signal's infrastructure (libsignal, our own X3DH/ratchet state machine, account provisioning per contact) versus borrowing its properties. SHARING-SPEC §3 already answered this: "its software is not the build... a heavy dependency for a star-topology circle of 10."
Q3 — sealing forced? The rail already gets the properties that matter (an untrusted relay sees only ciphertext) via age/X25519 sealing on top of shared-folder or text-message transport. The age/X25519 rung lacks X3DH's specific forward-secrecy guarantee, which we judge to protect against a threat model (future device compromise unwinding today's messages) that a 10-person, voice-verified circle does not currently need. If that judgment changes for a specific circle, real libsignal is the correct upgrade. A home-grown ratchet is never the answer.
Status: FUTURE, researched only. The design does not reach build-readiness.
Q1 — moves bytes? Yes: KSP1 framing, base64url chunks, bounded/TTL'd reassembly (pna_text_courier.py).
Q2 — operator trust? No: uniform distrust of every messaging operator, forced in code (configure_text_courier() hardcodes trusted: false; a hand-edited override is re-refused at every use).
Q3 — sealing forced? Yes: frame_for_text() raises TextCourierError on anything not sealing: "e2e". No exception path exists.
Status: BUILT — 25/25 tests green at its July 12, 2026 build, the full pre-existing Personal Neutral Archive (PNA) suite unaffected; current whole-suite counts live on the build log. Not yet wired to a real OS Messages bridge; no live age round-trip in this build environment (no binary present). Full detail on the text-message transport page.
Q1 — moves bytes? Technically yes: an opaque blob could ride in an event's description field, or a custom extendedProperties.private value (visible only to the inserting application, per Google's docs). The API also natively supports attendees[].responseStatus (needsAction/accepted/declined/tentative), a real propose/accept/decline verb set already built into the platform.
Q2 — operator trust? No, and this is the disqualifying answer. Q1 is not what rules it out. Google Calendar's freebusy.query and native invite flow exist to broadcast availability — the platform's entire value proposition is knowing your schedule. Routing PROPOSE/ACCEPT through it, even sealed, would still leak that a negotiation with this specific contact is happening on this specific day to an operator whose business model is schedule intelligence — the same social-graph/rhythm leakage the text-message transport spec already names as an accepted, bounded cost for SMS (COURIER-SMS-SPEC §3); accepting it a second time for a platform built specifically to mine calendar data is a different risk calculus, and this catalog answers Q2 "no" and leaves the SMS acceptance where it stands.
Q3 — sealing forced? N/A: Q2 already disqualifies it as a negotiation transport.
Where it's a legitimate future feature: once state == "agreed" (SHARING-SPEC §6), pushing that single confirmed event — via events.insert, no negotiation history, no other party's identity beyond a display name — into the agreeing party's own Google Calendar is the same operation as writing derived/event.ics today, aimed at a hosted target. This publishes a result. No negotiation is routed, and none of I1–I15 changes.
Status: FUTURE as a derived-output integration; not specified. REJECTED as message transport.
Two distinct things share this name and get separate verdicts.
CalDAV (RFC 4791, WebDAV-based, federated). Q1: yes, any CalDAV server (iCloud's, or a self-hosted one) can carry arbitrary event data. Q2: same disqualifying answer as Google's — the calendar-never-leaves invariant (I1) applies to any calendar service the negotiation would route through, regardless of who operates it; a self-hosted CalDAV server run by an operator the circle already trusts changes the operator-trust math for other purposes. Even so, this catalog routes negotiation through no calendar server at all, however much the circle trusts its operator. Q3: N/A, disqualified at Q2.
EventKit (on-device framework, with no network model of its own). This is the mechanism for spec §7's "the person is the last hop." It is not a transport candidate at all. Where stage_text_send() hands framed text to Messages via a share sheet today, an Apple-platform build of pna_share could hand a confirmed event directly to EKEventStore. That drops the manual import of derived/event.ics — same last-hop doctrine, one fewer manual step, on Apple hardware specifically.
Status: FUTURE for the EventKit last-hop integration; not specified. REJECTED as message transport (both CalDAV and any calendar-hosted transport).
What it actually is, precisely: each identity is a DID (decentralized identifier) resolving to a DID document; a person's data lives in a PDS (Personal Data Server, self-hostable); records are typed by lexicons (JSON-schema-like definitions) and committed into a repository — a signed, Merkle-Search-Tree-backed commit log; a public relay ingests every subscribed PDS's commits and republishes them on a firehose that any client (including BlueSky's own app) subscribes to.
Q1 — moves bytes? Yes, and in an interesting way: a custom lexicon (e.g. org.kisop.together.propose) is a well-defined path to typed, versioned KISOP record types living in a repo with real provenance — the same "signed thread is canonical" doctrine SHARING-SPEC §6 already uses for exchange/, arrived at independently by an unrelated protocol.
Q2 — operator trust? No, and structurally so: the relay/firehose's entire purpose is public broadcast of every subscribed repo's writes. This is the load-bearing mismatch: SHARING-SPEC §2's founding rule ("known people only... not a social network," I3 "unknown senders never reach the human") is the *opposite* of AT Protocol's default posture. A private PDS that never subscribes to or publishes on any relay is possible, but at that point it has re-derived shared-folder transport with a heavier identity/schema layer bolted on. Nothing AT-Protocol-specific is gained.
Q3 — sealing forced? Yes if attempted at all — records would need encryption before they ever leave the PDS, which is exactly the same age/e2e work every other untrusted-operator transport on this page already requires. AT Protocol's own machinery adds nothing on top of it.
What's worth a second look, separated from message transport entirely: the DID identity model as a possible future contact-id namespace (portable, person-owned, closer to the spirit of a contact-id than a phone number), and the repo/commit-log pattern as a possible alternate storage engine for exchange/ in a much later version. Neither requires adopting the public firehose transport.
Status: FUTURE, researched only — the furthest from build-readiness of the five; would require a private-PDS operating model, a custom lexicon, and a DID key-management story this catalog does not specify. REJECTED as message transport.
Same discipline as every technical page in this series: a claim is ENFORCED only when a test refuses the violation today; RECORDED is written down and honored by convention; FUTURE is researched or designed. The build has not started.
| Claim | Standing | Where |
|---|---|---|
| Shared-folder transport moves envelopes between paired archives, trust declared and enforced at send | ENFORCED | pna_share.py — I7/A10 |
| Text-message transport refuses to frame anything not sealed e2e; uniform distrust hardcoded | ENFORCED | pna_text_courier.py — test B1 |
| The three-question test applied to Signal, Google Calendar, Apple Calendar, AT Protocol | RECORDED | COURIER-CONCEPT-v0.1.md §2 — reasoning written down; nothing coded yet |
| Google/Apple Calendar as derived-output (post-agreement) targets | FUTURE | not specified |
| EventKit as the Apple-platform last-hop mechanism | FUTURE | not specified |
| AT Protocol DID as a contact-id namespace / repo-log as an exchange/ storage engine | FUTURE | research idea only, no spec |
| Real libsignal integration (X3DH/ratchet) for a higher-threat-model circle | FUTURE | explicitly deferred, reopen only if the threat model changes |
Good-faith security research is welcome through the main site's Write to us → security door — a safe harbor written into our Terms, §15.
Written July 12, 2026, as a research catalog. Nothing was built in that session. Two transport options are real and tested: shared-folder transport (built earlier, 88-test adversarial suite green) and text-message transport (built this week, 25 tests green). The other three candidates on this page were evaluated on paper against the same three-question test and rejected as message transport for named, specific reasons. Time was not the constraint.
Open design calls (Carmen's, recorded in COURIER-CONCEPT-v0.1.md §4; work continues while they wait): whether the Google/Apple Calendar derived-output integrations are worth speccing next · whether AT Protocol's identity model is worth a dedicated research session · confirming the Signal-properties-without-Signal-software judgment stands.