fix(imessage): avoid DM self-chat false positives#61619
Conversation
Greptile SummaryFixes iMessage DM self-chat false positives by using Confidence Score: 5/5Safe to merge — additive fix with no breaking changes, backward-compatible fallback, and targeted test coverage for both the false-positive and true self-chat shapes. No P0 or P1 issues. The new isSelfChat condition correctly handles all three cases (true self-chat, DM false-positive, legacy payload without destination_caller_id), the type/parser/decision layers are aligned, and two new tests lock in the regression surface. No files require special attention. Reviews (1): Last reviewed commit: "fix(imessage): avoid DM self-chat false ..." | Re-trigger Greptile |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 4d73fe8682
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 10fedad565
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
60c12d5 to
322e6a8
Compare
🔒 Aisle Security AnalysisWe found 1 potential security issue(s) in this PR:
1. 🟡 Unbounded participant list normalization can cause CPU/memory DoS in self-chat detection
Description
Because
can trigger excessive allocations and CPU work (mapping + normalization + Vulnerable code: const chatParticipantHandles = new Set(
(params.message.participants ?? [])
.map((participant) => normalizeIMessageHandle(participant))
.filter((participant): participant is string => participant.length > 0),
);RecommendationAdd defensive limits before processing untrusted arrays/strings, and avoid building the Example: const MAX_PARTICIPANTS = 64;
const MAX_HANDLE_LEN = 256;
const rawParticipants = Array.isArray(params.message.participants)
? params.message.participants.slice(0, MAX_PARTICIPANTS)
: [];
const chatParticipantHandles = new Set(
rawParticipants
.map((p) => (typeof p === "string" ? p.slice(0, MAX_HANDLE_LEN) : ""))
.map((p) => normalizeIMessageHandle(p))
.filter((p): p is string => p.length > 0),
);Also consider only constructing Analyzed PR: #61619 at commit Last updated on: 2026-04-09T11:44:18Z |
obviyus
left a comment
There was a problem hiding this comment.
Reviewed latest changes; landing now.
|
Landed on main. Thanks @neeravmakwana. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 322e6a89eb
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| destinationCallerIdNormalized == null || | ||
| destinationCallerIdNormalized === senderNormalized || | ||
| chatParticipantHandles.has(destinationCallerIdNormalized); |
There was a problem hiding this comment.
Exclude DM participant lists from self-chat classification
matchesSelfChatDestination currently treats destination_caller_id appearing in participants as proof of self-chat, but that also matches normal 1:1 DM payloads where participants contains both the peer and the local handle. In that shape, outbound is_from_me=true rows with sender===chat_identifier are still classified as self-chat and can be dispatched on an echo-cache miss, reintroducing the DM self-echo/loop path this change is trying to prevent. This severity applies when imsg emits full participant arrays for those DM rows.
Useful? React with 👍 / 👎.
) * fix(imessage): avoid DM self-chat false positives * fix(imessage): treat blank destination caller id as missing * fix(imessage): preserve alias self-chat * fix: preserve iMessage self-chat aliases (#61619) (thanks @neeravmakwana) --------- Co-authored-by: Ayaan Zaidi <[email protected]>
…eravmakwana) * fix(imessage): avoid DM self-chat false positives * fix(imessage): treat blank destination caller id as missing * fix(imessage): preserve alias self-chat * fix: preserve iMessage self-chat aliases (openclaw#61619) (thanks @neeravmakwana) --------- Co-authored-by: Ayaan Zaidi <[email protected]>
…eravmakwana) * fix(imessage): avoid DM self-chat false positives * fix(imessage): treat blank destination caller id as missing * fix(imessage): preserve alias self-chat * fix: preserve iMessage self-chat aliases (openclaw#61619) (thanks @neeravmakwana) --------- Co-authored-by: Ayaan Zaidi <[email protected]>
…eravmakwana) * fix(imessage): avoid DM self-chat false positives * fix(imessage): treat blank destination caller id as missing * fix(imessage): preserve alias self-chat * fix: preserve iMessage self-chat aliases (openclaw#61619) (thanks @neeravmakwana) --------- Co-authored-by: Ayaan Zaidi <[email protected]>
…eravmakwana) * fix(imessage): avoid DM self-chat false positives * fix(imessage): treat blank destination caller id as missing * fix(imessage): preserve alias self-chat * fix: preserve iMessage self-chat aliases (openclaw#61619) (thanks @neeravmakwana) --------- Co-authored-by: Ayaan Zaidi <[email protected]>
…eravmakwana) * fix(imessage): avoid DM self-chat false positives * fix(imessage): treat blank destination caller id as missing * fix(imessage): preserve alias self-chat * fix: preserve iMessage self-chat aliases (openclaw#61619) (thanks @neeravmakwana) --------- Co-authored-by: Ayaan Zaidi <[email protected]>
Summary
imsgreports the peer handle in bothsenderandchat_identifier.destination_caller_idwhen available to distinguish true self-chat from DM false positives, and it preserves that metadata in the parsed payload.destination_caller_id.Change Type (select all)
Scope (select all touched areas)
Linked Issue/PR
Root Cause (if applicable)
resolveIMessageInboundDecision()treatedsender === chat_identifieras sufficient proof of self-chat, but currentimsgpayloads can use the peer handle for both fields in a normal DM outbound row.destination_caller_id, which is the field that differentiates a real self-chat from this DM false positive.Regression Test Plan (if applicable)
extensions/imessage/src/monitor/self-chat-dedupe.test.ts,extensions/imessage/src/monitor.gating.test.tsis_from_me=trueDM rows withsender===chat_identifierbut a differentdestination_caller_idmust still take the normalfrom medrop path, while real self-chat still dispatches.User-visible / Behavior Changes
imsgprovides a differentdestination_caller_id.from medrop path and avoids self-echo loops caused by cache misses.Diagram (if applicable)
Security Impact (required)
NoNoNoNoNoYes, explain risk + mitigation:Repro + Verification
Environment
imsgSteps
imsgreports an outbound row with the peer handle in bothsenderandchat_identifier.is_from_me=truerow.from medrop path.Expected
from me.Actual
from mewhendestination_caller_idpoints at a different local handle.Evidence
Attach at least one:
Human Verification (required)
node --import tsxrepro againstresolveIMessageInboundDecision()for the reported DM false-positive payload shape and for the true self-chat shape; the DM case now drops asfrom meand the true self-chat case still dispatches.destination_caller_id; current fallback behavior remains unchanged when that field is absent.pnpm test,pnpm test:extension imessage, and a focused Vitest invocation) stalled after Vitest startup in this environment, so I did not get a completed test summary from those commands.Review Conversations
Compatibility / Migration
YesNoNoRisks and Mitigations
Risk: older
imsgpayloads that omitdestination_caller_idstill rely on the legacy heuristic.Risk: this assumes
destination_caller_idis the local sending identity for the normal DM false-positive shape.is_from_meself-chat classification only.AI Disclosure
This PR was prepared with AI assistance and reviewed before submission.
Made with Cursor