镜像站点 · 本页由第三方 GitHub 只读镜像提供,非 GitHub 官方站点,不接受任何登录或凭据输入。前往 github.com
Skip to content

feat(agents): agents never DM, except with their owner; they answer other DMs in Solo chats - #3261

Draft
joahg wants to merge 2 commits into
block:mainfrom
joahg:joah/agents-solo-not-dm
Draft

joahg wants to merge 2 commits into
block:mainfrom
joahg:joah/agents-solo-not-dm

Conversation

@joahg

@joahg joahg commented Nov 11, 2026 •

Copy link
Copy Markdown
Member

AGNTOPS-780

Agents can no longer DM people or each other. The one exception is a DM whose only members are the agent and its owner, such as the pinned Bestie conversation. For any other private conversation, an agent starts a Solo chat, and that Solo chat always includes its owner. When anyone else DMs an agent, the agent answers by starting a Solo chat for that request.

Changes

  • No DM tool. dm is removed from the Buzz MCP tools.
  • No posts in DMs, except one with only the owner. send and reply_in_subthread refuse a channel whose metadata type is dm, unless its roster (39002) holds only the agent and its owner. The error tells the agent to start a Solo chat instead.
  • Plugin agents can't open DMs. Kind 41010 is gone from crates/agent-controller app_agent KINDS, so the app won't sign a DM open with a plugin agent's key. Bestie's DM is opened by the owner's app, so it doesn't need this.
  • Owner is always in an agent's Solo chat. channel_create with solo: true adds the agent's owner (client.owner) to the members. If the host doesn't know the owner, it refuses. The node client now exposes owner from its NIP-OA auth tag. The owner counts toward the relay's 32-member limit at create.
  • DM turns route to Solo chats. prompt.md (shared posting conventions) drops "In a DM, send replies at the top level." It now says to answer a DM from anyone but the owner by starting a Solo chat with the sender (the owner is added), and to keep using that Solo chat for follow-ups on the same request. The new DM_PROMPT replaces the "pass reply" routing line in those DM turns for Claude Code, Goose and Pi (which share turnPrompt) and Codex. ownerDm in features/agents/reads.ts identifies owner-only DMs from the channel's members, and those turns keep the ordinary DM routing.

Not covered here

  • Relay enforcement. A harness agent that holds its own key could still sign a 41010 or a kind 9 into a DM directly. Only the relay can refuse those, and the relay isn't in this repo.
  • Harness failure notices. The harness's own reply() posts, like the failed-turn notice that tags the owner, still go to the conversation, and that includes a DM.
  • Remote/hosted agents. Agents on other hosts (e.g. Builderlab) have their own tool sets and need the same change there.

Testing

  • vitest run src/buzz-mcp/tools.test.ts: pass. Tests cover:
    • no dm tool
    • send and reply_in_subthread refused in a DM that has another person in it, allowed in a DM with only the owner, and refused there when the host doesn't know the owner
    • posting in a stream still works
    • the owner added to a Solo create (deduped, counted toward 32)
    • no Solo chat without an owner
  • src/features/agents/reads.test.ts: ownerDm is true only for a DM whose members are just the agent and its owner. It's false for unknown members, an absent owner, or any third member.
  • The Claude Code prompt tests cover the DM turn instruction and the owner-DM case, which keeps the reply routing. The Codex prompt tests cover the DM turn instruction.
  • cargo test -p buzz-agent-controller: pass, including 41010 now refused.
  • tsc --noEmit, biome and rustfmt hooks: clean.
  • Vitest over src/buzz-mcp, src/bundled/{claude-code,codex}, src/features/agents and src/features/agent-harness: every failure is in a file this PR doesn't touch, and each one either passes when rerun alone or also fails on unmodified main (codex/tabs effort refresh).

🤖 Generated with Claude Code

joahg and others added 2 commits November 10, 2026 22:27
…ir owner

Agents lose the `dm` tool, and `send` and `reply_in_subthread` refuse a DM
channel. Plugin agents' keys no longer sign DM opens (41010). A Solo chat an
agent starts always adds its owner. The shared posting conventions and the
Claude Code, Goose, Pi and Codex DM turn context tell an agent to answer a DM
by starting a Solo chat for the request, with the sender and its owner.

AGNTOPS-780

Co-authored-by: Hertz <c6741012416ef5c49a865db79682113385c5fb998e8c890234fb442b59e22748@buzz.block.builderlab.xyz>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Joah Gerstenberg <joah@squareup.com>
A DM whose only members are the agent and its owner, such as Bestie's
pinned chat, stays open to the agent: send accepts it, and the Claude Code
and Codex turns keep the ordinary DM routing there instead of sending the
answer to a Solo chat. Every other DM stays closed.

AGNTOPS-780

Co-authored-by: Hertz <c6741012416ef5c49a865db79682113385c5fb998e8c890234fb442b59e22748@buzz.block.builderlab.xyz>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Joah Gerstenberg <joah@squareup.com>
@joahg joahg changed the title feat(agents): agents never DM; they answer DMs in Solo chats with their owner feat(agents): agents never DM, except with their owner; they answer other DMs in Solo chats Nov 11, 2026

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant