docs(generator): добавлены задачи реализации и handoff
- Зачем:
- переработку steady-stream генератора нужно передать агентам как набор
проверяемых вертикальных задач, а не как один крупный rewrite.
- Что:
- создан локальный набор из семи ready-for-agent задач для реализации новой
иерархической модели генератора.
- добавлен handoff с текущим состоянием обсуждения, рекомендуемым следующим
шагом через TDD и примером команды /goal для запуска задачи 01.
- Проверка:
- git diff HEAD~1 --stat.
This commit is contained in:
@@ -0,0 +1,38 @@
|
|||||||
|
Status: ready-for-agent
|
||||||
|
|
||||||
|
# Минимальный связанный визит в новом ядре
|
||||||
|
|
||||||
|
## What to build
|
||||||
|
|
||||||
|
Построить первый проверяемый срез нового steady-stream генератора: публичный
|
||||||
|
вызов генеративного ядра создаёт один визит, который выглядит как нормальная
|
||||||
|
единица доменной модели `пользователь -> визит -> событие`.
|
||||||
|
|
||||||
|
Визит должен выпускать несколько связанных событий: один общий `click_id`,
|
||||||
|
разные `event_id`, общий device/geo-контекст и согласованные записи для четырёх
|
||||||
|
Kafka-топиков. Kafka на этом шаге не нужна: задача проверяет форму данных на
|
||||||
|
выходе генеративного ядра.
|
||||||
|
|
||||||
|
Источник решений: `docs/specs/2026-06-09-generator-rework-hierarchical.md`,
|
||||||
|
`docs/specs/2026-06-10-generator-math-model.md`, `CONTEXT.md`.
|
||||||
|
|
||||||
|
## Acceptance criteria
|
||||||
|
|
||||||
|
- [ ] Тест через публичный интерфейс генератора создаёт один визит с несколькими
|
||||||
|
browser-событиями под одним `click_id`.
|
||||||
|
- [ ] У всех событий визита разные валидные `event_id`, а `click_id` не берётся
|
||||||
|
из исходного сида.
|
||||||
|
- [ ] Для каждого browser-события есть связанная location-запись с тем же
|
||||||
|
`event_id`.
|
||||||
|
- [ ] Для каждого события визита публикуются device- и geo-записи с тем же
|
||||||
|
`click_id`; их содержимое в рамках визита одинаковое, как в сиде.
|
||||||
|
- [ ] Один `click_id` связан ровно с одним `user_domain_id`.
|
||||||
|
- [ ] Старый тестовый контракт "одно событие = один новый click_id" удалён или
|
||||||
|
заменён на новый контракт визита.
|
||||||
|
|
||||||
|
## Blocked by
|
||||||
|
|
||||||
|
None - can start immediately.
|
||||||
|
|
||||||
|
## Comments
|
||||||
|
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
Status: ready-for-agent
|
||||||
|
|
||||||
|
# Путь визита по страницам и монотонное время
|
||||||
|
|
||||||
|
## What to build
|
||||||
|
|
||||||
|
Расширить минимальный визит до правдоподобного пути по страницам. Визит должен
|
||||||
|
начинаться со страницы, выбранной по стартовому распределению, дальше идти по
|
||||||
|
марковской цепочке и назначать событиям запланированные метки времени, которые
|
||||||
|
строго растут внутри `click_id`.
|
||||||
|
|
||||||
|
Задача остаётся без Kafka и без популяции пользователей: она проверяет качество
|
||||||
|
одного визита как учебного объекта и как основы будущей воронки.
|
||||||
|
|
||||||
|
Источник решений: `docs/specs/2026-06-10-generator-math-model.md`, раздел
|
||||||
|
«События и путь по страницам».
|
||||||
|
|
||||||
|
## Acceptance criteria
|
||||||
|
|
||||||
|
- [ ] Тест через публичный интерфейс генератора показывает, что
|
||||||
|
`event_timestamp` внутри одного `click_id` строго возрастает.
|
||||||
|
- [ ] Метки времени событий являются запланированными моментами визита, а не
|
||||||
|
одинаковым `now()` для всего набора событий.
|
||||||
|
- [ ] Паузы внутри визита меньше 30 минут; 95-й перцентиль на симуляции лежит в
|
||||||
|
масштабе единиц минут.
|
||||||
|
- [ ] Визит не может зациклиться бесконечно: длина ограничена потолком
|
||||||
|
`GEN_MAX_SESSION_EVENTS` или его новым эквивалентом.
|
||||||
|
- [ ] Доля визитов, дошедших до `/confirmation`, на симуляции сопоставима с
|
||||||
|
ориентиром сида около 25%.
|
||||||
|
- [ ] Визит может продолжаться после `/confirmation`; `/confirmation` не
|
||||||
|
считается обязательным последним событием визита.
|
||||||
|
|
||||||
|
## Blocked by
|
||||||
|
|
||||||
|
- `.scratch/feature-data-generator/issues/01-minimal-connected-visit.md`
|
||||||
|
|
||||||
|
## Comments
|
||||||
|
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
Status: ready-for-agent
|
||||||
|
|
||||||
|
# Поток по тикам с активными визитами
|
||||||
|
|
||||||
|
## What to build
|
||||||
|
|
||||||
|
Разложить визиты по тикам генератора. Визит может жить дольше одного тика:
|
||||||
|
генератор хранит активные визиты между вызовами, выпускает только те события,
|
||||||
|
чьё запланированное время наступило, и не приклеивает все события к текущему
|
||||||
|
тику.
|
||||||
|
|
||||||
|
Задача проверяет основную потоковую механику без Kafka и без восстановления
|
||||||
|
после рестарта.
|
||||||
|
|
||||||
|
Источник решений: `docs/specs/2026-06-10-generator-math-model.md`, раздел
|
||||||
|
«Раскладка по тикам».
|
||||||
|
|
||||||
|
## Acceptance criteria
|
||||||
|
|
||||||
|
- [ ] Тест через публичный интерфейс генератора показывает, что один `click_id`
|
||||||
|
может появляться в выходе нескольких последовательных тиков.
|
||||||
|
- [ ] На каждом тике выпускаются только созревшие события активных визитов.
|
||||||
|
- [ ] `event_timestamp` отражает запланированное время события, а не время
|
||||||
|
фактической отправки тика.
|
||||||
|
- [ ] Завершённые визиты больше не выпускают события в следующих тиках.
|
||||||
|
- [ ] При достижении потолка активных визитов новые рождения в этот тик
|
||||||
|
пропускаются, а бюджет не копится бесконечно.
|
||||||
|
- [ ] Конфигурация запрещает состояние, где потолок активных визитов не меньше
|
||||||
|
потолка популяции пользователей.
|
||||||
|
|
||||||
|
## Blocked by
|
||||||
|
|
||||||
|
- `.scratch/feature-data-generator/issues/02-visit-page-path-and-monotonic-time.md`
|
||||||
|
|
||||||
|
## Comments
|
||||||
|
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
Status: ready-for-agent
|
||||||
|
|
||||||
|
# Популяция пользователей и возвраты
|
||||||
|
|
||||||
|
## What to build
|
||||||
|
|
||||||
|
Добавить ограниченную популяцию пользователей с постоянными `user_domain_id`.
|
||||||
|
Новые визиты должны доставаться либо новым пользователям, либо возвращающимся
|
||||||
|
пользователям из популяции, доступным после кулдауна и не имеющим активного
|
||||||
|
визита.
|
||||||
|
|
||||||
|
Задача должна превратить поток из набора независимых визитов в живую модель
|
||||||
|
возвратов пользователей.
|
||||||
|
|
||||||
|
Источник решений: `docs/specs/2026-06-10-generator-math-model.md`, разделы
|
||||||
|
«Популяция пользователей» и «Визиты».
|
||||||
|
|
||||||
|
## Acceptance criteria
|
||||||
|
|
||||||
|
- [ ] На длинной симуляции получается здоровая пирамида
|
||||||
|
`users < sessions < events`.
|
||||||
|
- [ ] Один пользователь может иметь несколько `click_id` во времени.
|
||||||
|
- [ ] Один `click_id` принадлежит ровно одному `user_domain_id`.
|
||||||
|
- [ ] Пользователь не получает новый визит раньше минимального кулдауна возврата.
|
||||||
|
- [ ] Если доступных возвращающихся пользователей нет, новый визит достаётся
|
||||||
|
новому пользователю.
|
||||||
|
- [ ] Размер активной популяции не растёт выше заданного потолка; при
|
||||||
|
переполнении вытесняется давно неактивный пользователь без активного визита.
|
||||||
|
|
||||||
|
## Blocked by
|
||||||
|
|
||||||
|
- `.scratch/feature-data-generator/issues/03-tick-stream-with-active-visits.md`
|
||||||
|
|
||||||
|
## Comments
|
||||||
|
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
Status: ready-for-agent
|
||||||
|
|
||||||
|
# Интенсивность и калибровка потока
|
||||||
|
|
||||||
|
## What to build
|
||||||
|
|
||||||
|
Связать иерархическую модель с целевой интенсивностью потока. Старая идея
|
||||||
|
Пуассона, часового коэффициента и jitter должна задавать бюджет активности, из
|
||||||
|
которого рождаются визиты; фактические события выходят по запланированным
|
||||||
|
паузам активных визитов.
|
||||||
|
|
||||||
|
На этом шаге также нужно проверить, что параметры модели дают поток,
|
||||||
|
сопоставимый с профилем сида: длина визита около 10 событий в среднем и по
|
||||||
|
медиане, доля дошедших до `/confirmation` около 25%, межсессионные паузы
|
||||||
|
согласованы с формулой из спеки.
|
||||||
|
|
||||||
|
Источник решений: `docs/specs/2026-06-10-generator-math-model.md`, разделы
|
||||||
|
«Связка с моделью интенсивности», «Параметры» и «Критерии приёмки».
|
||||||
|
|
||||||
|
## Acceptance criteria
|
||||||
|
|
||||||
|
- [ ] Средняя интенсивность событий за длинное окно соответствует
|
||||||
|
`GEN_LAMBDA_BASE_PER_MIN * часовой коэффициент` с разумным отклонением.
|
||||||
|
- [ ] Рождения визитов рассчитываются из бюджета событий и средней длины визита,
|
||||||
|
а не из старых границ `GEN_MIN/MAX_EVENTS_PER_TICK` в прежнем смысле.
|
||||||
|
- [ ] Доля новых пользователей за длинное окно близка к `GEN_P_NEW_USER`.
|
||||||
|
- [ ] Межсессионные паузы одного пользователя не меньше кулдауна, а среднее на
|
||||||
|
дефолтах находится в районе расчёта из спеки.
|
||||||
|
- [ ] Распределение длины визита на симуляции сопоставимо с сидом: медиана около
|
||||||
|
10, среднее около 10, максимум не выше потолка.
|
||||||
|
- [ ] Воронка по шагам `/home -> товары -> /cart -> /payment -> /confirmation`
|
||||||
|
монотонно затухает на длинной симуляции.
|
||||||
|
|
||||||
|
## Blocked by
|
||||||
|
|
||||||
|
- `.scratch/feature-data-generator/issues/04-user-population-and-returns.md`
|
||||||
|
|
||||||
|
## Comments
|
||||||
|
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
Status: ready-for-agent
|
||||||
|
|
||||||
|
# Состояние версии 2 и рестарт
|
||||||
|
|
||||||
|
## What to build
|
||||||
|
|
||||||
|
Расширить состояние генератора до версии 2: кроме тика и состояния генератора
|
||||||
|
случайных чисел сохранять популяцию пользователей и активные визиты. После
|
||||||
|
рестарта генератор должен продолжать коротко прерванные визиты и закрывать
|
||||||
|
сильно просроченные, не теряя популяцию пользователей.
|
||||||
|
|
||||||
|
Задача проверяет поведение состояния через публичные методы сохранения и
|
||||||
|
восстановления, без реального Kafka-брокера там, где достаточно сериализации.
|
||||||
|
|
||||||
|
Источник решений: `docs/specs/2026-06-10-generator-math-model.md`, раздел
|
||||||
|
«Персистентность через рестарты».
|
||||||
|
|
||||||
|
## Acceptance criteria
|
||||||
|
|
||||||
|
- [ ] Состояние версии 2 сериализуется в JSON и восстанавливает тик, ГПСЧ,
|
||||||
|
популяцию пользователей и активные визиты.
|
||||||
|
- [ ] Старое состояние версии 1 или битое состояние не валит генератор:
|
||||||
|
фиксируется предупреждение, генератор начинает с чистого листа.
|
||||||
|
- [ ] После простоя не больше 30 минут активный визит продолжается, а созревшие
|
||||||
|
события досылаются со своими исходными запланированными метками времени.
|
||||||
|
- [ ] После долгого простоя просроченный активный визит закрывается без досылки
|
||||||
|
остатка.
|
||||||
|
- [ ] Популяция пользователей переживает простой любой длины.
|
||||||
|
- [ ] `GEN_STATE_RESET=true` явно сбрасывает состояние, как и раньше.
|
||||||
|
|
||||||
|
## Blocked by
|
||||||
|
|
||||||
|
- `.scratch/feature-data-generator/issues/05-intensity-and-flow-calibration.md`
|
||||||
|
|
||||||
|
## Comments
|
||||||
|
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
Status: ready-for-agent
|
||||||
|
|
||||||
|
# Подключение к сервису и документации
|
||||||
|
|
||||||
|
## What to build
|
||||||
|
|
||||||
|
Подключить новое генеративное ядро к рабочему steady-stream сервису. Генератор
|
||||||
|
должен запускаться прежними командами, писать сообщения в прежние Kafka-топики,
|
||||||
|
сохранять полезные метрики Prometheus и больше не документироваться как
|
||||||
|
концептуально сломанный источник.
|
||||||
|
|
||||||
|
На этом шаге нужно синхронизировать пользовательскую документацию и заметку об
|
||||||
|
известных проблемах с новой моделью.
|
||||||
|
|
||||||
|
Источник решений: `docs/specs/2026-06-09-generator-rework-hierarchical.md`,
|
||||||
|
`docs/specs/2026-06-10-generator-math-model.md`, `generator/README.md`,
|
||||||
|
`generator/KNOWN_ISSUES.md`.
|
||||||
|
|
||||||
|
## Acceptance criteria
|
||||||
|
|
||||||
|
- [ ] Генератор в режиме steady-stream пишет связанные сообщения в
|
||||||
|
`browser_events`, `location_events`, `device_events`, `geo_events`.
|
||||||
|
- [ ] Существующие команды запуска и остановки генератора остаются рабочими или
|
||||||
|
документация явно описывает замену.
|
||||||
|
- [ ] Метрики Prometheus продолжают показывать успешные тики, ошибки публикации
|
||||||
|
и объём отправленных событий.
|
||||||
|
- [ ] Интеграционный тест или проверка с мок-публикацией подтверждает, что
|
||||||
|
сервисный контур использует новую модель, а не старую плоскую генерацию.
|
||||||
|
- [ ] `generator/README.md` описывает новые параметры и новую модель без старых
|
||||||
|
предупреждений о сломанном `click_id`.
|
||||||
|
- [ ] `generator/KNOWN_ISSUES.md` обновлён: старый дефект закрыт или перенесён в
|
||||||
|
исторический раздел, не как актуальный блокер.
|
||||||
|
|
||||||
|
## Blocked by
|
||||||
|
|
||||||
|
- `.scratch/feature-data-generator/issues/06-state-v2-and-restart.md`
|
||||||
|
|
||||||
|
## Comments
|
||||||
|
|
||||||
@@ -0,0 +1,66 @@
|
|||||||
|
# Handoff: генератор разбит на AFK-задачи
|
||||||
|
|
||||||
|
Дата: 2026-06-11
|
||||||
|
Ветка: `feature/data-generator`
|
||||||
|
Жанр: одноразовые леса по [ADR-0003](../../docs/adr/0003-handoffs-in-scratch.md).
|
||||||
|
|
||||||
|
## Где остановились
|
||||||
|
|
||||||
|
После обсуждения с пользователем дизайн переработки steady-stream генератора
|
||||||
|
переведён из больших спек в локальные задачи для агентов. Код генератора не
|
||||||
|
меняли.
|
||||||
|
|
||||||
|
Создан каталог задач:
|
||||||
|
|
||||||
|
- `.scratch/feature-data-generator/issues/01-minimal-connected-visit.md`
|
||||||
|
- `.scratch/feature-data-generator/issues/02-visit-page-path-and-monotonic-time.md`
|
||||||
|
- `.scratch/feature-data-generator/issues/03-tick-stream-with-active-visits.md`
|
||||||
|
- `.scratch/feature-data-generator/issues/04-user-population-and-returns.md`
|
||||||
|
- `.scratch/feature-data-generator/issues/05-intensity-and-flow-calibration.md`
|
||||||
|
- `.scratch/feature-data-generator/issues/06-state-v2-and-restart.md`
|
||||||
|
- `.scratch/feature-data-generator/issues/07-service-integration-and-docs.md`
|
||||||
|
|
||||||
|
Все задачи имеют `Status: ready-for-agent`. Разрез сделан как последовательные
|
||||||
|
вертикальные срезы, а не как слои архитектуры. Решение пользователя: идти по
|
||||||
|
этому варианту.
|
||||||
|
|
||||||
|
## Важный контекст
|
||||||
|
|
||||||
|
- Старый генератор считаем слабым прототипом, а не ценным кодом для сохранения.
|
||||||
|
Сохранять надо внешние контракты, если они полезны: топики Kafka, формат
|
||||||
|
сообщений для текущего ETL, команды запуска, метрики, идею compact-топика
|
||||||
|
состояния.
|
||||||
|
- Отдельную задачу "зафиксировать внешний контракт" не создавали: контракт
|
||||||
|
встроен в первый и последний срезы.
|
||||||
|
- Детали модели не дублировать отсюда. Источники истины:
|
||||||
|
- `docs/specs/2026-06-10-generator-math-model.md`
|
||||||
|
- `docs/specs/2026-06-09-generator-rework-hierarchical.md`
|
||||||
|
- `docs/adr/0004-steady-stream-synthetic-generator.md`
|
||||||
|
- `CONTEXT.md`
|
||||||
|
- `generator/KNOWN_ISSUES.md`
|
||||||
|
- Предыдущий handoff `.scratch/handoffs/2026-06-10-generator-spec-to-codex.md`
|
||||||
|
остаётся полезным как предыстория спек.
|
||||||
|
|
||||||
|
## Следующий шаг
|
||||||
|
|
||||||
|
Начать с задачи 01 через TDD:
|
||||||
|
|
||||||
|
1. написать один красный тест на публичное поведение "минимальный связанный
|
||||||
|
визит";
|
||||||
|
2. реализовать минимальное новое генеративное ядро без Kafka;
|
||||||
|
3. не тащить старую плоскую модель `generate_batch()`;
|
||||||
|
4. после зелёного теста переходить к следующему поведению, не писать все тесты
|
||||||
|
заранее.
|
||||||
|
|
||||||
|
Пример запуска задачи:
|
||||||
|
|
||||||
|
```text
|
||||||
|
/goal Реализовать .scratch/feature-data-generator/issues/01-minimal-connected-visit.md с использованием /tdd. Соблюдать цикл: один тест на наблюдаемое поведение → минимальная реализация → зелёный тест → остановиться и отчитаться. Не писать все тесты заранее, не реализовывать задачи 02-07.
|
||||||
|
```
|
||||||
|
|
||||||
|
## Suggested skills
|
||||||
|
|
||||||
|
- `tdd` — для реализации каждой задачи короткими циклами red-green-refactor.
|
||||||
|
- `adversarial-review` или `claude-team-review` — после реализации нескольких
|
||||||
|
срезов, чтобы сверить код с мат-спекой.
|
||||||
|
- `conventional-commits` — при фиксации следующих изменений.
|
||||||
Reference in New Issue
Block a user