Status: draft, pre-implementation. Nothing here has been run on two devices yet. The ledger merge (§10) and key rotation (§7) are the parts most likely to change under test; everything else is expected to survive with field-level edits. Wire encodings are provisional until 1.0 and will be versioned, not silently edited, from 1.0 on.
What this is. The rules two devices follow to work together after the infrastructure is gone: how they find each other, keep a family's traffic private, let a lost person be found, record a community's trade without money, and keep time when the satellites stop. It is hardware-independent. A phone running compatible firmware, a maker board, or the Civilization Seed Vault kit (the reference implementation, model CIV-SV-01) can all be Protocol nodes.
What it is not. Not a hardware specification, not a currency, not a rescue system. A registered 406 MHz PLB reaches satellite search-and-rescue; nothing in this Protocol leaves the mesh.
License. This text: CC BY 4.0. Reference implementation: published under the licences of its components (the mesh layer inherits GPL from Meshtastic).
t (type), v (Protocol version, integer, currently 0), ts (Unix seconds, integer) and tq (time quality: 0 unknown, 1 manual, 2 shortwave, 3 GNSS).by (the signing identity's 32-byte public key) and sig (64-byte Ed25519 signature over the deterministic CBOR of the record with sig — and, for co-signed records, all signature fields — removed). Co-signed records carry two by/sig pairs named for their roles.7K2QM-9X). Nodes display the short form and verify the long one.| Tier | Who | Protection | Carries |
|---|---|---|---|
| Open | anyone on the region preset | Meshtastic default (effectively public) | discovery; interop with strangers' nodes; cleartext beacon of last resort |
| Community | vouched nodes | AES-256 shared channel key, rotatable | market posts; ledger sync; notices; community voice notes; anchor records |
| Family | the kit's nodes | AES-256 shared channel key, rotatable | messages; positions; beacons |
| Direct | one node to one node | X25519 agreement, AES-CCM per Meshtastic PKI | private messages; ledger co-signing; rekey delivery; commands |
Channel keys protect content, not existence. Packet headers — sender, recipient, hop count — are cleartext, and the Protocol does not attempt to hide them: implementations MUST state in their user documentation that who-talks-to-whom is visible to any receiver. There is no forward secrecy at the channel tier; a captured node exposes the channels it holds until they are rotated (§7).
Records signed by identity keys (§4) are valid regardless of which channel carried them; the channel is transport, the signature is trust.
At kit provisioning: a family channel key, each node's keys, and a family root key are generated. The family root key and the initial channel keys are printed on a sealed recovery card and the root key is then erased from every node. Each family node's trusted list is seeded with the other family identities.
Over a physical pairing link (a cable between expansion ports) or over BLE with a six-digit numeric comparison. Both require approval on an existing trusted node, which then delivers the family channel key over Direct and adds the new identity to its trusted list; other family nodes learn the new identity by a signed trust record from the approving node.
trust record: t="trust", v, ts, tq, subject (public key), scope ("family"), by, sig.
A community is a channel key plus a set of vouch records. An admitting member (any member; communities may restrict this socially) issues the community key over a pairing link or PIN, and both parties sign a vouch:
vouch record: t="vouch", v, ts, tq, community (16-byte community id = SHA-256 prefix of the founding vouch), member (public key), voucher (public key), sig_member, sig_voucher.
A node presents its vouch chain on request. Membership is revoked socially: a revoke record signed by the original voucher removes the member from the voucher's trusted list; other members decide whether to honour it. The Protocol does not adjudicate.
When a person's device is lost or replaced, the family root key signs:
successor record: t="successor", v, ts, old (public key), new (public key), sig_root (family root key signature).
Nodes that hold the family root public key (all family nodes, and community nodes that received it in the founding vouch) treat new as old for trust and ledger purposes from the record's timestamp. The ledger balance of old carries over to new (§10.6).
lost (t="lost", subject, by, sig). Every receiving family node removes subject's keys from its trusted list.rekey record — t="rekey", channel ("family"), key_enc (the new key sealed to the recipient's mesh public key), by, sig — one record per remaining node. Rekeys MUST NOT be broadcast on the old channel: the lost node holds that key.wipe (t="wipe", subject, by, sig) from a trusted node: the subject node erases its keys, messages and ledger copy (the ledger is replicated elsewhere, so nothing is lost) and continues only its beacon, now on the Open channel in cleartext (§8.5). Being found beats being private.A three-second hold of a dedicated control; a cmd of beacon_on from a trusted identity; optionally, an impact detected by an IMU followed by five minutes without motion and an unanswered on-device prompt (opt-in; implementations MUST default this off because its false-positive rate will get it disabled).
t="beacon", v, ts, tq, seq (uint16, increments per frame), pos (optional: lat, lon as int32 in 1e-7 degrees, age seconds since fix, src 0 none/1 GNSS/2 anchor), batt (0–100), status (UTF-8, ≤ 40 bytes), pwr (transmit power in dBm, so that signal-strength readings mean something), by, sig. Fits one packet.
Every 30 s for the first hour; every 2 min until hour six; every 5 min after. Each frame is followed by a 2 s listen window for commands. The schedule backs off because the lost node's battery is the one that matters. Implementations MAY tighten the schedule while a seeker is actively exchanging commands.
The schedule is region-dependent: at Meshtastic's default preset a beacon frame is about 1 s of airtime, so the first hour is ~3.5 % duty — legal under US Part 15 and in the EU 10 % sub-band Meshtastic uses, and over a 1 % limit. Where a 1 % duty limit applies, implementations MUST start at ≥ 2 min. Nodes learn the limit from their region preset.
At or below 10 % charge, a beaconing node MUST shut down everything except the beacon schedule and its listen windows.
Beacons go on the Family channel. A node whose keys have been wiped continues beaconing in cleartext on the Open channel with the same frame minus sig.
A second three-second hold, or cmd beacon_off from a trusted identity; the node confirms audibly.
The seeker displays which tier it is on and the age of the data.
cmd strobe makes the beaconing node sound its speaker and flash its light, overriding any battery lockout.t="anchor", v, ts, tq, node (public key), lat, lon (int32, 1e-7 °), alt (optional, metres), method (1 GNSS survey / 2 map / 3 measured), by, sig. Gossiped on the Community channel. Anchors are surveyed while GNSS still works, or placed from a map.
t="cmd", v, ts, target (public key), cmd (ping, strobe, beacon_on, beacon_off), by, sig. Accepted only from the target's trusted list. ping elicits an immediate beacon frame.
t="tx", v, ts, tq, payer, payee (public keys), amt (integer, thousandths of the unit), unit (string: "h" for hours, or a community-defined unit code), memo (UTF-8, ≤ 64 bytes), nonce (8 random bytes), sig_payer, sig_payee.
A record with one signature is a proposal and has no effect. Both signatures make it a transaction. There is no unilateral entry, so there is nothing to double-spend.
Balance = Σ(received) − Σ(paid) over all valid transactions, computed locally. A community sets a credit limit (default −40 h) in its founding vouch. Before co-signing as payee, a node MUST show the payer's balance and limit and MUST refuse to co-sign a transaction that would take the payer below the limit unless the record also carries sig_override from a third trusted identity — which makes exceptions visible in the ledger.
Hours by default. A community may define at most one additional unit with a stated ratio in its founding vouch; implementations MUST refuse a third, because more units recreate money-changing.
t="dispute", ref (tx id), reason (≤ 120 bytes), by, sig — a signed statement that a record is contested, visible to all. Resolution is social. It closes with a correction: a new tx co-signed by both parties that references the disputed id in memo as re:<id>.
Ledger and market records form an append-only set per community. Nodes gossip on the Community channel:
t="sum", community, n (record count), h (XOR of all record ids), recent (up to 8 most recent ids).t="want" (list of ids, ≤ 12) and receives t="have" records in reply. Full reconciliation happens over a pairing link.This section is the one the partition test decides. Expected changes: the summary format and the request/reply budget.
Balances attach to identities. A successor record (§6.5) moves a balance. A wipe (§7) deletes a node's copy of the ledger, not the ledger.
Implementations MUST export the ledger as CSV (id, ts, payer, payee, amount, unit, memo) for anyone who needs to report it. Implementations MUST use the words credit, hours and balance and MUST NOT use money, coin, token or wallet in the user interface.
The Protocol defines no conversion to fiat, no operator, no fee, no custody, and no minting. Implementations that add any of these are not conforming and should not describe themselves as Protocol ledgers.
t="post", v, ts, tq, kind (offer/want), cat (category, ≤ 24 bytes), qty (≤ 24 bytes, free text), price (integer thousandths, or absent for "ask"), unit, loc (≤ 24 bytes hint), exp (expiry Unix seconds; default now + 7 days), by, sig. Withdrawn by t="unpost", ref, by, sig from the same identity. Nodes keep a per-category price history from posts and transactions so a community can see what a dozen eggs has cost over a season.
Playbooks are structured, cited decision trees; calculators are deterministic formulas with cited sources. They are content, not wire traffic, but conforming implementations share a schema so playbooks can be exchanged.
playbook: id, title, lang, ver, sources (list of {id, title, edition}), nodes (list of {id, text, options: [{label, next}], cite: [source ids]}), entry (node id). Every node cites at least one source. Rendering MUST be possible with a five-way control alone.
calculator: id, title, inputs (list of {name, unit, min, max}), formula (a reference to a named, reviewed formula in the implementation; never user-supplied code), cite. Calculators may compute doses; language models may not.
Time is a navigation instrument once satellites are gone (one second of clock error is ~0.46 km of longitude at the equator). Conforming nodes:
tq (§4).Encryption is permitted on unlicensed bands such as US Part 15 at 915 MHz; all Protocol traffic lives there. Encryption is prohibited on amateur bands (US Part 97) and not permitted on FRS/GMRS (Part 95): any voice module a node carries is a party line, and implementations MUST say so. Standard, published cryptography only; an export-classification check is required before hardware crosses a border. Regional LoRa presets and encryption legality both vary by jurisdiction.
Implementations state their level and their Protocol version. A Node that speaks 0.x is expected to break; from 1.0, records carry v and nodes MUST ignore records with a higher major version they do not understand rather than misinterpret them.