feat: add poll unvote updates#162
Conversation
|
Codex review: needs maintainer review before merge. Reviewed July 10, 2026, 3:11 PM ET / 19:11 UTC. Summary Reproducibility: not applicable. as a current-main bug because this PR introduces a new capability; the exact-head live A+B→B run and deterministic fixtures provide a high-confidence feature verification path. 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:
Risk before merge
Maintainer options:
Next step before merge
Security Review detailsBest possible solution: Merge the focused selective-unvote implementation with its exact-head A+B→B proof and full-snapshot regression coverage intact, while continuing to exclude add-option and other unproven poll mutation surfaces. Do we have a high-confidence way to reproduce the issue? Not applicable as a current-main bug because this PR introduces a new capability; the exact-head live A+B→B run and deterministic fixtures provide a high-confidence feature verification path. Is this the best way to solve the issue? Yes. Native poll mutations are full-selection snapshots, so reading the sender's latest snapshot, removing one validated option, and resending the remainder through a shared CLI and RPC path is the narrowest maintainable solution. AGENTS.md: found and applied where relevant. Codex review notes: model internal, reasoning high; reviewed against 39c205860904. Label changesLabel changes:
Label 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
Review history (15 earlier review cycles; latest 8 shown)
|
|
@clawsweeper re-review |
|
🦞🧹 I asked ClawSweeper to review this item again. |
|
@clawsweeper re-review |
|
🦞🧹 I asked ClawSweeper to review this item again. |
|
@clawsweeper re-review |
|
🦞🧹 I asked ClawSweeper to review this item again. |
|
@clawsweeper re-review |
|
🦞🧹 I asked ClawSweeper to review this item again. |
|
@clawsweeper re-review |
This reverts commit 6c98cdb.
ff5860c to
34f0b45
Compare
|
@steipete rebased #162 onto current What changed:
Verification:
|
|
@clawsweeper re-review |
|
🦞🧹 I asked ClawSweeper to review this item again. |
|
Thanks for narrowing this after #169. One semantic blocker remains: the requested option is validated but discarded for unvote; every option produces the identical Please reconstruct the active sender’s selected options, remove only the requested one, and send the remaining votes, or explicitly narrow the API to “clear all votes.” Required regression: A+B selected, unvote A, B remains; then exact-head sender/recipient proof. |
|
Addressed the selective unvote blocker in 4d85dc2. What changed:
Local verification:
@clawsweeper re-review |
|
🦞🧹 I asked ClawSweeper to review this item again. Re-review progress:
|
|
@clawsweeper re-review |
|
🦞🧹 I asked ClawSweeper to review this item again. Re-review progress:
|
Summary
imsg poll unvotepoll.unvote,polls.unvote, andmessages.poll.unvoteRedacted exact-head proof
Proof collected on lobster against exact head
1d38dc1in the realLobster Test GroupiMessage group with the branch-built universal CLI/helper. Raw logs are local under/Users/lobster/imsg-pr-proofs/2026-07-10/162-selective-unvote-*because they include chat GUIDs, message GUIDs, handles, and participant identifiers.Setup note: Messages.app has no public imsg command to create a multi-select poll snapshot. To create the required precondition, I used the branch helper's raw v2
send-poll-unvotebridge action once withremainingOptionIdentifiers=[Alpha,Beta]. The behavior under review was then exercised through the publicimsg poll unvotecommand.Fresh poll created on exact head:
{ "messageGuid": "CF492830-8495-4620-9F0A-A3DDCF3F5880", "poll": { "question": "PR162 A+B unvote proof 20260710-115344", "options": [ { "id": "1D130315-134B-4C52-8487-FB48A5F08E85", "text": "Alpha" }, { "id": "7E83A9E9-A665-4793-A734-F5F4BD2A9897", "text": "Beta" } ] } }Before state, read back from
imsg history --chat-id 22 --json, showed both selections in the native full snapshot:{ "guid": "41FA9252-E3E9-4563-8B7F-DDDEB984DCC7", "poll_guid": "CF492830-8495-4620-9F0A-A3DDCF3F5880", "poll": { "votes": [ { "option_id": "1D130315-134B-4C52-8487-FB48A5F08E85", "option_text": "Alpha", "event_type": "selected" }, { "option_id": "7E83A9E9-A665-4793-A734-F5F4BD2A9897", "option_text": "Beta", "event_type": "selected" } ] } }Public command under test:
./bin/imsg poll unvote \ --chat 'any;+;<redacted-group-id>' \ --poll CF492830-8495-4620-9F0A-A3DDCF3F5880 \ --option-id 1D130315-134B-4C52-8487-FB48A5F08E85 \ --jsonCommand output showed only Beta carried forward:
{ "removed": true, "optionIdentifier": "1D130315-134B-4C52-8487-FB48A5F08E85", "messageGuid": "D55975CD-5FF6-4976-92C6-6D812CE5ABFA", "remainingOptionIdentifiers": ["7E83A9E9-A665-4793-A734-F5F4BD2A9897"] }After state, read back from
imsg history --chat-id 22 --json, showed Beta remained and Alpha was absent:{ "guid": "D55975CD-5FF6-4976-92C6-6D812CE5ABFA", "poll_guid": "CF492830-8495-4620-9F0A-A3DDCF3F5880", "poll": { "votes": [ { "option_id": "7E83A9E9-A665-4793-A734-F5F4BD2A9897", "option_text": "Beta", "event_type": "selected" } ] } }SQLite proof for the public unvote row:
{ "ROWID": 6897, "guid": "D55975CD-5FF6-4976-92C6-6D812CE5ABFA", "associated_message_guid": "CF492830-8495-4620-9F0A-A3DDCF3F5880", "associated_message_type": 4000, "balloon_bundle_id": "com.apple.messages.MSMessageExtensionBalloonPlugin:0000000000:com.apple.messages.Polls", "payload_bytes": 670, "summary_bytes": 201, "chat_guid": "any;+;<redacted-group-id>" }Verification
make buildpassed on1d38dc1DEVELOPER_DIR=/Applications/Xcode.app/Contents/Developer make lintpassed; existing warnings only, 0 seriousDEVELOPER_DIR=/Applications/Xcode.app/Contents/Developer make testpassed: 409 testsgit diff --checkpassed