Skip to content

feat: set your Messages Name & Photo - #377

Merged
steipete merged 2 commits into
openclaw:mainfrom
kilianc:name-photo-set
Nov 5, 2026
Merged

steipete merged 2 commits into
openclaw:mainfrom
kilianc:name-photo-set

Conversation

@kilianc

@kilianc kilianc commented Nov 1, 2026 •

Copy link
Copy Markdown
Contributor

imsg name-photo set and the explicit contacts.setNamePhoto RPC can replace the account-wide Messages Name & Photo through the daemon's personal-nickname setter. An optional photo is staged for the transfer agent; an optional sharing setting is applied only after the daemon setter call returns.

The setter never runs implicitly from startup, status, discovery, or profile repair. Both entry points require the running helper's selectors.namePhotoSet capability before staging. The CLI rejects a chat target because this changes the account's identity. Invalid input, an unavailable daemon, and a refused daemon call leave the sharing setting untouched. Omitted last-name/photo fields remove those fields; omitted sharing preserves its setting.

The result distinguishes the request from a matching first/last-name echo. stored does not verify photo upload or recipient visibility, and has_photo describes the requested record. Setting the profile does not share it into a chat.

Validation: focused Swift Name & Photo, read/status, and bridge-protocol fixtures; isolated Objective-C setter fixtures with substituted private classes and a temporary home directory; lint and documentation tests; independent P0–P2 review. Regression fixtures reproduced missing capability checks and partial sharing mutations before the fixes. Full macOS and Linux checks run in this PR's GitHub Actions.

No live run happened during this maintainer pass. This Mac's Name & Photo and sharing setting were not changed, and no messages were sent. All proof used synthetic fixtures and no-send validation.

Thanks @kilianc for the implementation.

@kilianc
kilianc requested a review from a team as a code owner November 1, 2026 21:07
@clawsweeper

clawsweeper Bot commented Nov 1, 2026 •

Copy link
Copy Markdown

🦞👀
ClawSweeper picked this up.

Pull request received. I will update this pull request when review starts.

ClawSweeper review complete

ClawSweeper finished reviewing this revision. The review result is being finalized.

View the workflow run.

@clawsweeper clawsweeper Bot added clawsweeper:intake:feature Preliminary submission classification; full source review pending. P2 Normal priority bug or improvement with limited blast radius. merge-risk: 🚨 security-boundary 🚨 Merging this PR could weaken sandboxing, authorization, credentials, or sensitive data. rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. and removed clawsweeper:intake:feature Preliminary submission classification; full source review pending. labels Nov 1, 2026
@clawsweeper

clawsweeper Bot commented Nov 1, 2026

Copy link
Copy Markdown

Codex review: needs real behavior proof before merge.

What this changes

Adds CLI and RPC commands to replace the account’s Messages Name & Photo and optionally change its sharing setting.

Example: Run imsg name-photo set --first-name Ada --last-name Lovelace --photo ~/Pictures/ada.jpg --sharing on.

  • Before: The CLI can inspect or share an existing profile, but setting one requires Messages UI.
  • After: The CLI stages the photo, requests the profile replacement, and reports whether Messages echoed a stored record.

Review scores

Measure Result What it means
Overall readiness 🦪 silver shellfish (2/6) The live CLI replacement provides meaningful evidence, but the security boundary and acknowledgement defects block merge, and product direction remains undecided.
Proof confidence 🦐 gold shrimp (3/6) Real behavior proof is necessary before merge. See Before merge.
Patch quality 🦪 silver shellfish (2/6) Security review found an item that needs attention.

Product

Kind: Feature · Worth it: Needs a maintainer decision · Fix scope: Complete
User problem: An agent operating a headless Mac cannot create its account’s Messages Name & Photo without someone using the Messages UI.
Reason: The headless use case is concrete, but the new RPC contract and persistent sharing control need an owner decision.

Merge readiness

⛔ Blocked before merge - 6 items remain

Keep open: this PR adds a useful headless setup capability absent from main, but the photo-path protection and stored-result check need repair.

Priority: P2
Reviewed head: 4d638f9b4107cc75f34629db421bda348fcfb487
Owner decision: Required. See Decision needed.

Decision needed

  • Question: Should imsg expose personal profile replacement and the persistent sharing switch through name-photo set and contacts.setNamePhoto?
  • Recommendation: Approve the proposed capability: Accept explicit profile replacement and the optional sharing switch, subject to the listed repairs and proof.
  • Why: This adds a public RPC method and control over an existing Messages preference; no owner approval of this direction appears in the discussion.

