block / block/buzz

[Bug] Provider-backed agents display local Claude config instead of remote runtime and expose env values

Open
#3,034 0 comments 1 reaction 0 assignees View on GitHub
Dominant language
Rust
Stars
32.7k
Forks
4.3k
Avg merge
1d 13h
Merged PRs (30d)
253

Description

## Summary

Provider-backed managed agents display the local desktop's inherited harness and configuration instead of the runtime that the remote provider actually deployed.

In our case, five agents were deployed through a `buzz-backend-*` provider to an always-on Linux host. Their saved records correctly have `backend.type = "provider"`, a provider ID, and a non-empty remote `backend_agent_id`. The remote services are active and execute different ACP commands (Hermes profiles, Codex ACP, and Claude Code ACP).

Despite that:

- **Edit agent** shows `Harness: Claude Code` and `Model: Harness default` for every provider-backed agent.
- Agent rows show `Default model` even where the provider enforces a remote model.
- The **Runtime** tab reads and renders the local machine's Claude configuration as though it applied to the remote agent.
- That Runtime tab includes full environment-variable values from the local Claude config. In testing, a credential-like value was rendered in plaintext.
- Removing the provider executable from discovery does not stop the already-running remote agent, but the card still presents local edit/runtime controls without clearly distinguishing stale deployment metadata from effective remote state.

This makes it very difficult to determine which harness/model is actually executing and can expose unrelated local secrets on a remote-agent details screen.

## Environment

- Buzz Desktop 0.4.26
- macOS
- `block/buzz` checkout at `a31fc4d2f35d51cdf45ff8c61fc3a07f49c665e8`
- Custom provider discovered as `buzz-backend-`
- Remote `buzz-acp` services managed by systemd on Linux
- Provider protocol: `info` + `deploy`

## Steps to reproduce

1. Configure the desktop's default local harness as Claude Code.
2. Install a valid `buzz-backend-` provider.
3. Create a managed agent using that remote provider.
4. Have the provider deploy a non-Claude runtime and return a remote `agent_id`.
5. Confirm that the saved managed-agent record has:
- `backend.type = "provider"`
- the expected provider ID/config
- a non-empty `backend_agent_id`
6. Confirm independently on the remote host that the running service uses a different ACP command/model.
7. Open the agent in Buzz:
- **Edit** → observe `Claude Code / Harness default`
- **Runtime** → observe local Claude config entries and full environment-variable values

An example of the contradictory state, with identifying values removed:

```text
Saved backend: provider / remote agent ID present
Saved local fallback agent_command: claude-agent-acp
Edit dialog: Claude Code / Harness default
Effective remote command: codex-acp (or another provider-selected runtime)
Status: DEPLOYED / online
```

## Expected behavior

For a provider-backed agent:

- The UI clearly labels it as **Remote ()**.
- Edit/runtime views show provider-backed deployment metadata, not an inherited local harness.
- Local harness/model controls are hidden or explicitly labelled as unused unless the provider declares that it consumes them.
- Displayed model/runtime state distinguishes **requested**, **provider-reported**, and **observed** values.
- The Runtime panel never renders credential values or arbitrary environment-variable contents.
- If effective remote runtime/model metadata is unavailable, the UI says **Unknown**, not `Claude Code` or `Default model`.

## Actual behavior

The local fallback harness is presented as authoritative even though the agent is provider-backed and the live remote process uses another runtime. The Runtime panel also merges unrelated local Claude configuration and displays environment values.

## Security impact

The Runtime view can surface plaintext credential-like environment values from a local config file. Provider-backed agents should not cause unrelated local runtime configuration or secret values to be projected into the UI.

At minimum, secret-like keys and all environment-variable values should be redacted. Prefer an allowlisted, display-safe runtime projection rather than rendering raw configuration values.

## Related provider lifecycle friction observed

These are secondary to the display/security bug but contributed to the ambiguity:

- The current provider contract supports deployment but has no symmetric undeploy/status contract.
- Deleting a deployed provider agent warns that the remote process may remain running without local management.
- There is no safe **detach local management record while preserving the shared remote identity** action.
- Provider-backed cards therefore conflate three concerns: shared identity, local management ownership, and remote runtime lifecycle.
- On another desktop, remote visibility/mentionability is already tracked in #2349.
- A first-party server-side reconciler/spawner is proposed in #2859.
- A broader capability/readiness manifest is proposed in #2931.

## Suggested direction

1. Branch Edit/Runtime rendering on `agent.backend.type`.
2. For provider-backed agents, show provider ID/config plus safe provider-reported deployment metadata.
3. Do not run local harness config discovery or render local config-file values for provider-backed agents.
4. Never display raw environment-variable values in runtime details; redact or project only safe metadata.
5. Consider extending provider responses with display-safe fields such as runtime name, model, deployment status, and last verification time.
6. Add explicit lifecycle semantics: status, undeploy, and/or local detach without relay identity deletion.

## Acceptance criteria

- [ ] A provider-backed agent no longer displays the local inherited harness as its effective runtime.
- [ ] Provider-backed Runtime details do not include unrelated local harness configuration.
- [ ] Environment-variable values and credential-like config are never displayed in plaintext.
- [ ] Requested, provider-reported, and observed runtime/model values are distinguishable.
- [ ] Tests cover a provider-backed record whose local fallback command differs from the deployed remote command.
- [ ] Deletion/detach copy clearly distinguishes local record removal, shared identity archival, and remote process lifecycle.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.