fix: Bug - User receiving direct call doesn't get notified (identity aliases)

Match incoming direct-call events against every local identity alias - home
id, entity id, peer id, and each provisioned signal-server actor id - instead
of only oderId||id. A caller who met the callee through a room on the
caller's signal server addresses the ring by the callee's provisioned actor
id, so the old admission check silently dropped it: the caller went "In
Voice" while the callee saw no modal, no ring audio, and no rail entry.
Incoming self aliases are normalized onto the canonical local id
(normalizeDirectCallPayloadSelfAliases) so they never appear as a phantom
third participant, and remoteParticipantIds / the DM-header peer lookup skip
all self aliases.

Adds a DM-header call ring e2e including the cross-signal topology (callee
homed on a secondary signal server) that fails on the old code.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-07-13 20:18:37 +02:00
co-authored by Cursor
parent 590e487250
commit 3e090933fd
7 changed files with 510 additions and 19 deletions
+7
View File
@@ -25,6 +25,13 @@ Durable rules for AI agents working on this project. Read this file at session s
## Lessons
### Match direct-call recipients against every local identity alias, exactly like DMs already do [direct-call] [identity]
- **Trigger:** "User receiving direct call doesn't get notified" — a caller who met the callee through a room on the caller's signal server addressed the ring by the callee's *provisioned actor id*; `handleIncomingCallEvent` admitted only `payload.participantIds.includes(oderId || id)`, so the ring was silently dropped, the caller sat "In Voice", and the callee saw nothing. DMs had the identical bug fixed earlier (`baa350e`), but the fix stopped at `DirectMessageService` and never reached `DirectCallService`.
- **Rule:** every self check on a cross-user event (admission, sender-echo filter, remote-participant filtering, DM-header peer lookup) must span all local aliases — home id, entity id, peer id, plus each `SignalServerCredentialStoreService.listValidCredentials()` actor id — and incoming aliases must be normalized onto the canonical local id before session state is keyed (`normalizeDirectCallPayloadSelfAliases`).
- **Why:** the failure only reproduces when caller and callee have different home signal servers, which no same-server e2e covers; and when one identity-alias bug is fixed in a domain, grep for the same `=== currentUserId` pattern in sibling domains that share the transport — the direct-call domain reused `PeerDeliveryService` but kept the naive check for another month.
- **Example:** `direct-call-participant-identity.rules.ts#directCallPayloadIncludesAnyId` / `normalizeDirectCallPayloadSelfAliases`; regression e2e `e2e/tests/voice/dm-header-call-ring.spec.ts` registers Bob on a secondary signal server, meets in a primary-signal room, and asserts the DM-header call rings Bob's incoming-call modal (fails on old code, passes after).
### Decide attachment receive admission once at request time; never re-gate size in the chunk handler [attachments]
- **Trigger:** "Sending files between users doesn't really work" — a browser user clicked Request on a 1050 MB generic file, the request gate (`canReceiveAttachment`) admitted it for in-memory receive, the sender streamed chunks, but `handleFileChunk` still had a leftover hard `size > MAX_AUTO_SAVE_SIZE_BYTES` rejection on the in-memory path, so every chunk was dropped, no ack was ever sent, the sender's `waitForAck` timed out, and the GUI never changed.