Live when you can, git when you cannot
Glitr has more than one way to move a message. You do not pick a mode in settings. The contact row tells you which path the next send will use — and whether git can save you if Live drops.
When both of you are here, a direct data channel carries text, receipts, and chunked files. When you are not, git-URL contacts still deliver. Groups stay on git either way. That split is the product: live when you can, git when you cannot.
Use this mental model: you ran into each other in the hallway, so you stop leaving notes on the door — but only the mailbox track still has a door to leave notes on.
Offline (git) — the mailbox
This is the path that still works if the other person is asleep — only for git-URL contacts when you have remotes.
- You write encrypted outbound into your repository and push.
- They fetch your repository when they next poll (or when you tap Poll now on their side).
- Delivery is as fast as git hosting and the poll interval — typically seconds, sometimes longer on a slow host or a large clone.
- History remains in the repositories. That is a feature (backup) and a responsibility (the host stores ciphertext).
You never write into someone else’s repository. api-core encrypts to them with crypto-cascade, writes outbound ciphertext on your repo, and their later poll decrypts into a sealed inbox. Send also keeps a sent copy on your side (sealed at rest).
Live — the direct link
When both apps are open and can form a peer connection, status shows Live. New 1:1 messages and files travel on that link. No outbound row for those lines. Receipts travel on the link too.
How you got Live matters:
| How you met | Broker | If the channel drops |
|---|---|---|
| Pair now (QR / paste / NFC) | Out-of-band invite (wu1:) | No git fallback — delivery stops until you are Live again |
| Git URL contact | Git signaling/ on each mailbox | Next send falls back to git |
For git-URL contacts with remotes, the introduction is yours:
- Each connected app publishes a signaling row for a contact on its own repository.
- The inner handshake (offer/answer, candidates) is encrypted to that contact.
- The other app’s poll decrypts rows addressed to it and completes the handshake.
- Status moves Connecting → Live.
Logout or disconnect deletes the signaling row. You are not leaving a permanent “call me” file after you close the door. One row per contact; refreshing it updates the handshake, it does not pile a new file beside the old one forever.
webrtc-core is that 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).
What rides the link
Chat bodies and file payloads on the data channel use the same recipient cascade as git outbound (AES → Signal → PQXDH, then RSA hybrid → ML-KEM), 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).
Live 1:1 file transfer can resume after a drop (file-transfers/). Soft cap is 32 MiB of plaintext. Progress in the thread updates about once a second. You can cancel; the other side stops.
Git attachments (offline DMs and every group send) write the file inside the outbound envelope instead. Groups never use the live file path.
Local sent and inbox still update so the UI does not forget what you just said (or attached). Git and live share one protocol session per contact so the ratchet does not fork.
If the channel dies and the contact has a git URL, the next text or file send is git again. You will see ticks follow the git table, not the live table. Pair-now contacts do not get that fallback.
What you have to do
Keep both sides open if you want Live. That is the only ritual.
For git-URL contacts you do not start a “call” to send live text. After a poll, status updates by itself. If it stays Connecting with both of you present, the network is not allowing the direct path — git still sends text and attachments.
NAT, corporate firewalls, and some mobile networks fail the direct path and succeed at git. That is expected on the mailbox track. On Pair now, the same network failure means you cannot deliver until ICE works or you switch to git contacts. Product ICE is STUN-only (no TURN in the messenger bundle).
What Live is not
Live is a data link for messages and files. Voice and video calls exist on an open live link and are in progress — treat them as experimental, live-only, and not a substitute for the mailbox.
Live also does not replace backups. Messages that only existed on a live link still get local sent/inbox writes; they do not rely on git outbound. Do not assume a host clone contains every live-only line unless you have synced in a way that persisted them.
Close a tab, lose a network, or wait until ICE gives up. The next send uses outbound again — if you have a mailbox.
How Live relates to git: Live vs offline. The handshake: Direct live links. The clock and ticks: Why not always instant. The crates: Network.


