Files
Toju/emergency-fix/08-messaging-visibility.md
T
myxelium e49b3ec112 chore: dev-stack switches, shared e2e harness, and desktop shell rules
- `LIVE_RELOAD=false npm run dev` keeps the renderer alive across a machine
  suspend; the reload client otherwise destroys the session under test.
- `dev-peer.sh` plus a separate userdata dir runs a second local peer.
- `tools/voice-probe.js` samples peer state and RTP counters from a live
  window, persisting to localStorage so a renderer reload cannot erase it.
- e2e helpers for voice pairs, peer-role election, and a TURN relay.
- Electron single-instance and dev-client-load decisions move into rules
  files with colocated specs.
2026-08-14 03:19:29 +02:00

4.3 KiB
Raw Blame History

08 — Messaging visibility (“messages not seen”)

User theme: “I sent a message but they dont 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 dont sync for multi-client users” root cause (serialized identify).

2 — Live works, history doesnt

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.