Meshbell Documentation

Meshbell is a neighborhood-scale emergency instrument. Its design principle is unusual for a consumer app: verification is the substrate, not a feature. This is how that works.

Overview

A hazard warning in Meshbell is a small, signed record — an assertion. Assertions are content-addressed (named by the hash of their own bytes), signed with a device key, and never altered: a correction is a new assertion that references the old one. That immutability is what lets a warning and its correction travel together across a mesh, and what lets any device re-check any message it receives.

Everything above the network is designed so that losing a connection, a server, or a model costs you an annotation, never the alert.

The trust model

Meshbell keeps two questions apart, because they are different facts and blurring them is how misinformation spreads:

QuestionWhat answers itWhat it can say
Which record is this, and is it intact?Content-address + signature check on your devicebound / preview / tampered
Who signed it, and can I check?The on-device keyringverified · could-not-check · forged

The second axis is deliberately three-valued. A forgery (checked against a known key, failed) is not the same as an unknown key (no way to check yet) — collapsing them into one "invalid" would hide exactly the distinction a person needs. A message is stored as trusted only when the keyring says verified.

Verified off the air, with no prior copy

A short radio frame is a preview — a pointer at a record. But a record can also be sent in full as a self-authenticating envelope, split across several frames and reassembled on the far side. A device that has never seen the record before can then reconstruct it, re-derive its content address, and verify its signature — reaching a verified verdict on a pure-radio neighborhood with no internet anywhere in the loop.

The instruction firewall

The one thing an emergency app must never do is turn a rumor into an order. Meshbell enforces this structurally, not by review discipline:

The promise, in one line: the app never launders a rumor into an instruction — and that sentence is a property of the code, not a mission statement.

The coordination layer

Verified alerts answer "what is happening, and can I trust it?" But a neighborhood in an emergency also has ordinary logistics to run: who's accounted for, where the shelter is, who has a generator. Meshbell carries a second, deliberately separate layer for that work — reachable natively in the app's Neighborhood tab, and in a browser for anyone without the app.

This layer is unverified by design. It is not content-addressed, not signed, and not part of the alert rail. It is mutable shared state that neighbors write and edit — treat it like a note taped to a door. The instruction firewall still holds: nothing here can ever render as an official instruction, and the trust model above governs alerts only.

What it holds

SurfaceWhat it isPrivacy shape
Safe roll-callOne-tap "I'm safe" check-in; everyone sees only an aggregate count against an approximate household total.No names, addresses, or locations. The count is withheld until a handful have checked in, so a single household can't be inferred.
Resource listsShared, editable lists — shelter/warming, water/supplies, power/charging, and a self-listed "who can help." Items can carry a place label.Anyone on the bridge can add or edit. Self-listed only; no one is added by someone else.
BoardShort posts tagged to a channel (info, offer, request, question) and windowed by recency, posted under a free-typed name.Whatever name you type — no account, no verified identity.
Printable snapshotA one-page /coord/print render of the roll-call, lists, and latest board, for when batteries die.Same aggregate-only roll-call; safe to post on a physical board.

Why it's held apart

Mixing mutable neighbor notes into a signed, append-only alert log would break both. So the coordination store is its own thing: LAN-only, mutable, and served by the bridge alongside — never inside — the verified feed. An operator holds an admin token for housekeeping (clearing test data, pruning a runaway board); posting and checking in need no credential at all. The two layers share a screen, never a trust boundary.

Working offline

Degradation is the expected state, not an error. When a data path is down, Meshbell serves the last known good data labeled with its age ("as of 40 minutes ago") rather than a confident-looking blank. The zero-ML tier — an old phone with no on-device model — is a first-class product tier: an emergency app that only works on the newest hardware fails the people most likely to need it.

Radios & hardware

Meshbell runs on your phone alone. Radios extend its reach when the network is down. A neighborhood mesh is built from inexpensive, off-the-shelf LoRa hardware running open MeshCore firmware:

PieceRole
A companion LoRa radio (e.g. a Heltec node)Your phone pairs with it over Bluetooth to send and hear bulletins on the mesh.
More radios around the neighborhoodEach one is a hop. Three or more begin to form real multi-hop reach across blocks and ridgelines.
An optional always-on node (e.g. a Raspberry Pi)Bridges the mesh to the wider internet whenever any uplink is available, and keeps a durable log — "the phone is the head, the mesh is the body."
US radio settings: Meshbell's reference bench runs 910.525 MHz, 62.5 kHz bandwidth, SF7 — inside the license-free 902–928 MHz band. Always read your radio's configuration back before transmitting; the region default may be a band you are not licensed to use.

Setting up a bridge

A "bridge" is one always-on node on the street — usually a Raspberry Pi — that carries the verified feed and the coordination layer over local Wi-Fi, so every neighbor's phone or browser can reach them with no cell and no internet. Meshbell is built so two very different people can get there without a manual.

If you're the host (one prepared neighbor)

The bridge installer ships inside the app. Guided setup walks you through flashing the node, and it comes up self-contained: it serves the app's coordination screens, an installable web app for browser-only neighbors, and an admin view for housekeeping. There is nothing to configure by hand and no account to create — the node advertises itself on the local network, and the app does the finding.

If you're a neighbor (never heard of a mesh)

Join the street's Wi-Fi and open the Neighborhood tab. The app looks for the bridge automatically and connects; the coordination screens are native, so they work even where a plain browser can't reach the node. When discovery needs a hand, the app offers plain-language diagnostics — is this the right network? is the bridge awake? — and a manual address field as a fallback, plus an in-app view of the browser web app if you'd rather use that.

The bridge delivers; it never decides. A bridge can pass a verified alert along, but it can't make one true — signatures are still checked on your own device, so a compromised or malicious bridge can drop or delay messages but can never forge a trusted one. That's why the trust model lives on the phone, not on the node.

Architecture

The domain logic is pure and portable — it builds and tests on a Raspberry Pi with no Apple hardware in the loop, so the parts that decide whether a message is trustworthy are verified continuously, not just at release. The iOS app is a thin renderer over it.

  • Canonical JSON (sorted keys, ASCII-pinned) gives every device a byte-identical pre-image, so a content address computed on a phone matches one computed on a node.
  • Ed25519 signing and verification, one implementation across Apple and Linux.
  • An append-only, insert-only log: records are never updated or deleted, so history — including corrections — is preserved and re-verifiable.
  • A cross-language conformance gate: the same frames are decoded by the app and by an independent Python node and asserted byte-for-byte, so the two can never silently drift.

Honest limits

Stated plainly, because an emergency tool that oversells itself is dangerous:

  • Meshbell is an early beta. It has carried a signed bulletin across real LoRa radios and verified it on a phone — but it is not yet a substitute for official emergency channels. Keep your existing alerts on.
  • Key distribution — how your device learns which public key belongs to whom — is an area of active work; a signature proves key-holding, and binding a key to a real identity is a separate, deliberate problem.
  • On-device signing keys live in the device keychain and are extractable by anything that can already read the app's keychain; we do not claim hardware-enclave protection we cannot deliver.
  • The coordination layer — the safe roll-call, resource lists, and board, native in the app and on the bridge — is unverified by design and separate from the signed alert rail: useful for logistics, never a source of official instruction, and not covered by the trust model above. It is LAN-only, so it reaches whoever is on the bridge, not the wider mesh.

← Back to the overview