Status: done # ×K и дневной коэффициент по модельному времени ## Parent `.scratch/generator-model-time-startup-history/PRD.md` ## What to build Добавить ускоренный живой ход модельных часов. При ×K за один реальный тик должна проходить большая модельная длительность, а событийный бюджет должен считаться по этой модельной длительности. Дневной коэффициент считается по модельному часу. Результат должен быть виден в ClickHouse: модельные метки уходят вперёд быстрее реального времени, а объём событий соответствует пройденному модельному интервалу. ## Acceptance criteria - [x] На ×1 поведение остаётся совместимым с обычным живым режимом. - [x] На ×K модельные `event_timestamp` за короткий реальный прогон покрывают примерно `K` раз большую модельную длительность. - [x] Событийный бюджет считается по модельной длительности тика, а не по реальному времени сна процесса. - [x] Дневной коэффициент меняется при переходе модельного времени через дневные/ночные часы в зафиксированном часовом поясе, независимо от реального часа запуска. - [x] ClickHouse-проверка показывает повторяемые контрольные числа при тех же `GEN_SEED`, `T0`, скорости и настройках. - [x] Worker даёт промежуточный статус, если статистический прогон или стендовая проверка занимает заметное время. - [x] В `generator/README.md` или `docs/OPERATIONS.md` кратко описано, что ×K ускоряет именно модельное время стенда. ## Решение `calculate_events_count()` теперь считает λ тика по модельной длительности: `GEN_TICK_SECONDS * GEN_MODEL_TIME_SPEED`. При `GEN_MODEL_TIME_SPEED=1` формула остаётся прежней. Для больших λ старый Knuth-алгоритм заменён нормальным приближением, чтобы ускорение ×K не упиралось в underflow `exp(-λ)` и событийный бюджет продолжал расти вместе с модельной длительностью. Добавлены проверки: - средний бюджет ×10 примерно в 10 раз больше бюджета ×1; - большой λ не залипает на старом underflow-ограничении; - `hour_factor()` берёт час из заданного `GEN_MODEL_TIMEZONE`; - сервисный live-тик при ×10 сдвигает `event_timestamp` с `10:00` на `10:10`; - старый live-сценарий ×1 остаётся зелёным. Документация в `generator/README.md` и `docs/OPERATIONS.md` уточняет, что ×K ускоряет модельную длительность тика и событийный бюджет. ## Проверка - `make generator-test` — `120 passed`. - ClickHouse, быстрый прогон ×60 с `GEN_STATE_RESET=true`, `GEN_MODEL_T0=2026-01-01T05:58:00+00:00`, `GEN_TICK_SECONDS=1`: за короткий реальный прогон `event_ts` покрыл `2026-01-01 05:58:00` … `2026-01-01 06:09:00`; после 06:00 UTC поминутные числа выросли с `40/42` до примерно `58..63`, что показывает смену ночного коэффициента. - ClickHouse, повторяемость: два чистых запуска с одинаковыми `GEN_SEED=4242`, `GEN_MODEL_T0=2026-01-01T10:00:00+00:00`, `GEN_MODEL_TIME_SPEED=60`, `GEN_TICK_SECONDS=60`, `GEN_STATE_RESET=true` дали одинаковые контрольные числа: `events=73`, `unique_events=73`, `unique_clicks=73`, `min_event_ts=max_event_ts=2026-01-01 10:00:00`. ## Риски и границы - State v2 resume, backfill, manifest и startup history не менялись. Известные риски по ним остаются задачами 04/05. - Сервис всё ещё пишет операционные метки state и истории пачек по настенному времени; это соответствует текущему контракту issue 03. - Нормальное приближение для больших λ не является точным Poisson, но для событийного бюджета учебного демо достаточно сохраняет масштаб, среднее и дисперсию. Точную статистическую выборку можно выделить в отдельную задачу, если она станет учебной целью. ## Blocked by - `.scratch/generator-model-time-startup-history/issues/02-model-time-to-clickhouse.md`