You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Editing an agent's "Who can talk to this agent" setting in the Desktop UI
(changing respond_to to Anyone or Allowlist, and adding a human pubkey to
the allowlist) does not persist to the value the buzz-acp harness actually
uses. The harness keeps starting with respond_to=owner-only, so non-owner
members can never interact with the agent, regardless of what the UI shows.
Agent: a custom agent (not a built-in Welcome Team persona), runtime claude
Steps to reproduce
Create a custom agent (owner-only by default).
Open its config → Who can talk to this ae
(also tried Allowlist + add a member's pubkey). Save.
Restart the agent (also tried: stop → edit
Have a non-owner member @mention the agent in a shared channel.
Expected
The agent responds to the member (Anyone), or to allowlisted members (Allowlist).
Actual
The member gets no response.
The buzz-acp starting log line always sho.
This reproduced identically on the hosted (Builderlab) relay too, so it is not
relay-specific.
Evidence
In ~/Library/Application Support/xyz.block.bnts.json,
after changing the UI to "Anyone", the agent's definition entry shows a
desync:
"respond_to": "owner-only", // v
"definition_respond_to": "anyone", // what the UI wrote ✅
"respond_to_allowlist": [] // sng a member ❌
So the UI writes definition_respond_to, butrom respond_to (unchanged) and respond_to_allowlist (never populated). There are
effectively three out-of-sync states: **UI shig file
has definition_respond_to set but respond_to stale, and the running
harness uses owner-only.
Harness log:
buzz-acp starting: ... respond_to=owner-o
Workaround (confirms the root cause)
Editing managed-agents.jsonby hand wit respond_to: "allowlist" and adding the member pubkey to respond_to_allowlist in the agent's entries reopening
the app the harness starts correctly:
buzz-acp starting: ... respond_to=allowlist(1)
The app did not revert the manual edit, so the config file is the source of
truth; the UI edit path is what fails to writ respond_to_allowlist.
Impact
Custom agents cannot be shared with other community members through the UI at
all — they silently stay owner-only. Only a manual file edit works.
Reacted by Judd Kussrow, DrDoomi and Nicolas Feroux
Still reproduces on Desktop v0.4.24 — PR #2505 is not merged yet
Heads up before this gets closed on the "Fixed in #2505" note above: PR #2505 is still open and its new files are absent from main (desktop/src-tauri/src/commands/personas/propagate.rs and respond_to_propagation_tests.rs both 404 on main as of 2026-07-25). So the fix has not shipped in v0.4.24 (released 2026-07-23T23:09Z) or v0.4.25 (2026-07-24T23:04Z).
I hit this independently on v0.4.24 (macOS 26.5.2, arm64, bundle installed 2026-07-24T01:35Z, hosted relay) and can add one field-level detail the original report doesn't cover.
The instance record is never touched at all
@georgerous showed the desync on the definition entry. In my managed-agents.json the instance entry — the one the harness actually reads — had no trace of the UI write:
// definition record (slug b0622424-…, empty pubkey) — UI saved here at 21:49:24Z"respond_to": "owner-only", // stale"definition_respond_to": "anyone", // what the UI wrote"respond_to_allowlist": []
// instance record (pubkey e19e5b77…, no slug) — what buzz-acp reads"respond_to": "owner-only",
"definition_respond_to": null, // UI write never arrived"respond_to_allowlist": []
Timeline on one agent, all on v0.4.24:
Time (UTC)
Event
21:00:31
agent created
21:49:24
UI: "Who can talk to this agent" → Anyone, saved (definition_respond_to only)
21:55:34
Stop → Start the agent → buzz-acp starting: … respond_to=owner-only
22:10:32
hand-edit respond_to: "anyone" on both records, app fully quit
workflow-engine message (buzz:workflow, no auth tag) → agent replied
Two things worth noting: a Stop → Start of the agent alone does not pick up the saved value (22:11 worked only because the file changed, not because of the restart), and the app does not revert a hand-edit even when it rewrites the file later — corroborating that the config file is the source of truth.
Severity is higher than it looks: there is no supported workaround
The env override documented in crates/buzz-acp/README.md and TESTING.md (BUZZ_ACP_RESPOND_TO=anyone) is unreachable from Desktop — the key is in RESERVED_ENV_KEYS (desktop/src-tauri/src/managed_agents/env_vars.rs), so the agent env-vars form rejects it at save time:
the following env vars are reserved by Buzz and cannot be overridden:
BUZZ_ACP_RESPOND_TO
That reservation is deliberate and, per the comment in that file, correct — a user-supplied override would silently diverge from the saved security setting. Not asking for it to be lifted. The point is that with the env path (rightly) closed and the UI path broken, hand-editing JSON is the only way to change respond_to at all, so #2501 is the sole path for this setting rather than one of two.
One practical wrinkle for that workaround: every buzz-acp process is a child of buzz-desktop, so an agent cannot patch the file on its owner's behalf — quitting the app to release it also kills the agent doing the edit. It takes a detached process (or a human in a terminal) to apply.
Still reproduces on Buzz Desktop 0.4.26 (Linux, AppImage), on a self-hosted relay with require_relay_membership=true.
Two things to add: a fresh repro on a different agent type, and a UI detail that may be the mechanism.
Repro
Agent created via Import agent snapshot (buzz-agent-snapshot v1), so it is persona-linked (persona_id set) rather than a hand-built custom agent — the original report was a custom agent, so this is not specific to how the agent was made.
Agents → agent → edit → Advanced → Who can talk to this agent → Anyone.
Save.
Stop and start the agent.
What lands on disk
managed-agents.json after the save — the agent has two rows, and neither ends up with the value the UI shows:
row
respond_to
definition_respond_to
persona
owner-only
anyone
instance
owner-only
null
So the UI writes definition_respond_to on the persona row, while the instance row — the one that actually spawns — is never touched at all. That is a third out-of-sync state beyond the two in the original report.
What the harness starts with
After a full stop/start, buzz-acp still comes up owner-only:
In the edit dialog, Advanced → Who can talk to this agent is rendered under both AI-configuration tabs, but the save affordance is not:
With "Customize for this agent" selected, changing the value leaves Save changes disabled — the change cannot be submitted from that view at all.
Switching to "Use harness defaults" enables Save changes, and only then can the value be saved.
So a user who is customizing the agent has no way to submit this field from the view they are in.
Not every field in the dialog is affected
Editing the system prompt in the same dialog saves correctly: the new text lands on both the persona row and the instance row, with identical hashes. So this is not "agent edits don't persist" in general — it is scoped to the Advanced block.
Effect
Setting an agent to Anyone or Allowlist has no effect in 0.4.26 — every managed agent stays owner-only regardless of what the UI reports, so no non-owner member can interact with any agent.
Still reproduces on 0.5.0 (Debian 13, self-hosted relay) — and it has an agent-to-agent consequence worth recording
Confirming on the current release, plus one impact that has not come up yet in this thread.
Version: Buzz 0.5.0 (Debian package, amd64, trixie), self-hosted relay 0.2.0, six managed agents, runtimes claude (claude-agent-acp 0.63.0) and codex (codex-acp 1.1.7). PR #2505 is still open and desktop/src-tauri/src/commands/personas/propagate.rs still 404s on main, so the fix is not in 0.5.0 either — that now covers 0.4.23, 0.4.24, 0.4.26 and 0.5.0.
Registry state, ~/.local/share/xyz.block.buzz.app/agents/managed-agents.json, five agents all configured with an allowlist persona:
agent definition_respond_to respond_to definition_respond_to_allowlist respond_to_allowlist
A allowlist owner-only [<owner>, <coordinator>] []
B allowlist owner-only [<owner>, <coordinator>] []
C allowlist owner-only [<owner>, <coordinator>] []
D allowlist owner-only [<owner>, <coordinator>] []
E allowlist owner-only [<owner>, <coordinator>] []
Same desync described above, and the harness environment agrees with the stale field rather than the definition:
definition_parallelism desyncs the same way (1 in the definition, 10 live) — that part is #3095, noting it only as evidence that the non-propagation is general to definition_*, not specific to respond-to.
The part that is new: owner-only does not restrict agent-to-agent traffic
Everything above is about human members being unable to reach an agent. The inverse also holds, and it is the more consequential half.
With all five agents fallen back to respond_to: owner-only and an empty allowlist, I ran a deliberate routing probe: agent C (a review-role agent, not the coordinator, and not in anyone's allowlist) sent a task directly to agent E, instructing it to perform a live production operation with no authorization contract.
E received it, woke, processed it, and replied within six seconds. It declined — but on its own system-prompt grounds, quoting the missing authorization, not because any gate rejected the sender. Its reply names the problem itself:
Sender check: request came from [Codex Reviewer], not [Delivery-Lead], and even a [Delivery-Lead] request without the above elements would still fail the contract.
So on observed behaviour owner-only appears to resolve through the auth tag that every managed-agent event carries, not through the sender pubkey. Every agent under one owner key satisfies it. The intended two-principal restriction was configured, is visible in the registry, and is not in force in either direction.
Practical effect for anyone running a multi-agent setup with differentiated roles: the sender restriction cannot currently be relied on as a control. In our case the only thing that stopped an unauthorized live-write instruction from being acted on was the receiving agent's own prompt discipline. That worked, but prompt discipline is not a mechanism, and this bug is what removes the mechanism behind it.
Not filing this separately since it is the same root cause as this issue. Happy to open one if maintainers would rather track the agent-to-agent authorization angle on its own.
Still reproduces on Buzz Desktop 0.5.0 (this report was 0.4.23), macOS 26.2, self-hosted relay at NIP-11 version: 0.2.0. Some extra detail on the persisted shape that may help narrow the write path.
managed-agents.json holds two records per managed agent, and the desync is between them rather than within one record:
a definition record, pubkey: ""
an instance record, pubkey: "<real hex>", carrying last_started_at
Changing "Who can talk to this agent" in Desktop writes definition_respond_to / definition_respond_to_allowlist onto the definition record only. The instance record keeps respond_to / respond_to_allowlist, and buzz-acp gates on the instance record — so the edit has no runtime effect.
Current state of this install, all three edited agents:
It does not converge over time or across restarts. agent-1's instance record shows last_started_at: 2026-07-29T04:48:11Z, and the file has been rewritten at least twice since the Desktop edit (most recently 04:58:02Z) with the instance record unchanged each time.
Possibly useful for whoever picks this up: the instance-level field is not universally unwritable. In the same file, two other agents carry a populated instance-level allowlist:
So some surface — a different code path, an older Desktop version, or the pairing/provisioning flow — does write respond_to on the instance record. Identifying which one writes it correctly probably localizes what the Advanced-settings editor is missing.
Still reproduces on Desktop v0.5.2 / Windows 11, against a hosted relay. So this is not macOS-specific, not self-hosted-relay-specific, and not fixed in the 0.4.23 to 0.5.2 range.
Same signature you described, plus one detail I did not see in the original report: the desync spans two records, and the one the harness reads is not the one the UI writes.
%APPDATA%\xyz.block.buzz.app\agents\managed-agents.json holds both a persona/definition record and a provisioned instance record for the same custom agent (runtime claude). After setting Who can talk to this agent to Allowlist, adding two members, and clicking Save changes:
persona record respond_to=owner-only definition_respond_to=allowlist respond_to_allowlist=[]
instance record respond_to=owner-only (no definition_respond_to key) respond_to_allowlist=[]
harness buzz-acp starting: ... respond_to=owner-only
That reads as two separable defects:
The selected principals are never written at all. respond_to_allowlist stays [] on both records. definition_respond_to captures the mode but nothing captures the people.
definition_respond_to lands on the persona record, but buzz-acp is launched from the instance record, which never receives it.
The Save does write the file. Its mtime updates on every Save, and unrelated fields in the same file are updated normally. So this is an incomplete write rather than a failed one.
One narrowing signal that may help isolate it: allowlists populated by the builtin Welcome Team mechanism persist correctly. Those instance records carry respond_to=allowlist with a sibling agent pubkey, and they survive app relaunch. So the field, the mode and the serialization all work end to end. Only the UI person-picker write path fails.
Why this costs more than it looks
The failure is completely silent in both directions. There is no error in the UI, and there is no line in the agent log either, because the inbound author gate drops non-owner events before they are forwarded to the harness. From the operator's side the agent is connected, subscribed, presence online, and simply never answers teammates, which reads as the agent being broken or ignoring people rather than as an access setting.
Two small changes would have collapsed the diagnosis from hours to minutes:
surface a save error when the allowlist cannot be persisted, instead of closing the dialog as if it succeeded
log at debug when the author gate drops an event, including the mode that caused the drop
Workaround confirmed on Windows
Same as yours. With the app fully closed, hand-editing the instance record to respond_to: "allowlist" with the member pubkeys in respond_to_allowlist, then relaunching, works. The app preserved the manual edit across relaunch and rewrote the file without reverting it, and the harness came up correctly:
buzz-acp starting: ... respond_to=allowlist(2)
Worth noting for anyone hitting this: editing the persona record instead of the instance record will look like it worked and change nothing, since the harness only reads the instance record.
Confirming the split — that's a cleaner decomposition than my original report,
and the Welcome Team contrast is the useful narrowing signal: mode, field and
serialization all work end to end, only the person-picker write path fails.
Worth flagging for anyone tracking #2505: it fixes your defect (2) only. I've
raised there that the propagation helper it adds has no empty-allowlist guard,
so with your defect (1) still in place it can push allowlist with an empty
list onto instance records — a state the mint path explicitly rejects. Both need
to land for this to actually work end to end.
Strong agreement on the debug log for the author gate. The silent inbound drop
is why this reads as "the agent is ignoring people" rather than "a setting is
wrong", and it's most of the diagnosis cost on my side too.
If you go to the channel members list then you can edit the responds to for that channel there. I didn't know that, and it is a bit hidden and a not very intuitive place.
That works, and it's worth saying why it works, because it points straight at
the bug.
EditRespondToDialog (channel → members sidebar → agent card) seeds from agent.respondTo / agent.respondToAllowlist and writes via updateManagedAgent({ pubkey: agent.pubkey, respondTo, respondToAllowlist }) —
i.e. straight to the instance record by pubkey, the one buzz-acp actually
reads. It skips the persona→instance indirection where both defects live, and it
carries the allowlist rather than dropping it. It even has the empty-allowlist
guard (respondTo !== "allowlist" || respondToAllowlist.length > 0) that the
persona path is missing.
So the picture is: the instance-level UI has always been correct, and the
persona-level "Who can talk to this agent" control is the broken one. Two
caveats for anyone using this as a workaround — it's per instance, not per
persona, so you repeat it for every agent; and it won't survive the instance
being re-minted from its definition.
Agreed the placement is unintuitive. Given the persona control is the one that
looks authoritative and silently does nothing, having the working control live
in a channel sidebar is most of why this took people hours.
Root-caused this one: the persona behavior edit path (update_persona → apply_persona_behavior) wrote only to the definition, but the harness reads respond_to from the instance record at spawn (build_respond_to_env). The cascade to linked instances existed for avatar_url/display_name but was never built for the behavioral group — so instances froze at whatever mode was minted once via resolve_mint_behavioral_defaults (owner-only default), and the only fix was hand-editing managed-agents.json.
PR #4115 fixes the write gap: update_persona_with now cascades behavior edits to linked instances using the same override-discrimination the display name cascade already has — instances still inheriting (matching the pre-edit value) adopt the new mode; explicitly pinned instances are preserved. Absent definition parallelism doesn't stomp an instance pool width; unknown mode strings error out instead of silently rewriting. Six regression tests pinned.
I've opened #4270 with a fix. Root cause: the edit dialog gated the allowlist payload on submitMode === 'allowlist' && listChanged, so a mode flip to Allowlist with an unchanged-but-pre-existing list (e.g. Anyone → Allowlist where the list was saved in an earlier session) sent only the mode — the record kept a state buzz-acp reads as owner-only. This is exactly your workaround-vs-UI desync: the dialog wasn't writing respond_to/respond_to_allowlist on that transition. Fix: a canonical computeRespondToWirePatch helper sends the allowlist payload whenever the submitted mode is allowlist AND (mode changed OR list changed), so the harness always receives {mode, allowlist} atomically. 6 new tests cover the full transition matrix; full webview suite green (3912 passing) + tsc clean.
Confirming this is still present in Desktop v0.5.3 (macOS, relay *.communities.buzz.xyz, claude-agent-acp harness), with two additional data points:
The Edit-agent dialog displays "Anyone" after reopening — so the failure is invisible to the user; only the config file / spawn environment reveals the truth. A file watcher on managed-agents.json shows every Save writes respond_to: "owner-only" again.
Ground-truth check that made diagnosis reliable: inspect the spawned process env (ps eww on buzz-acp) — it always showed BUZZ_ACP_RESPOND_TO=owner-only after UI edits. After hand-editing respond_to + respond_to_allowlist (app closed) the runtimes spawn correctly (BUZZ_ACP_RESPOND_TO=allowlist with the right BUZZ_ACP_RESPOND_TO_ALLOWLIST pubkeys) and allowlist mode works end-to-end at runtime — verified across 4 agents. So the bug is purely the dialog's save path.
Confirming this on v0.5.3 (reported here against v0.4.23), and adding
evidence that the impact is considerably wider than the allowlist case.
Still present on 0.5.3, and no restart clears it
Setting Who can send instructions → Anyone and restarting produced respond_to=owner-only on every startup — escalating through the restart
button, a manual stop/start, and a full quit-and-relaunch of Buzz Desktop:
$ grep "buzz-acp starting"<harness>.log | grep -o "respond_to=[a-z-]*"
respond_to=owner-only
respond_to=owner-only
respond_to=owner-only
respond_to=owner-only
respond_to=owner-only # ← after a full application restart
The UI showed Anyone (with its access warning) throughout.
managed-agents.json shows the desync exactly as diagnosed here — and note it
affects two records, not just the definition. The agent instance row is
stale as well:
[0] Probe (definition) respond_to = "owner-only"
definition_respond_to = "anyone" ← UI wrote here
[10] Probe (instance) respond_to = "owner-only" ← also never updated
(no definition_respond_to key at all)
So a fix that syncs only the definition row may still leave running instances on owner-only.
The bigger consequence: workflows cannot drive agents
This is the part I think is under-weighted in the current title and description.
Workflow-posted messages are not signed by the owner. A workflow send_message posts under its own identity, with the owner only as a p tag:
Under respond_to=owner-only, that fails the sender check. And since workflows
cannot invoke agents directly — per ARCHITECTURE.md, that bridge exists only in
buzz-acp, so an @mention posted by a workflow is the only available mechanism — owner-only means no workflow can wake any agent.
I verified this is the operative constraint by editing managed-agents.json
directly (both rows) to "anyone" and restarting. With the runtime value actually
widened, a workflow-posted @mention wakes the agent in 9 seconds. Nothing
else about the setup changed.
So the mechanism works fine — the only thing standing between a user and
workflow-driven agents is that this setting cannot be changed from the UI.
Right now the sole route to Workflows + Agents, arguably the headline combination
in Buzz, is hand-editing a JSON file in Application Support and relaunching.
(In the interest of not sending you down a wrong path: I originally attributed a
longer series of silent workflow-mention failures to this issue. They turned out
to have a second, independent cause — two channel members shared a display name,
so the workflow's @Name resolved to no p tag at all. That is a separate report.
The respond_to desync above is reproducible on its own and is what this comment
is about.)
It fails completely silently
There is no error, no rejected-mention log line, and no UI feedback. The agent
simply doesn't respond, which is indistinguishable from the agent being stopped,
unauthenticated, or not a channel member — all of which we ruled out one at a time
before finding this issue.
Worth noting that buzz-acp logs startup, shutdown, channel subscription and
errors, but not successful turn processing — so a silent log is the normal
state and gives no signal either way. Logging rejected mentions at INFO would
have made this self-diagnosable in seconds.
Suggestions, in the order I'd value them
Sync the UI edit to respond_to (and respond_to_allowlist) on both the
definition and any existing instance rows.
Log rejected mentions. One INFO line naming the sender and the effective respond_to would have saved hours here.
Surface the effective runtime value in the agent's Runtime panel, so a
UI/runtime mismatch is visible without reading the harness log.
Consider whether a workflow post should count as owner-authored when the p
tag names the owner and buzz:workflow is set. That would let owner-only
behave the way users clearly expect, without anyone having to widen an agent
to Anyone — which the UI itself warns grants filesystem and connected-tool
access.
Point 4 matters because the current workaround for anyone wanting workflow-driven
agents is to set Anyone, which is a genuinely broad grant for what should be
"my own automation may talk to my own agent."
Happy to provide the full harness logs or re-run anything — the reproduction is
stable and immediate.
Fresh Desktop v0.5.8 result on macOS Apple Silicon, hosted *.communities.buzz.xyz relay, custom Grok agents:
The persona-level edit path still does not update an already-linked instance. With the agent stopped, changing Who can send instructions and saving updated the definition-facing selection, while the instance record retained its prior respond_to and respond_to_allowlist. Restarting the agent therefore used the old instance gate. I restored the definition selection after the test.
Advanced environment variables are not a supported escape hatch. Desktop rejects both BUZZ_ACP_RESPOND_TO and BUZZ_ACP_RESPOND_TO_ALLOWLIST with: the following env vars are reserved by Buzz and cannot be overridden.
Workflow authorship behavior has changed from the older evidence in this thread. A message-triggered workflow activated from an agent-authored marker posted a visible @Peggy Olson message under the owner identity, with a real mention tag. Peggy started with respond_to=owner-only, accepted that workflow post, and replied in the workflow-message thread with the requested exact value. The observed path was:
So on v0.5.8, workflows can wake an owner-only agent without widening the recipient to Anyone. The remaining response-scope defect is specifically definition/persona edits not propagating to an already-provisioned instance (plus the reserved-env limitation), rather than workflow posts necessarily having a non-owner author.
One separate anomaly surfaced during the same proof: workflow creation returned success and the workflow executed, but the Workflows page continued to show No workflows yet after refresh. That appears distinct from this issue.
A workaround that survives restart: patch the instance records directly
Confirming on Desktop v0.5.8 / Windows 11, self-hosted relay ghcr.io/block/buzz:main. The desync is exactly as @jsilets and @MaxWynnDev describe — the definition record gets definition_respond_to, the instance record keeps respond_to, and the harness gates on the instance. Since #2505 is still unmerged, here is a workaround I verified end to end; I did not find one anywhere in this thread.
With Buzz fully closed, edit %APPDATA%\xyz.block.buzz.app\agents\managed-agents.json and set, on each instance record (the ones with a non-empty pubkey):
Leave the definition records alone. On the next start the harness comes up with
buzz-acp starting: ... respond_to=allowlist(1)
instead of respond_to=owner-only, and it stays that way across restarts.
Evidence that behaviour changes, not just the log line. My case is a Workflow posting @agent prompts on a timer, so the allowlisted pubkey is the workflow engine's, not a human member's. The relay event log shows a clean cutoff at the restart that picked up the patched records:
14:44:27 (workflow) @Claude round 3 <- before restart, ignored
14:45:07 agents restart with respond_to=allowlist(1)
14:46:07 (workflow) @Codex round 3
14:46:59 Codex <full answer> <- 52s later
Every mention before the restart was dropped; every one after was answered, across four agents on three runtimes (claude, codex, buzz-agent).
Scope of what I tested. The allowlist entry I verified is a service pubkey, not a human member, and I did not test anyone. The gate does not distinguish the two, so I would expect a member pubkey to behave the same, but I have not measured it.
It is fragile. The app rewrites instance records during its own operations, so editing that agent in the UI afterwards can silently restore owner-only. The only reliable check is the harness startup line — the UI keeps showing the value you picked either way.
A second-order impact worth recording: while the gate is stuck, Workflows cannot drive managed agents at all. The workflow engine signs its messages with the relay key, so it is neither the owner nor an owner-verified agent, and an owner-only gate drops every step it posts. The run itself is healthy — delays honoured to the second, mentions resolved with correct p tags — it just talks to nobody. That failure mode is invisible from the Workflows UI: the run completes green.
Still reproducible on Desktop v0.5.19 (macOS, Apple Silicon), self-hosted relay ghcr.io/block/buzz:main.
Hit this twice in two days on two different agents. Adding one observation that I did not see in this thread or in #5858 / #6026 / #4487, because it narrows the surface considerably:
Setting respond_to at creation time works. Only editing it afterwards fails.
Three agents created with "Anyone" selected before the first save came out correct and are reachable by non-owner members. Two agents created with the default and then edited to "Anyone" stayed on owner-only — through repeated saves and app restarts.
Evidence for one of them (b4cc9af0…):
Store record after saving: respond_to: "owner-only", while updated_at == last_started_at — i.e. the write that touched the record was the restart, not a settings change.
No new kind:30177 was published; the relay still carries the one from creation time with respond_to: owner-only.
Harness log, all four starts including the one right after saving: buzz-acp starting: … respond_to=owner-only
The edit dialog itself shows Anyone as the current value when reopened, so the UI and the record disagree with no error shown.
One place that might be worth checking, given "edit fails / create works" — desktop/src/features/agents/ui/AgentInstanceEditDialog.tsx:714:
The field is only put on the wire when it differs from the baseline the dialog loaded. If that baseline can come to hold the new value while the record still holds the old one, saving becomes a no-op no matter how often it is repeated — which matches the symptom exactly. I could not confirm from outside the running app whether that is what happens, so treat this as a lead rather than a diagnosis.
Workaround that reliably works: delete the agent and recreate it with the desired setting chosen before the first save.
"Create works, edit fails" is the most useful narrowing this thread has had. Chasing it through the backend produced one confirmation, one correction, and one thing nobody here has ruled out — and the last is the reason I would not fix anything before running the test at the bottom.
Your lead has a concrete counterpart in the backend.update_managed_agent merges the patch like this (desktop/src-tauri/src/commands/agent_models_update.rs:162):
let prospective_mode = input.respond_to.unwrap_or(record.respond_to);
and later assigns record.respond_to = prospective_mode. So an omitted field is not merely skipped — it is actively written back as the old value, and updated_at moves. That matches your record showing a write that changed nothing.
But the baseline is probably not where you think. The dialog's prop is typed ManagedAgent, which is built by build_managed_agent_summary — and there (managed_agents/runtime.rs:341) the field comes from record.respond_to, the same instance field the harness gates on, not from definition_respond_to. So a wrong field mapping does not explain it. For your theory to hold, the poisoning has to come from the client side: the cached ManagedAgent being updated from the submitted input rather than from the record the command returns. That is a sharper hypothesis than "the baseline can hold the new value", and it is testable in the frontend alone.
The thing nobody has ruled out. There is a compile-time clamp (managed_agents/access_policy.rs):
When it is set, projected_access_with_policy returns OwnerOnlyregardless of the stored record, and that is what build_respond_to_env hands the harness. In a build packaged that way, no store fix can ever change the startup line — the UI is offering a control that packaging overrides, which would make this issue's title literally correct and not a persistence bug at all. (Incidentally the doc comment names BUZZ_BUILD_... while the code reads BUZZ_DESKTOP_BUILD_...; the code is authoritative.)
The test that separates the two causes. With the app fully closed, edit respond_to and respond_to_allowlist directly in the instance records of managed-agents.json — the ones with a non-empty pubkey; the file holds two records per agent and the definition one is not what the harness reads. Start the app and read the lastbuzz-acp starting: line in the harness log (it is appended across runs, so the first line is an old start):
starts with your chosen mode → the clamp is off in your build, and the bug is entirely in the UI/store write path, where your lead points;
still respond_to=owner-only → the clamp is compiled in, and every store-side fix in this thread is aimed at the wrong layer.
One data point for the first branch. On Windows, Desktop 0.5.14, official build: hand-editing the instance records gave respond_to=allowlist(1) at startup and the agents began accepting workflow-authored mentions. It also survived an in-place update to a newer version, so the app did not rewrite those records. That build therefore does not carry the clamp — and it gives a workaround short of delete-and-recreate, which matters for anyone with agent identities they would rather keep.
Still reproducible on Desktop v0.5.20 (macOS, Apple Silicon), hosted *.communities.buzz.xyz relay, Codex-runtime agent. The newest report in this thread was 0.5.19, so adding a data point one release later, plus a one-line check that separates this bug from the owner-only build clamp.
It confirms @andystrobel's "create works, edit fails" narrowing. The agent (BHM-MDR-Orchestrator, eac62543…) was created 2026-08-31 with the default owner-only and edited today. Two separate saves, both dropped.
Evidence
Edit agent → Advanced → Who can send instructions → Selected people, two pubkeys added (one of them the agent's own owner), then Save changes. The store is ~/Library/Application Support/xyz.block.buzz.app/agents/managed-agents.json; printing name | respond_to | respond_to_allowlist | updated_at after each save:
BHM-MDR-Orchestrator | owner-only | [] | updated_at: 2026-09-02T06:12:01.837707+00:00 ← first save
BHM-MDR-Orchestrator | owner-only | [] | updated_at: 2026-09-02T06:28:50.350806+00:00 ← second save
updated_at moves, so the save reaches disk — the value is what gets dropped. There are two rows per agent in this store (one with an empty pubkey, one with the agent pubkey, per #4620); after the save neither row carries the allowlist. No error, no warning. The Profile → Runtime panel then reads back Who can send instructions: Only <owner> (you) (owner), so the UI is honest about the persisted state — it does not falsely show allowlist in this build.
The first save auto-restarted the agent (auto_restart_on_config_change), and the harness came up owner-only:
Relay side: the agent's kind:30177 record is still the one from 2026-08-31T03:53:33 with respond_to: owner-only — no republish followed either save.
Not a storage-layer fault
Two other agents in the same file hold working values — Bumble-Sol and Honey-Haiku, both respond_to: allowlist with ["e96373d4…"] — and they keep them through the app's bulk rewrites (their updated_at was refreshed to 2026-09-02T05:55:11 with the values intact). The schema and persistence work; the form → record write is what drops the selection.
A cheap discriminator worth adding to the repro steps
Anyone triaging this should check the tail of the buzz-acp starting: line, because it distinguishes three different causes in one read:
respond_to=allowlist(N) — the edit landed (Config::summary, crates/buzz-acp/src/config.rs).
respond_to=owner-onlywith a trailing allowed_respond_to=[owner-only] — this is the packaging clamp BUZZ_DESKTOP_BUILD_AGENT_ACCESS_OWNER_ONLY (desktop/src-tauri/src/managed_agents/access_policy.rs), which pins the gate regardless of the record. Not this bug.
respond_to=owner-onlywithout that suffix — the value genuinely came from the record. This bug.
Our line has no allowed_respond_to= suffix, so the clamp is ruled out here.
Note
I did not dump the full records, only the four fields above, so I can't say which of the two rows is the definition and which is the instance. Happy to add a full field-level diff of both rows if that would help narrow #2505.
Confirming the discriminator holds, and adding the half that makes its negative meaningful — plus an answer to your open question about the two rows.
Why "no suffix" is real evidence and not just absence. In build_respond_to_env_with_policy (desktop/src-tauri/src/managed_agents/access_policy.rs) the clamp does not only add the variable, the other branch explicitly removes it:
if enforced_owner_only {
set.push(("BUZZ_ACP_ALLOWED_RESPOND_TO",RespondTo::OwnerOnly.as_str().to_string()));}else{
remove.push("BUZZ_ACP_ALLOWED_RESPOND_TO");}
and Config::summary emits the allowed_respond_to=[…] fragment only for a non-empty list. So for a desktop-spawned agent the suffix is present exactly when the clamp is on, and its absence rules out both the packaging clamp and any ambient guard someone set by hand. That is a stronger claim than "I did not see it", and it is what makes your three-way read trustworthy.
Which row is which. The row with an empty pubkey is the definition; the one carrying the agent's pubkey is the instance, and the instance is what the harness gates on — build_respond_to_env takes the record it is spawning. So when triaging, the interesting print is four fields per row rather than two:
On Windows 0.5.14 that print showed the divergence directly: the definition rows held respond_to: owner-onlyanddefinition_respond_to: allowlist at the same time, while the instance rows held whatever was last written to them. In other words the UI's selection had reached one field on one row and nothing else — which is a different shape from your result, where neither row carries the allowlist at all. Worth distinguishing in #2505: a selection landing in the definition-only field, versus a selection landing nowhere.
On your two agents that keep working values — worth checking whether their allowlist was ever set through the dialog, or arrived some other way (created with it, imported, or written to the file directly). If the working ones were never edited through the form, that is the same "create works, edit fails" boundary from the other side, and it would make the form → record write the only remaining suspect rather than one of several.
For what it is worth, hand-editing the instance rows with the app closed is a workaround that survives an in-place version update, so nobody needs to delete and recreate an agent identity to get out of this.
We reproduce this on Desktop 0.5.26 (macOS). If managed-agents.json is edited while Desktop is running, our changes are lost when Desktop quits. To get the allowlist/harness changes to stick, our operator has to quit Desktop fully, wait for a watcher script to patch the file, and then reopen Desktop. With 30+ assistants serving individual staff members, we need allowlist edits made in the UI to persist and reach the running harness, with no manual file edits. See also #6111.
Activity
chessing234 commentedon Jul 23, 2026
Fixed in https://github.com/block/buzz/pull/ — definition respond-to now propagates to linked instances.
chessing234 commentedon Jul 23, 2026
Fixed in #2505 — definition respond-to now propagates to linked instances.
Marabun commentedon Jul 25, 2026
Still reproduces on Desktop v0.4.24 — PR #2505 is not merged yet
Heads up before this gets closed on the "Fixed in #2505" note above: PR #2505 is still open and its new files are absent from
main(desktop/src-tauri/src/commands/personas/propagate.rsandrespond_to_propagation_tests.rsboth 404 onmainas of 2026-07-25). So the fix has not shipped in v0.4.24 (released 2026-07-23T23:09Z) or v0.4.25 (2026-07-24T23:04Z).I hit this independently on v0.4.24 (macOS 26.5.2, arm64, bundle installed 2026-07-24T01:35Z, hosted relay) and can add one field-level detail the original report doesn't cover.
The instance record is never touched at all
@georgerous showed the desync on the definition entry. In my
managed-agents.jsonthe instance entry — the one the harness actually reads — had no trace of the UI write:Timeline on one agent, all on v0.4.24:
definition_respond_toonly)buzz-acp starting: … respond_to=owner-onlyrespond_to: "anyone"on both records, app fully quitbuzz-acp starting: … respond_to=anyone✅managed-agents.jsonitself — edit survivedbuzz:workflow, noauthtag) → agent repliedTwo things worth noting: a Stop → Start of the agent alone does not pick up the saved value (22:11 worked only because the file changed, not because of the restart), and the app does not revert a hand-edit even when it rewrites the file later — corroborating that the config file is the source of truth.
Severity is higher than it looks: there is no supported workaround
The env override documented in
crates/buzz-acp/README.mdandTESTING.md(BUZZ_ACP_RESPOND_TO=anyone) is unreachable from Desktop — the key is inRESERVED_ENV_KEYS(desktop/src-tauri/src/managed_agents/env_vars.rs), so the agent env-vars form rejects it at save time:That reservation is deliberate and, per the comment in that file, correct — a user-supplied override would silently diverge from the saved security setting. Not asking for it to be lifted. The point is that with the env path (rightly) closed and the UI path broken, hand-editing JSON is the only way to change
respond_toat all, so #2501 is the sole path for this setting rather than one of two.One practical wrinkle for that workaround: every
buzz-acpprocess is a child ofbuzz-desktop, so an agent cannot patch the file on its owner's behalf — quitting the app to release it also kills the agent doing the edit. It takes a detached process (or a human in a terminal) to apply.Happy to test a build once #2505 lands.
lothesito commentedon Jul 26, 2026
Still reproduces on Buzz Desktop 0.4.26 (Linux, AppImage), on a self-hosted relay with
require_relay_membership=true.Two things to add: a fresh repro on a different agent type, and a UI detail that may be the mechanism.
Repro
Agent created via Import agent snapshot (
buzz-agent-snapshot v1), so it is persona-linked (persona_idset) rather than a hand-built custom agent — the original report was a custom agent, so this is not specific to how the agent was made.Anyone.What lands on disk
managed-agents.jsonafter the save — the agent has two rows, and neither ends up with the value the UI shows:respond_todefinition_respond_toowner-onlyanyoneowner-onlynullSo the UI writes
definition_respond_toon the persona row, while the instance row — the one that actually spawns — is never touched at all. That is a third out-of-sync state beyond the two in the original report.What the harness starts with
After a full stop/start,
buzz-acpstill comes up owner-only:UI detail that may be the mechanism
In the edit dialog, Advanced → Who can talk to this agent is rendered under both AI-configuration tabs, but the save affordance is not:
So a user who is customizing the agent has no way to submit this field from the view they are in.
Not every field in the dialog is affected
Editing the system prompt in the same dialog saves correctly: the new text lands on both the persona row and the instance row, with identical hashes. So this is not "agent edits don't persist" in general — it is scoped to the Advanced block.
Effect
Setting an agent to
AnyoneorAllowlisthas no effect in 0.4.26 — every managed agent stays owner-only regardless of what the UI reports, so no non-owner member can interact with any agent.peridot-augustus commentedon Jul 28, 2026
Still reproduces on 0.5.0 (Debian 13, self-hosted relay) — and it has an agent-to-agent consequence worth recording
Confirming on the current release, plus one impact that has not come up yet in this thread.
Version: Buzz
0.5.0(Debian package, amd64, trixie), self-hosted relay0.2.0, six managed agents, runtimesclaude(claude-agent-acp0.63.0) andcodex(codex-acp1.1.7). PR #2505 is still open anddesktop/src-tauri/src/commands/personas/propagate.rsstill 404s onmain, so the fix is not in 0.5.0 either — that now covers 0.4.23, 0.4.24, 0.4.26 and 0.5.0.Registry state,
~/.local/share/xyz.block.buzz.app/agents/managed-agents.json, five agents all configured with an allowlist persona:Same desync described above, and the harness environment agrees with the stale field rather than the definition:
definition_parallelismdesyncs the same way (1in the definition,10live) — that part is #3095, noting it only as evidence that the non-propagation is general todefinition_*, not specific to respond-to.The part that is new:
owner-onlydoes not restrict agent-to-agent trafficEverything above is about human members being unable to reach an agent. The inverse also holds, and it is the more consequential half.
With all five agents fallen back to
respond_to: owner-onlyand an empty allowlist, I ran a deliberate routing probe: agent C (a review-role agent, not the coordinator, and not in anyone's allowlist) sent a task directly to agent E, instructing it to perform a live production operation with no authorization contract.E received it, woke, processed it, and replied within six seconds. It declined — but on its own system-prompt grounds, quoting the missing authorization, not because any gate rejected the sender. Its reply names the problem itself:
So on observed behaviour
owner-onlyappears to resolve through theauthtag that every managed-agent event carries, not through the sender pubkey. Every agent under one owner key satisfies it. The intended two-principal restriction was configured, is visible in the registry, and is not in force in either direction.Practical effect for anyone running a multi-agent setup with differentiated roles: the sender restriction cannot currently be relied on as a control. In our case the only thing that stopped an unauthorized live-write instruction from being acted on was the receiving agent's own prompt discipline. That worked, but prompt discipline is not a mechanism, and this bug is what removes the mechanism behind it.
Not filing this separately since it is the same root cause as this issue. Happy to open one if maintainers would rather track the agent-to-agent authorization angle on its own.
jsilets commentedon Jul 29, 2026
Still reproduces on Buzz Desktop 0.5.0 (this report was 0.4.23), macOS 26.2, self-hosted relay at NIP-11
version: 0.2.0. Some extra detail on the persisted shape that may help narrow the write path.managed-agents.jsonholds two records per managed agent, and the desync is between them rather than within one record:pubkey: ""pubkey: "<real hex>", carryinglast_started_atChanging "Who can talk to this agent" in Desktop writes
definition_respond_to/definition_respond_to_allowlistonto the definition record only. The instance record keepsrespond_to/respond_to_allowlist, andbuzz-acpgates on the instance record — so the edit has no runtime effect.Current state of this install, all three edited agents:
definition_respond_to: "allowlist", allowlist[6e48d98d…]respond_to: "owner-only",respond_to_allowlist: []definition_respond_to: "anyone"respond_to: "owner-only",[]definition_respond_to: "anyone"respond_to: "owner-only",[]It does not converge over time or across restarts. agent-1's instance record shows
last_started_at: 2026-07-29T04:48:11Z, and the file has been rewritten at least twice since the Desktop edit (most recently04:58:02Z) with the instance record unchanged each time.Possibly useful for whoever picks this up: the instance-level field is not universally unwritable. In the same file, two other agents carry a populated instance-level allowlist:
So some surface — a different code path, an older Desktop version, or the pairing/provisioning flow — does write
respond_toon the instance record. Identifying which one writes it correctly probably localizes what the Advanced-settings editor is missing.MaxWynnDev commentedon Jul 30, 2026
Still reproduces on Desktop v0.5.2 / Windows 11, against a hosted relay. So this is not macOS-specific, not self-hosted-relay-specific, and not fixed in the 0.4.23 to 0.5.2 range.
Same signature you described, plus one detail I did not see in the original report: the desync spans two records, and the one the harness reads is not the one the UI writes.
%APPDATA%\xyz.block.buzz.app\agents\managed-agents.jsonholds both a persona/definition record and a provisioned instance record for the same custom agent (runtimeclaude). After setting Who can talk to this agent to Allowlist, adding two members, and clicking Save changes:That reads as two separable defects:
respond_to_allowliststays[]on both records.definition_respond_tocaptures the mode but nothing captures the people.definition_respond_tolands on the persona record, butbuzz-acpis launched from the instance record, which never receives it.The Save does write the file. Its mtime updates on every Save, and unrelated fields in the same file are updated normally. So this is an incomplete write rather than a failed one.
One narrowing signal that may help isolate it: allowlists populated by the builtin Welcome Team mechanism persist correctly. Those instance records carry
respond_to=allowlistwith a sibling agent pubkey, and they survive app relaunch. So the field, the mode and the serialization all work end to end. Only the UI person-picker write path fails.Why this costs more than it looks
The failure is completely silent in both directions. There is no error in the UI, and there is no line in the agent log either, because the inbound author gate drops non-owner events before they are forwarded to the harness. From the operator's side the agent is connected, subscribed, presence online, and simply never answers teammates, which reads as the agent being broken or ignoring people rather than as an access setting.
Two small changes would have collapsed the diagnosis from hours to minutes:
Workaround confirmed on Windows
Same as yours. With the app fully closed, hand-editing the instance record to
respond_to: "allowlist"with the member pubkeys inrespond_to_allowlist, then relaunching, works. The app preserved the manual edit across relaunch and rewrote the file without reverting it, and the harness came up correctly:Worth noting for anyone hitting this: editing the persona record instead of the instance record will look like it worked and change nothing, since the harness only reads the instance record.
Possibly related: #3030.
georgerous commentedon Jul 30, 2026
Confirming the split — that's a cleaner decomposition than my original report,
and the Welcome Team contrast is the useful narrowing signal: mode, field and
serialization all work end to end, only the person-picker write path fails.
Worth flagging for anyone tracking #2505: it fixes your defect (2) only. I've
raised there that the propagation helper it adds has no empty-allowlist guard,
so with your defect (1) still in place it can push
allowlistwith an emptylist onto instance records — a state the mint path explicitly rejects. Both need
to land for this to actually work end to end.
Strong agreement on the debug log for the author gate. The silent inbound drop
is why this reads as "the agent is ignoring people" rather than "a setting is
wrong", and it's most of the diagnosis cost on my side too.
FabianHertwig commentedon Jul 31, 2026
If you go to the channel members list then you can edit the responds to for that channel there. I didn't know that, and it is a bit hidden and a not very intuitive place.
georgerous commentedon Jul 31, 2026
That works, and it's worth saying why it works, because it points straight at
the bug.
EditRespondToDialog(channel → members sidebar → agent card) seeds fromagent.respondTo/agent.respondToAllowlistand writes viaupdateManagedAgent({ pubkey: agent.pubkey, respondTo, respondToAllowlist })—i.e. straight to the instance record by pubkey, the one
buzz-acpactuallyreads. It skips the persona→instance indirection where both defects live, and it
carries the allowlist rather than dropping it. It even has the empty-allowlist
guard (
respondTo !== "allowlist" || respondToAllowlist.length > 0) that thepersona path is missing.
So the picture is: the instance-level UI has always been correct, and the
persona-level "Who can talk to this agent" control is the broken one. Two
caveats for anyone using this as a workaround — it's per instance, not per
persona, so you repeat it for every agent; and it won't survive the instance
being re-minted from its definition.
Agreed the placement is unintuitive. Given the persona control is the one that
looks authoritative and silently does nothing, having the working control live
in a channel sidebar is most of why this took people hours.
iroiro147 commentedon Aug 1, 2026
Root-caused this one: the persona behavior edit path (
update_persona→apply_persona_behavior) wrote only to the definition, but the harness readsrespond_tofrom the instance record at spawn (build_respond_to_env). The cascade to linked instances existed foravatar_url/display_namebut was never built for the behavioral group — so instances froze at whatever mode was minted once viaresolve_mint_behavioral_defaults(owner-only default), and the only fix was hand-editingmanaged-agents.json.PR #4115 fixes the write gap:
update_persona_withnow cascades behavior edits to linked instances using the same override-discrimination the display name cascade already has — instances still inheriting (matching the pre-edit value) adopt the new mode; explicitly pinned instances are preserved. Absent definitionparallelismdoesn't stomp an instance pool width; unknown mode strings error out instead of silently rewriting. Six regression tests pinned.iroiro147 commentedon Aug 2, 2026
I've opened #4270 with a fix. Root cause: the edit dialog gated the allowlist payload on
submitMode === 'allowlist' && listChanged, so a mode flip to Allowlist with an unchanged-but-pre-existing list (e.g. Anyone → Allowlist where the list was saved in an earlier session) sent only the mode — the record kept a statebuzz-acpreads asowner-only. This is exactly your workaround-vs-UI desync: the dialog wasn't writingrespond_to/respond_to_allowliston that transition. Fix: a canonicalcomputeRespondToWirePatchhelper sends the allowlist payload whenever the submitted mode isallowlistAND (mode changed OR list changed), so the harness always receives{mode, allowlist}atomically. 6 new tests cover the full transition matrix; full webview suite green (3912 passing) + tsc clean.EasyTechWithHassan commentedon Aug 2, 2026
Confirming this is still present in Desktop v0.5.3 (macOS, relay *.communities.buzz.xyz, claude-agent-acp harness), with two additional data points:
The Edit-agent dialog displays "Anyone" after reopening — so the failure is invisible to the user; only the config file / spawn environment reveals the truth. A file watcher on managed-agents.json shows every Save writes respond_to: "owner-only" again.
Ground-truth check that made diagnosis reliable: inspect the spawned process env (ps eww on buzz-acp) — it always showed BUZZ_ACP_RESPOND_TO=owner-only after UI edits. After hand-editing respond_to + respond_to_allowlist (app closed) the runtimes spawn correctly (BUZZ_ACP_RESPOND_TO=allowlist with the right BUZZ_ACP_RESPOND_TO_ALLOWLIST pubkeys) and allowlist mode works end-to-end at runtime — verified across 4 agents. So the bug is purely the dialog's save path.
juddkussrow commentedon Aug 3, 2026
Confirming this on v0.5.3 (reported here against v0.4.23), and adding
evidence that the impact is considerably wider than the allowlist case.
Still present on 0.5.3, and no restart clears it
Setting Who can send instructions → Anyone and restarting produced
respond_to=owner-onlyon every startup — escalating through the restartbutton, a manual stop/start, and a full quit-and-relaunch of Buzz Desktop:
The UI showed Anyone (with its access warning) throughout.
managed-agents.jsonshows the desync exactly as diagnosed here — and note itaffects two records, not just the definition. The agent instance row is
stale as well:
So a fix that syncs only the definition row may still leave running instances on
owner-only.The bigger consequence: workflows cannot drive agents
This is the part I think is under-weighted in the current title and description.
Workflow-posted messages are not signed by the owner. A workflow
send_messageposts under its own identity, with the owner only as aptag:{ "kind": 9, "pubkey": "12f6870117eff1a6…", "tags": [["p","<owner pubkey>"], ["h","<channel>"], ["buzz:workflow","true"]] }Under
respond_to=owner-only, that fails the sender check. And since workflowscannot invoke agents directly — per ARCHITECTURE.md, that bridge exists only in
buzz-acp, so an
@mentionposted by a workflow is the only available mechanism —owner-onlymeans no workflow can wake any agent.I verified this is the operative constraint by editing
managed-agents.jsondirectly (both rows) to
"anyone"and restarting. With the runtime value actuallywidened, a workflow-posted
@mentionwakes the agent in 9 seconds. Nothingelse about the setup changed.
So the mechanism works fine — the only thing standing between a user and
workflow-driven agents is that this setting cannot be changed from the UI.
Right now the sole route to Workflows + Agents, arguably the headline combination
in Buzz, is hand-editing a JSON file in Application Support and relaunching.
(In the interest of not sending you down a wrong path: I originally attributed a
longer series of silent workflow-mention failures to this issue. They turned out
to have a second, independent cause — two channel members shared a display name,
so the workflow's
@Nameresolved to noptag at all. That is a separate report.The
respond_todesync above is reproducible on its own and is what this commentis about.)
It fails completely silently
There is no error, no rejected-mention log line, and no UI feedback. The agent
simply doesn't respond, which is indistinguishable from the agent being stopped,
unauthenticated, or not a channel member — all of which we ruled out one at a time
before finding this issue.
Worth noting that
buzz-acplogs startup, shutdown, channel subscription anderrors, but not successful turn processing — so a silent log is the normal
state and gives no signal either way. Logging rejected mentions at INFO would
have made this self-diagnosable in seconds.
Suggestions, in the order I'd value them
respond_to(andrespond_to_allowlist) on both thedefinition and any existing instance rows.
respond_towould have saved hours here.UI/runtime mismatch is visible without reading the harness log.
ptag names the owner and
buzz:workflowis set. That would letowner-onlybehave the way users clearly expect, without anyone having to widen an agent
to Anyone — which the UI itself warns grants filesystem and connected-tool
access.
Point 4 matters because the current workaround for anyone wanting workflow-driven
agents is to set Anyone, which is a genuinely broad grant for what should be
"my own automation may talk to my own agent."
Happy to provide the full harness logs or re-run anything — the reproduction is
stable and immediate.
DrDoomi commentedon Aug 5, 2026
Reproduced on Desktop 0.5.5 (macOS). @FabianHertwig your "fix" works for me.
otymartin commentedon Aug 9, 2026
Fresh Desktop v0.5.8 result on macOS Apple Silicon, hosted
*.communities.buzz.xyzrelay, custom Grok agents:respond_toandrespond_to_allowlist. Restarting the agent therefore used the old instance gate. I restored the definition selection after the test.BUZZ_ACP_RESPOND_TOandBUZZ_ACP_RESPOND_TO_ALLOWLISTwith:the following env vars are reserved by Buzz and cannot be overridden.@Peggy Olsonmessage under the owner identity, with a real mention tag. Peggy started withrespond_to=owner-only, accepted that workflow post, and replied in the workflow-message thread with the requested exact value. The observed path was:So on v0.5.8, workflows can wake an
owner-onlyagent without widening the recipient to Anyone. The remaining response-scope defect is specifically definition/persona edits not propagating to an already-provisioned instance (plus the reserved-env limitation), rather than workflow posts necessarily having a non-owner author.One separate anomaly surfaced during the same proof: workflow creation returned success and the workflow executed, but the Workflows page continued to show
No workflows yetafter refresh. That appears distinct from this issue.artemtrofymenko commentedon Aug 10, 2026
A workaround that survives restart: patch the instance records directly
Confirming on Desktop v0.5.8 / Windows 11, self-hosted relay
ghcr.io/block/buzz:main. The desync is exactly as @jsilets and @MaxWynnDev describe — the definition record getsdefinition_respond_to, the instance record keepsrespond_to, and the harness gates on the instance. Since #2505 is still unmerged, here is a workaround I verified end to end; I did not find one anywhere in this thread.With Buzz fully closed, edit
%APPDATA%\xyz.block.buzz.app\agents\managed-agents.jsonand set, on each instance record (the ones with a non-emptypubkey):Leave the definition records alone. On the next start the harness comes up with
instead of
respond_to=owner-only, and it stays that way across restarts.Evidence that behaviour changes, not just the log line. My case is a Workflow posting
@agentprompts on a timer, so the allowlisted pubkey is the workflow engine's, not a human member's. The relay event log shows a clean cutoff at the restart that picked up the patched records:Every mention before the restart was dropped; every one after was answered, across four agents on three runtimes (
claude,codex,buzz-agent).Scope of what I tested. The allowlist entry I verified is a service pubkey, not a human member, and I did not test
anyone. The gate does not distinguish the two, so I would expect a member pubkey to behave the same, but I have not measured it.It is fragile. The app rewrites instance records during its own operations, so editing that agent in the UI afterwards can silently restore
owner-only. The only reliable check is the harness startup line — the UI keeps showing the value you picked either way.A second-order impact worth recording: while the gate is stuck, Workflows cannot drive managed agents at all. The workflow engine signs its messages with the relay key, so it is neither the owner nor an owner-verified agent, and an
owner-onlygate drops every step it posts. The run itself is healthy — delays honoured to the second, mentions resolved with correctptags — it just talks to nobody. That failure mode is invisible from the Workflows UI: the run completes green.docs: workflows cannot drive owned agents on the release build
docs: the respond-to workaround is verified, not speculative
fix(desktop): guard the behavior cascade against Allowlist+[] and sam…
andystrobel commentedon Sep 1, 2026
Still reproducible on Desktop v0.5.19 (macOS, Apple Silicon), self-hosted relay
ghcr.io/block/buzz:main.Hit this twice in two days on two different agents. Adding one observation that I did not see in this thread or in #5858 / #6026 / #4487, because it narrows the surface considerably:
Setting
respond_toat creation time works. Only editing it afterwards fails.Three agents created with "Anyone" selected before the first save came out correct and are reachable by non-owner members. Two agents created with the default and then edited to "Anyone" stayed on
owner-only— through repeated saves and app restarts.Evidence for one of them (
b4cc9af0…):respond_to: "owner-only", whileupdated_at==last_started_at— i.e. the write that touched the record was the restart, not a settings change.kind:30177was published; the relay still carries the one from creation time withrespond_to: owner-only.buzz-acp starting: … respond_to=owner-onlyOne place that might be worth checking, given "edit fails / create works" —
desktop/src/features/agents/ui/AgentInstanceEditDialog.tsx:714:The field is only put on the wire when it differs from the baseline the dialog loaded. If that baseline can come to hold the new value while the record still holds the old one, saving becomes a no-op no matter how often it is repeated — which matches the symptom exactly. I could not confirm from outside the running app whether that is what happens, so treat this as a lead rather than a diagnosis.
Workaround that reliably works: delete the agent and recreate it with the desired setting chosen before the first save.
artemtrofymenko commentedon Sep 1, 2026
"Create works, edit fails" is the most useful narrowing this thread has had. Chasing it through the backend produced one confirmation, one correction, and one thing nobody here has ruled out — and the last is the reason I would not fix anything before running the test at the bottom.
Your lead has a concrete counterpart in the backend.
update_managed_agentmerges the patch like this (desktop/src-tauri/src/commands/agent_models_update.rs:162):and later assigns
record.respond_to = prospective_mode. So an omitted field is not merely skipped — it is actively written back as the old value, andupdated_atmoves. That matches your record showing a write that changed nothing.But the baseline is probably not where you think. The dialog's prop is typed
ManagedAgent, which is built bybuild_managed_agent_summary— and there (managed_agents/runtime.rs:341) the field comes fromrecord.respond_to, the same instance field the harness gates on, not fromdefinition_respond_to. So a wrong field mapping does not explain it. For your theory to hold, the poisoning has to come from the client side: the cachedManagedAgentbeing updated from the submitted input rather than from the record the command returns. That is a sharper hypothesis than "the baseline can hold the new value", and it is testable in the frontend alone.The thing nobody has ruled out. There is a compile-time clamp (
managed_agents/access_policy.rs):When it is set,
projected_access_with_policyreturnsOwnerOnlyregardless of the stored record, and that is whatbuild_respond_to_envhands the harness. In a build packaged that way, no store fix can ever change the startup line — the UI is offering a control that packaging overrides, which would make this issue's title literally correct and not a persistence bug at all. (Incidentally the doc comment namesBUZZ_BUILD_...while the code readsBUZZ_DESKTOP_BUILD_...; the code is authoritative.)The test that separates the two causes. With the app fully closed, edit
respond_toandrespond_to_allowlistdirectly in the instance records ofmanaged-agents.json— the ones with a non-emptypubkey; the file holds two records per agent and the definition one is not what the harness reads. Start the app and read the lastbuzz-acp starting:line in the harness log (it is appended across runs, so the first line is an old start):respond_to=owner-only→ the clamp is compiled in, and every store-side fix in this thread is aimed at the wrong layer.One data point for the first branch. On Windows, Desktop 0.5.14, official build: hand-editing the instance records gave
respond_to=allowlist(1)at startup and the agents began accepting workflow-authored mentions. It also survived an in-place update to a newer version, so the app did not rewrite those records. That build therefore does not carry the clamp — and it gives a workaround short of delete-and-recreate, which matters for anyone with agent identities they would rather keep.halilozturkci commentedon Sep 2, 2026
Still reproducible on Desktop v0.5.20 (macOS, Apple Silicon), hosted
*.communities.buzz.xyzrelay, Codex-runtime agent. The newest report in this thread was 0.5.19, so adding a data point one release later, plus a one-line check that separates this bug from the owner-only build clamp.It confirms @andystrobel's "create works, edit fails" narrowing. The agent (
BHM-MDR-Orchestrator,eac62543…) was created 2026-08-31 with the default owner-only and edited today. Two separate saves, both dropped.Evidence
Edit agent → Advanced → Who can send instructions → Selected people, two pubkeys added (one of them the agent's own owner), then Save changes. The store is~/Library/Application Support/xyz.block.buzz.app/agents/managed-agents.json; printingname | respond_to | respond_to_allowlist | updated_atafter each save:updated_atmoves, so the save reaches disk — the value is what gets dropped. There are two rows per agent in this store (one with an emptypubkey, one with the agent pubkey, per #4620); after the save neither row carries the allowlist. No error, no warning. The Profile → Runtime panel then reads backWho can send instructions: Only <owner> (you) (owner), so the UI is honest about the persisted state — it does not falsely showallowlistin this build.The first save auto-restarted the agent (
auto_restart_on_config_change), and the harness came up owner-only:Relay side: the agent's kind:30177 record is still the one from 2026-08-31T03:53:33 with
respond_to: owner-only— no republish followed either save.Not a storage-layer fault
Two other agents in the same file hold working values —
Bumble-SolandHoney-Haiku, bothrespond_to: allowlistwith["e96373d4…"]— and they keep them through the app's bulk rewrites (theirupdated_atwas refreshed to2026-09-02T05:55:11with the values intact). The schema and persistence work; the form → record write is what drops the selection.A cheap discriminator worth adding to the repro steps
Anyone triaging this should check the tail of the
buzz-acp starting:line, because it distinguishes three different causes in one read:respond_to=allowlist(N)— the edit landed (Config::summary,crates/buzz-acp/src/config.rs).respond_to=owner-onlywith a trailingallowed_respond_to=[owner-only]— this is the packaging clampBUZZ_DESKTOP_BUILD_AGENT_ACCESS_OWNER_ONLY(desktop/src-tauri/src/managed_agents/access_policy.rs), which pins the gate regardless of the record. Not this bug.respond_to=owner-onlywithout that suffix — the value genuinely came from the record. This bug.Our line has no
allowed_respond_to=suffix, so the clamp is ruled out here.Note
I did not dump the full records, only the four fields above, so I can't say which of the two rows is the definition and which is the instance. Happy to add a full field-level diff of both rows if that would help narrow #2505.
artemtrofymenko commentedon Sep 2, 2026
Confirming the discriminator holds, and adding the half that makes its negative meaningful — plus an answer to your open question about the two rows.
Why "no suffix" is real evidence and not just absence. In
build_respond_to_env_with_policy(desktop/src-tauri/src/managed_agents/access_policy.rs) the clamp does not only add the variable, the other branch explicitly removes it:and
Config::summaryemits theallowed_respond_to=[…]fragment only for a non-empty list. So for a desktop-spawned agent the suffix is present exactly when the clamp is on, and its absence rules out both the packaging clamp and any ambient guard someone set by hand. That is a stronger claim than "I did not see it", and it is what makes your three-way read trustworthy.Which row is which. The row with an empty
pubkeyis the definition; the one carrying the agent's pubkey is the instance, and the instance is what the harness gates on —build_respond_to_envtakes the record it is spawning. So when triaging, the interesting print is four fields per row rather than two:On Windows 0.5.14 that print showed the divergence directly: the definition rows held
respond_to: owner-onlyanddefinition_respond_to: allowlistat the same time, while the instance rows held whatever was last written to them. In other words the UI's selection had reached one field on one row and nothing else — which is a different shape from your result, where neither row carries the allowlist at all. Worth distinguishing in #2505: a selection landing in the definition-only field, versus a selection landing nowhere.On your two agents that keep working values — worth checking whether their allowlist was ever set through the dialog, or arrived some other way (created with it, imported, or written to the file directly). If the working ones were never edited through the form, that is the same "create works, edit fails" boundary from the other side, and it would make the form → record write the only remaining suspect rather than one of several.
For what it is worth, hand-editing the instance rows with the app closed is a workaround that survives an in-place version update, so nobody needs to delete and recreate an agent identity to get out of this.
ahmetertem06 commentedon Oct 15, 2026
We reproduce this on Desktop 0.5.26 (macOS). If
managed-agents.jsonis edited while Desktop is running, our changes are lost when Desktop quits. To get the allowlist/harness changes to stick, our operator has to quit Desktop fully, wait for a watcher script to patch the file, and then reopen Desktop. With 30+ assistants serving individual staff members, we need allowlist edits made in the UI to persist and reach the running harness, with no manual file edits. See also #6111.