CI / validate (pull_request) Failing after 1s
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
65 lines
3.3 KiB
Markdown
65 lines
3.3 KiB
Markdown
# 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
|