Before merge

  • Add real behavior proof - The supplied terminal transcript exercises the real CLI, injected helper, and imagent on macOS 27.0.1, replacing an existing profile and retaining it after restart. It does not exercise the central first-profile creation case or rejection of a symlink targeting a photo outside the staging root before daemon I/O. RPC stopped before dispatch; its coverage is mocked. The contributor should add redacted terminal output or logs for the missing scenarios, removing phone numbers, keys, IPs, and non-public endpoints. After adding proof, update the PR body, then request a new review with @clawsweeper re-review. The PR author or someone with repository write access can request it.
  • Reject symlinked photos before handing their paths to imagent (P1) - A photoPath such as ~/Library/Messages/Attachments/imsg/staged/photo.jpg can be a symlink to a readable private JPEG elsewhere in Messages attachments. richLinkPathIsTrusted only checks the lexical prefix, and isReadableFileAtPath follows the link, so this request reaches the avatar initializer and setNewPersonalNickname instead of being rejected. Parent-directory symlinks work too. This bypasses the explicit symlink boundary already enforced by handleSendAttachment and handleUpdateGroupPhoto. Reuse the existing path protection and secure snapshot machinery before the daemon consumes the photo.
  • Match the stored acknowledgement to the requested profile (P2) - An earlier set request for Ada Lovelace with photo A can return stored:false after ten seconds while its daemon echo remains pending. If the next request sets Ada Byron with photo B, that earlier echo satisfies this predicate: the object changed and the first name is Ada. The second request then reports stored:true, potentially returning Lovelace as the stored last name while has_photo describes photo B merely because it was constructed. Compare a request-specific nickname or avatar identity and the requested profile fields before confirming storage; an unrelated or delayed echo must remain unconfirmed.
  • Resolve security concern: Preserve the same-UID photo boundary - The established threat model includes another local process substituting a symlink for an accepted attachment; the new setter passes that path into the account-profile upload flow.
  • Resolve maintainer decision - Resolve the maintainer decision shown above before merge.
  • Explain or restore the original intent of Helper photo-path security - 2432269: Reject symlinks at IPC and attachment boundaries to prevent same-UID exfiltration.

Findings

  • [P1] Reject symlinked photos before handing their paths to imagent — Sources/IMsgHelper/AccountHandlers.inc:392-396
  • [P2] Match the stored acknowledgement to the requested profile — Sources/IMsgHelper/AccountHandlers.inc:450-452
  • [high] Preserve the same-UID photo boundary — Sources/IMsgHelper/AccountHandlers.inc:392

Provenance

  • Helper photo-path security changes intended behavior without addressing why it exists (2432269: Reject symlinks at IPC and attachment boundaries to prevent same-UID exfiltration.)

Tests

  • Low-value test Tests/imsgTests/NamePhotoCommandTests.swift: The added source-string assertions at lines 427–447 pin implementation tokens without exercising the setter, delayed echoes, or symlink rejection; remove them in favor of behavioral regression coverage.
  • Missing end-to-end proof: Provide redacted shipped-entry-point output for creating the first profile on an unset account and rejecting a photo outside the staging boundary through a symlink; base-failing behavioral coverage for the two findings is also absent.
Agent review details

How this fits together

The CLI and stdio RPC server stage local photos and send bridge requests to the injected Messages helper, which calls imagent and reads the resulting personal nickname.

flowchart LR
  A[CLI or stdio RPC] --> B[Existing photo stager]
  B --> C[Messages attachment directory]
  A --> D[Bridge request queue]
  D --> E[Injected Messages helper]
  C --> E
  E --> F[imagent profile storage]
  F --> G[Nickname controller echo]
Loading

Technical review

Best possible solution:

Keep the existing command, registry, stager, and helper owners, but enforce their photo-path boundary and correlate stored confirmation with the exact requested profile.

Do we have a high-confidence way to reproduce the issue?

Main’s source confirms the missing setter; this is a feature request rather than a broken existing contract, and no target code was run during review.

Is this the best way to solve the issue?

Extending the existing bridge owners is a focused approach, but lexical path validation and first-name-only acknowledgement do not satisfy the proposed safety and stored-result contracts.

Full review comments:

  • [P1] Reject symlinked photos before handing their paths to imagent — Sources/IMsgHelper/AccountHandlers.inc:392-396
    A photoPath such as ~/Library/Messages/Attachments/imsg/staged/photo.jpg can be a symlink to a readable private JPEG elsewhere in Messages attachments. richLinkPathIsTrusted only checks the lexical prefix, and isReadableFileAtPath follows the link, so this request reaches the avatar initializer and setNewPersonalNickname instead of being rejected. Parent-directory symlinks work too. This bypasses the explicit symlink boundary already enforced by handleSendAttachment and handleUpdateGroupPhoto. Reuse the existing path protection and secure snapshot machinery before the daemon consumes the photo.
    Confidence: 0.97
  • [P2] Match the stored acknowledgement to the requested profile — Sources/IMsgHelper/AccountHandlers.inc:450-452
    An earlier set request for Ada Lovelace with photo A can return stored:false after ten seconds while its daemon echo remains pending. If the next request sets Ada Byron with photo B, that earlier echo satisfies this predicate: the object changed and the first name is Ada. The second request then reports stored:true, potentially returning Lovelace as the stored last name while has_photo describes photo B merely because it was constructed. Compare a request-specific nickname or avatar identity and the requested profile fields before confirming storage; an unrelated or delayed echo must remain unconfirmed.
    Confidence: 0.94

