Forge
markdowndeeb25a2
1# ADR 0142: Intercom — открытый wire, подключаемые transport и опциональные мосты
2
3**Статус:** Accepted
4**Дата:** 2026-05-24
5
6## Связанные ADR
7
8| ADR | Роль |
9|-----|------|
10| [0080](0080-intercom-naming-and-multi-party-channel-model.md) | Intercom как канал; слой A (IDE) vs B (внешний контур) |
11| [0045](0045-agent-chat-persistence-event-log-and-projections.md) | Event log и проекции — модель событий на клиенте |
12| [0132](0132-intercom-federated-transport-and-multi-client-boundary.md) | Multi-client, REST/WS sketch, фазы transport; **этот ADR — канон wire и стратегия адаптеров** |
13| [0128](0128-intercom-attachment-anchors-and-code-references.md) | `AttachmentAnchor` в wire — JSON, не prose |
14| [0134](0134-intercom-message-prepare-pipeline-v1.md) | Prepare/commit до transport |
15| [0133](0133-commander-cockpit-shared-attention-model-and-instrument-deck.md) | MCC подписывается на transport, не владеет store |
16| [0143](0143-intercom-feed-participant-lens.md) | **Participant lens** (All/Humans/Agents/System) — проекция UI, не wire channel |
17| [0144](0144-intercom-team-transport-cide-sync-and-reference-service.md) | **Accepted:** reference Intercom service, team id, CIDE FederatedSync, SSE |
18
19### Вне ADR
20
21| Документ | Роль |
22|----------|------|
23| [intercom-ux-reference-slack-mattermost-v1.md](../design/intercom-ux-reference-slack-mattermost-v1.md) | UX-паттерны; слой B — мосты, не клон продукта |
24| [iop-manifest-v1.md](../iop-manifest-v1.md) | IOP: transport не подменяет git/kb/workspace truth |
25
26## Резюме
27
28**Принято:**
29
301. **Канон командного Intercom** — **открытая схема событий** (topics, messages, roles, structured attach), версионируемая в репозитории; не привязка к одному мессенджеру.
312. **Transport** — **подключаемый** (`IntercomTransport` / sync-адаптер): reference implementation (Intercom service) **и** внешние адаптеры (Matrix, Mattermost, webhooks, …) — **опционально**, без обязанности «все в Element».
323. **Много клиентов у людей** — норма: CIDE, Intercom Web, MCC, Element, корп. Slack/MM — через **мосты** и capability flags, а не через выбор единственного победителя.
334. **Стандарты** — на **конверте** (при необходимости CloudEvents-подобная обёртка), **не** замена доменной семантики Intercom готовым чат-протоколом «как есть».
345. **CIDE** остаётся богатым клиентом: Roslyn, reveal, MCP, prepare-pipeline — **вне** transport; на wire уходит уже подготовленный JSON.
35
36[0132](0132-intercom-federated-transport-and-multi-client-boundary.md) остаётся **картой фаз и multi-client**; этот ADR фиксирует **политику открытого wire** и отношение к Matrix/MM без выбора вендора в v0.
37
38---
39
40## Контекст
41
42Участники команды сидят в **разных** мессенджерах; продукт Cascade **открытый** — сторонние реализации клиента и сервера допустимы. Варианты обсуждались:
43
44- полностью **свой** Intercom service ([0132](0132-intercom-federated-transport-and-multi-client-boundary.md) вариант A);
45- **Matrix** (или иной готовый сервер) + тонкий C# wrapper;
46- **свой открытый протокол** «на стандартах».
47
48Риск без решения: либо **дублирование** Slack + локальный чат + JIRA ([0132](0132-intercom-federated-transport-and-multi-client-boundary.md) § «Проблема»), либо **замена** Intercom чужой моделью (rooms без topics/attach/agent), либо **вечный Proposed** без канона wire.
49
50---
51
52## Решение
53
54### 1. Три слоя (нормативно)
55
56```mermaid
57flowchart TB
58 subgraph clients["Клиенты"]
59 CIDE["CIDE (full)"]
60 Web["Intercom Web"]
61 MCC["MCC"]
62 Ext["Element / MM / … через мост"]
63 end
64 wire["Intercom wire\nоткрытая схема событий"]
65 subgraph transport["Pluggable transport"]
66 Ref["IntercomService (reference)"]
67 Local["LocalOnly / HybridSync"]
68 Matrix["MatrixBridge"]
69 MM["MattermostBridge"]
70 Hook["WebhookIngress"]
71 end
72 subgraph workspace["Workspace — не подменяется"]
73 Git["git · kb · hybrid index · Roslyn · MCP"]
74 end
75 clients --> wire
76 wire --> transport
77 transport -.->|не заменяет| workspace
78```
79
80- **Wire** — *что* передаётся (события [0045](0045-agent-chat-persistence-event-log-and-projections.md), поля [0132](0132-intercom-federated-transport-and-multi-client-boundary.md) §2, attach [0128](0128-intercom-attachment-anchors-and-code-references.md)).
81- **Transport** — *как* доставляется и хранится (REST/WS, Matrix CS API, MM REST, …).
82- **UX** — *как* рисуется в CIDE ([0123](0123-intercom-full-skia-surface-evolution.md)) — **не** часть wire.
83
84### 2. Открытый wire (канон)
85
86| Артефакт | Назначение |
87|----------|------------|
88| **Схема событий** | JSON Schema / OpenAPI для message, topic, member; версия `schema_version` |
89| **Reference types** | human \| agent \| system; `clientKind`: cide \| web \| mcc \| agent |
90| **Attachment** | structured JSON ([0128](0128-intercom-attachment-anchors-and-code-references.md)); prose bracket — convenience на клиенте |
91| **Экспорт/импорт** | CIDE local log ↔ wire ([0132](0132-intercom-federated-transport-and-multi-client-boundary.md) фаза 1) |
92
93Публикация: канон в [`wire/intercom-wire`](../../wire/intercom-wire/README.md) ([0146](0146-intercom-wire-canonical-protocol-package.md)); лицензия совместима с открытым продуктом ([0101](0101-licensing-and-commercialization-strategy.md) при выборе зависимостей мостов).
94
95**Обратная совместимость wire:** при изменении полей — явная версия схемы; потребители вне репо — отдельная политика, когда появятся.
96
97### 3. Pluggable transport (контракт)
98
99Минимальный интерфейс (имена в коде — черновик):
100
101| Операция | Смысл |
102|----------|--------|
103| `AppendMessage` | idempotent по client message id |
104| `SubscribeTopic` | live / poll cursor |
105| `ListTopics` | для Web/MCC |
106| `EnsureTopic` | spine key optional |
107
108Реализации (не взаимоисключающие в экосистеме):
109
110| Реализация | Роль |
111|------------|------|
112| **LocalOnly** | только [0045](0045-agent-chat-persistence-event-log-and-projections.md) в CIDE (сегодня) |
113| **IntercomService** | reference server ([0132](0132-intercom-federated-transport-and-multi-client-boundary.md) фаза 2) |
114| **HybridSync** | local + periodic push ([0132](0132-intercom-federated-transport-and-multi-client-boundary.md) вариант B) |
115| **MatrixBridge** | room ↔ topic; custom event `io.cascade.intercom.message` |
116| **MattermostBridge** | channel ↔ topic ([0132](0132-intercom-federated-transport-and-multi-client-boundary.md) фаза 5) |
117| **WebhookIngress** | уведомления в Telegram/email без полноценного клиента |
118
119Выбор transport на deployment — **конфиг**, не compile-time ветка в CIDE.
120
121### 4. Много мессенджеров — политика мостов
122
123| Принцип | Содержание |
124|---------|------------|
125| **Одна правда по задаче** | Канон — Intercom event log на выбранном primary transport; мост **не** создаёт второй независимый store в MCC |
126| **Read-only в чужой UI допустим** | Уведомление + deep link в Web/CIDE |
127| **Не цель** | Заставить всех перейти на один мессенджер |
128| **Matrix / MM** | **Адаптеры**, не замена §2 wire; mapping документируется в ADR моста при внедрении |
129
130### 5. Стандарты (конверт, не семантика)
131
132Допустимо:
133
134- **CloudEvents**-подобный envelope (`id`, `time`, `type`, `data` = Intercom payload) для логов, webhooks, observability;
135- **JSON Schema** / OpenAPI 3 для HTTP reference server.
136
137Не требуется:
138
139- полная совместимость с Matrix event types как каноном;
140- ActivityPub/XMPP как обязательный transport v0.
141
142### 6. Связь с [0132](0132-intercom-federated-transport-and-multi-client-boundary.md)
143
144| [0132](0132-intercom-federated-transport-and-multi-client-boundary.md) | Этот ADR |
145|------------------------------------------------------------------------|----------|
146| Фазы 0–5, multi-client, REST sketch | **Статус Accepted** для wire-политики |
147| «Intercom service MVP» | **Reference** transport, не единственный |
148| «Mattermost bridge optional» | Пример **pluggable** адаптера |
149| Proposed (объём transport) | Реализация фаз остаётся по [0132](0132-intercom-federated-transport-and-multi-client-boundary.md); wire — **Accepted** здесь |
150
151---
152
153## Последствия
154
155### Положительные
156
157- Открытый продукт может поставлять **схему + reference server**, сообщество — **мосты** без форка CIDE.
158- Matrix/MM снимают ops **доставки**, не заставляя отказаться от topics/attach/agent.
159- CIDE, Web, MCC делят **один wire**, разные capability ([0132](0132-intercom-federated-transport-and-multi-client-boundary.md) §1.1).
160
161### Отрицательные / риски
162
163- Поддержка нескольких transport + мостов — **тестовая матрица**.
164- Конфликты sync (local vs remote) — политика merge ([0132](0132-intercom-federated-transport-and-multi-client-boundary.md)).
165- Лицензии SDK мостов (AGPL Matrix libs и т.д.) — [0101](0101-licensing-and-commercialization-strategy.md).
166
167---
168
169## Не цели
170
171- Выбор Matrix vs Mattermost vs own server **в этом ADR** (отдельный ADR моста при пилоте).
172- E2EE, federation, mobile-клиенты v0.
173- Замена Skia Intercom UI чужим WebView ([0080](0080-intercom-naming-and-multi-party-channel-model.md) §5).
174
175---
176
177## Anti-patterns
178
179| Anti-pattern | Почему |
180|--------------|--------|
181| Два независимых message store (MCC + Intercom) | Ломает SA и attach |
182| «Канон = Matrix room timeline» без custom mapping | Теряются topic/spine/attach |
183| Prose `[M:…]` как единственный wire | [0128](0128-intercom-attachment-anchors-and-code-references.md), [0132](0132-intercom-federated-transport-and-multi-client-boundary.md) §2 |
184| Обязательный Element для PO/Lead | Нарушает паритет [0132](0132-intercom-federated-transport-and-multi-client-boundary.md) §1.1 |
185
186---
187
188## Фазы (согласовано с [0132](0132-intercom-federated-transport-and-multi-client-boundary.md))
189
190| Фаза | Содержание | Wire / transport |
191|------|------------|------------------|
192| **1** | OpenAPI/schema + CIDE export/import | **Accepted** (этот ADR) |
193| **2** | Reference Intercom service | `IntercomService` transport |
194| **3** | Intercom Web | тот же wire |
195| **4** | MCC read/compose | подписка, не свой store |
196| **5+** | Matrix / MM / webhook bridges | адаптеры поверх wire |
197
198---
199
200## Отклонённые альтернативы (кратко)
201
202| Альтернатива | Почему не канон |
203|--------------|-----------------|
204| Только Matrix как единственный backend | Привязка к room model и ops homeserver; mapping всё равно нужен |
205| Только свой closed server | Открытый продукт без wire затрудняет мосты и сторонние клиенты |
206| «Ничего не писать» — только embed Element | Две правды, слабый attach/reveal ([0080](0080-intercom-naming-and-multi-party-channel-model.md)) |
207| Mesh/CRDT v0 | [0132](0132-intercom-federated-transport-and-multi-client-boundary.md) вариант C — отложить |
208
209---
210
211<a id="adr0142-history"></a>
212
213## История
214
215| Дата | Изменение |
216|------|-----------|
217| 2026-05-24 | Accepted: открытый wire, pluggable transport, мосты опциональны; уточнение к [0132](0132-intercom-federated-transport-and-multi-client-boundary.md). |
218
View only · write via MCP/CIDE