# ADR 2: DM-First Routing **Date**: 2026-06-21 (supersedes 2026-04-28 @mention-based routing) ### Decision Agents are triggered primarily by **Zulip Direct Messages (DMs)**. Users send a DM to any agent's bot user (e.g., `@tanko-bot`) to communicate with that agent. Stream-based `@mention` routing is **deprecated** for agent-owner communication but retained for `@all-bots` broadcasts and multi-agent coordination in `#agent-hub`. ### Context The original design required users to `@mention` an agent in `#agent-hub` stream topics. This proved unreliable because: 1. Zulip 12.0 SDK may not populate `mentioned_users` on stream message events 2. Every bot subscribed to `#agent-hub` receives every message — wasteful 3. Topic routing (capturing origin stream + topic for reply) adds parsing complexity 4. Distinguishing `type: 'stream'` vs `type: 'private'` required extra event filtering DMs eliminate all of these concerns: - Only the recipient bot receives the DM — no broadcast noise - No @mention parsing needed — the DM itself is the signal - No topic/stream capture needed — reply in the same DM thread - `message.type: 'private'` is trivially detectable in the event queue ### DM Event Flow ``` User sends DM to @tanko-bot → Zulip pushes event to tanko-bot's event queue → Event has: {type: 'message', message: {type: 'private', ...}} → Bot checks: message.type === 'private' (trivial) → Bot reads message.content, processes, responds → Bot sends reply to same DM via /api/v1/messages with {type: 'private', to: [user_id], content: 'response'} ``` ### @all-bots Exception The stream-based approach is retained **only** for `@all-bots` broadcasts: - `@all-bots` in `#agent-hub` → all bots detect the mention and respond - This remains necessary for cross-platform broadcasts - Detection can use Zulip SDK `mentioned_users` or content-based `@**All Bots**` matching ### Consequences - **Positive:** Dramatically simpler routing logic — no @mention parsing, no topic/stream tracking - **Positive:** Each bot only processes its own DMs — no wasted event processing - **Positive:** Zulip's native DM threading handles all reply threading automatically - **Positive:** No dependency on `mentioned_users` field behavior in Zulip 12.0 - **Negative:** Owners must DM their agent directly instead of using stream topics - **Negative:** Cross-agent visibility in stream topics is reduced (mitigated by `@all-bots`) - **Neutral:** `@all-bots` in `#agent-hub` still uses the original @mention detection pattern