- Зачем: - генератор даёт здоровую пирамиду, и стенду нужен единый источник аналитики вместо вырожденного статического сида. - Что: - добавлен ADR-0006: генерация — единственный источник аналитики, статический сид становится архивным (кладовка значений до синтеза фактуры). - добавлена спека модельного времени: точка отсчёта, заливка прошлого, стартовая история, сохранение состояния, воспроизводимость и проверка в два шага. - в ADR-0004 и ADR-0005 добавлены указатели вперёд на ADR-0006 и спеку. - Проверка: - чтение документов; перекрёстные ссылки между ADR-0004/0005/0006 и спекой согласованы. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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— только после того, как генератор научится своей фактуре (отдельная спека). - Учебная ценность растёт: со своей фактурой проектируем интересные распределения (перекос по странам, набор устройств, привязка кампаний, намеренный брак) вместо случайного набора из чужого сида — но это уже шаг про фактуру, не этот.