Files
zulip-platform-plugins/docs/adr/ADR-001-dm-topology.md
T
kagentz-bot 705c29a4e0
CI / validate (pull_request) Failing after 1s
feat: DM-First v2 architecture - Tanko live on CT 112
Architecture change: DM-First (v2) replaces @mention-in-stream (v1) as primary
agent interaction channel. See ADR-001-dm-topology and ADR-002-dm-routing.

Key changes:
- New DM-first Zulip adapter (adapter_dm.py) deployed on CT 112
  - Registers empty narrow to receive ALL events
  - Demuxes DMs (type: 'private') vs stream events
  - Replies to DMs back in private thread, stream replies to #agent-hub
  - Uses blocking long-poll (dont_block=False) to eliminate rate limiting
- Rewritten ARCHITECTURE.md, CONTEXT.md, PRD.md for v2 DM-First
- New ADRs: ADR-001 (DM Topology), ADR-002 (DM Routing)
- Archived old ADRs: 001, 002, 005 (topic-topology, mention-routing, mention-detection)
- Updated ADRs: 003 (agent-naming), 004 (per-agent-bots), 006 (all-bots-model)
- Updated PI extension (index.ts) with DM-aware patterns
- Tanko agent confirmed responding in both DM and @all-bots in #agent-hub
2026-06-21 07:50:30 -04:00

3.3 KiB

ADR 1: DM-First Communication Topology

Date: 2026-06-21 (supersedes 2026-04-28 topic-based topology)

Decision

Each agent communicates primarily via Zulip Direct Messages (DMs). The #agent-hub stream is retained as an optional broadcast-only channel for inter-agent coordination, @all-bots announcements, and cross-agent visibility. Agent-private topics (<agent>-private) are deprecated in favor of native Zulip DMs.

Context

Zulip bots are regular user accounts — any user can send a private message to any bot by composing a DM with the bot as the sole recipient. The bot's event queue then receives an event with message.type: 'private', which requires no @mention detection, no topic parsing, no stream subscription checks.

The original design used topics under #agent-hub with @mention routing, but this introduced several failure modes:

Problem Impact
mentioned_users field not populated by Zulip 12.0 SDK @mention detection silently fails
Topic routing required capturing origin topic + stream for reply Added parsing complexity
All 6 bots subscribed to same stream Every bot receives every message, wasting resources
type:'stream' events different from type:'private' Required additional event filtering logic

DMs solve all of this natively:

  • Every DM is inherently for the bot recipient — no @mention needed
  • Reply in the same DM thread — Zulip handles threading
  • Only the recipient bot sees the message — no broadcast noise
  • message.type: 'private' is trivially detectable

Architecture Change

Before (Deprecated):

User @mentions @tanko-bot in #agent-hub > tanko-private
  → Zulip fires event to ALL 6 bot event queues
  → Each bot checks mentioned_users for its user_id
  → Only matching bot processes the event
  → Bot replies to same stream+topic

After (DM-First):

User DMs @tanko-bot directly
  → Zulip fires event ONLY to tanko-bot's event queue
  → Bot receives message.type: 'private'
  → No @mention detection, no topic parsing
  → Bot processes and replies in same DM thread

Consequences

  • Positive: Dramatically simpler event processing — no @mention detection, no topic routing, no mentioned_users dependency, no stream subscription requirement
  • Positive: Each bot only receives its own messages — less noise, less resource usage
  • Positive: Zulip's native DM threading handles all reply routing automatically
  • Positive: No need to subscribe all 6 bots to #agent-hub stream (except for @all-bots broadcast capability)
  • Negative: Single #agent-hub stream topic no longer shows all agent activity in one timeline
  • Negative: Cross-agent visibility requires @all-bots broadcast or agents explicitly CC each other
  • Neutral: #agent-hub stream is retained for: @all-bots broadcasts, inter-agent coordination, and user-initiated multi-agent topics

Migration Path

  1. All plugins listen for type: 'private' events as primary communication channel
  2. #agent-hub stream listener is secondary — only for @all-bots broadcast detection
  3. Existing <agent>-private topics are deprecated but not deleted (grace period)
  4. Owners communicate with their agents via DM, not via private topics
  5. @all-bots continues to work in #agent-hub for cross-platform broadcasts