docs(issues): дооформлены задачи 12 и 14, обновлён граф бэклога генератора
- Зачем:
- подготовить цепочку 12 -> 14 -> 09 -> 10 -> 08 к передаче в coordinator-loop:
задаче 12 не хватало решений после 07 и 11, задача 14 родилась из обсуждения
учебного UX (суточная волна вживую).
- Что:
- issue 12 (DAG-пульт): решения 2026-07-04 — без Docker-доступа из Airflow,
операции как Python-код генератора в тасках, генератор без автостарта,
границы пульта, предпроверки чистоты (топики + STG), ожидание ETL перед
check; учтены находки адверсарного ревью и ревью Codex.
- issue 14 (новая): профиль daily-wave переводится на speed=60 при тике 1 с —
модельный час за настенную минуту без изменения фактуры мира.
- issue 08: мягкие зависимости от 14 и 09 (артефакт курса рождается после
них), режим ревью; PRD: задача 14 в списке и графе, 12 помечена дооформленной.
- Проверка:
- вычитка: статусы задач ready-for-agent, порядок в PRD и Blocked by
согласованы; mermaid-граф рендерится.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,94 @@
|
||||
Status: ready-for-agent
|
||||
|
||||
# Быстрый учебный профиль: суточная волна за минуты занятия
|
||||
|
||||
## Parent
|
||||
|
||||
`.scratch/generator-model-time-startup-history/PRD.md`
|
||||
|
||||
## Why
|
||||
|
||||
Мир по умолчанию живёт со скоростью настенных часов (`speed=1`): чтобы
|
||||
наблюдать суточную волну вживую, стенд должен непрерывно работать сутки.
|
||||
Столько стенды включёнными не живут, и люди не вытерпят (пользователь,
|
||||
2026-07-04). Стартовая история закрывает только половину проблемы: она даёт
|
||||
закономерности **в статике**, но правый край графика ползёт 1:1 — на занятии
|
||||
live выглядит мёртвой картинкой.
|
||||
|
||||
Решение пользователя (2026-07-04): учебному миру нужна скорость 60 — модельный
|
||||
час за настенную минуту, полная суточная волна проживается за ~24 минуты
|
||||
занятия.
|
||||
|
||||
## What to build
|
||||
|
||||
- Перевести профиль `daily-wave` (`launch.py`) на `GEN_MODEL_TIME_SPEED=60`
|
||||
при `GEN_TICK_SECONDS=1`. Модельный тик остаётся прежним: 1 настенная
|
||||
секунда × 60 = 60 модельных секунд, поэтому фактура потока (крупность пачек,
|
||||
бюджет тика до 72 событий в пике: 60/мин × 1.2) не отличается от
|
||||
сегодняшней, и колпак `GEN_MAX_EVENTS_PER_TICK` трогать не нужно.
|
||||
- Наивный вариант «speed=60 при тике 60 с» отвергнут при разборе
|
||||
(2026-07-04): модельный тик стал бы часом; первые события всех визитов тика
|
||||
получают один таймстемп — старт тика (`runtime.py:433`,
|
||||
`generation.py:198`) — история слиплась бы в почасовые гребёнки, а пиковый
|
||||
тик (4320 событий) упёрся бы в колпак 1000 и срезал бы верхушку волны.
|
||||
- **Оценить цену тика в 1 Гц.** Сейчас каждый live-тик пишет state в
|
||||
compact-топик, запись в историю пачек и несколько INFO-строк
|
||||
(`service.py:566, 584-585, 591-600`): на тике 1 с это 86 400 сохранений и
|
||||
~полмиллиона строк лога за настенные сутки против 1 440 сегодня. Пер-тиковые
|
||||
INFO приглушить до DEBUG (или логировать раз в N тиков); частоту сохранения
|
||||
state менять только с оглядкой на спеку — она входит в контракт
|
||||
возобновления после сбоя.
|
||||
- Профиль `ci` не трогать: это дефолт CI, его мир и контрольные суммы должны
|
||||
остаться прежними.
|
||||
- Обновить документы, где живут предположения о старом `daily-wave`:
|
||||
runbook `docs/runbooks/startup-history.md` (таблица профилей; продолжение
|
||||
мира — `PROFILE=daily-wave make generator-continue`; старые артефакты
|
||||
профиля становятся несовместимыми — антисмешивание отработает громко, это
|
||||
ожидаемо), `docs/OPERATIONS.md` (smoke-последовательность со `sleep 130` —
|
||||
ожидание двух минутных тиков — на тике 1 с теряет смысл), `README.md`,
|
||||
`generator/README.md`.
|
||||
- Спеку `docs/specs/2026-06-14-generator-model-time-and-startup-history.md`
|
||||
дополнить: выбранная пара tick/speed и почему именно она.
|
||||
|
||||
## Acceptance criteria
|
||||
|
||||
- [ ] После backfill/импорта `daily-wave` и `PROFILE=daily-wave make
|
||||
generator-continue` модельное время идёт ~в 60 раз быстрее настенного; на
|
||||
дашборде суточная волна проживается за ~24 настенные минуты.
|
||||
- [ ] Пиковые тики не упираются в `GEN_MAX_EVENTS_PER_TICK` — волна не
|
||||
срезана.
|
||||
- [ ] Стык «история → live» бесшовный: без дублей и дыр, антисмешивание
|
||||
работает как раньше.
|
||||
- [ ] Многочасовой live на тике 1 с не заливает журналы и compact-топики:
|
||||
пер-тиковые INFO приглушены или их объём обоснован в PR; объём
|
||||
state-записей (86 400/сутки) измерен и обоснован — либо частота сохранения
|
||||
state осознанно изменена вместе с правкой спеки (контракт возобновления).
|
||||
- [ ] Профиль `ci`, его контрольные суммы и поведение по умолчанию не
|
||||
изменились; существующие тесты генератора проходят.
|
||||
- [ ] Runbook, `docs/OPERATIONS.md`, README'и и спека обновлены.
|
||||
|
||||
## Notes
|
||||
|
||||
- Нагрузка по событиям: ~42–72 события в секунду (ночь–пик) — незаметно для
|
||||
Kafka и ClickHouse; backfill не дорожает (число тиков на 2 суток то же, что
|
||||
сейчас: модельный шаг тика не изменился).
|
||||
- Если генерация тика займёт больше 1 настенной секунды, тики пойдут реже и
|
||||
фактическая скорость окажется чуть ниже 60 (`service.py:623-627`) — это
|
||||
допустимо, точная скорость не обещается.
|
||||
- Несовместимость со старыми мирами ловится по-разному: импорт артефакта и
|
||||
continue от стартовой истории сверяют полный набор настроек (включая
|
||||
`tick_seconds` в манифесте), а обычный live-continue — только
|
||||
seed/T0/timezone/speed (`service.py:213-230`); для этой правки хватает и
|
||||
его — speed изменился.
|
||||
- Альтернатива «третий профиль fast-live» отвергнута: у медленного
|
||||
`daily-wave` не остаётся сценария использования, а лишний профиль усложняет
|
||||
выпадашку пульта (задача 12).
|
||||
- Рекомендуемый режим ревью по coordinator-loop: обычный (значения профиля и
|
||||
логирование). Исключение: если по ходу решат менять частоту сохранения
|
||||
state — это уже контракт возобновления, эскалировать в **гейт**.
|
||||
|
||||
## Blocked by
|
||||
|
||||
Нет: профили из задачи 11 сделаны. Мягкие связи: задача 12 (профиль появится
|
||||
в форме пульта автоматически) и задача 08 (артефакт курса рождается из этого
|
||||
профиля — эту задачу лучше сделать до него).
|
||||
Reference in New Issue
Block a user