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

10 KiB

ADR-0006: Единственный источник аналитики — генерация; статический сид становится архивным

Принято: 2026-06-14 Статус: accepted Связано: ADR-0004 (частично пересматривает — тезис о сосуществовании сида и потока), ADR-0005 (запускает направление «стартовая история стенда»), мат-спека docs/specs/2026-06-10-generator-math-model.md (модель распределений), спека механизма docs/specs/2026-06-14-generator-model-time-and-startup-history.md (как это устроено), CONTEXT.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 — только после того, как генератор научится своей фактуре (отдельная спека).
  • Учебная ценность растёт: со своей фактурой проектируем интересные распределения (перекос по странам, набор устройств, привязка кампаний, намеренный брак) вместо случайного набора из чужого сида — но это уже шаг про фактуру, не этот.