# Модельное время и стартовая история генератора Status: Implemented ## Зачем Нужно довести решение ADR-0005 и ADR-0006 до рабочего процесса: генератор живёт по модельному времени, умеет быстро создать прошлое, сохранить слепок состояния и продолжить поток так, чтобы результат был проверяем в ClickHouse. Источник решений: - `docs/specs/2026-06-14-generator-model-time-and-startup-history.md` - `docs/adr/0005-generator-model-clock.md` - `docs/adr/0006-generation-as-sole-analytics-source.md` - `docs/research/2026-06-11-subagent-coordinator-experiment.md` ## Общие правила приёмки - Каждый кодовый срез должен заканчиваться проверкой через ClickHouse, а не только локальными тестами генератора. - Кодовые AFK-задачи идут через `/tdd`: один поведенческий тест, минимальная реализация, зелёная проверка. HITL- и документные задачи идут через обсуждение и фиксацию решения, без искусственного теста. - Координатор не работает в `/goal` на всю цепочку. Один worker получает один issue, не коммитит и не реализует следующие задачи. - После реализации worker делает саморевью без правок. Координатор классифицирует находки и возвращает только обязательные исправления. - В задачах 03 и 05 worker заранее даёт промежуточный статус, если статистический прогон или стендовая проверка идут долго. - Если исправление после review gate меняет дизайн, формат state, манифест или схему проверки, результат исправления проходит повторный review gate. - Коммиты делает координатор после своих проверок и `git status --short`. - Ручная проверка дашбордов глазами выполняется только в конце всей цепочки. ## Сквозные инварианты - Рабочий контракт реализации живёт в `docs/specs/2026-06-14-generator-model-time-and-startup-history.md`, раздел «Рабочий контракт реализации». Задачи 02–06 берут имена настроек, формат манифеста, границу `T_end` и правила проверки оттуда. - `event_timestamp` — модельное время, а не настенные часы компьютера. - Операционные метки сервиса, история пачек, метрики здоровья и длительность тика остаются настенным временем, если отдельная задача не докажет обратное. - Живой ход часов идёт фиксированным модельным шагом `GEN_TICK_SECONDS * GEN_MODEL_TIME_SPEED`; промотка прошлого тоже повторяется точно при тех же настройках и чистом состоянии. - При ×K модельное время и событийный бюджет идут по модельной длительности тика, а не по реальной длительности сна процесса. - Часовой пояс модельных часов явно задан в контракте; дневной коэффициент считается по нему, а не по неявному локальному времени. - После сбоя точка возобновления считается из сохранённой связки модельного и настенного времени, а не простым `datetime.now()`. - Стартовая история — это события плюс слепок состояния плюс манифест, чтобы не смешать данные от разных `GEN_SEED`, `T0` и `T_end`. - Стартовая история покрывает `[T0, T_end)`, живое продолжение начинается из слепка на `T_end`; на стыке не должно быть дублей и дыр. - Повторная проверка на чистом стенде должна быть воспроизводимой: либо команда явно чистит ClickHouse, Kafka-топики данных и состояние генератора, либо процесс идемпотентен. ## Задачи Номер в имени файла — просто идентификатор задачи, порядок выполнения он не задаёт. Порядок и зависимости живут здесь и в секциях «Blocked by» самих задач; при изменении порядка файлы не переименовываются. Сделано (ядро фичи, закрыто на триаже 2026-07-04): - `issues/01-time-and-startup-history-contract.md` — контракт модельного времени и стартовой истории. - `issues/02-model-time-to-clickhouse.md` — минимальный поток по модельному времени до ClickHouse. - `issues/03-model-speed-and-day-factor.md` — ×K и дневной коэффициент по модельному времени. - `issues/04-state-v2-model-resume.md` — восстановление state v2 от модельной точки возобновления. - `issues/05-startup-history-backfill-to-clickhouse.md` — промотка прошлого, стартовая история и живое продолжение до ClickHouse. - `issues/06-generated-history-as-analytics-source.md` — штатный путь стенда переводится на стартовую историю как источник аналитики. - `issues/07-startup-history-portable-artifact-and-usage-docs.md` — портативный артефакт стартовой истории и runbook. - `issues/11-generator-launch-verbs-and-profiles.md` — глаголы, длительность и профили запуска генератора. - Airflow-пульт генератора, быстрый `daily-wave`, фикс фактуры визита на восстановлении, читаемый гео-график и миграция курса на генерацию — закрыты в очереди 2026-07-04. - Доработки по кросс-линейному ревью 2026-07-05 закрыты в очереди 2026-07-05: граница миров, свежий стенд и Airflow-пульт, доверенные проверки startup-history/Superset, курс на чистом стенде. Подробности и коммиты см. в issue-файлах и `coordinator-journal.md`. Оставшаяся задача вне текущей очереди: - `issues/13-...` — доливка истории от слепка; без приоритета, `needs-triage`. После кросс-линейного ревью 2026-07-05 блокируется задачами 15 и 17: доливка тиражирует стыки мира и должна опираться на доверенную проверку фактической границы. Дополнительная задача закрыта: - `issues/19-test-and-lint-targets.md` — единые `make test` и `make lint` для коммит-гейта; `done`. Возникло из coordinator-loop 2026-07-05: координатору пришлось вручную собирать тестовый набор из частных команд. Доработки по кросс-линейному ревью 2026-07-05 (закрыто): - `issues/15-world-boundary-after-cross-review.md` — граница миров после обновления, сброса и консольных запусков. - `issues/16-fresh-stand-generator-control.md` — свежий стенд и Airflow-пульт без неявных ручных шагов. - `issues/17-trusted-checks-startup-history-superset.md` — доверенные проверки startup-history и Superset export. - `issues/18-course-clean-stand-startup-history.md` — курс на чистом стенде по startup-history. ```mermaid flowchart LR i07["07 артефакт + runbook"] --> i11["11 глаголы запуска"] i11 --> i12["12 DAG-пульт"] i07 --> i08["08 миграция курса"] i12 -. "приёмка через пульт" .-> i08 i14["14 быстрый профиль"] --> i08 i09["09 фикс стыка"] --> i13["13 доливка"] i10["10 гео-карта"] i15["15 граница миров"] --> i18["18 курс на чистом стенде"] i16["16 свежий стенд"] --> i18 i17["17 доверенные проверки"] --> i18 i15 --> i13 i17 --> i13 i19["19 make test/lint"] ``` ## Контрольные точки - После задачи 3 нужен внешний review gate по сквозному инварианту времени: проверить, где ещё остались настенные часы, и не расходятся ли живой путь, расчёт интенсивности и сохранение состояния. - После задачи 5 нужен внешний review gate по распределениям и двум путям генерации: проверить форму данных, стык истории и живого продолжения, однородность визита до и после восстановления. Для review gate после задачи 3 reviewer другой родословной сильно желателен. Для review gate после задачи 5 он обязателен: research показал, что форма распределений и свойства на стыке двух путей хуже ловятся одной линией проверки. Если такого reviewer-а нет, координатор останавливает цепочку и явно отдаёт решение человеку. ## Финальная ручная приёмка После задачи 6 человек смотрит Superset/Grafana и проверяет, что стенд живёт на генерации: видны история, возвраты, воронка и суточное «дыхание». Если текущих панелей не хватает для такого просмотра, создаётся отдельная задача на панель или runbook, а не расширяется эта цепочка задним числом. Миграция уроков по ADR-0006 сознательно отслеживается отдельно. Задача 6 должна создать follow-up, если учебные материалы требуют нетривиальной переделки.