block / block/buzz

Bug: `respond_to` change saved in Desktop UI never propagates to the runtime record

Open
#6,026 1 comment 0 reactions 0 assignees View on GitHub
bug
Dominant language
Rust
Stars
32.7k
Forks
4.3k
Avg merge
1d 13h
Merged PRs (30d)
253

Description

**Reported by:** MC (self-hosted Buzz)
**Date observed:** 2026-08-15 / 2026-08-16
**Severity:** High — a security-relevant setting silently does not take effect, and the UI reports success.

## Summary

Changing an agent's inbound author gate ("send instructions" → **allowlist**) in Buzz Desktop
persists to the agent's **definition** fields but never reaches the **runtime** fields that
Desktop actually uses to build the child process environment. The agent therefore keeps
booting with `respond_to=owner-only` indefinitely, across any number of restarts, while the
UI continues to show `allowlist`.

There is no error, no warning, and no visible symptom other than the agent silently ignoring
everyone except the owner.

## Environment

- Buzz Desktop, self-hosted relay (`ghcr.io/block/buzz:main`, Docker stack)
- Windows 11 Pro for Workstations 10.0.26200
- Store: `%APPDATA%/xyz.block.buzz.app/agents/managed-agents.json`
- Affected agents: 4 Desktop-managed agents (Researcher, Investor, Critic, Engineer)

## Steps to reproduce

1. Create a Desktop-managed agent (owner-only by default).
2. In Desktop, set the agent's inbound gate to **allowlist** and add a non-owner pubkey.
3. Restart Buzz Desktop fully so the agent harness relaunches.
4. Have the allowlisted (non-owner) identity `@mention` the agent in a channel it belongs to.

**Expected:** the agent receives and acts on the mention.
**Actual:** the mention is dropped at the gate. The agent never sees it. Only the owner can
reach the agent. The Desktop UI still displays `allowlist`.

## Evidence

### 1. The store holds two different values

From `managed-agents.json`, for each affected agent:

| field | value |
|---|---|
| `definition_respond_to` | `allowlist` ← the user's change, saved |
| `definition_respond_to_allowlist` | `["1ed0ff40…5ff66"]` ← saved |
| `respond_to` | `owner-only` ← **stale, used at spawn** |
| `respond_to_allowlist` | `[]` ← **stale, used at spawn** |

`updated_at` on those records is `2026-08-16T02:33–02:35Z`, matching when the change was made
in the UI — so the write happened, it just landed only on the `definition_*` fields.

### 2. The runtime record is the one that builds the environment

`desktop/src-tauri/src/managed_agents/runtime.rs:396` — `build_respond_to_env()` reads
`record.respond_to` and `record.respond_to_allowlist` (the runtime fields) to emit
`BUZZ_ACP_RESPOND_TO` / `BUZZ_ACP_RESPOND_TO_ALLOWLIST`. It never consults the
`definition_*` fields.

### 3. The harness confirms it at every boot

`%APPDATA%/xyz.block.buzz.app/agents/logs/__.log`, most recent boot:

```
buzz-acp starting: relay=wss://… pubkey=4aa5131b… agent_cmd=… permission_mode=bypassPermissions respond_to=owner-only
```

Seven consecutive boots over ~4.5 hours all log `respond_to=owner-only`, including boots that
occurred *after* the UI change. The allowlisted pubkey appears **zero times** in the log —
events were dropped before reaching the agent.

### 4. Control case

A non-Desktop agent launched from a PowerShell script with explicit
`--respond-to allowlist --respond-to-allowlist ` works correctly and responds to the
same non-owner identity immediately. So the gate logic in `buzz-acp` is fine; only the
Desktop definition → runtime propagation is broken.

## Impact

- The setting appears applied but is not. Users cannot tell without reading the JSON store or
the harness log.
- Restarting — the documented remedy for a launch-time setting — does not help, because the
value being relaunched with never changed. This makes the failure look intermittent and
sends users down the wrong diagnostic path.
- It fails **closed** rather than open, so it is not a security hole. It is a silent
correctness and trust problem: the UI asserts a state the runtime does not hold.

## Suggested fix

Propagate `definition_respond_to` / `definition_respond_to_allowlist` onto the runtime fields
when the definition is saved (or resolve the effective value from the definition at spawn
time). Given `build_respond_to_env()` already returns `Err` for `allowlist` with an empty
list, an empty propagated allowlist should surface as a visible error rather than a silent
fallback.

A UI affordance showing the **effective** gate the harness last booted with — distinct from
the configured value — would have made this self-diagnosing.

## Notes

`auto_restart_on_config_change` exists on the record, which suggests config changes are
expected to reach the runtime. Worth checking whether that path is also affected.

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.