Files
clickstream-ch-kafka-supers…/docs/adr/0006-generation-as-sole-analytics-source.md
ddadminandClaude Opus 4.8 49512b190a docs(generator): зафиксированы источник аналитики и стартовая история
- Зачем:
  - генератор даёт здоровую пирамиду, и стенду нужен единый источник аналитики вместо вырожденного статического сида.
- Что:
  - добавлен ADR-0006: генерация — единственный источник аналитики, статический сид становится архивным (кладовка значений до синтеза фактуры).
  - добавлена спека модельного времени: точка отсчёта, заливка прошлого, стартовая история, сохранение состояния, воспроизводимость и проверка в два шага.
  - в ADR-0004 и ADR-0005 добавлены указатели вперёд на ADR-0006 и спеку.
- Проверка:
  - чтение документов; перекрёстные ссылки между ADR-0004/0005/0006 и спекой согласованы.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-14 14:47:20 +03:00

113 lines
10 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# ADR-0006: Единственный источник аналитики — генерация; статический сид становится архивным
Принято: 2026-06-14
Статус: accepted
Связано: [ADR-0004](./0004-steady-stream-synthetic-generator.md) (**частично
пересматривает** — тезис о сосуществовании сида и потока),
[ADR-0005](./0005-generator-model-clock.md) (**запускает** направление
«стартовая история стенда»), мат-спека
[`docs/specs/2026-06-10-generator-math-model.md`](../specs/2026-06-10-generator-math-model.md)
(модель распределений), спека механизма
[`docs/specs/2026-06-14-generator-model-time-and-startup-history.md`](../specs/2026-06-14-generator-model-time-and-startup-history.md)
(как это устроено), [`CONTEXT.md`](../../CONTEXT.md) (три значения слова «сид»),
[`generator/KNOWN_ISSUES.md`](../../generator/KNOWN_ISSUES.md).
## Решение
Аналитический контур стенда (Kafka → STG→ODS→DDS→DM → Superset) питается **только
генерацией**: стартовой историей (готовое сгенерированное прошлое) при создании
стенда и живым потоком далее. Статический сид `data/*.jsonl` **выводится из этого
процесса и становится архивным** — он больше не грузится в Kafka и не строит
витрины. Перевод процесса на новый, сгенерированный сид — **цель этой работы**, а
не отложенный шаг.
У старого сида остаётся одна временная роль — **кладовка готовых значений** для
генератора (браузеры, страны, устройства, метки кампаний): генератор берёт оттуда
«фактуру», чтобы одевать ею события, и так же делает сам новый сид. Поэтому файл
пока остаётся в репозитории, хотя из рабочего процесса уже вышел.
- **Что делаем в этой работе:** новый сид становится источником аналитики; процесс
(загрузка, витрины, дашборды, уроки) перестраивается на него; старый сид выходит
из процесса в архив.
- **Что остаётся на отдельный шаг:** научить генератор придумывать фактуру
самостоятельно. После этого старый файл можно удалить совсем — последняя
зависимость от него исчезнет.
- **Целевое состояние:** самодостаточный генератор, старого сида в репозитории нет.
Это решение перекрывает тезис ADR-0004 «генератор сосуществует с сидом, не
заменяет его»: для аналитики генерация сид заменяет.
## Контекст
ADR-0004 (2026-06-09) зафиксировал: «`bootstrap`-сид и уроки 0–6 не трогаем,
генератор сосуществует с сидом». На старте переработки это было верно. Две вещи
изменили посылку: генератор теперь даёт здоровую пирамиду `users < sessions <
events`, а ADR-0005 ввёл модельное время — с ним стартовая история (готовое
сгенерированное прошлое) становится несущей: именно она даёт стенду историческую
глубину с первой минуты.
Почему старый сид перестаёт быть источником:
- **Вырождение `users == sessions`** — у каждого пользователя ровно один визит;
это ровно то, от чего уходим (см. `CONTEXT.md`).
- **Неизвестное происхождение и качество** — это срез чужого учебного задания
(видно, что данные сделаны библиотекой-заполнителем: `dummywebsite.com`,
выдуманные почты, случайные локали). Считать его авторитетным образцом оснований
нет.
- **Одноразовость** — заливается одной пачкой, не показывает живой стенд во
времени.
Скрытая зависимость, найденная при разборе кода: генератор **одевает события
значениями из сида**. Профиль пользователя хранится ссылкой на сид-сессию
(мат-спека, §«Профиль пользователя»), а `generate_batch` копирует поля сид-строк,
переопределяя лишь идентификаторы, время и путь страниц. Поэтому старый сид нельзя
убрать одним движением: сначала генератору нужна своя «фактура». Отсюда разделение
на два шага.
Побочный факт: путь для «грязных» записей (`ods.*_errors`) сид **не наполняет**
проверка показала, что все 1000 записей во всех четырёх файлах чисты, ни одна не
попадает в ошибки. Значит вывод сида из процесса не вредит уроку про грязные
данные; наоборот, генератор, умеющий **намеренно** подсыпать брак, научит этому
лучше идеально чистого среза.
## Рассмотренные варианты
- **A — сид остаётся источником, генерация сосуществует (текущее положение по
ADR-0004).** Отклонено: тащит вырождение `users == sessions` в аналитику и
держит два источника вместо одного.
- **B — генерация заменяет источник, но сид остаётся жёстким образцом для сверки**
(генератор обязан число-в-число повторять профиль сида). Отклонено как
направление: образцовость сида сомнительна, а подгонять генерацию под
вырожденный профиль — шаг назад от того, ради чего всё затевалось.
- **C — генерация единственный источник; старый сид становится архивным
(принято).** Свои намеренно спроектированные распределения вместо
унаследованных; своя «фактура» генератора — отдельным шагом, до него сид
временно остаётся кладовкой значений. Цена — переход в два шага и временно
сохранённая зависимость от сида.
## Последствия
- Аналитический контур переключается на генерацию; **стартовая история становится
несущей** — без неё свежий стенд стартует с пустым прошлым. Это связывает
решение со спекой механизма (модельное время + стартовая история).
- **Порядок шагов важен.** Старый сид выходит из процесса не раньше, чем
(1) готова стартовая история и (2) процесс — загрузка, витрины, дашборды,
уроки — переведён на новый сид. Удалить файл совсем можно только третьим шагом —
после того как генератор научится своей фактуре. Вынуть сид раньше — оставить
стенд без данных.
- **ADR-0004 частично пересмотрен**: «генератор сосуществует с сидом, не заменяет»
остаётся верным лишь для временной роли сида как кладовки значений; для аналитики
генерация сид заменяет. Ссылка вперёд добавлена в ADR-0004.
- **Глоссарий `CONTEXT.md`** (раздел «три значения слова сид») надо выровнять:
статический сид → архивная кладовка значений с целью полного вывода. Обновляется
отдельным шагом.
- **Перестройка процесса** — перевод загрузки (`kafka_load_dag`), витрин/Superset
и уроков на новый сид — входит в эту работу как её цель; детальный план этой
перестройки — отдельная спека на этапе реализации.
- **Полное удаление `data/*.jsonl`** — только после того, как генератор научится
своей фактуре (отдельная спека).
- **Учебная ценность растёт**: со своей фактурой проектируем интересные
распределения (перекос по странам, набор устройств, привязка кампаний, намеренный
брак) вместо случайного набора из чужого сида — но это уже шаг про фактуру, не
этот.