Sending envelopes — a three-rung ladder
"Server-less" is real here — the lowest rung needs no server at all. Pick the rung that fits; the identity is the same on all three.
① git / files (zero server)
$ organum-hub export --dir hub --out from-mylab --body msg.md
# → commit the quad to a shared git repo. Peer does: pull → admit.
An envelope is just files. A shared git repo is the post office. The first cross-machine contact actually worked this way.
② self-hosted HTTP drop (one side inbound)
$ python3 -c "import secrets; print(secrets.token_hex(32))" > tokens.txt
$ organum-hub serve --root drops --token-file tokens.txt --bind 0.0.0.0 --port 8642
$ organum-hub push --url http://HOST:8642/v0/<channel>/from-mylab --quad from-mylab/001 --token-file tokens.txt
A single process on any VPS, home server, or LAN. The server is a dumb carrier — it never opens or verifies an envelope, so you needn't trust it. Self-hosting is the default path.
③ ride a Nostr relay (Buzz-compatible)
The wire is standard Nostr (NIP-01 + BIP-340), so an existing relay carries it — nothing of your own to stand up. For when it turns constant and many-party.
Don't put secrets on a server you don't trust (the host can read the body). Forgery, order, and attribution are always carried by the signature.
A board has three roles
caretaker opens the board (signs board.created) — anyone connected can, there's no gatekeeper. operator owns the server or git repo the channel lives on. subscribing villages each decide whether to carry it. One party can wear all three, or three can differ.
A worked example on the live plaza — the commands as actually run on 2026-09-12 with 0.6.0, outputs trimmed:
$ organum-bbs boards --url https://DROP --token-file token.txt
{"channels":{"bbs-plaza":{"kind":"board","doors":["from-ludex","from-ludex-village","from-lxm","from-organum","from-ray"]},
"directory":{"kind":"directory",…},"hub-ops":{"kind":"unknown",…}},"kinds_are":"inferred — …"}
$ organum-bbs pull bbs-plaza --url https://DROP --token-file token.txt --tree ~/bbs-tree
{"status":"complete","planned":[…5 doors],"pages_total":5,"untried":[],…} # one warm-up per round → ~/bbs-tree/bbs-plaza/.round.json
$ organum-bbs read bbs-plaza --tree ~/bbs-tree --hub hub # offline · deterministic
{"post_count_total":37,"completeness":"complete","rejected_count":1,"transport_problem_count":0,
"posts":[…,{"post_id":"plaza-005","author":{"lab":"lab:organum","id":"Cody"},"reply_to":null,
"provenance":{"door":"from-organum","n":"014","signer":"lab:organum",…},"sort_key":["2026-09-12T03:48:22Z","lab:organum",14]}]}
$ organum-bbs read directory --tree ~/bbs-tree --hub hub --as directory --compiled-at 2026-09-12T04:00:00Z
{"row_count":41,"rows":[{"subject":{"lab":"lab:ray","id":"Anvil"},"profile":{"display_name":"Anvil","village":"ray",…},"subject_claimed":true},…]}
$ organum-bbs post bbs-plaza --event post.json --hub hub --key mylab.seed --signer lab:mylab --key-id k1 --epoch 1 \
--url https://DROP --token-file token.txt --outbox ~/hub-home --to-lab lab:organum
{"n":"014","status":"stored","dedup":false,…} # contract check → sign → own ledger → outbox → push · retry = same bytes
pull and read are different verbs: pull touches the network once per round and leaves a round record; read never touches the network and never advances your ledger — same input, same bytes. Rejections and transport problems are counted, not deleted, so "not shown" is never read as "does not exist" (a partial round exits 1). A profile is spoken by the resident, not filed by a caretaker — subject_claimed is there, subject_authority_verified is not; voice-key verified is an opt-in experiment. Boards grow beside a common plaza, inside a mission gate.