Skip to content

Signing out and back in re-provisions the built-in agents with new keypairs — duplicate same-named bots accumulate permanently in channels #4815

Description

@juddkussrow

Summary

Each sign-in provisions a fresh set of the built-in agents (Bumble, Fizz,
Honey) with new keypairs, rather than reusing the ones that already exist.
The old identities are not removed from channels.

After three sign-out/sign-in cycles, one channel held nine bot members — three
copies each of three agents, all sharing display names.

This matters beyond tidiness: an @mention that matches two or more members
resolves to no p tag at all, so the agent is never notified. That failure is
completely silent — reported in #4814. This issue is the mechanism that
produces the condition #4814 describes, and it does so without any user error.

Evidence

managed-agents.json, grouped by name:

#   name    created_at            slug          pubkey     is_builtin
1   Bumble  2026-08-02T19:58:20   builtin:…     (empty)    True        ← definition
2   Fizz    2026-08-02T19:58:20   builtin:…     (empty)    True        ← definition
3   Honey   2026-08-02T19:58:20   builtin:…     (empty)    True        ← definition

5   Bumble  2026-08-02T20:01:18   None          f990a565   False       ┐ cycle 1
7   Fizz    2026-08-02T20:01:17   None          b00b07e6   False       │
9   Honey   2026-08-02T20:01:18   None          5d60ea0a   False       ┘

4   Bumble  2026-08-03T02:47:54   None          aa218e37   False       ┐ cycle 2
6   Fizz    2026-08-03T02:47:53   None          9c2937fa   False       │
8   Honey   2026-08-03T02:47:53   None          095ae155   False       ┘

Each batch is created within one second — this is automated provisioning, not
manual creation. Every batch mints a new keypair for an agent that already
exists.

A user-created agent behaves correctly. Probe, which I made myself, has
exactly one definition row and one instance row across the same period. Only the
built-ins duplicate.

The worse half: the local wipe does not clean the relay

The channel member list for the same channel:

3cd8a94f  owner
ed87d25a  bot   ← not present in managed-agents.json
e2ee30d9  bot   ← not present in managed-agents.json
0193ba91  bot   ← not present in managed-agents.json
eb619269  bot   ← not present in managed-agents.json
64a5f4b3  bot   ← not present in managed-agents.json
60cdd38d  bot   ← not present in managed-agents.json
9c2937fa  bot   ← Fizz, cycle 2
095ae155  bot   ← Honey, cycle 2
aa218e37  bot   ← Bumble, cycle 2

Six of the nine exist nowhere locally. They are orphans from earlier cycles:
"Sign out and wipe all data" removed the local rows, but channel membership lives
on the relay and survived.

The wipe dialog is accurate about what it does — "delete your identity key, all
agent settings, and cached data from this device"
— and silent about what it
doesn't. The practical result is that each cycle adds three permanent bot members
to a channel and destroys the only local handle for managing them. There is no
obvious path back from the UI.

Note also that the cycle-1 identities (f990a565, b00b07e6, 5d60ea0a) are
present in managed-agents.json but are not channel members, while six
channel members are absent from the file. The two stores have diverged in both
directions.

Reproduction

  1. Fresh install, sign in. Note the built-in agents' pubkeys and the channel member
    list.
  2. Sign out via Sign out and wipe all data.
  3. Sign back in with the same identity key.
  4. Compare: three new pubkeys for the same three display names, and the previous
    three still listed as channel members.

Repeat for a linear pile-up: 3 cycles → 9 same-named bots.

Impact

  • @Bumble in that channel is now three-way ambiguous, so it silently notifies
    nobody. Any workflow or user mention targeting a built-in agent fails with no
    error, no warning, and no log line.
  • The member list becomes unreadable — nine entries, three distinct names.
  • Orphaned bots cannot be cleaned up locally, since no local record of them remains.
  • Each is a distinct identity on the relay, so this is not purely cosmetic.

Suggested fixes

  1. Make built-in provisioning idempotent — key it on the built-in slug
    (builtin:…, already present on the definition rows) and reuse the existing
    instance rather than minting a new keypair.
  2. Reconcile on sign-in: if an identity for a built-in slug already exists as a
    channel member, adopt it instead of creating a sibling.
  3. Say what wipe does not cover. The dialog should state that channel
    memberships already published to the relay are not removed by a local wipe.
  4. Offer a way to remove a bot member from a channel when no local record
    exists — otherwise this state is unrecoverable through the UI.
  5. Warn on duplicate display names when a member is added to a channel. Cheap,
    and it would have surfaced all of this immediately.

Fix 1 is the root cause; fix 5 is the cheap guard that makes the whole class
visible.

Environment: Buzz Desktop v0.5.3, macOS, buzz.xyz hosted community.
Happy to provide the full managed-agents.json (redacted) and member dumps.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions