feat(generator): добавлено ускорение модельного времени

- Зачем:
  - ускоренный стенд должен проходить больше модельного времени и давать соответствующий событийный бюджет.
- Что:
  - расчёт интенсивности переведён на модельную длительность тика.
  - добавлена устойчивая выборка бюджета при больших λ.
  - усилены тесты ×K, дневного коэффициента и независимости от настенного часа.
- Проверка:
  - make generator-test.
  - review gate после issue 03 пройден после исправления underflow Poisson.
This commit is contained in:
2026-06-14 17:48:51 +03:00
parent efb07b0283
commit 589e2321b3
7 changed files with 237 additions and 47 deletions
@@ -1,4 +1,4 @@
Status: ready-for-agent
Status: ready-for-human
# ×K и дневной коэффициент по модельному времени
@@ -19,21 +19,68 @@ Status: ready-for-agent
## Acceptance criteria
- [ ] На ×1 поведение остаётся совместимым с обычным живым режимом.
- [ ] На ×K модельные `event_timestamp` за короткий реальный прогон покрывают
- [x] На ×1 поведение остаётся совместимым с обычным живым режимом.
- [x] На ×K модельные `event_timestamp` за короткий реальный прогон покрывают
примерно `K` раз большую модельную длительность.
- [ ] Событийный бюджет считается по модельной длительности тика, а не по
- [x] Событийный бюджет считается по модельной длительности тика, а не по
реальному времени сна процесса.
- [ ] Дневной коэффициент меняется при переходе модельного времени через
- [x] Дневной коэффициент меняется при переходе модельного времени через
дневные/ночные часы в зафиксированном часовом поясе, независимо от реального
часа запуска.
- [ ] ClickHouse-проверка показывает повторяемые контрольные числа при тех же
- [x] ClickHouse-проверка показывает повторяемые контрольные числа при тех же
`GEN_SEED`, `T0`, скорости и настройках.
- [ ] Worker даёт промежуточный статус, если статистический прогон или стендовая
- [x] Worker даёт промежуточный статус, если статистический прогон или стендовая
проверка занимает заметное время.
- [ ] В `generator/README.md` или `docs/OPERATIONS.md` кратко описано, что ×K
- [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`