Skip to main content

How Glitr is assembled

Research, not an audit
These pages are research and development and may not match the live app. Do not treat this as an audit. Shared for testing and demo only. Please use responsibly.

Glitr is a messenger whose “cloud” is a git repository you own. This page is the product map: which pieces talk to which, and what each one is for.

It is not a protocol specification. Treat this as a picture of how the shipped stack fits together, not a claim of wire compatibility with the Signal app.

For the user story of mailboxes, ticks, and live links, start at Git as your mailbox. For what a host can see, see encryption visibility. The product threat model — assets, platforms, and residual risk — is Threat model.

The pieces​

These are the parts of the product path. Signal, ML-KEM, and PQXDH appear as libraries inside the recipient cascade, not as separate apps you run.

PieceWhat it does
whatsupThe Glitr client (web PWA, desktop, mobile, TUI). It hosts connect, chats, contacts, live pairing, calls, Local AI, and Drive. UI/UX
whatsup-uiThe chat chrome: lists, threads, ticks, pairing panels, file explorer, and the terminal frontend. UI/UX
glitr-clientShared session, poll, send, and UI adapter used by whatsup and the api-gallery story. Network
api-coreThe in-process messaging API: connect, profile, contacts, groups, send, poll, seal/unseal. It orchestrates storage and crypto. Network
db-coreA small GraphQL store over files. Documents and collections live in your git workdir. Types marked for sealing are password-wrapped on flush. Persistence
git-coreGit for that workdir. On a desktop it uses a native git library. In the browser it uses isomorphic-git and origin-private storage. Persistence
crypto-cascadeEncrypt to a person: AES → MLS → Signal → PQXDH (inner), then RSA hybrid → ML-KEM (outer). Pairwise MLS per contact. Cryptography
crypto-coreThe primitives: AES, RSA, Argon2id password envelopes, and a generic cascade manager. Password sealing for your files lives here. It is not part of the recipient stack. Persistence
mls (sibling library)RFC 9420 suite-1 façade (mls-core). Pairwise MLS inside 1:1 cascade; Glitr groups use N-party GroupSession with outer delivery seals. Cryptography, MLS formal verification
webrtc-coreThe live path: git-brokered signaling, a data channel, chat frames (text, receipts, and file offer/chunk/ack/complete/cancel/resume) that use the same cascade, adaptive chunking with backpressure, and a git fallback for text and files when the channel drops (git-URL contacts). Groups stay on git. Network
tor-coreNative Arti client. After login it bootstraps circuits, publishes one duplex hidden service per device, opens framed onion chat, and offers localhost SOCKS so git HTTPS can leave through Tor. The browser never links it. Network
ai (sibling library)On-device Local AI: browser ai-web (WebLLM chat + ORT image) and desktop ai-core (Candle). Not part of the mailbox or recipient cascade. Local AI
office (sibling library)Document, spreadsheet, slide, and notes engines plus office-ui hosts. whatsup opens Drive files through them. Not part of the recipient cascade. Drive and Office
glitr-websiteThis documentation site.
glitr-domainHosting for glitr.io and app.glitr.io. It is not a chat server.

Drive vault rows live in db-core (sealed drive/ + drive-blobs/). glitr-client exposes Drive ops; whatsup mounts the /drive tab and wires office / office-ui for open/save. Record shapes: Data structures.

The UI talks to api-core. api-core writes records through db-core, encrypts recipient payloads with crypto-cascade, and uses webrtc-core when both people are online. Native whatsup starts tor-core through glitr-client; api-core never links Arti. whatsup also hosts ai for on-device Local AI, and office for Drive editors — both in-process, not on the recipient cascade. Drive bytes still go through glitr-client → api-core → db-core like other sealed mailbox types. glitr-website and glitr-domain only publish this site.

Built as layers​

The product map above is the assembled stack. The crates were built in this order, each with a public gallery:

  1. UI/UX — whatsup shell and whatsup-ui chrome.
  2. Cryptography — Signal, ML-KEM, and PQXDH.
  3. Persistence — git, a crypto utility, and a GraphQL store (including the Drive vault).
  4. Network — schema-driven routes, git as a WebRTC broker, and native Tor.
  5. Local AI — on-device chat and image generation (WebLLM / Candle).
  6. Drive and Office — mailbox vault plus in-app document editors.

Git mailbox: send and poll​

You never write into someone else’s repository. You write outbound on yours. They keep a fetch-only clone of yours and ingest what is addressed to them. The product story is in Git as your mailbox; this is the same flow named by pieces.

Send also keeps a sent copy on your side (sealed at rest). Their poll writes inbox (also sealed). If they mark the message read, a read receipt appears on their repo; your later poll can drop the outbound row. Delivery ticks and latency live on Why not always instant.

Live path​

Git is a mailbox, not an instant messenger. When both of you are here, Glitr publishes a signaling row on each repo (offer or answer, already cascaded to the other person), completes a WebRTC handshake, and carries new chat bodies and file attachments on the data channel — the same cascade, not plaintext over DTLS. A file is sealed first, then the ciphertext is chunked; the data channel itself stays a text JSON frame (chunks are slices of that ciphertext).

Local sent and inbox still update so the thread does not forget what you just said. Incomplete file transfers persist in a sealed file-transfers collection so a dropped channel can resume. If the channel dies, the next text send is git again; files wait for Live. Details: Direct live links.

On native desktop and TUI there is a third live path that does not use ICE: onion pairing. Each device publishes a duplex hidden service. A QR or paste bundle (on1:) exchanges the .onion address. Chat frames on that link use the same cascade. There is no git mailbox fallback — if the circuit is down, delivery waits. Linux WebKitGTK often has no RTCPeerConnection; onion is the WebRTC-free path there.

Git, WebRTC, and onion share one protocol session per contact so the ratchet does not fork — see Data structures.

Two crypto jobs​

These must stay separate.

Recipient cascadePassword at rest
JobEncrypt a payload to a contactSeal your documents so a host is not reading the file
UnlockTheir public bundles and the shared sessionThe encryption password you type at connect
WhereOutbound, signaling, live chat bodies, live file payloadsContacts, inbox, sent, file transfers, Drive, profile secrets, protocol sessions

Stacking Signal plus a standalone ML-KEM wrap plus PQXDH is defense-in-depth, not a spec-recommended profile. PQXDH already includes X25519, ML-KEM-1024, and a ratchet. The extra layers are independent wraps on the same payload. Full wording: Signal and post-quantum. The encryption try path can toggle a password layer for teaching; the product recipient path never does.

Where it runs​

  • Cores are Rust libraries. They run in a desktop process and, compiled to WebAssembly, in the browser. tor-core is the exception: Arti, SOCKS, and hidden services stay in the native process. WASM never links it.
  • The browser app uses those WASM builds plus origin-private storage for the git workdir. Onion chrome is hidden. A web tab can only use Tor by proxying through a linked native device.
  • Try pages under Try Glitr open the product app for messaging, and Dioxus galleries for live, storage, and crypto. The galleries are how you press the buttons; they are not a second messenger.
  • glitr.io is this static documentation site. It does not hold mailboxes.

Next: the layer pages, starting at UI/UX. Record shapes stay on Data structures.