docs(generator): добавлены задачи по модельному времени

- Зачем:
  - нужен рабочий план для реализации модельного времени и стартовой истории.
- Что:
  - добавлен parent PRD с инвариантами, зависимостями и review gate.
  - добавлены шесть локальных issue для последовательной работы.
  - добавлен handoff для продолжения в новой сессии.
- Проверка:
  - git diff --check.
This commit is contained in:
2026-06-14 15:59:12 +03:00
parent fa93aef150
commit 796c3f26a9
8 changed files with 380 additions and 0 deletions
@@ -0,0 +1,39 @@
Status: ready-for-human
# Контракт модельного времени и стартовой истории
## Parent
`.scratch/generator-model-time-startup-history/PRD.md`
## What to build
Зафиксировать рабочий контракт для реализации модельного времени и стартовой
истории. Это HITL-срез: до кода нужно решить внешний интерфейс, формат
стартовой истории и правила восстановления, чтобы worker-и не угадывали
поведение через тесты.
Контракт должен остаться коротким и понятным: что задаёт `T0`, как задаётся ×K,
что такое `T_end`, как выглядит стартовая история, какие метки времени
модельные, а какие операционные.
## Acceptance criteria
- [ ] Выбраны имена и формат настроек для `T0`, скорости ×K и режима промотки
прошлого.
- [ ] Описано, как после сбоя вычисляется модельная точка возобновления при ×K:
из сохранённой модельной метки, сохранённой настенной метки и скорости.
- [ ] Описан манифест стартовой истории: минимум `GEN_SEED`, `T0`, `T_end`,
настройки генерации, версия state и контрольные числа.
- [ ] Описана граница `T_end`: где заканчивается прошлое и с какой метки
начинается живое продолжение, без дублей и дыр.
- [ ] Разделены модельные метки событий и настенные операционные метки сервиса.
- [ ] Решено, как координатор будет получать повторяемую ClickHouse-проверку:
через очистку данных или идемпотентный прогон.
- [ ] Контракт записан в durable-документ: обновление `PRD.md`, короткий
design note в `.scratch/generator-model-time-startup-history/` или уточнение
спеки. Сам issue 01 только ссылается на источник истины.
## Blocked by
None - can start immediately
@@ -0,0 +1,34 @@
Status: ready-for-agent
# Модельное время до ClickHouse
## Parent
`.scratch/generator-model-time-startup-history/PRD.md`
## What to build
Сделать минимальный живой поток, где генератор стартует от `T0`, пишет
`event_timestamp` по модельному времени и доводит события до ClickHouse
обычным путём стенда. Срез должен доказать не внутренний класс часов, а
наблюдаемое поведение: данные в ClickHouse начинаются от модельной точки и
повторяются при тех же настройках.
## Acceptance criteria
- [ ] При фиксированных `GEN_SEED` и `T0` первый короткий прогон пишет события с
модельными `event_timestamp`, начинающимися около `T0`.
- [ ] Повторный чистый прогон с теми же настройками даёт те же контрольные
числа в ClickHouse.
- [ ] Расчёт дневного коэффициента в этом срезе больше не зависит от реального
часа запуска процесса.
- [ ] Локальные тесты проверяют поведение через публичный интерфейс генератора
или сервиса, без привязки к внутреннему устройству часов.
- [ ] Есть команда или короткая инструкция для координатора: поднять стенд,
прогнать поток, выполнить SQL-проверку в ClickHouse.
- [ ] Документация запуска не утверждает, что `event_timestamp` равен
настенному времени.
## Blocked by
- `.scratch/generator-model-time-startup-history/issues/01-time-and-startup-history-contract.md`
@@ -0,0 +1,36 @@
Status: ready-for-agent
# ×K и дневной коэффициент по модельному времени
## Parent
`.scratch/generator-model-time-startup-history/PRD.md`
## What to build
Добавить ускоренный живой ход модельных часов. При ×K за один реальный тик
должна проходить большая модельная длительность, а событийный бюджет должен
считаться по этой модельной длительности. Дневной коэффициент считается по
модельному часу.
Результат должен быть виден в ClickHouse: модельные метки уходят вперёд быстрее
реального времени, а объём событий соответствует пройденному модельному
интервалу.
## Acceptance criteria
- [ ] На ×1 поведение остаётся совместимым с обычным живым режимом.
- [ ] На ×K модельные `event_timestamp` за короткий реальный прогон покрывают
примерно `K` раз большую модельную длительность.
- [ ] Событийный бюджет считается по модельной длительности тика, а не по
реальному времени сна процесса.
- [ ] Дневной коэффициент меняется при переходе модельного времени через
дневные/ночные часы, независимо от реального часа запуска.
- [ ] ClickHouse-проверка показывает повторяемые контрольные числа при тех же
`GEN_SEED`, `T0`, скорости и настройках.
- [ ] В `generator/README.md` или `docs/OPERATIONS.md` кратко описано, что ×K
ускоряет именно модельное время стенда.
## Blocked by
- `.scratch/generator-model-time-startup-history/issues/02-model-time-to-clickhouse.md`
@@ -0,0 +1,40 @@
Status: ready-for-agent
# Восстановление state v2 от модельной точки
## Parent
`.scratch/generator-model-time-startup-history/PRD.md`
## What to build
Привести восстановление state v2 к модельному времени. Один и тот же слепок
должен уметь восстанавливаться в двух разных случаях: после сбоя, где время
действительно прошло, и при старте из стартовой истории, где продолжение идёт
от `T_end` без искусственного разрыва.
Срез должен доказать поведение не только локальными тестами состояния, но и
данными в ClickHouse: активные визиты продолжаются или закрываются по правилам
модельного времени.
## Acceptance criteria
- [ ] State сохраняет достаточно данных, чтобы после сбоя вычислить модельную
точку возобновления при ×K.
- [ ] Восстановление после короткого сбоя продолжает активные визиты и досылает
созревшие события с исходными модельными метками.
- [ ] Восстановление после долгого сбоя закрывает сильно просроченные активные
визиты без досылки остатка.
- [ ] Восстановление из стартовой истории использует `T_end` как точку
возобновления и не обрывает активные визиты из-за настенного простоя.
- [ ] Повреждённый или несовместимый state не валит сервис: генератор стартует
с чистого листа и пишет предупреждение.
- [ ] ClickHouse-проверка подтверждает, что на стыке восстановления нет дублей
событий и нет разрыва `click_id` внутри продолжающегося визита.
- [ ] После реализации выполнено саморевью worker-а и отдельное reviewer-ревью,
потому что задача меняет state/serialization и сервисное восстановление.
## Blocked by
- `.scratch/generator-model-time-startup-history/issues/03-model-speed-and-day-factor.md`
- Review gate из `PRD.md`: сквозной инвариант времени после задачи 3
@@ -0,0 +1,43 @@
Status: ready-for-agent
# Стартовая история до ClickHouse
## Parent
`.scratch/generator-model-time-startup-history/PRD.md`
## What to build
Сделать промотку прошлого: генератор быстро проходит от `T0` до `T_end`, создаёт
события за этот отрезок, сохраняет слепок состояния и манифест стартовой
истории. Эту историю нужно загрузить в ClickHouse и доказать, что живой поток
может продолжить её с `T_end`.
Это главный срез стартовой истории. Он должен проверять не только факт наличия
данных, но и форму данных: пирамиду, возвраты, длину визита, воронку и стык
между прошлым и живым продолжением.
## Acceptance criteria
- [ ] Промотка прошлого создаёт события за `[T0, T_end]`, слепок состояния и
манифест с контрольными данными.
- [ ] При одинаковых `GEN_SEED`, `T0`, `T_end` и настройках результат промотки
повторяем в пределах согласованных допусков.
- [ ] История загружается в ClickHouse штатной или явно описанной командой.
- [ ] SQL-проверка показывает здоровую пирамиду: пользователей меньше, чем
визитов, визитов меньше, чем событий.
- [ ] SQL-проверка показывает возвраты: у части пользователей больше одного
визита.
- [ ] SQL-проверка длины визита проверяет форму, а не только среднее: долю
коротких визитов, медиану и долю срезов о потолок.
- [ ] SQL-проверка воронки `/home -> товары -> /cart -> /payment ->
/confirmation` монотонно убывает, а доля дошедших до `/confirmation` в
согласованном коридоре.
- [ ] Живое продолжение после `T_end` не создаёт дублей на границе и не выглядит
как независимый второй мир.
- [ ] Подготовлены данные, команды и SQL-проверки, достаточные для внешнего
review gate по распределениям и двум путям генерации из `PRD.md`.
## Blocked by
- `.scratch/generator-model-time-startup-history/issues/04-state-v2-model-resume.md`
@@ -0,0 +1,47 @@
Status: ready-for-agent
# Стартовая история как источник аналитики
## Parent
`.scratch/generator-model-time-startup-history/PRD.md`
## What to build
Перевести штатный путь стенда на стартовую историю как источник аналитики.
Чистый стенд должен получать данные из генерации: стартовая история загружается,
STG→ODS→DDS→DM строится на ней, а Superset работает с этими витринами. Архивный
статический сид остаётся только временной кладовкой фактуры для генератора, а не
источником аналитического контура.
Срез не требует финальной ручной оценки красоты дашбордов, но должен дать
техническое доказательство: витрины и датасеты не пустые, контрольные числа
берутся из генерации.
Границы среза: штатный путь стенда и документы запуска. Переписывание уроков,
новые панели и улучшение формы дашбордов остаются follow-up, если по ходу не
окажутся маленькой обязательной правкой для запуска.
## Acceptance criteria
- [ ] Штатная команда запуска чистого стенда создаёт или загружает стартовую
историю и прогоняет её до DM-витрин.
- [ ] `kafka_load_dag` или заменяющий его путь больше не использует архивный
`data/*.jsonl` как источник аналитики.
- [ ] ClickHouse-проверки из задачи 5 доступны как повторяемая команда для
координатора или CI.
- [ ] Основные DM-витрины, на которых стоят дашборды, непустые и показывают
данные генерации.
- [ ] Superset-датасеты и дашборды технически открываются на данных генерации;
ручная оценка формы графиков остаётся финальной HITL-приёмкой.
- [ ] `README.md`, `docs/OPERATIONS.md` и `generator/README.md` больше не
описывают архивный сид как основной источник аналитики.
- [ ] Если уроки или дашборды требуют нетривиальной переделки, создан follow-up
issue вместо расширения этой задачи.
- [ ] Описан повторный чистый прогон: какие данные очищаются и какие команды
выполняются, чтобы координатор мог надёжно перепроверить результат.
## Blocked by
- `.scratch/generator-model-time-startup-history/issues/05-startup-history-backfill-to-clickhouse.md`
- Review gate из `PRD.md`: распределения и два пути генерации после задачи 5