Threading the Flood: How Echomail Learned to Stay in Line

July 19, 2026

Federation is easy to demo and hard to make boring. The exciting part — a post appears on three servers — takes a weekend. The boring part, where the same post shows up in the right thread, with the right timestamp, exactly once, on every node, takes a month of small fixes. This is that month, told through echomail: Phosphor’s flooded, group-addressed message type, the modern replacement for the classic echo areas.

The problem in one sentence

Every node stores the same conversation independently, so every fix to “which thread does this belong to?” has to survive serialization, radios, and restarts — without a central authority to arbitrate.

Three separate defects made that hard, and each taught a lesson.

Lesson one: identity can’t be derived, it must be carried

The first threading bug looked like bad luck: replies arriving from remote nodes kept spawning new threads instead of joining the conversation. The cause was structural. We were deriving thread identity from a suffix of the message ID — so any difference in message ID construction between nodes (a rebuild, a re-send, a different path) produced a different thread key for the same logical conversation.

The fix was to stop deriving and start carrying. Echomail messages now include explicit threadUuid, postUuid, and parentUuid fields — real UUIDs minted once where the post was created and shipped with the message everywhere it goes. The wire format on constrained transports (MeshCore, our LoRa path) grew the same fields, compressed but present.

Now “which thread?” isn’t a guess based on message provenance — it’s data. Inbound messages that reference a thread UUID the node has never seen can still create the thread with the remote’s UUID, so when the rest of the thread arrives, every node agrees on identity without reconciliation.

The general rule: in a federated system, identity is part of the payload. Anything you compute from transport details will eventually differ between two nodes, and the divergence will look like a data bug when it’s really a protocol bug.

Lesson two: timestamps are content

The second defect was quieter: posts synced to a peer showed the sync time as their creation time. On a relay chain, a post could drift hours from when it was actually written — and thread ordering scrambled with it, because boards sort by timestamp.

The fix sounds trivial and wasn’t: preserve the original post timestamps through sync. The sender carries the original creation time in the message; the receiver writes it through instead of stamping now(). The subtlety is that some timestamps are legitimately new — the sync event, the local fetch — and those keep their own fields. Conflating “when this was written” with “when this arrived” is how you end up with a thread that reads backward.

Lesson three: routing needs two coordinates

The third defect was an over-delivery bug. An area name matched more than one board (or boards on different nodes configured the same area with different names), and inbound echomail landed on whichever board matched first — sometimes the wrong one, sometimes twice.

Routing now uses two coordinates: the sync area and the board name, instead of first-match on either. The board-side change pairs with a protocol change — board name travels in the echomail frame — so a message says exactly which board it belongs to, not just which area it transited. Combined with dedup on message ID, the same post can’t double-post even when two paths deliver it.

The boring parts are the product

None of this shows up in a screenshot. A user sees: replies stay in the thread, posts appear in the order they were written, nothing repeats. That’s the whole feature. Federation engineering is mostly making the unglamorous invariants hold — identity, time, and routing — because a community that can’t trust its own conversation history doesn’t have one.

Full post: https://phosphorbbs.net/blog/threading-echomail-uuids-timestamps-routing/

#BBS #federation #terminal #opensource #jterm #echomail