docs(generator): зафиксировано направление переработки генератора
- Зачем:
- при возврате к генератору не переоткрывать выбор «генератор 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>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
dd2c3cdaf9
commit
6ddc7a90d4
@@ -0,0 +1,78 @@
|
||||
# ADR-0004: Steady-stream источник — синтетический иерархический генератор, не реплей
|
||||
|
||||
Принято: 2026-06-09
|
||||
Статус: accepted
|
||||
Связано: [`generator/KNOWN_ISSUES.md`](../../generator/KNOWN_ISSUES.md) (диагноз
|
||||
дефекта), [`CONTEXT.md`](../../CONTEXT.md),
|
||||
[ADR-0002](./0002-specs-as-durable-design-docs.md) (спеки как durable design-доки),
|
||||
спека [`docs/specs/2026-06-09-generator-rework-hierarchical.md`](../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-спеку** и здесь
|
||||
намеренно не фиксируется.
|
||||
Reference in New Issue
Block a user