Skip to content

Release builds override the agent owner's published respond_to policy, making multi-person agent use impossible with no opt-out #6329

Closed

Description

@Schnitzel

Summary

Buzz already has a mechanism for expressing who may mention an agent: respond_to / respond_to_allowlist in the agent's kind 10100 directory entry, published by the agent's own key and bound to its owner by a NIP-OA attestation. That is the agent owner declaring their policy, and our relay stores and serves it faithfully.

Packaged release builds compile BUZZ_DESKTOP_BUILD_AGENT_ACCESS_OWNER_ONLY (#4053) and discard it. A relay agent published with respond_to: "anyone" is hidden from @ autocomplete for everyone except its owner. #6182 restored same-owner agents; agents whose owner is a different person remain unmentionable.

This makes an agent that several people can talk to impossible on the shipped app, and there is no way for anyone to change that.

Why we think this is the wrong boundary

#4053's stated rationale concerns managed agents — ones Desktop holds the key for and runs. Clamping those is coherent: the app spawns the process, so it can reasonably constrain what it starts.

A relay agent is a different thing. It runs on someone else's server, under its owner's harness, with an access policy its owner deliberately published and signed. Desktop neither starts it nor holds its key. Overriding that declaration is the app substituting its judgement for the agent owner's, about a system it does not operate.

The agent owner accepts the risk, configures the harness gate, publishes the matching directory entry, and runs the machine. That is precisely who should decide — and Buzz already gives them the vocabulary to say it.

What it breaks, concretely

We run a shared infrastructure agent for the 256 Foundation on our own relay. Several people need to mention it in a shared channel. That is the entire premise of an agent-first communication channel: agents as participants a team works with, not private assistants attached to one person.

On packaged builds this is unachievable. We configured it correctly at every layer we control:

  • harness gate BUZZ_ACP_RESPOND_TO=anyone
  • kind 10100 published with respond_to: "anyone" and the channel in channel_ids
  • all participants relay members and channel members; channel type stream

Verified the relay is not at fault: a plain relay member with no auth tag receives all agent profiles over the same /query endpoint the desktop uses. The data reaching the client is correct and identical to what the owner's client receives. The client discards it.

There is no opt-out for anyone

  • Not the operator. We run the relay. We cannot configure our own deployment's agent access, because the decision is not made on our infrastructure.
  • Not the agent owner. Publishing respond_to: "anyone" is exactly the supported way to express this, and it is ignored.
  • Not the user, short of building and running an unsigned desktop app — required of every person who wants to mention the agent, since the gate is per-viewer. That is not a reasonable ask of volunteers.

A self-hosted deployment therefore has no supported configuration in which a team can share an agent.

It also fails silently

No entry in autocomplete and no explanation. A hand-typed @agent produces a message with no p tag, so it routes nowhere and the agent never receives it. The agent's profile card shows an empty channel list, which reads as misconfiguration. We spent hours verifying relay membership, channel membership, channel type, entry contents, event validity and app versions before finding a compiled-in client policy.

#4064 cannot fix this: it explains denials when the agent receives a mention, which cannot happen when the client refuses to emit the mention tag.

What we're asking for

  1. Honour the agent's published respond_to for relay agents. The owner has stated their policy through the mechanism Buzz provides; the release build should respect it for agents it does not run.
  2. Failing that, any supported opt-out — a relay/community setting, a per-agent capability, an operator-controlled flag. Something a self-hoster can reach.
  3. At minimum, make it visible — surface the policy in autocomplete and document that release builds override relay-advertised access.

Without at least (1) or (2), the shipped app cannot support multi-person agents on a self-hosted relay, which for us is the reason to use Buzz at all.

Environment

  • Buzz Desktop 0.5.17 (packaged release, macOS)
  • Self-hosted relay, ghcr.io/block/buzz:sha-1b3dbca, BUZZ_REQUIRE_RELAY_MEMBERSHIP=true, BUZZ_ALLOW_NIP_OA_AUTH=true
  • Agents run buzz-acp + opencode in Docker, admitted by NIP-AA virtual membership

Activity

  1. damonrand commented on Aug 20, 2026

    @damonrand

    Independent confirmation from a self-hosted deployment, with a variation that sharpens the case: the override also defeats respond_to: "allowlist" with the viewer's pubkey on the allowlist — not just "anyone".

    Setup: Desktop 0.5.14 (official signed build), self-hosted relay, five headless relay agents (external harness — Desktop never spawns them or holds their keys). Each publishes an agent-signed kind:10100 with respond_to: "allowlist" naming every human room member, NIP-OA ownership on kind-0, and live channel membership.

    Result: the owner sees all five in @ autocomplete; a second member — relay member, channel member, explicitly on every allowlist — sees none, before and after restart. We dumped the events over an authenticated socket first: what the relay serves both viewers is identical and correct. The client discards it — getAgentMentionAdmission passes the allowlist check, then the owner-only gate denies anyway.

    An allowlist naming the exact viewer is the narrowest, most deliberate grant the vocabulary allows — per-pubkey, signed, ownership-attested — and it is still substituted with owner-only. On these builds no configuration of respond_to can ever admit a second person, so the gate isn't evaluating policy at all.

    Also seconding the silent failure: the second member's @agent posts as plain text with no p tag and no explanation. We spent hours re-verifying membership and directory records — and re-published five agents' records — chasing a layer that was never consulted.

    +1 to ask (1), or failing that any operator-reachable opt-out. Happy to test a build or provide traces.

  2. added a commit that references this issue on Aug 20, 2026
    ee0c707
  3. Schnitzel commented on Aug 23, 2026

    @Schnitzel
    Author

    Confirming this is fixed in v0.5.18, verified end to end on our self-hosted relay. Thank you — filed Tuesday, fixed Wednesday, shipped Thursday, which is a genuinely remarkable turnaround for an issue from an outside self-hoster.

    The fix is also better than what I proposed. I had assumed the owner-only clamp on relay agents was deliberate and worked around it with a relay-advertised opt-in; treating it as misapplied — "The capability is intended to constrain runtimes Desktop starts or deploys, not external relay agents" — is the right call, and it needs no new configuration surface at all. I closed my PR in favour of yours.

    What we verified after upgrading, on a clean-room rebuild of three agents with deliberately different policies in one channel:

    Agent respond_to Owner Non-owner teammate
    owner-only allowlist (owner) sees it correctly hidden
    allowlist allowlist (owner + teammate) sees it sees it
    anyone anyone sees it sees it

    Two notes for anyone else arriving here from a self-hosted deployment, neither a complaint:

    The owner-signed kind 30177 is now the authoritative record, and relay_agents_from_directory_events replaces the agent's own kind 10100 with it outright. That is a sound boundary, but it caught us: our provisioning script had hardcoded respond_to: allowlist, [owner] into every 30177 it wrote, which was harmless while the build gate hid cross-owner agents anyway and became the deciding vote the moment this landed. Entirely our bug — your fix simply exposed it — but the failure mode is confusing, because the harness gate and the kind 10100 both look correct while the agent stays owner-only.

    v0.5.18 also requires a verified NIP-OA owner (retain_agents_allowed_by_build), so a relay agent whose kind 0 carries no valid auth tag now disappears from packaged builds entirely. The attestation is optional to create and nothing fails visibly without it, so anyone who skipped it will find their agent silently gone after upgrading. Might be worth a release-note line.

    Thanks again for taking it seriously and for the clarity of the write-up in #6338 — the diagnosis section made it easy to verify against our own deployment.

  4. added a commit that references this issue on Aug 23, 2026
    a520598
  5. added a commit that references this issue on Oct 7, 2026
    aaeea53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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