Summary
Two managed agents that have different keypairs and live in different communities share a single persona record. Renaming one of them renames the other. The agent identity is scoped per community and per install; the definition that names it is install-global and keyed by a value that is byte-identical everywhere.
Observed with two agents created from the built-in Welcome Team, on two separate machines and two separate relays.
Not a data-exposure issue
Stating this up front so severity is not misjudged: KIND_PERSONA (30175) is a member of SHARED_GATED_KINDS (crates/buzz-core/src/kind.rs:215), so persona events are author-only unless they carry exactly ["shared","true"], enforced at every relay read chokepoint. System prompts do not become readable across communities, no identity signs on the wrong relay, and no message crosses. What crosses is configuration — display name, and by the same path prompt/model/runtime.
Reproduction
- Install the built-in Welcome Team.
- Create an agent from one of its personas in Community A. It gets its own keypair.
- Create an agent from the same persona in Community B (separate relay; a second machine makes it more visible). It gets a different keypair.
- Rename the agent in Community A via the Agents view.
- The agent in Community B is renamed too.
Root cause — three factors converging
1. The definition store is install-global.
agents/personas.json, agents/managed-agents.json, and agents/teams.json are one file per install, with no per-community partition — while agents/retention/ is correctly partitioned into one database per community. The isolation boundary was drawn at events but not at definitions.
2. Editing an agent edits the shared persona.
The Agents view routes the edit through updatePersonaAndPublish (desktop/src/features/agents/ui/usePersonaActions.ts:195) — the shared definition, not the per-pubkey managed-agent record.
3. The persona d-tag is the bare team slug.
persona_d_tag (desktop/src-tauri/src/managed_agents/persona_events.rs:65) prefers source_team_persona_slug and only falls back to the record's UUID id. Every persona sourced from a built-in team therefore keys on a slug that is identical across every community and every install.
apply_inbound_persona (desktop/src-tauri/src/commands/personas/inbound.rs:342) then overwrites display_name, avatar_url, system_prompt, runtime, model, provider, respond_to, and parallelism on whatever record matches that d-tag.
rename in Community A
→ patches the one global persona keyed by the team slug
→ agent in Community B (different keypair, different relay) is renamed
The managed-agent path is correctly scoped by contrast — its d-tag is the agent pubkey (inbound.rs:365), so those events never collide.
Relay sync is not required to trigger this
The shared local file alone is sufficient: both agents resolve the same persona record on the same install. The kind:30175 sync (inbound.rs:22 — "so Device B inherits Device A's edits") extends the same collision across machines, but is not the origin.
This also means the per-community retention scoping does not mitigate it, even though that scoping is otherwise correct.
Suggested fix
Real fix: scope the persona d-tag. persona_d_tag should mix in the community (and arguably the install) rather than returning the bare team slug, so two agents instantiated from the same built-in persona in different communities occupy different coordinates.
Cheap mitigation: make the managed agent's own name authoritative for presentation, so a persona behaves as a template applied at creation rather than a live binding.
Worth deciding explicitly which of these is intended, since "built-in personas stay in sync across my devices" is plausibly a feature for the single-community case — but it should not reach across communities.
Not verified
I traced the Agents view to the persona update path but did not step through which exact form field the rename submits. The empirical behaviour (rename crosses communities) is confirmed; the precise UI field binding is inferred.
Line references are against 6c16354.
Summary
Two managed agents that have different keypairs and live in different communities share a single persona record. Renaming one of them renames the other. The agent identity is scoped per community and per install; the definition that names it is install-global and keyed by a value that is byte-identical everywhere.
Observed with two agents created from the built-in Welcome Team, on two separate machines and two separate relays.
Not a data-exposure issue
Stating this up front so severity is not misjudged:
KIND_PERSONA(30175) is a member ofSHARED_GATED_KINDS(crates/buzz-core/src/kind.rs:215), so persona events are author-only unless they carry exactly["shared","true"], enforced at every relay read chokepoint. System prompts do not become readable across communities, no identity signs on the wrong relay, and no message crosses. What crosses is configuration — display name, and by the same path prompt/model/runtime.Reproduction
Root cause — three factors converging
1. The definition store is install-global.
agents/personas.json,agents/managed-agents.json, andagents/teams.jsonare one file per install, with no per-community partition — whileagents/retention/is correctly partitioned into one database per community. The isolation boundary was drawn at events but not at definitions.2. Editing an agent edits the shared persona.
The Agents view routes the edit through
updatePersonaAndPublish(desktop/src/features/agents/ui/usePersonaActions.ts:195) — the shared definition, not the per-pubkey managed-agent record.3. The persona d-tag is the bare team slug.
persona_d_tag(desktop/src-tauri/src/managed_agents/persona_events.rs:65) preferssource_team_persona_slugand only falls back to the record's UUIDid. Every persona sourced from a built-in team therefore keys on a slug that is identical across every community and every install.apply_inbound_persona(desktop/src-tauri/src/commands/personas/inbound.rs:342) then overwritesdisplay_name,avatar_url,system_prompt,runtime,model,provider,respond_to, andparallelismon whatever record matches that d-tag.The managed-agent path is correctly scoped by contrast — its d-tag is the agent pubkey (
inbound.rs:365), so those events never collide.Relay sync is not required to trigger this
The shared local file alone is sufficient: both agents resolve the same persona record on the same install. The kind:30175 sync (
inbound.rs:22— "so Device B inherits Device A's edits") extends the same collision across machines, but is not the origin.This also means the per-community retention scoping does not mitigate it, even though that scoping is otherwise correct.
Suggested fix
Real fix: scope the persona d-tag.
persona_d_tagshould mix in the community (and arguably the install) rather than returning the bare team slug, so two agents instantiated from the same built-in persona in different communities occupy different coordinates.Cheap mitigation: make the managed agent's own
nameauthoritative for presentation, so a persona behaves as a template applied at creation rather than a live binding.Worth deciding explicitly which of these is intended, since "built-in personas stay in sync across my devices" is plausibly a feature for the single-community case — but it should not reach across communities.
Not verified
I traced the Agents view to the persona update path but did not step through which exact form field the rename submits. The empirical behaviour (rename crosses communities) is confirmed; the precise UI field binding is inferred.
Line references are against
6c16354.