- Зачем:
- подготовить цепочку 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>
11 KiB
Модельное время и стартовая история генератора
Status: Draft
Зачем
Нужно довести решение ADR-0005 и ADR-0006 до рабочего процесса: генератор живёт по модельному времени, умеет быстро создать прошлое, сохранить слепок состояния и продолжить поток так, чтобы результат был проверяем в ClickHouse.
Источник решений:
docs/specs/2026-06-14-generator-model-time-and-startup-history.mddocs/adr/0005-generator-model-clock.mddocs/adr/0006-generation-as-sole-analytics-source.mddocs/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— глаголы, длительность и профили запуска генератора.
Остаток — порядок выполнения (решение 2026-07-04: пульт вперёд, потому что узкое место — время человека на ручную приёмку; тяжелее всего проверять руками миграцию курса, поэтому она идёт последней, когда пульт уже есть):
- Основная ветка:
issues/12-...(Airflow-DAG как пульт; дооформлен 2026-07-04: без Docker-доступа из Airflow, конечные операции — Python-код генератора в тасках, live и полный сброс остаются консолью). - Параллельно, независимы:
issues/09-...(фикс браузерной фактуры на стыке),issues/10-...(читаемость гео-карты) иissues/14-...(быстрый учебный профиль: суточная волна вживую за ~24 минуты; заведён 2026-07-04, лучше до 08 — артефакт курса рождается из этого профиля). - После фикса 09:
issues/13-...(доливка истории от слепка; без приоритета,needs-triage— доливка тиражирует стыки восстановления, дооформлять после фикса). - Последней:
issues/08-...(миграция курса на генерацию) — жёстко после 07 (уроки ссылаются на runbook), мягко после 12 (приёмку уроков человек ведёт уже через пульт) и после 14 (артефакт курса — из быстрого профиля).
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 гео-карта"]
Контрольные точки
- После задачи 3 нужен внешний review gate по сквозному инварианту времени: проверить, где ещё остались настенные часы, и не расходятся ли живой путь, расчёт интенсивности и сохранение состояния.
- После задачи 5 нужен внешний review gate по распределениям и двум путям генерации: проверить форму данных, стык истории и живого продолжения, однородность визита до и после восстановления.
Для review gate после задачи 3 reviewer другой родословной сильно желателен. Для review gate после задачи 5 он обязателен: research показал, что форма распределений и свойства на стыке двух путей хуже ловятся одной линией проверки. Если такого reviewer-а нет, координатор останавливает цепочку и явно отдаёт решение человеку.
Финальная ручная приёмка
После задачи 6 человек смотрит Superset/Grafana и проверяет, что стенд живёт на генерации: видны история, возвраты, воронка и суточное «дыхание». Если текущих панелей не хватает для такого просмотра, создаётся отдельная задача на панель или runbook, а не расширяется эта цепочка задним числом.
Миграция уроков по ADR-0006 сознательно отслеживается отдельно. Задача 6 должна создать follow-up, если учебные материалы требуют нетривиальной переделки.