Skip to content

fix(mobile): tag all candidates when an @mention is ambiguous - #4371

Closed
CryptoJones wants to merge 1 commit into
block:mainfrom
CryptoJones:fix/mobile-ambiguous-mention-resolution
Closed

CryptoJones wants to merge 1 commit into
block:mainfrom
CryptoJones:fix/mobile-ambiguous-mention-resolution

Conversation

@CryptoJones

Copy link
Copy Markdown

Fixes the mobile half of #4303.

The bug

_resolveMentions in mobile/lib/features/channels/send_message_provider.dart took the first profile whose display name matched and stopped:

for (final profile in cache.values) {
  ...
  pubkeys.add(profile.pubkey);
  break;                          // first match wins
}

There is no ambiguity detection. When two channel members share a display name, cache is a Map, so "the first match" is really "whichever entry the map happened to yield first" — and that decides which pubkey lands in the p tag.

Why it matters

Agents match mentions purely on p tags (event_mentions_agent in crates/buzz-acp/src/lib.rs). If the tag names the wrong identity, the intended agent never sees the mention — and nothing surfaces to the sender.

This was found in a community where five bot display names each resolved to two pubkeys: a live identity and a stale one left behind by a re-key. The observed behaviour was that some agents answered @Name and others silently never did, consistently, for hours. It read as "the agents are ignoring me". Mentioning the same agent in the same channel with an explicit pubkey got a reply in seconds.

The split was purely map ordering: names whose live profile happened to be enumerated first worked; the rest tagged a dead identity.

buzz-cli already handles this correctly — resolve_names_to_pubkeys returns a CliError::Usage listing the candidates, with the comment:

Lookup failures are fatal when mention processing is requested: publishing visible mention text without its intended p tag is worse than not sending.

Mobile silently did the thing that comment warns against.

The change

Collect every matching candidate instead of breaking at the first, and tag them all.

Erroring the way the CLI does would be more consistent, but the CLI's remedy is "retry with --mention <pubkey>" and mobile has no way to supply one — so failing would leave a duplicated display name permanently unmentionable from the phone. Tagging all candidates keeps the intended recipient reachable; the cost is a redundant p tag on the other identities sharing that name.

Channel-member scoping is unchanged, so candidates are still restricted to members of the channel being posted to.

Tests

Adds tags every candidate when a display name is ambiguous, which builds two members sharing a display name with the stale one deliberately ordered first — the production condition. Verified it fails against the previous behaviour (+1 -1 … [E]) and passes with the change.

  • dart analyze lib test — no issues
  • flutter test test/features/channels/send_message_provider_test.dart — 3/3 pass
  • Full flutter test — 1022 pass, 1 pre-existing failure in channel_detail_page_test.dart that reproduces identically on unmodified upstream/main

Note

This fixes mention resolution in the presence of duplicate display names. It does not prevent duplicate display names from existing — #4303 also covers agents archive reporting ok:true without applying, and archived identities still appearing in users get --name, both of which are relay-side and unaddressed here.

🤖 Generated with Claude Code

https://claude.ai/code/session_01SZQxkSFrkD6MHCLz6wbYkr

Proudly Made in Nebraska. Go Big Red! 🌽 https://xkcd.com/2347/

_resolveMentions took the first profile whose display name matched and
broke out of the loop. When two members share a display name — a stale
identity left behind by a re-key is the common case — "first match" means
whichever entry the user-cache Map happened to yield first, so the `p` tag
landed on an arbitrary one of them.

In practice this made mention delivery depend on map ordering: some names
resolved to the live identity and worked, others resolved to a dead one and
silently notified nobody. The agent never saw a `p` tag for itself, and
nothing surfaced to the sender to indicate the mention had gone nowhere.

buzz-cli rejects an ambiguous mention outright and directs the user to retry
with an explicit --mention <pubkey>, but mobile has no way to supply one, so
failing would leave a duplicated display name permanently unmentionable. Tag
every candidate instead: the intended recipient stays reachable, at the cost
of a redundant `p` tag on the identities sharing that name.

Adds a regression test that fails against the previous behaviour.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SZQxkSFrkD6MHCLz6wbYkr
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant