feat: add guarded contact-card probes#166
Conversation
|
Codex review: needs maintainer review before merge. Reviewed July 9, 2026, 7:35 PM ET / 23:35 UTC. Summary Reproducibility: not applicable. as a user bug. The PR body provides redacted live output and the diff gives a high-confidence patch review path, but I did not run local runtime tests in this read-only review. Review metrics: 3 noteworthy metrics.
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
Maintainer decision needed
Security Review detailsBest possible solution: If maintainers accept the partial contract, land the guarded status/share surface with fail-closed behavior and treat future real sharing support as a separate runtime-proven change. Do we have a high-confidence way to reproduce the issue? Not applicable as a user bug. The PR body provides redacted live output and the diff gives a high-confidence patch review path, but I did not run local runtime tests in this read-only review. Is this the best way to solve the issue? Unclear pending maintainer product direction. The fail-closed implementation is safer than invoking the blocking controller, and the remaining question is whether core should expose this partial surface now. AGENTS.md: found and applied where relevant. Codex review notes: model internal, reasoning high; reviewed against d9bd9c754d50. 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 (6 earlier review cycles)
|
|
@clawsweeper re-review |
|
🦞🧹 I asked ClawSweeper to review this item again. |
|
@clawsweeper re-review |
f45875d to
ffdcb7e
Compare
|
@clawsweeper re-review |
|
🦞🧹 I asked ClawSweeper to review this item again. |
|
Thanks @omarshahine. I’m closing this surface rather than shipping permanent endpoints that cannot perform or observe their advertised action. At The watcher finding is useful, but it should be a separate change. This branch adds a second 100 ms main-thread inbox scan beside the existing one—up to 20 directory scans per second—and still cannot rescue a genuinely blocked main thread. A follow-up should use one watcher, measure idle CPU/I/O and request latency, and include exact-head injected-bridge proof. |
|
@omarshahine — I'm sorry. I closed this too categorically and should have discussed your intent with you first. The branch had implementation problems, but I conflated “this patch should not merge as-is” with “this feature does not belong in imsg.” You were extending the BlueBubbles-compatible Messages Name & Photo surface, and your fail-closed live work exposed real selector and bridge-liveness problems. I've rebuilt the feature as #173. It fixes the existing nickname path, uses the verified Name & Photo selector family, keeps the watcher finding separate as a measured follow-up, and exposes sharing only as an explicit request. The PR is draft while I finish receiver-visible proof. I preserved your authorship and would especially value your review of the intended contract and sender-handle routing. Thanks for pushing this forward, and sorry again for shutting down the conversation instead of separating the useful findings from the patch shape. |
Important caveat
This PR does not make native contact-card sharing work on lobster. Live proof showed the private controller path can block Messages.app, so the implementation deliberately fails closed:
statusreports unavailable andsharereturns a clear error instead of attempting a send.Summary
imsg contact-card status|share --chat <guid>commands that expose the attempted surface without claiming share support is availablecontacts.shouldShareContactandcontacts.shareContactCard, withshareContactCardreturning unavailable on current macOS/lobster proofIMNicknameController.sharedController, which live proof showed can block Messages.appNSTimerso bridge RPC requests are consumed reliably after injectionRedacted runtime proof on lobster
Proof collected on lobster with branch-local artifacts from
feat/contact-cardafter relaunching Messages.app with the branch dylib. Raw logs stay local because they include chat GUIDs and local identifiers.f45875d/Users/lobster/imsg-pr-proofs/2026-07-08/166-contact-card/run-20260708-220445Lobster Test Group(chat row 22; GUID redacted in PR text)./bin/imsg launch --dylib "$PWD/bin/imsg-bridge-helper.dylib"pingrequest was consumed after adding the retained GCD inbox timer and returned{"success":true,"data":{"pong":true}}imsg contact-card status --chat <redacted> --jsonexited 0 and returnedavailable:false,controller_class_available:1,controller_available:false,should_share:null,status_probe_invoked:false, and all known contact-card selectors as falseimsg contact-card share --chat <redacted> --jsonexited 1 withContact-card sharing unavailable: private controller probing is disabled because it can block Messages.appcontact-card statuscould time out after resolving the chat becauseIMNicknameController.sharedControllerprobing blocked inside Messages.appRedacted status output:
{ "chat": "Lobster Test Group", "chat_id": 22, "chat_guid": "<redacted>", "controller_class_available": 1, "controller_available": false, "available": false, "should_share": null, "status_probe_invoked": false, "status_probe_reason": "selector availability only; private status selectors are not invoked", "probe_reason": "IMNicknameController.sharedController probing is disabled because it can block Messages.app", "selectors": { "sharingStateForChat:": false, "shouldShareMyNameAndPhotoWithChat:": false, "setShouldShareNickname:forChat:": false, "sharingStateForChatGUID:": false, "shouldShareNameAndPhotoForChat:": false, "shareNicknameWithChat:": false, "shareNameAndPhotoWithChat:": false, "shouldShareNicknameWithChat:": false, "shareMyNameAndPhotoWithChat:": false, "setShouldShareMyNameAndPhoto:forChat:": false } }Redacted share output:
{ "chat": "Lobster Test Group", "chat_id": 22, "chat_guid": "<redacted>", "success": false, "error": "Dylib error: Contact-card sharing unavailable: private controller probing is disabled because it can block Messages.app" }Verification
make build✅ on lobster forf45875dswift format lint --recursive Sources Tests TestsLinux✅git diff --check✅make lintLoading sourcekitdInProc.framework/Versions/A/sourcekitdInProc failedmake testTests/IMsgCoreTests/BridgeHelperLocatorTests.swift:2:8: error: no such module 'Testing'f45875d(macos, linux-read-core, and Socket checks passed)