Forge
markdowndeeb25a2
1# ADR 0172: Session graph habitat — Intercom как рабочая память сессии
2
3**Статус:** Proposed (концепт / north-star)
4**Дата:** 2026-07-10
5**Обновлено:** 2026-07-12 — habitat ≠ TOML axis; G1 = `primary_work_surface` default; session_graph prefs — future UI only
6
7## Резюме
8
9Часть операторов живёт **почти целиком в Intercom**; редактор — по attach/reveal. Их stance — **conversation-first** [0120](0120-primary-work-surface-intercom-or-editor.md).
10
11**Моат CIDE — не «ещё один чат»**, а **нелинейная сессия**: темы, ветки, rewind, scope на экране [0031](0031-agent-chat-clarification-batches-and-threading.md), [0116](0116-intercom-session-tree-and-agent-message-steering.md). Линейная flat feed — **проекция одной ветки**, не единственная правда.
12
13[0171](0171-presentation-tiers-compact-vs-cockpit.md) задаёт tier (compact/cockpit). **0172** задаёт **habitat** (имя session-graph canvas в глоссарии) для conversation-first: **Session graph canvas** в Forward, код on demand. **Habitat — не ось `settings.toml`**; продукт conversation-first выражается через `primary_work_surface = intercom` [0120](0120-primary-work-surface-intercom-or-editor.md).
14
15**Принято направление (концепт):**
16
171. **Session graph habitat** — Forward = Intercom canvas (scope + worklines + tree/timeline); не отдельный переключатель `habitat = …` в TOML.
182. **Topics = worklines index** — параллельные `ThreadNode` [0072](0072-chat-topic-cards-intent-melody-keyboard-contract.md); **не** аналог Cursor New Chat.
193. **Detail default** — scope strip + **Tree | Timeline**; flat feed только для **выбранной ветки** [0170](0170-intercom-feed-readability-mlp.md).
204. **Composer modes:** continue · **steer** · **follow-up** [0116](0116-intercom-session-tree-and-agent-message-steering.md).
215. **Harness неизменен** [0166](0166-agent-centric-harness-model-comfort-and-pay-per-token-economics.md).
22
23## Design thesis
24
25Классические IDE заточены под **написание кода**: редактор в центре, а сопутствующее — решения, intent, история рассуждения, «почему так» — размазано по боковым панелям, файлам в репо и внешним тредам, и **читается плохо**. В agentic-цикле **писать код в основном берёт на себя агент**; работа человека смещается к **пониманию, направлению и фиксации решений**. Редактор не исчезает — он для проверки и точечных правок, когда нужно руками.
26
27Session graph habitat — ответ на эту ось: Intercom — не «ещё один чат», а **инфраструктура восприятия сессии** (ветки, scope, worklines, batches). Moat — удобство **читать и управлять** нелинейной работой, а не паритет линейной ленты с Cursor.
28
29---
30
31## Связанные ADR
32
33| ADR | Роль |
34|-----|------|
35| [0031](0031-agent-chat-clarification-batches-and-threading.md) | Пакеты уточнений; обзор размаха; ветвления |
36| [0045](0045-agent-chat-persistence-event-log-and-projections.md) | Append-only события; проекции |
37| [0072](0072-chat-topic-cards-intent-melody-keyboard-contract.md) | Topic overview/detail/back |
38| [0096](0096-intercom-topic-card-summary-and-product-spine.md) | Сводка; spine ортогонален main |
39| [0116](0116-intercom-session-tree-and-agent-message-steering.md) | Session tree; rewind; steer/follow-up |
40| [0120](0120-primary-work-surface-intercom-or-editor.md) | `primary_work_surface = intercom` |
41| [0126](0126-intercom-inspect-slash-and-compact-chrome-status.md) | `/topic tree`, inspect |
42| [0166](0166-agent-centric-harness-model-comfort-and-pay-per-token-economics.md) | Harness ≠ habitat |
43| [0170](0170-intercom-feed-readability-mlp.md) | Comfortable flat feed внутри ветки |
44| [0171](0171-presentation-tiers-compact-vs-cockpit.md) | Compact ≠ session-graph default |
45| [0173](0173-intercom-intent-card-session-decision-capture.md) | Intent card: фиксация решений в workline; event log; эскалация в ADR |
46| [0174](0174-sedm-software-engineering-decision-making-ux-spine.md) | SEDM: операционная модель; context card; UX spine; SM/CRS перепривязка |
47
48---
49
50## Дифференциация от линейного agent chat (Cursor и аналоги)
51
52| | Linear agent chat | Session graph (CIDE) |
53|--|-----------------|----------------------|
54| Единица «нового» | New Chat / New Agent | **Fork branch** / новая **workline** в той же сессии |
55| История | Хронология | **Дерево** + хронология как проекция |
56| Восстановление контекста | Скролл | **Scope strip** + tree |
57| Уточнения плана | Одна строка | **Clarification batch** [0031](0031-agent-chat-clarification-batches-and-threading.md) |
58| Долгий tool-run | Сообщение в ленту | **Steer** vs **follow-up** [0116](0116-intercom-session-tree-and-agent-message-steering.md) |
59| Продуктовая нить | — | **Spine** [0096](0096-intercom-topic-card-summary-and-product-spine.md) |
60
61**Anti-pattern moat loss:** topics как список чатов + только flat feed в detail → **паритет с Cursor без нелинейности**.
62
63---
64
65## Контекст
66
67### Три оси (не смешивать)
68
69```text
70Tier (пространство) : compact | cockpit ← [display.presentation] tier
71Forward [0120] : intercom | editor ← [workspace] primary_work_surface
72Stance (продукт) : session-graph-first ← не TOML; Agent/Intent/Conversation-first
73```
74
75**Не путать:** **Habitat** в глоссарии = имя canvas (scope + worklines + tree/timeline), не четвёртая ось настроек рядом с tier и `primary_work_surface`.
76
77### Оператор session-graph-first
78
79| ~99% | Intercom canvas: worklines, scope, tree/timeline, composer |
80| Редко | Editor reveal из attach |
81| Фон | Solution warmup; **не** SE tree вместо чата после `load_solution` |
82
83---
84
85## Решение
86
87### 1. Session graph canvas (не «lanes + feed»)
88
89```text
90┌─ Scope: N branches · open batch · last decision @msg ─────────┐
91│ Worklines │ [ Tree ] [ Timeline ] │
92│ index │ graph of selected topic / branch │
93│ (rows) │ + flat feed (THIS branch only, measure cap) │
94├───────────┴──────────────────────────────────────────────────────┤
95│ Composer: Continue | Steer | Follow-up + slash │
96└──────────────────────────────────────────────────────────────────┘
97 Code · Terminal — on demand (MFD / mon2 / reveal)
98```
99
100### 2. Слои UI
101
102| Слой | Назначение | Cursor-like? |
103|------|------------|--------------|
104| **Worklines index** | Параллельные темы; строка + branch count + open Q | Внешне как channel list |
105| **Scope strip** | Снимок сессии/темы без скролла | **Нет** |
106| **Tree view** | Ветки, rewind, continue from | **Нет** |
107| **Timeline view** | Flat feed выбранной ветки | Да (гигиена читаемости) |
108| **Spine** | Ортогональная продуктовая линия | **Нет** |
109
110### 3. Инварианты
111
112| # | Инвариант |
113|---|-----------|
114| S1 | Канон — **event log / session tree** [0045](0045-agent-chat-persistence-event-log-and-projections.md); лента — проекция |
115| S2 | Forward default = **Intercom** (`primary_work_surface = intercom`) |
116| S3 | Overview worklines = **строки** (title + branches + summary), не hero cards |
117| S4 | Detail **не** только timeline; есть **Tree** и scope |
118| S5 | **Continue from here** на узле → новые события как потомки [0116](0116-intercom-session-tree-and-agent-message-steering.md) |
119| S6 | `load_solution` не переключает на SE/Terminal |
120| S7 | Measure cap в timeline ветки [0170](0170-intercom-feed-readability-mlp.md) |
121
122### 4. Мониторы
123
124#### 1 × 16:9
125
126Forward ~90% = полный session canvas (index + scope + tree/timeline + composer).
127
128#### 2 × 16:9 (operator default)
129
130| Primary | Secondary |
131|---------|-----------|
132| Session graph maximized | Editor host **on reveal**; иначе пусто/браузер |
133
134Не `(P+F)(M)` cockpit.
135
136### 5. Настройки (целевые)
137
138```toml
139[workspace]
140primary_work_surface = "intercom" # conversation-first default [0120]
141
142[display.presentation]
143tier = "compact"
144# compact_intercom_placement = "side" | "bottom" — см. [0171](0171-presentation-tiers-compact-vs-cockpit.md)
145
146# Будущие UI-префы session graph (не ось habitat):
147# [display.presentation.session_graph]
148# workline_rail_width_px = 200
149# feed_max_measure_ch = 72
150# detail_default_view = "tree" # tree | timeline
151# overview_style = "rows"
152
153[intercom]
154feed_metrics = "comfortable"
155```
156
157**Убрано из target settings:** `habitat = "session-graph"` — продукт уже conversation-first; отдельный runtime knob дублировал бы `primary_work_surface` и tier.
158
159### 6. Anti-patterns
160
161| Anti-pattern | Почему |
162|--------------|--------|
163| Detail = только flat feed | = Cursor; моат мёртв |
164| Topics = New Chat | Линейные сессии вместо worklines |
165| Hero cards overview | Кринж на wide canvas |
166| SE после load_solution | Отбирает session canvas |
167
168### 7. Concept vs implementation ladder
169
170Wireframe v2 — **north-star poster**, не acceptance criteria для первого PR. На кадре всё уже случилось: scope заполнен, tree и timeline согласованы, worklines с branch count, пустые состояния скрыты. В коде слои появляются **по фазам**; сравнение poster ↔ G1 почти всегда выглядит как «фиаско», хотя это **непровал moat**, а незавершённая лестница.
171
172**Два класса артефактов:**
173
174| Артефакт | Роль | Критерий успеха |
175|----------|------|-----------------|
176| Wireframe / генерация | Сжатая визуальная гипотеза; согласование stance | «Понятно, куда смотрим» |
177| Фаза Gn | Ship-единицу с проверяемым инвариантом | Deliverable фазы + S1–S7, **не** pixel-match PNG |
178
179**Что ожидать по фазам (намеренно «уродливо» — ок):**
180
181| Фаза | UI может выглядеть как | Это **не** провал, если |
182|------|------------------------|-------------------------|
183| **G1** | Обычный Intercom + flat feed | Forward = Intercom; `load_solution` не отбирает чат (S6) |
184| **G2** | Лента + тонкая полоска scope (2–3 поля) | Scope читается **без скролла**; данные из log/projection |
185| **G3** | Tree на mock/реальном `parent_id`; timeline = та же ветка | Toggle Tree↔Timeline; **continue from** пишет потомка в log (S5) |
186| **G4** | Composer с явным steer/follow-up | Режим влияет на **когда** и **куда** в дереве попадает user msg [0116](0116-intercom-session-tree-and-agent-message-steering.md) |
187| **G5+** | Batch UI, spine polish | Clarification batch виден в scope/tree |
188
189**Реальный провал moat** (стоп-кран, не «ещё не дорисовали»):
190
191- Detail застрял **только** на timeline без плана G3 (anti-pattern §6).
192- Topics = New Chat / линейные сессии вместо worklines.
193- Нет `parent_id`/ветки в log, но UI притворяется session graph.
194- Сравниваем с wireframe и **откатываем** G2–G4 ради «красивой ленты».
195
196**Порядок работ:** сначала **data** (event log, `parent_id`, head, branch path [0116](0116-intercom-session-tree-and-agent-message-steering.md)), потом chrome. Timeline (Skia feed) уже есть — tree/scope **надстраиваются**, не переписывают Intercom с нуля.
197
198**Один инвариант за спринт** — не «habitat как v2», а например: «scope strip с N branches + open batch» (G2) или «toggle + continue from на одной workline» (G3).
199
200### 8. API boundary (stateless FM)
201
202Session graph — **клиентская** модель. Cloud.ru Foundation Models и любой OpenAI-compatible провайдер — **stateless** `POST /v1/chat/completions`: массив `messages[]`, опционально tools. API **не** знает topics, tree, timeline, steer/follow-up, `session_id` от CIDE.
203
204```text
205┌──────────────── CIDE (локально) ─────────────────┐
206│ Event log NDJSON ← канон [0045] │
207│ Session tree ← parent_id, branch, head │
208│ Worklines / scope ← продуктовые проекции │
209│ │ │
210│ ▼ │
211│ Orchestrator │
212│ · messages[] только для АКТИВНОЙ ветки │
213│ · ContextMinimizer / compactor [0166] │
214│ · MCP tools → ide_execute_command │
215│ · steer / follow-up → семантика вставки user │
216└─────────┼──────────────────────────────────────────┘
217
218┌──────────────── Cloud.ru FM (stateless) ───────────┐
219│ messages: [system, user, assistant, tool, …] │
220│ stream; нет branch_id / rewind на стороне API │
221└────────────────────────────────────────────────────┘
222```
223
224| Слой | Где живёт | FM API видит? |
225|------|-----------|---------------|
226| Session tree, ветки | Локальный log + Tree UI | **Нет** |
227| Topics / worklines | Проекция + meta | **Нет** (кроме summary в system при compact) |
228| Timeline | UI + источник для prompt | **Да** — как `messages[]` одной ветки |
229| Steer / follow-up | Оркестратор CIDE | **Косвенно** — состав следующего request |
230| Clarification batch | События `clarification_*` [0031](0031-agent-chat-clarification-batches-and-threading.md) | Структурированный user content в turn |
231
232**Один ход:** user msg → событие в log → проекция пути `root → head` → orchestrator собирает `messages[]` (только эта ветка; соседние ветки **не** жгут токены [0166](0166-agent-centric-harness-model-comfort-and-pay-per-token-economics.md)) → stream FM → `message_completed` с `parent_id` = текущий head → tool loop при function calling.
233
234**Fork / continue from:** меняется head и `parent_id` нового сообщения; следующий request несёт **другой путь** — без переписывания истории на стороне API (её там нет). Pay-per-token: нелинейность — **экономия**, не overhead.
235
236Конфиг провайдера (пример): `[ai.cloud.openai]` `base_url = https://foundation-models.api.cloud.ru`; harness [0166](0166-agent-centric-harness-model-comfort-and-pay-per-token-economics.md) не меняется от habitat.
237
238### 9. Worklines — ретро-проекция, не форум
239
240Оператор **не обязан** создавать тему до разговора. Один composer, один поток реплик — как в обычном чате. **Workline** — имя и граница **уже идущей** линии работы, которую система и агент выводят из event log (и при необходимости уточняют одной фразой).
241
242| Принцип | Смысл |
243|---------|--------|
244| Разговор первичен | Структура следует за диалогом, не наоборот |
245| Индекс сбоку | Параллельные линии видны без скролла всей сессии |
246| Большинство реплик | Остаются в **активной** workline без split |
247| Инициатор split | Оператор, агент или checkpoint — **предложение**, не модалка «создай топик» |
248
249**Anti-pattern:** обязательный title/summary или New-Chat-подобный вход перед первым сообщением.
250
251### 10. Переключение worklines и доделывание хвостов
252
253Переключение строки в **worklines index** — смена **фокуса**, не новая сессия. У каждой workline свой **head** в session tree; при возврате head сохранён.
254
255```text
256Оператор кликает workline B
257 → timeline = flat feed ветки B до head_B
258 → tree/scope = проекция workline B
259 → composer пишет в B (новые события — потомки head_B)
260 → orchestrator: messages[] только путь active workline
261```
262
263**Доделать в старой линии:** зайти в workline → закрыть open item (коммит, smoke, ADR) → при желании отметить в meta «closed» → вернуться в предыдущую workline (parked, head не сдвинулся). Scope strip показывает несколько open worklines без слияния их в один prompt.
264
265Статусы в индексе (продуктовые, не обязательный протокол): **active** · **parked** · open count на строке.
266
267### 11. Spin-off — вынесение диапазона сообщений
268
269Когда линия внутри workline или целый смысловой блок вырос в отдельную работу, стороны договариваются **в чате**, система фиксирует **событие** (канон [0045](0045-agent-chat-persistence-event-log-and-projections.md)):
270
271```text
2721. Предложение (user или agent): «вынести msg A…B в workline X?»
2732. Согласие или отказ одной короткой репликой
2743. Событие spin_off (имя в log уточняется при реализации):
275 source_workline, target_workline, msg_range, agreed
2764. Проекция: сообщения rehome в target; в source — collapsed marker
277```
278
279**UI в timeline (активная ветка source):** system card / спойлер, свёрнут по умолчанию:
280
281```text
282┌─ Вынесено в «VDS» (msg 840–1020) ─── [перейти] [развернуть] ─┐
283└───────────────────────────────────────────────────────────────┘
284```
285
286Сообщения **не удаляются** из log; меняется **принадлежность workline** и материализация prompt. Отказ на шаге 2 — no-op, лента без изменений.
287
288**Отличие от fork branch:** fork — ветвление **внутри** workline (tree); spin-off — перенос **диапазона** в другую workline (или новую).
289
290### 12. Materialization для агента (двухслойный роутинг)
291
292Ограниченный контекст FM и дефицит внимания оператора — **одна экономика**. Агент не «живёт во всём графе»; habitat задаёт, **что попадает в ход**.
293
294| Слой | Что решает | Аналог |
295|------|------------|--------|
296| **Структурный** | Какая workline активна; путь `root → head` в дереве | Активная ветка в `messages[]` |
297| **Семантический** | Какие знания и тулы подтянуть | KB: status → playbook → pull; `route_context` [0166](0166-agent-centric-harness-model-comfort-and-pay-per-token-economics.md) |
298
299Соседние ветки и worklines **не** входят в `messages[]`, пока не станут активными. Scope strip и one-liner в system — сжатая карта («2 open worklines»), не полный dump. Решения и checkpoint — KB / export, chat context — кэш.
300
301Workline может нести **intent tag** (например `cascade-ide/habitat`) → bias для `route_context` и MCP pull без чтения всей сессии.
302
303**Intent card** [0173](0173-intercom-intent-card-session-decision-capture.md) — типизированная фиксация решения **внутри** workline (`outcome`, `trigger`, `considered[]`, `chosen_approach` + `selection_rationale`); не заменяет intent tag и не равна ADR. В лестнице **SEDM** [0174](0174-sedm-software-engineering-decision-making-ux-spine.md) — артефакт **T1**; **context card** (T2) — Perceive для файла в scope strip.
304
305---
306
307## Фазы
308
309| Фаза | Содержание | Moat? |
310|------|------------|-------|
311| **G0** | ADR + wireframe v2 | Док |
312| **G1** | `primary_work_surface = intercom` + Intercom Forward (без coercion tier→editor) | Habitat |
313| **G2** | Scope strip (minimal) | **Да** |
314| **G3** | Tree ↔ Timeline toggle; continue from | **Да** |
315| **G4** | Steer/follow-up в composer | **Да** |
316| **G5** | Clarification batch UI | **Да** |
317| **G6** | 2-mon wizard | Habitat |
318
319**Приоритет moat:** G2–G4 выше ширины панели и hero polish.
320
321---
322
323## Визуальный концепт
324
325- v1 (устарел для moat): [cide-conversation-habitat-concept.png](../design/cide-conversation-habitat-concept.png)
326- **v2 (актуальный):** [cide-session-graph-habitat-concept-v2.png](../design/cide-session-graph-habitat-concept-v2.png)
327
328**North-star:**
329
330> **Одна сессия — много линий и веток; scope и tree на экране; лента — вид одной ветки; код по attach.**
331
View only · write via MCP/CIDE