fix(poll): stamp vote balloon/payload on each responding target (macOS 26.4 regression)#150
Conversation
|
Codex review: needs maintainer review before merge. Reviewed July 2, 2026, 5:42 AM ET / 09:42 UTC. Summary Reproducibility: no. independent high-confidence reproduction was run in this Linux read-only review environment. Current main shows the exact one-target check and the PR supplies live macOS 26.4.1 before/after chat.db output for the failing and fixed paths. Review metrics: 3 noteworthy metrics.
Root-cause cluster Members:
Proposal only: this assessment does not dispatch repair, suppress jobs, mutate sibling items, close, or merge anything. 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 narrow helper fix after maintainer review accepts the supplied live macOS 26.4.1 proof, preserving fail-closed construction when either required field cannot be stamped anywhere. Do we have a high-confidence way to reproduce the issue? No independent high-confidence reproduction was run in this Linux read-only review environment. Current main shows the exact one-target check and the PR supplies live macOS 26.4.1 before/after chat.db output for the failing and fixed paths. Is this the best way to solve the issue? Yes: this is a narrow repair to the shipped private bridge helper rather than a new API, config path, or behavior mode. The main remaining question is maintainer acceptance of the private-runtime proof boundary. AGENTS.md: found and applied where relevant. Codex review notes: model internal, reasoning high; reviewed against 9452489d8f2e. Label changesLabel justifications:
Evidence reviewedWhat 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
|
Live proof (macOS 26.4.1)Same machine, same poll flow, from The pre-fix vote shipped with no Polls payload and never delivered, so it did not appear on the recipient's poll. After stamping each setter on every responding target, the vote carries the 7333-byte Polls payload, delivers, and is associated to the poll — confirmed registering on the recipient device across repeated sends. |
…r comment fold Makes native iMessage polls behave correctly end to end. What changed: - Inbound polls render with a numbered-options vote cue so the agent casts a native vote instead of answering the poll in prose. - poll-vote resolves the poll reference from pollId/pollGuid/messageId and now defaults to the current inbound poll message when the model omits it; still errors when no reference exists. - poll-vote echo suppression is session-scoped, so the redundant spoken answer is dropped across the separate poll and comment runs. - A poll's inline-reply caption is folded (not delivered as a standalone question) only when the poll creator and reply sender are both known and equal; unknown/mismatched sender falls through to the normal inbound decision gate, so no inbound reply is silently dropped. Evidence: - 64 passing tests in the poll suites (poll-comment, poll-render, actions), incl. sender fail-closed regressions; pnpm build clean. - Two Codex autoreviews clean (patch is correct); ClawSweeper re-review rated it platinum hermit. - Live-verified on macOS 26.4.1 on the deployed gateway: poll "What color pill?" -> native vote delivered with a 7333-byte payload, caption folded, zero echo. Note: vote delivery also depends on the imsg vote-stamp fix (openclaw/imsg#150); OpenClaw ships ahead of imsg per owner decision.
…r comment fold Makes native iMessage polls behave correctly end to end. What changed: - Inbound polls render with a numbered-options vote cue so the agent casts a native vote instead of answering the poll in prose. - poll-vote resolves the poll reference from pollId/pollGuid/messageId and now defaults to the current inbound poll message when the model omits it; still errors when no reference exists. - poll-vote echo suppression is session-scoped, so the redundant spoken answer is dropped across the separate poll and comment runs. - A poll's inline-reply caption is folded (not delivered as a standalone question) only when the poll creator and reply sender are both known and equal; unknown/mismatched sender falls through to the normal inbound decision gate, so no inbound reply is silently dropped. Evidence: - 64 passing tests in the poll suites (poll-comment, poll-render, actions), incl. sender fail-closed regressions; pnpm build clean. - Two Codex autoreviews clean (patch is correct); ClawSweeper re-review rated it platinum hermit. - Live-verified on macOS 26.4.1 on the deployed gateway: poll "What color pill?" -> native vote delivered with a 7333-byte payload, caption folded, zero echo. Note: vote delivery also depends on the imsg vote-stamp fix (openclaw/imsg#150); OpenClaw ships ahead of imsg per owner decision.
Co-authored-by: Omar Shahine <10343873+omarshahine@users.noreply.github.com>
a88b367 to
4b943dc
Compare
|
Maintainer proof for exact head
Contributor credit is retained in the commit trailer and changelog. |
|
Landed as Final proof for the landed tree:
Contributor credit is present in the squash commit and changelog. No release was performed. |
Problem
Casting a vote on a native Messages poll silently produced a vote with no balloon payload on macOS 26.4.x, so the associated
4000message shipped (is_sent=1) but never delivered (is_delivered=0) and never registered on the recipient's poll.Cause
buildPollVoteIMMessagestampsballoonBundleID+payloadDataonto the message after constructing it with the association-atomic initializer. The stamping loop required a single target to respond to both setters, otherwise itcontinued:On macOS 26.4.x the backing
_imMessageItemdoes not respond to both, so the loop fell through to the transientIMMessagewrapper — whose stamped values do not persist to the serialized item. The vote was emitted without the payload.Fix
Stamp each setter on every target that responds to it (item and/or wrapper), so both values land on whatever object serializes. Fail only if a value could not be stamped anywhere:
Evidence (macOS 26.4.1)
chat.db, same machine, before vs after:Confirmed live: the vote now carries the 7333-byte Polls payload, delivers, and is associated to the poll (bare poll GUID).