Repair anchorless iMessage watch payload routing#86150
Conversation
|
Codex review: needs maintainer review before merge. Reviewed May 24, 2026, 7:05 PM ET / 23:05 UTC. Summary PR surface: Source +187, Tests +250, Docs +1. Total +438 across 5 files. Reproducibility: yes. source inspection plus the linked live report give a high-confidence reproduction path: current main accepts the chat_id=0, blank-anchor, is_group=false payload and can route it as a sender DM. I did not run live iMessage tests in this read-only review. Merge readiness Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch. Rank-up moves:
Mantis proof suggestion Risk before merge
Maintainer options:
Next step before merge Security Review detailsBest possible solution: Land the focused iMessage plugin fix after iMessage owner review accepts the fail-closed default, bounded recovery search, live proof, and regression coverage. Do we have a high-confidence way to reproduce the issue? Yes, source inspection plus the linked live report give a high-confidence reproduction path: current main accepts the chat_id=0, blank-anchor, is_group=false payload and can route it as a sender DM. I did not run live iMessage tests in this read-only review. Is this the best way to solve the issue? Mostly yes: repairing by GUID before debounce/routing is the narrowest maintainable fix boundary for the observed bug. The remaining decision is whether maintainers accept fail-closed drop and the bounded search limits as the default compatibility behavior. Codex review notes: model gpt-5.5, reasoning high; reviewed against 3c8d101f5a85. Label changesLabel changes:
Label justifications:
Evidence reviewedPR surface: Source +187, Tests +250, Docs +1. Total +438 across 5 files. View PR surface stats
What I checked:
Likely related people:
What the crustacean ranks mean
Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics. How this review workflow works
|
|
ClawSweeper PR egg ✨ Hatched: 🥚 common Velvet Proofling Hatch commandComment Hatchability rules:
Rarity: 🥚 common. What is this egg doing here?
|
ff1d9da to
c89bbe2
Compare
|
@clawsweeper re-review |
|
🦞🧹 I asked ClawSweeper to review this item again. |
Local verification on Lobster Mac (macOS, real iMessage account)Unit tests — Live
Live gateway regression — fast-patched the PR build into the running gateway, then sent a real iPhone message into a 3-person group chat: The anchored payload took the repair wrapper's pass-through path — no |
|
@clawsweeper re-review |
|
🦞👀 Command router queued. I will update this comment with the next step. Re-review progress:
|
|
Maintainer verification before merge:
Local proof run from the PR branch: node scripts/run-vitest.mjs extensions/imessage/src/monitor/conversation-repair.test.ts extensions/imessage/src/monitor.last-route.test.ts extensions/imessage/src/monitor.watch-subscribe-retry.test.ts extensions/imessage/src/monitor.gating.test.ts
node scripts/run-tsgo.mjs -p test/tsconfig/tsconfig.extensions.test.json --incremental --tsBuildInfoFile .artifacts/tsgo-cache/extensions-test.tsbuildinfo
pnpm lint:extensions:bundled
pnpm exec oxfmt --check CHANGELOG.md extensions/imessage/src/monitor/conversation-repair.ts extensions/imessage/src/monitor/conversation-repair.test.ts extensions/imessage/src/monitor/monitor-provider.ts extensions/imessage/src/monitor.last-route.test.ts
git diff --checkReal-machine proof on Lobster Mac:
Known proof note: the exact malformed bridge event is rare; proof uses real iMessage bridge/chat history plus a synthetic anchorless transform matching the reported failure shape, and a real anchored gateway group-message route check. |
Summary
Why
A group link-preview watch payload can arrive with
chat_id=0, empty conversation identifiers, andis_group=false. Without a pre-routing repair/drop guard, OpenClaw can treat the payload as a direct message and send the reply toimessage:<sender>instead of the originating group.Closes #84470.
Refs #84503.
Credit: this follows the bug report and mitigation direction from @zqchris and the contributor work in #84503 by @zhangguiping-xydt, but reapplies the fix on current
mainwith broader anchorless detection and route-level assertions.Verification
node scripts/run-vitest.mjs extensions/imessage/src/monitor/conversation-repair.test.ts extensions/imessage/src/monitor.last-route.test.ts extensions/imessage/src/monitor.watch-subscribe-retry.test.ts extensions/imessage/src/monitor.gating.test.tsnode scripts/run-tsgo.mjs -p test/tsconfig/tsconfig.extensions.test.json --incremental --tsBuildInfoFile .artifacts/tsgo-cache/extensions-test.tsbuildinfopnpm lint:extensions:bundledpnpm exec oxfmt --check CHANGELOG.md extensions/imessage/src/monitor/conversation-repair.ts extensions/imessage/src/monitor/conversation-repair.test.ts extensions/imessage/src/monitor/monitor-provider.ts extensions/imessage/src/monitor.last-route.test.tsgit diff --checkLive iMessage proof
Ran on the Lobster Mac against the live
imsg rpcbridge from this PR branch (c89bbe2862). The probe usedchats.listandmessages.history, built a synthetic anchorless payload from a real group-history message, and called the same repair helper added by this PR.Repair proof, redacted:
{ "ok": true, "sourceWasAnchorless": true, "repairedWasAnchorless": false, "groupCount": 3, "selectedChatId": 18, "repairedChatId": 18, "sourceGuid": "A3294...CCF2E5", "repairedChatGuid": "any;+...b7e6aa", "repairedIsGroup": true, "participantsRecovered": 8 }Fail-closed proof with a non-existent anchorless GUID, redacted:
{ "ok": true, "sourceWasAnchorless": true, "result": "dropped", "diagnosticCount": 1 }Re-verified locally with a fast-patched gateway (Lobster Mac)
Re-ran end-to-end against a different real group (3 participants) and exercised the wired-in code path on a live gateway.
Harness against the live
imsg rpcbridge (3 cases):guidpreservedchat_id,chat_guid,is_group=true, 3 participants in 2 RPC calls (chats.list+ 1messages.history)null) after scanning 10 chats; no fallback DM to senderLive gateway regression — fast-patched this branch's dist into the running gateway, then sent a real iPhone message into a 3-person test group:
Anchored payload took the repair wrapper's pass-through path — no
recovered anchorless/dropping anchorlesslog entries — and end-to-end routing was unchanged.