# 08 — Messaging visibility (“messages not seen”) > **User theme:** “I sent a message but they don’t see it / history missing / only some devices have chat.” > **Severity:** P0. --- ## How messaging is supposed to work (user view) ### Server text channels - Send in a text channel → everyone currently in that community sees it quickly. - If someone was offline or just joined, they still get recent history after connecting to peers (or from their other logged-in device). - Edits, deletes, reactions converge. - Typing indicators are ephemeral. - The **signal server does not keep a chat log** — history lives on clients. ### Direct messages - 1:1 and group DMs deliver even without a shared community when signaling can reach the peer. - Delivery ticks: queued → sent → delivered → acknowledged (monotonic). - Offline: queue until peer/network returns. ### Multi-device - Second device receives live + catch-up via `account_sync` when siblings are online. --- ## How messaging is supposed to work (system) | Path | Role | |------|------| | P2P `chat-message` / revisions | Primary live + sync plane | | WS `chat_message` | Narrow **live** fallback to room members | | Inventory / sync-batch | Catch-up on DC (limit 20_000, chunk 200) | | `account_sync` chat batches | Sibling devices | | DM PeerDelivery | DC → signaling → offline queue | Feature contract: `agents-docs/features/messaging.md`. Domain: `domains/chat/`, `domains/direct-message/`, `store/messages/`. --- ## Failure modes ### 1 — Invisible membership → no live fallback If identify/join failed (`04`/`05`), user is not in server membership → server never broadcasts `chat_message` to them; peers may not offer DC. **Classic “chats don’t sync for multi-client users”** root cause (serialized identify). ### 2 — Live works, history doesn’t DC down: live WS fallback OK; inventory never runs → “they only see new messages after refresh if a peer happens to sync later” / empty history for late joiners. ### 3 — Sync poll too slow after “clean” cycle Fast poll 10s while catching up; **15 min** when clean. A false “clean” leaves long windows without repair. ### 4 — Cross-signal identity forks DMs Incoming DM `conversationId` carries foreign actor id → second empty thread; replies invisible on the thread the user is watching (`09`). Lessons claim canonicalize/merge — **symbols not in tree**. ### 5 — Recipient alias miss DM/call ignored if local admission only checks home id. Inbound DM aliases largely fixed; verify call + any new surfaces. ### 6 — Attachment-only emptiness Message text arrives; image stuck “Waiting…” — announce/bind race (lesson). Looks like “message incomplete / not really received.” ### 7 — NgRx prune confusion Inactive rooms pruned to 100 messages in memory; DB still has more. User switching rooms may think history vanished until reload/sync — document vs bug. ### 8 — Doc lie on inventory cap Chat domain README still says **1000**; code `INVENTORY_LIMIT = 20_000`. --- ## Investigation checklist (agents) 1. Did both users `identify` + `join_server` on the **same** signal URL as the room? 2. Is there an open DC between them? (`connectedPeers`, debug metrics) 3. Does live send emit both DC and `chat_message`? 4. On receive, is `roomId` in saved/current rooms? 5. For DM: conversation id aliases; delivery state machine stuck at QUEUED? 6. Multi-device: `account_sync_peer_online` fired; batches received? --- ## Proof of done 1. Two clients: send N messages with DC disabled (force) → live still appears via WS. 2. Re-enable DC → inventory brings missing history. 3. Third client late join → receives recent history from a peer with DB. 4. Cross-home users in foreign room: messages visible both ways without authorize prompt. 5. Cross-signal DM: single conversation thread; replies visible to both. 6. Multi-device: second device gets `chat-sync-batch` after identify. 7. Regression covering identify-before-join (presence + chat broadcast). --- ## Fix order 1. Auth + identify (`04`/`05`) — without presence, messaging “fixes” are theater. 2. Ensure fallback + DC resync on repair (`07`). 3. Identity canonicalize for DMs (`09`). 4. Attachment re-queue invariants. 5. Correct stale chat README inventory number.