architecture

Standing on a protocol, not a silo.

Xoyo doesn’t invent a messaging protocol. It builds on Matrix, an open, federated standard with a decade of hardening behind its encryption, and adds the pieces Matrix deliberately leaves out: phone-first onboarding, push infrastructure, brandable clients, and a bridge into the organizational tools people already run.

The pieces, and why they’re shaped this way

Synapse: the Matrix homeserver

Rooms, history, device management, federation and the encryption machinery come from Synapse, the reference Matrix homeserver. We validated it hands-on before committing: multi-device encryption exercised end to end, with a direct database check confirming zero plaintext rows server-side. We deploy and configure it; we never fork it.

Xoyo server: the platform layer

An Elixir/Phoenix service that owns what Matrix doesn’t: phone verification, the device-token registry and push fan-out, the media pipeline, background jobs, and the Layer-2 bridge. It talks to Synapse over the Application Service API. Extension, not modification.

The bridge: thin by rule

The bridge translates and enforces policy between Matrix and Glific: envelope shapes, the session window, consent, interactive rendering, pacing, signing. It holds no business logic. A written six-item checklist is applied to every bridge change in review to keep it that way.

Clients: one codebase, any brand

The React web client and the React Native mobile client both read a typed brand config: name, icon, splash, colors, bundle identifiers. White-labeling is a build input, not a fork. This site’s header switcher runs on the same tokens.

The trust boundary is drawn in ink

An accepted decision record commits the UI to a rule: encryption is end-to-end between Xoyo users, and any room bridged to an organization is visibly marked. Consent to bridge is captured once, at signup. The product never implies blanket encryption where a bridge exists.

Verified, not just tested

A green test suite is treated as a compile check. Every change also runs a live smoke: two accounts register, message, exchange media byte-for-byte, verify cross-signing, round-trip the Application Service, and drive eleven bridge cases. Evidence is written as JSON per run.

Separate by decision, not accident

Xoyo shares no code or database with any other system, including Glific, which it bridges to. That separation is a recorded architecture decision. It keeps the bridge honest: an integration through a published contract, never a backdoor.

ADR-007

A fully separate system. Layer 1 is the network; Layer 2 is a thin bridge with no business logic.

ADR-008

Matrix on self-hosted Synapse. Apache-2.0 for everything we write; the homeserver stays an external dependency.

ADR-009

Encryption is device-to-device only and terminates at the bridge for bridged rooms. The UI must say so.

ADR-010

A verified phone number is the primary identity. Email is optional and secondary.

ADR-018

The bridge contract: Gupshup-v2-shaped JSON, bridge-side policy state, HMAC-signed webhooks. Shared with the Glific-side provider.

ADR-019 · proposed

Generalising the bridge into a public multi-integrator API. Under review; not built against until accepted.

Decisions are written down.

Every significant call lives in a numbered, immutable decision record in the repository. Join the project, or run a pilot, and you inherit the reasoning, not just the code.