Overall correctness: patch is incorrect
Overall confidence: 0.95

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning medium; reviewed against 5af52a029b3d.

Provenance checked

  • Existing Name & Photo commands and sharing guards keeps the original intent (f6cc39e: Provide explicit-consent sharing, reject unsupported services and missing profiles, and distinguish submission from delivery.)
  • RPC descriptor registry keeps the original intent (b0165e4: Keep discovery, capabilities, request lanes, and dispatch under one descriptor-owned registry.)

Testing

Proof path: shipped entry point.

Security

Needs attention: The new avatar path bypasses the helper’s established symlink protection before a photo is handed to imagent.

Evidence

Security concerns:

  • [high] Preserve the same-UID photo boundary — Sources/IMsgHelper/AccountHandlers.inc:392
    The established threat model includes another local process substituting a symlink for an accepted attachment; the new setter passes that path into the account-profile upload flow.
    Confidence: 0.97

What I checked:

Likely related people:

  • Peter Steinberger: Raw commit cb58dec adds Sources/IMsgHelper/AccountHandlers.inc:48 relative to its recorded parents. This identifies author metadata, not feature responsibility or a PR merger. (role: source-line author; confidence: high; commits: cb58dec17663; files: Sources/IMsgHelper/AccountHandlers.inc)

Labels

Label changes:

  • add P2: This is an optional advanced bridge feature with concrete value for headless accounts and a limited affected surface.
  • add merge-risk: 🚨 security-boundary: The new photo-upload path accepts symlinks that existing attachment handlers reject under the repository’s documented same-UID threat model.
  • add rating: 🦪 silver shellfish: Overall readiness is 🦪 silver shellfish; proof is 🦐 gold shrimp and patch quality is 🦪 silver shellfish.
  • add status: 📣 needs proof: The PR needs real behavior proof before ClawSweeper can clear the contributor ask.

Label justifications:

  • P2: This is an optional advanced bridge feature with concrete value for headless accounts and a limited affected surface.
  • merge-risk: 🚨 security-boundary: The new photo-upload path accepts symlinks that existing attachment handlers reject under the repository’s documented same-UID threat model.
  • rating: 🦪 silver shellfish: Overall readiness is 🦪 silver shellfish; proof is 🦐 gold shrimp and patch quality is 🦪 silver shellfish.
  • status: 📣 needs proof: The PR needs real behavior proof before ClawSweeper can clear the contributor ask.

Rating scale

6/6 🦀 challenger crab · 5/6 🦞 diamond lobster · 4/6 🐚 platinum hermit · 3/6 🦐 gold shrimp · 2/6 🦪 silver shellfish · 1/6 🧂 unranked krab. Overall follows the weaker of proof and patch quality; ✨ marks media proof (a screenshot, video, or linked artifact) that directly shows the changed behavior.

Workflow

ClawSweeper edits this one comment on every review. Comment @clawsweeper re-review for a fresh review only. Repair and merge execution lanes are retired.

Reviewed November 1, 2026, 4:21 PM ET / 21:21 UTC.

steipete and others added 2 commits November 5, 2026 10:32
Add an opt-in CLI command and RPC method for replacing the account-wide profile. Check helper capability before staging, validate identity fields, and do not change sharing when the daemon cannot accept the setter request. Keep startup, discovery, and read paths free of identity mutations.

Cover the setter with isolated private-class fixtures and Swift safety tests. No live run happened, no messages were sent, and this Mac's identity was not changed.

Co-authored-by: Kilian Ciuffolo <kilian.ciuffolo@gmail.com>
@steipete
steipete merged commit fdd51c4 into openclaw:main Nov 5, 2026
7 of 8 checks passed
steipete added a commit that referenced this pull request Nov 5, 2026
Prepare imsg 0.21.0 for mentions, sticker placement, explicit Name & Photo setters, and the accumulated fixes. Preserve existing changelog entries and contributor credit, synchronize generated version metadata, and document that #365, #366, and #377 have fixture proof only with no live sends or identity changes.

Validation: all 316 existing changelog bullets preserved; version metadata agrees; docs tests pass; independent review has no actionable P0–P2 findings; macOS/Linux CI and CodeQL passed at 8fa910a.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

merge-risk: 🚨 security-boundary 🚨 Merging this PR could weaken sandboxing, authorization, credentials, or sensitive data. P2 Normal priority bug or improvement with limited blast radius. rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants