- Зачем:
- при возврате к генератору не переоткрывать выбор «генератор vs реплей»
и иметь готовую рамку требований под реализацию steady-stream.
- Что:
- ADR-0004: steady-stream питается синтетическим иерархическим генератором,
не реплеем сида (обоснование + отклонённые варианты C/B).
- спека docs/specs/2026-06-09: требования к иерархической модели сущностей
и критерии приёмки; математика делегирована follow-up-спеке.
- CONTEXT.md: термины «популяция пользователей», «возвращающийся пользователь».
- Проверка:
- прочитать ADR-0004 и спеку; сверить термины в CONTEXT.md.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
6.8 KiB
ADR-0004: Steady-stream источник — синтетический иерархический генератор, не реплей
Принято: 2026-06-09
Статус: accepted
Связано: generator/KNOWN_ISSUES.md (диагноз
дефекта), CONTEXT.md,
ADR-0002 (спеки как durable design-доки),
спека docs/specs/2026-06-09-generator-rework-hierarchical.md
(форма доработки).
Решение
Режим steady-stream (живой поток на стенде) питается синтетическим
генератором, переписанным с нуля по иерархической модели «популяция
пользователей → сессии → события», а не реплеем статического сида. Модель
интенсивности текущего генератора (Poisson по тикам + дневной коэффициент +
jitter) сохраняется. Режим bootstrap (статический сид data/*.jsonl) и уроки
0–6 остаются прежними — генератор сосуществует с сидом, не заменяет его.
Контекст
Проект сменил назначение на учебный стенд с курсом. Базовый курс стоит на
статическом сиде, и это осознанно: сид честен внутри визита (click_id
группирует 1..7 событий — настоящая воронка). Но у сида два потолка, которые
сид принципиально не закрывает:
users == sessions— каждый пользователь имеет ровно одинclick_id(1:1), возвращающихся пользователей нет (см.CONTEXT.md).- одноразовость — сид заливается батчем; не видно, как ClickHouse и витрины ведут себя на непрерывном живом потоке.
Нужен режим, в котором стенд живёт и движется на правдоподобных данных (воронка + жизнеподобные колебания интенсивности), при скромном объёме (у менти может не быть мощного железа — на объём/стресс не закладываемся).
Двойная учебная ценность — ключевой критерий выбора: ценны не только данные
(живой стенд + честная пирамида users < sessions < events), но и сам
генератор как объект изучения — его генеративная модель достойна того, чтобы её
разбирать в курсе.
Текущая реализация генератора не дорабатывается инкрементально: у неё
концептуальный дефект модели сущностей (свежий click_id на каждое событие
схлопывает иерархию — см. generator/KNOWN_ISSUES.md), переписываем с нуля.
Рассмотренные варианты
- A — синтетический иерархический генератор (принято). Популяция юзеров с
постоянным
user_domain_id→ 1..N сессий (click_idна сессию) → 1..M упорядоченных по времени событий с правдоподобной воронкой. Единственный вариант, дающий возвращающихся пользователей (users < sessions < events) и учебную ценность самого моделирования. Цена — самый большой объём работы и риск ошибиться в статистической модели. - C — реплей честного сида на часах. Лить реальные записи сида в Kafka во
времени, переписывая
event_timestampв «сейчас», зацикливая пул и модулируя rate. Отклонено. Дёшев и даёт гарантированно честную воронку почти без риска, но: (1) обходит ровно ту генеративно-модельную часть, ради учебной ценности которой всё и затевается; (2) наследует вырождениеusers == sessionsиз сида — полную пирамиду не даёт никогда; (3) «бесконечность» = зацикленный конечный пул. - B — минимальный «живой» генератор с грубой воронкой. Тот же rewrite, но воронка на фиксированных вероятностях, без глубины. Отклонено как половинчатое: числа воронки менее убедительны, а вопрос возвратов всё равно надо решать — то есть основной сложности не избегает.
Последствия
- Режим
steady-streamфиксируется как синтетическая генерация; направление переоткрывать не нужно (типовой вопрос «почему не реплей?» закрыт здесь). bootstrap-сид и уроки 0–6 не трогаем; живой поток подаётся отдельным уроком 7.- Контракт данных потока: здоровая пирамида
users < sessions < events, монотонное время внутри сессии,click_idпереиспользуется внутри сессии. Этот контракт наследуют будущие артефакты (спека доработки, урок 7, возможные правки витрин). - Детальная архитектура/требования — в спеке
2026-06-09-generator-rework-hierarchical.md. - Статистическая модель (распределения событий/сессия, сессий/пользователь, межсессионные паузы; нужен ли настоящий session-timeout; персистентность популяции через рестарты) выносится в отдельную follow-up-спеку и здесь намеренно не фиксируется.