# Слепок трекера на 2026-07-26 (аккаунт GitHub заблокирован)

Страховочная копия wayfinder-карты и ключевых резолюций из GitHub Issues.
Снята из контекста сессии в момент блокировки аккаунта `dementev-dev`
(сразу после закрытия #15). Если аккаунт восстановят — файл можно удалить;
если нет — это источник для восстановления трекера на новом месте.

**Хвост, не доехавший до GitHub:** строка про #15 в Decisions so far карты #10
(текст — в разделе «Карта», помечен как НЕ ОПУБЛИКОВАНО).

## Состояние issues (все, на момент блокировки)

| # | Состояние | Метки | Название |
|---|---|---|---|
| 27 | CLOSED | wayfinder:research | Что отдаёт Яндекс как кликстрим: форма события и выгрузка |
| 24 | CLOSED | needs-triage | Вычистить прозаические тесты из test_world_dags_contract.py |
| 23 | CLOSED | ready-for-agent | Сверка цифр курса на живом стенде и финальная проверка |
| 22 | CLOSED | ready-for-agent | Лабы 07 (next-day) и 08 (continue) + метадокументы курса |
| 21 | CLOSED | ready-for-agent | Каркас курса и переобвязка уроков 0–6 под путь import |
| 20 | OPEN | wayfinder:task | Обновить мажорную версию airflow до версии 3 |
| 18 | CLOSED | wayfinder:grilling | Модель данных: широкое событие и второй источник |
| 17 | OPEN | wayfinder:task | Собрать спеку боевого реализма |
| 16 | OPEN | wayfinder:grilling | Анонимы и identity stitching: нужно ли и сколько |
| 15 | CLOSED (2026-07-26) | wayfinder:grilling | Purchase с выручкой: форма события и место в стенде |
| 14 | OPEN | wayfinder:grilling | Кластер: где живёт опыт менти и какая топология |
| 13 | CLOSED | wayfinder:research | Цена кластера для пайплайна |
| 12 | CLOSED | wayfinder:research | Ресурсный бюджет стенда на 16 ГБ |
| 11 | CLOSED | wayfinder:task | Реализм генератора: границы применимости стенда |
| 10 | OPEN | wayfinder:map | Карта: боевой реализм стенда |
| 9 | CLOSED | — | Редизайн пути менти: мир из артефакта и две ветки роста |
| 8 | CLOSED | wontfix | Техдолг: инкрементальный ETL вместо full_refresh на каждый день |
| 7 | CLOSED | ready-for-agent | Редизайн лаб курса под три режима менти |
| 6 | CLOSED | ready-for-agent | Один учебный профиль: daily-wave — учебный, ci — служебный |
| 5 | CLOSED | ready-for-agent | Инкрементальные счётчики manifest: next-day без перечитки всей Kafka |
| 4 | CLOSED | ready-for-agent | Поверхность DAG'ов: generator_control → world_init, беспараметрный world_next_day |
| 3 | CLOSED | ready-for-agent | Эталонный мир: 3-дневный артефакт в git и import по умолчанию |
| 2 | CLOSED | wontfix | Airflow Grid: всплывающая JS-ошибка при авто-обновлении |
| 1 | CLOSED | — | Быстрый разлогин в Airflow и Superset |

Блокировки #15 (нативные dependencies): blocked_by #11, #18 — обе закрыты.

## Карта #10 «Карта: боевой реализм стенда» (тело)

### Destination

Принятая спека в `docs/specs/` «Боевой реализм стенда»: где менти получает
кластерный опыт ClickHouse и в какой топологии; какие доработки реализма
данных генератора делаем; явные границы. Спека готова к разбиению через
`/to-tickets`.

### Notes

- Расчёт на ноутбук менти 16 ГБ RAM (у кого 8 ГБ — VDS за счёт менти).
- Исполнение доработок — после фичи «Редизайн пути менти» (#9); карта
  решений может идти параллельно с ней.
- Изменения генератора тянут пересборку эталонного мира
  (`data/startup_history/reference-world.json.xz`) и «поплывшие» числа
  в лабах — учитывать в каждом решении.
- Скиллы: `/grilling` и `/domain-modeling` для тикетов-решений,
  `/research` для тикетов-исследований.
- Рабочая гипотеза владельца: кластер здесь, облегчённо (2 шарда без
  реплик), цель — Distributed и ON CLUSTER на живом потоке; «голый»
  clickhouse-learning-cluster этого не даёт.
- Порядок: решение по модели данных предшествует кластерному — иначе
  межшардовые джойны четырёх топиков придётся оплатить дважды.

### Decisions so far

- [Реализм генератора: границы применимости стенда](#11) — документ
  `docs/generator-realism.md` (коммит 068d96f): честно как в бою —
  схема/воронка/сессии/волна/обвязка; упрощено — четыре топика, только
  pageview, клоны пользователей, нет «грязи», масштаб.
- [Ресурсный бюджет стенда на 16 ГБ](#12) — полный стенд в покое ≈3,4 ГБ;
  2×1 добавляет ≈0,6–0,8 ГБ (влезает свободно), 2×2 — ≈1,7–1,9 ГБ (влезает,
  но впритык к дефолтному бюджету WSL2 ~8 ГБ); координатором брать
  clickhouse-keeper, не ZooKeeper.
- [Цена кластера для пайплайна](#13) — объём средне-крупный (~15–20 файлов,
  тяжёлое — SQL); главная боль — JOIN поверх Distributed и TRUNCATE в
  трансформациях (риск для контрольных сумм), приём из Kafka требует одного
  консьюмера + Distributed-цели; рекомендация исследования — опциональный
  `make up-cluster`, не дефолт.
- [Что отдаёт Яндекс как кликстрим](#27) — плоское широкое ядро (~140
  колонок) плюс параллельные массивы для многозначного, вложенного JSON
  нет (Яндекс ближе к Snowplow, чем к Segment); доставка батчем (Logs API,
  TSV, лог доформировывается ~3 дня), поток только в «Метрике Про» через
  Data Transfer с задержкой до 15 минут — Kafka у Яндекса нет, наша Kafka
  учебная замена; детали в `docs/research/2026-07-26-yandex-clickstream-format.md`
  (ветка `research/yandex-clickstream-format`, коммит `e6e34f2`).
- [Модель данных: широкое событие и второй источник](#18) — переходим на
  одно широкое событие по образцу Яндекс Метрики (плоское ядро +
  параллельные массивы + сырое поле `ecommerce`, таксономия event_type);
  интеграционная ценность — заказы бэкенда той же Kafka, но пачками с
  опозданиями и отменами (одна труба, два режима), каталог товаров —
  словарь ClickHouse из файла; прямое чтение прод-Postgres и файловые
  источники отклонены (файлы — зона Lakehouse-стенда); Kafka — учебная
  замена батчевого Logs API, фиксируем в docs/generator-realism.md.
- **[НЕ ОПУБЛИКОВАНО — добавить при восстановлении доступа]**
  [Purchase с выручкой: форма события и место в стенде](#15) — деньги на
  обеих сторонах (клиент объявляет через dataLayer, бэкенд — итоговая
  правда; атрибуция по трекеру, деньги по бэкенду); клиент:
  `pageview`+`add_to_cart`+`purchase`; заказы — ежедневный полный слепок
  окна изменяемости K со статусами и JSON-позициями, приём через
  ReplacingMergeTree; сверка по `purchaseID`=`order_id` с четырьмя
  конструируемыми расхождениями (отмена, потеря, дельта суммы, дубль);
  выручка в DM — только от заказов.

### Not yet specified

- «Грязь» в данных: боты, дубли событий, опоздавшие мобильные батчи,
  расхождение часов клиент/коллектор — вернуться после решений по
  purchase и identity.
- Политика версионирования эталонного артефакта при изменениях
  генератора (когда пересобирать, как жить лабам со сменой чисел).
- Как новые возможности лягут в лабы курса (после редизайна лаб, #7).

### Out of scope

- ~~Формат доставки событий: закрыть теорией~~ — решение отменено
  2026-07-22: исследование цены кластера показало, что четыре топика
  несовместимы с шардированием без GLOBAL JOIN; вопрос вернулся в рамку
  тикетом «Модель данных: широкое событие и второй источник».
- Редизайн лаб курса — отдельный issue #7.
- Инкрементальный ETL — отдельный issue #8; багфиксы — #1, #2.

### Комментарии карты

1. Решение 2026-07-23: дальнейшая работа карты пойдёт в новом
   v2-репозитории. v1 замораживается как стабильный стенд для менти
   (добить путь менти, баги #1/#2, лекции). v2 стартует пустым
   репозиторием с осознанным первым коммитом (переносим только нужное;
   генератор переписывается, переиспользуются идеи). Имя нового
   репозитория выберем из решения о нише; карта и открытые тикеты
   переедут туда после создания.
2. Рабочий кандидат имени v2-репозитория: **clickstream-data-platform**
   (согласован 2026-07-23). Мотив: стенд перерастает классическое DWH —
   потоковый приём, оркестрация, кластер, витрины; «data platform»
   описывает целое. Финальное закрепление — при решении тикета о нише.

## Тикет #15 «Purchase с выручкой: форма события и место в стенде»

### Тело

Part of #10

**Question:** Решить форму события покупки с суммой заказа: схема и носитель
(клиентское событие в широкой модели, источник заказов бэкенда или обе
стороны со сверкой — зависит от решения «Модель данных» #18), как ложится
в DDL/DM и дашборд, что делает с эталонным миром (пересборка артефакта
и чисел лаб).

Комментарий владельца: решение #18 добавило вторую сущность — заказ бэкенда
(Kafka, пачками, с опозданиями и отменами). При решении формы purchase решить
и форму события заказа, и сюжет сверки «клиентский purchase против
бэкенд-заказа». Фактура по ecommerce Яндекса — в
docs/research/2026-07-26-yandex-clickstream-format.md.

### Резолюция (опубликована 2026-07-26, тикет закрыт)

Опубликованный текст: комментарий
`issues/15#issuecomment-5084445090`. Полная копия — в
`.scratch/backup/20260726-resolution-15.md` (соседний файл).

## Тикет #18 «Модель данных: широкое событие и второй источник» (резолюция)

**Да, переходим на широкое событие.** Четыре топика-осколка уходят; модель
одна, целевая (двух моделей «для дефолта и для кластера» не держим). Мотив —
реализм: менти должен узнавать в стенде тот кликстрим, с которым столкнётся
на работе. Кластер — побочный довод, не причина.

**Форма события — по образцу Яндекс Метрики** (фактура — #27,
`docs/research/2026-07-26-yandex-clickstream-format.md`): плоское широкое
ядро плюс параллельные массивы для многозначного (товары, цели, свои
параметры) плюс одно сырое поле-строка `ecommerce`. Вложенных объектов в
стиле Segment/Amplitude не делаем. Таксономия `event_type` вместо «только
pageview». Точный состав полей — в спеку (#17), опора — таблица 53 полей
из исследования.

**Интеграционная учебная ценность** (взамен склейки осколков):

- **Второй источник — заказы бэкенда.** Вторая версия правды о покупке;
  учебный сюжет — сверка клиентского purchase против заказа, расхождения,
  отмены. Форма события заказа и сверка — тикет #15.
- **Транспорт заказов — та же Kafka, но пачками**: бэкенд выгружает заказы
  раз в модельный день, с опозданиями и отменами. Одна труба, два режима —
  как в бою, где батчи льют в брокер из удобства. Открывает темы, которых
  у менти нет после курсовой airflow-greenplum: согласование потока и
  батча, поздние данные, кросс-источниковые проверки, сенсоры/Datasets
  (DAG слоя DDS ждёт дневной батч).
- **Каталог товаров — словарь ClickHouse из файла** (CSV в репозитории;
  тот же файл использует генератор — расхождений нет по построению).
  Даёт `dictGet` и политику обновления словаря.

**Ландшафт итогом:** Kafka — единственная труба (кликстрим потоком, заказы
пачками); Postgres остаётся только служебной базой Airflow; смешанность
ландшафта выражена режимами и частотами, а не второй трубой.

**Отклонено по дороге:** прямое чтение прод-базы магазина из ClickHouse
(анти-приём: нагрузка на прод и связность; в документе о реализме
зафиксировать как явный учебный пункт «в бою — реплика или выгрузка»);
файловые дропы как источник (зона Lakehouse-стенда; остаются теорией —
«настоящий Logs API — это скачанный TSV»); HTTP-сервис заказов и CDC
(Debezium) — цена выше учебной отдачи; каталог отдельным топиком Kafka —
выдумка, в бою так не делают.

**Честность к Яндексу:** у Метрики кликстрим — батч (Logs API), потока в
общем доступе нет; наша Kafka — учебная замена, так и называем в
`docs/generator-realism.md`.

**Что это открывает дальше:** #15 (purchase и форма заказа) и #14 (кластер:
с широким событием склейка осколков исчезает, ключ шардирования решается
там) разблокированы; новые приёмы стенда — ARRAY JOIN, словари,
сенсоры/Datasets, кросс-источниковый DQ; кандидат — версии записи через
Sign (механика CollapsingMergeTree из потока Метрики Про).
