Persona definition (kind:30175) force-syncs model/provider/prompt to every device, collapsing per-device instance configs
- Dominant language
- Rust
- Stars
- 32.7k
- Forks
- 4.3k
- Avg merge
- 1d 13h
- Merged PRs (30d)
- 253
Description
## Summary
Persona definition events (kind:30175) are applied **unconditionally** on every receiving device, overwriting the local persona record's `model`, `provider`, `system_prompt`, `runtime`, `respond_to`, `parallelism`, `shared` and more — not just `display_name`. For the common two-device setup (same owner, same community, one local agent instance per device, each with its own independently minted keypair), editing the model/provider on device A silently rewrites the configuration of device B's instance. The two instances are separate identities (separate pubkeys) but their configuration is force-merged into a single definition.
## Environment
- Buzz Desktop, same owner identity on two devices (Windows + macOS) in the same community
- Local source verified at `main` @ `7bee84d` (`desktop/src-tauri/src/commands/personas/inbound.rs`)
## Observed behavior
1. Each device mints its own agent instance keypair for a persona (builtin agents: one keypair per machine × community), so the *identities* are distinct.
2. The persona definition is shared: `display_name`, **`model`**, **`provider`**, `system_prompt`, `runtime`, `respond_to`, `respond_to_allowlist`, `parallelism`, `shared`, `avatar_url`, `name_pool` all come from the single relay-side definition (kind:30175).
3. When the owner edits the model on device A, device B receives the kind:30175 event and **overwrites** its local persona fields — including `model`/`provider` — with no merge, no conflict handling, and no "local override" concept.
4. Net result: per-device agent instances that should be independently configurable are collapsed into one globally-synced configuration. The name sync is only the visible tip; the configuration sync is the same code path with more fields.
## Root cause
`apply_inbound_persona` (`desktop/src-tauri/src/commands/personas/inbound.rs`, ~L342-364) overwrites these fields on any local record matching the persona d-tag:
```rust
local.display_name = inbound.display_name;
local.avatar_url = inbound.avatar_url;
local.system_prompt = inbound.system_prompt;
local.runtime = inbound.runtime;
local.model = inbound.model;
local.provider = inbound.provider;
local.name_pool = inbound.name_pool;
local.respond_to = inbound.respond_to;
local.respond_to_allowlist = inbound.respond_to_allowlist;
local.parallelism = inbound.parallelism;
local.shared = inbound.shared;
local.updated_at = inbound.updated_at;
```
Only `id`, `env_vars`, `source_team`, and `created_at` survive. On no match the record is inserted as-is (`None => personas.push(inbound)`).
The instance path is deliberately asymmetric: `apply_inbound_managed_agent` (same file, ~L381-405) is a no-op when there is no local record (an instance without a local secret key is useless), and for definition-linked events it does **not** carry the prompt/model/provider quad — those fields resolve through the kind:30175 definition. So `model`/`provider` live exclusively in the shared definition layer, which means "one definition, identical everywhere" is guaranteed by construction.
This asymmetry is documented as intentional (see the comment on `apply_inbound_managed_agent`), which is why this is a design problem rather than a one-line bug: the model field is in the wrong layer for the per-device-instance use case.
## Why the existing issues don't cover this
- **#5128** ("Agents tab is not community-scoped…") is about *per-instance* settings (e.g. `start_on_app_launch`) being written to the **wrong instance** because the profile UI preselects the wrong identity. The data model there is per-instance and correct — the defect is selection/presentation. It never mentions model/provider sync.
- **#3753** ("Managed-agent instance config (kind:30177) never syncs cross-device…") is the *reverse* direction: instance config does not propagate, so every device offers a duplicate unconfigured instance. Its root-cause analysis does mention that the persona definition propagates unconditionally, but it frames that as the *missing* signal ("is this persona hosted elsewhere?") — it does not report that the propagated definition fields overwrite local configuration.
Neither issue reports that the shared definition's `model`/`provider`/`system_prompt` fields overwrite per-device configuration.
## Steps to reproduce
1. Device A (owner): create an agent persona, configure it (provider/model set), and verify it runs.
2. Device B (same owner identity, second machine, same community): let the persona sync in; an independent local instance keypair is minted. Note the model shown on device B's agent card.
3. On device A, change the agent's model (or provider/system prompt) and save.
4. Observe device B: the model (and every other definition field) is now the value set on device A, with no prompt, no per-device override, no way to keep device B's instance on its own configuration.
## Expected behavior
- Per-device agent instances should be independently configurable; a configuration change on one device should not silently rewrite the configuration of instances on other devices.
- At minimum, `model`/`provider` (and ideally `system_prompt`/`runtime`) should be per-instance fields carried by kind:30177 (the instance layer), not by the kind:30175 definition — or the definition layer should support explicit local overrides for these fields.
- If shared definitions are deliberate, the UI must make the overwrite visible (e.g. "configuration synced from another device") instead of silently replacing local values.
## Impact
- Users running the same persona on multiple machines (a common pattern for "one agent per machine" or multi-community setups, see also the desired setup in #5128) cannot keep distinct per-device configurations.
- Silent overwrites are worse than the visible name sync: a model/provider change on one machine can break or change the behavior of the agent on another machine with no indication of where the value came from.
## Related
- #5128 — instance selection/settings misrouting in the same multi-device area (open)
- #3753 — instance config non-sync, duplicate local instances (open)
- #3414 / #4634 — second-device keypair reminting, persona_id link loss (open)
Local source reference: `main` @ `7bee84d`, `desktop/src-tauri/src/commands/personas/inbound.rs` (`apply_inbound_persona`), `desktop/src-tauri/src/commands/personas/update.rs` (`propagate_persona_name_rename`).
Contributor guide
Assessment
This issue has not been assessed yet.