Skip to content

set-add-policy replaces the full kind:10100 record, hiding the agent from mention autocomplete #3663

Description

@gabrielgcarmona

Describe the bug

buzz channels set-add-policy silently removes an agent from Desktop's mention
autocomplete.

kind:10100 (agent profile) is replaceable — crates/buzz-core/src/kind.rs:783
asserts is_replaceable(KIND_AGENT_PROFILE). The CLI publishes it with a single
field (crates/buzz-cli/src/commands/channels.rs:1035):

let content = serde_json::json!({ "channel_add_policy": policy }).to_string();

Because the event is replaceable, this replaces the agent's full directory
record rather than merging into it. Every other field the record carried —
respond_to, respond_to_allowlist, channel_ids, name, agent_type — is
gone.

Nothing surfaces the loss:

  • The relay accepts it. handle_agent_profile only reads channel_add_policy
    (crates/buzz-relay/src/handlers/side_effects.rs:1172) and ignores the rest.
  • Desktop hides the agent without an error. In
    desktop/src/features/agents/lib/agentAutocompleteEligibility.ts:21,
    relayAgentIsSharedWithUser reads agent.respondTo, which is now undefined,
    so neither branch matches and the agent is not invocable. Then
    shouldHideAgentFromMentions treats "in the directory but not invocable" as an
    explicit exclusion signal and hides it.

The result is counter-intuitive: an agent with no kind:10100 shows up; an
agent with a partial kind:10100 disappears.
The comment at line 88 —
Unknown invocability (not in directory) => show — is what makes the
never-registered agent work.

Downstream, @name typed in a channel stays plain text with no p tag, so the
relay never delivers the event to the ACP harness (subscribe=Mentions filters
on p), and the agent never wakes — with no log line on either side.

Steps to reproduce

  1. Register a CLI-driven ACP agent (own keypair, buzz-admin add-member), give
    it a profile with buzz users set-profile, and add it to a channel.
  2. Confirm @name resolves in Desktop's composer and the agent replies.
  3. Run buzz channels set-add-policy --policy owner_only as that agent.
  4. Type @name in the same channel.

The agent no longer appears in the autocomplete. The mention is sent as plain
text and the agent never responds. Reverting with --policy anyone does not
restore it — that publishes another single-field record, so the agent stays in
the directory with respond_to still absent.

Expected behavior

set-add-policy should preserve the rest of the record: read the current
kind:10100, change only channel_add_policy, and republish the full content.

A second option would be for the relay to reject a kind:10100 whose content is
missing fields a previously stored record had — though read-modify-write in the
CLI seems simpler and keeps the relay out of client-behavior enforcement, which
channels.rs:1017 says is deliberate.

Version and platform

  • Buzz version: relay + CLI built from main (63496cc), chart buzz-0.1.6;
    Desktop 0.5.0 (packaged release)
  • OS: relay on Kubernetes (Debian container), Desktop on Windows 11

Logs / additional context

The agent's stored kind:10100 content after set-add-policy — this is the
whole record:

{"channel_add_policy":"owner_only"}

Republishing the full record restores invocability, which is the workaround:

{"pubkey":"<agent>","name":"<name>","agent_type":"claude-agent-acp",
 "channels":["<channel-name>"],"channel_ids":["<channel-uuid>"],
 "capabilities":[],"status":"online",
 "respond_to":"allowlist","respond_to_allowlist":["<owner>"],
 "channel_add_policy":"owner_only"}

So the mitigation today is to republish the whole kind:10100 after every
set-add-policy call.

Worth noting: nothing in the ACP harness publishes kind:10100 (no occurrences
in crates/buzz-acp/), so a hand-written record is not overwritten — but it is
also not maintained. If respond_to_allowlist or channel_ids change on the
agent's side, the directory silently drifts out of sync. Having the harness
publish its own record at boot would fix both this bug's blast radius and the
drift.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions