ManagedAgentRecord: add disable_local_spawn flag to prevent Desktop from reactively spawning an agent whose runtime is externally managed
- Dominant language
- Rust
- Stars
- 32.7k
- Forks
- 4.3k
- Avg merge
- 1d 13h
- Merged PRs (30d)
- 253
Description
### **Problem**
When an agent identity is served by an externally-provisioned runtime (e.g. a VPS running buzz-acp as a systemd unit), Buzz Desktop still spawns a local process for that agent on every reactive trigger, channel open, member-sidebar load, @mention click. The local spawn competes with the remote instance: both connect to the relay under the same identity key, both receive channel events, and both may respond.
start_on_app_launch: false does not help. It only gates reconcile_managed_agent_runtimes at startup. The reactive path...
start_managed_agent_runtime_pair_lazy → start_pair in runtime_commands.rs, checks only backend == BackendKind::Local and fires regardless.
### **Repro**
1. Configure an agent in Buzz Desktop (Local backend, start_on_app_launch: false).
2. Run the same identity on an external host (e.g. VPS via systemd, same nsec).
3. Mention the agent in any channel the Desktop user has open.
4. Desktop spawns a local buzz-acp process alongside the external one. Both connect. Both may reply.
### **Expected behaviour**
Desktop should provide a way to say: "this identity is owned by a remote runtime, do not spawn locally." The persona must stay in managed-agents.json (on Windows the nsec lives in Credential Manager, keyed by pubkey; deleting the persona loses the key). Only the local process spawn is suppressed, and it is trivially reversible.
### **Relevant design context**
VISION_REMOTE_AGENTS.md (PR #3924) describes exactly this use case as the intended long-term feature. The planned mechanism (Provider backend + deploy handshake) would address it eventually, but:
Provider mode is not usable for self-hosted/VPS deployments yet (it requires a buzz-backend-* binary on PATH)
Switching to Provider backend today triggers deploy_to_provider on channel mention clicks, breaking mentions with "provider not found on PATH"
The vision doc targets a Kubernetes-based managed deploy; self-provisioned VPS is out of scope for that path
A minimal flag is the correct stepping stone.
### **Proposed fix**
Add disable_local_spawn: bool (default false, serde default) to ManagedAgentRecord in types.rs. Add one guard in start_pair() before the spawn:
```
if record.disable_local_spawn {
return Err("local spawn disabled, runtime is externally managed".into());
}
```
Expose as a toggle in Settings → Agents alongside start_on_app_launch. This is intentionally narrower than the Provider-deploy path, it is a flag for operators who are already running agents on external infrastructure and simply need Desktop to step aside.
### **Notes**
The fix must be in start_pair(), not only in reconcile_managed_agent_runtimes. Two paths reach start_pair: the boot reconciliation (gated today by start_on_app_launch) and the lazy reactive spawn (start_managed_agent_runtime_pair_lazy), which is the unfixed one.
The flag should default false so existing behaviour is unchanged for everyone not explicitly opting in.
Toggling back to false restores normal local-spawn behaviour immediately, no persona or key changes.
Contributor guide
Research direction
Start with ManagedAgentRecord in types.rs and the start_pair() path in runtime_commands.rs, including the lazy reactive spawn entry point. Add the opt-in setting and expose it beside start_on_app_launch in Settings → Agents. Done means externally managed identities no longer spawn locally when enabled, while disabling the flag restores normal spawning.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- backend, desktop
- Issue type
- Feature
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 76/100