diff --git a/.scratch/generator-model-time-startup-history/PRD.md b/.scratch/generator-model-time-startup-history/PRD.md index ef1a66f..593de01 100644 --- a/.scratch/generator-model-time-startup-history/PRD.md +++ b/.scratch/generator-model-time-startup-history/PRD.md @@ -74,6 +74,26 @@ Status: Draft 6. `issues/06-generated-history-as-analytics-source.md` — штатный путь стенда переводится на стартовую историю как источник аналитики. +Дополнено по итогам независимого ревью (2026-06-14) и триажа (2026-07-04) — +номера отражают рекомендуемый порядок внутри веток зависимостей: + +7. `issues/07-startup-history-portable-artifact-and-usage-docs.md` — + портативный артефакт (импорт через Kafka, не напрямую в ClickHouse), + громкий отказ при несовместимом state, runbook. +8. `issues/08-migrate-course-from-archive-seed.md` — миграция учебных + материалов на генерацию; после задачи 7 (уроки ссылаются на runbook). +9. `issues/09-seam-browser-fixture-not-preserved.md` — дефект: браузерная + фактура не переживает восстановление визита на стыке. Независим, можно + параллельно. +10. `issues/10-dashboard-geo-map-readability.md` — читаемость гео-карты + дашборда. Независим, можно параллельно. +11. `issues/11-generator-launch-verbs-and-profiles.md` — глаголы, длительность + и профили запуска; после задачи 7, до задачи 12. +12. `issues/12-generator-control-dag.md` — Airflow-DAG как пульт генератора; + после задачи 11 (оборачивает глаголы). +13. `issues/13-backfill-top-up-from-snapshot.md` — доливка истории от слепка; + без приоритета, после задачи 9 (доливка тиражирует стыки восстановления). + ## Контрольные точки - После задачи 3 нужен внешний review gate по сквозному инварианту времени: diff --git a/.scratch/generator-model-time-startup-history/issues/01-time-and-startup-history-contract.md b/.scratch/generator-model-time-startup-history/issues/01-time-and-startup-history-contract.md index e09c5cf..c4ee829 100644 --- a/.scratch/generator-model-time-startup-history/issues/01-time-and-startup-history-contract.md +++ b/.scratch/generator-model-time-startup-history/issues/01-time-and-startup-history-contract.md @@ -1,4 +1,4 @@ -Status: ready-for-human +Status: done # Контракт модельного времени и стартовой истории diff --git a/.scratch/generator-model-time-startup-history/issues/02-model-time-to-clickhouse.md b/.scratch/generator-model-time-startup-history/issues/02-model-time-to-clickhouse.md index 4684dd6..8534269 100644 --- a/.scratch/generator-model-time-startup-history/issues/02-model-time-to-clickhouse.md +++ b/.scratch/generator-model-time-startup-history/issues/02-model-time-to-clickhouse.md @@ -1,4 +1,4 @@ -Status: ready-for-human +Status: done # Модельное время до ClickHouse diff --git a/.scratch/generator-model-time-startup-history/issues/03-model-speed-and-day-factor.md b/.scratch/generator-model-time-startup-history/issues/03-model-speed-and-day-factor.md index f9a576e..e854fcc 100644 --- a/.scratch/generator-model-time-startup-history/issues/03-model-speed-and-day-factor.md +++ b/.scratch/generator-model-time-startup-history/issues/03-model-speed-and-day-factor.md @@ -1,4 +1,4 @@ -Status: ready-for-human +Status: done # ×K и дневной коэффициент по модельному времени diff --git a/.scratch/generator-model-time-startup-history/issues/04-state-v2-model-resume.md b/.scratch/generator-model-time-startup-history/issues/04-state-v2-model-resume.md index b034487..75671ce 100644 --- a/.scratch/generator-model-time-startup-history/issues/04-state-v2-model-resume.md +++ b/.scratch/generator-model-time-startup-history/issues/04-state-v2-model-resume.md @@ -1,4 +1,4 @@ -Status: ready-for-human +Status: done # Восстановление state v2 от модельной точки diff --git a/.scratch/generator-model-time-startup-history/issues/05-startup-history-backfill-to-clickhouse.md b/.scratch/generator-model-time-startup-history/issues/05-startup-history-backfill-to-clickhouse.md index b5cf5fa..27c1104 100644 --- a/.scratch/generator-model-time-startup-history/issues/05-startup-history-backfill-to-clickhouse.md +++ b/.scratch/generator-model-time-startup-history/issues/05-startup-history-backfill-to-clickhouse.md @@ -1,4 +1,4 @@ -Status: ready-for-human +Status: done # Стартовая история до ClickHouse diff --git a/.scratch/generator-model-time-startup-history/issues/06-generated-history-as-analytics-source.md b/.scratch/generator-model-time-startup-history/issues/06-generated-history-as-analytics-source.md index e7c5ecd..5c4d983 100644 --- a/.scratch/generator-model-time-startup-history/issues/06-generated-history-as-analytics-source.md +++ b/.scratch/generator-model-time-startup-history/issues/06-generated-history-as-analytics-source.md @@ -1,4 +1,4 @@ -Status: ready-for-human +Status: done # Стартовая история как источник аналитики @@ -197,7 +197,7 @@ Superset technical check: Follow-up: -- `.scratch/generator-model-time-startup-history/issues/07-migrate-course-from-archive-seed.md` +- `.scratch/generator-model-time-startup-history/issues/08-migrate-course-from-archive-seed.md` — миграция учебных материалов с архивного сида на генерацию. ## Риски и что не проверено diff --git a/.scratch/generator-model-time-startup-history/issues/07-migrate-course-from-archive-seed.md b/.scratch/generator-model-time-startup-history/issues/07-migrate-course-from-archive-seed.md deleted file mode 100644 index 6846212..0000000 --- a/.scratch/generator-model-time-startup-history/issues/07-migrate-course-from-archive-seed.md +++ /dev/null @@ -1,40 +0,0 @@ -Status: needs-triage - -# Миграция учебных материалов с архивного сида на генерацию - -## Parent - -`.scratch/generator-model-time-startup-history/PRD.md` - -## Why - -После перевода штатного аналитического контура на стартовую историю генератора -часть учебных материалов всё ещё описывает `data/*.jsonl` как основной источник -данных стенда. Это нельзя править внутри issue 06: потребуется пройти уроки и -сохранить понятный учебный путь. - -## What to build - -Обновить курс и демо-материалы так, чтобы основной путь был: - -```text -startup-history/backfill -> Kafka -> STG -> ODS -> DDS -> DM -> Superset -``` - -Архивный `data/*.jsonl` оставить только как временную фактуру генератора. - -## Acceptance criteria - -- [ ] `docs/course/` больше не ведёт ученика через `make data` или `kafka_load` - как основной путь получения аналитических данных. -- [ ] Уроки явно объясняют, что `data/*.jsonl` пока остаётся кладовкой значений - для генератора, а не источником аналитического контура. -- [ ] Демо-шпаргалки и тест-план согласованы с новым штатным путём запуска. -- [ ] Если для уроков нужны новые скриншоты или ручная оценка dashboard, это - вынесено в HITL-приёмку. - -## Notes - -Найденные места для начала: `docs/course/PRD.md`, -`docs/course/lessons/06_superset_bi.md`, `docs/DEMO_CHEATSHEET_5MIN.md`, -`docs/DEMO_SCRIPT_10_15MIN.md`, `docs/TEST_PLAN.md`. diff --git a/.scratch/generator-model-time-startup-history/issues/07-startup-history-portable-artifact-and-usage-docs.md b/.scratch/generator-model-time-startup-history/issues/07-startup-history-portable-artifact-and-usage-docs.md new file mode 100644 index 0000000..ec07139 --- /dev/null +++ b/.scratch/generator-model-time-startup-history/issues/07-startup-history-portable-artifact-and-usage-docs.md @@ -0,0 +1,117 @@ +Status: ready-for-agent + +# Портативный артефакт стартовой истории и runbook по стенду + +## Parent + +`.scratch/generator-model-time-startup-history/PRD.md` + +## Why + +Сейчас стартовая история персистится только в Kafka compact-топиках +(`generator_state`, `generator_startup_history_manifest`) и в ClickHouse. Чистая +пересборка стенда (`make generated-history-analytics` делает `down -v`) каждый раз +**заново генерирует** backfill. Портативного файла-артефакта, который можно +сгенерировать один раз и быстро восстановить на чистом стенде без запуска +генератора, нет. + +Из-за этого неудобно: мгновенно сбросить стенд, держать длинную стартовую +историю (2+ суток, чтобы суточная волна повторялась на графике) без повторной +генерации. Сейчас «дёшево» только live-возобновление из слепка и перезапуск без +`down -v`; полный сброс требует регенерации. + +Этот пункт работает на главную цель: если стенд поднимается одной командой и есть +короткий runbook, генератор остаётся скрытой инфраструктурой и менти не нужно +знать его устройство. Развилка курса «урок про генератор vs скрытая +инфраструктура» уже закрыта в пользу скрытой инфраструктуры +(`docs/course/PRD.md` §7, 2026-07-04) — эта задача обеспечивает решению опору. + +## What to build + +- **Экспорт** стартовой истории в портативный файл-артефакт: события (в формате + сообщений топиков) плюс слепок состояния плюс манифест — один связный набор, + чтобы не смешать `GEN_SEED`, `T0`, `T_end` и настройки генерации. +- **Импорт** (решение 2026-07-04): воспроизвести события артефакта в Kafka-топики + и вернуть слепок с манифестом в служебные compact-топики. **Напрямую в + ClickHouse импорт не пишет ничего**: стенд наполняется штатным путём + (Kafka engine + MV -> STG, батч-ETL -> витрины). Так не появляется обходного + пути данных, каждый импорт заодно прогоняет весь пайплайн, а менти видит, + как пустой стенд наполняется изучаемыми механизмами. Live продолжает с `T_end`. +- **Громкий отказ при несовместимом state** (решение 2026-07-04, пересмотр + правила спеки). Различать два случая. Нет состояния или оно повреждено -> + чистый старт с предупреждением (как сейчас, оставить). Состояние есть и + читается, но настройки несовместимы при `GEN_STATE_RESET=false` (оператор + намерен продолжить) -> жёсткое падение с указанием разошедшихся полей + (`seed`/`T0`/`timezone`/`speed`) и подсказкой выставить `GEN_STATE_RESET=true`, + если новый мир нужен осознанно. Текущее тихое поведение — `service.py:217-220`. + Правка идёт вместе с обновлением + `docs/specs/2026-06-14-generator-model-time-and-startup-history.md`. +- **Runbook «как пользоваться стендом на генерации»**: как сгенерировать, + сохранить, восстановить, выбрать длительность стартовой истории; что дёшево + (live-возобновление, перезапуск без чистки), а что требует регенерации. +- Новые команды экспорта/импорта делать в стиле глаголов (явное действие одной + командой), а не новыми комбинациями env-переменных. + +## Acceptance criteria + +- [ ] Есть команда экспорта: стартовая история -> портативный файл-артефакт + (события + слепок + манифест) одним связным набором. +- [ ] Есть команда импорта: на чистом стенде артефакт воспроизводится в Kafka + (события + служебные compact-топики) **без запуска генерации**; напрямую в + ClickHouse импорт не пишет. После штатного ETL контрольные числа в ClickHouse + совпадают с манифестом и исходной генерацией. +- [ ] После импорта live продолжает с `T_end`: без дублей на границе и без + смешения миров. +- [ ] Сохранено антисмешивание: импорт отвергает артефакт, несовместимый по + манифесту (`GEN_SEED`, `T0`, `T_end`, настройки генерации, версия state). +- [ ] Громкий отказ: живое читаемое состояние + несовместимые настройки при + намерении продолжить -> падение с перечислением разошедшихся полей и + подсказкой; нет состояния или повреждено -> чистый старт с предупреждением + (как сейчас). Спека обновлена в этом же изменении. +- [ ] Runbook описывает генерацию один раз, дешёвое восстановление, выбор + длительности и то, что переживает перезапуск, а что требует регенерации. +- [ ] Runbook — про **использование**, устройство генератора в нём не + объясняется; за конструкцией он отсылает к `generator/README.md` и + `docs/specs/`. +- [ ] Документы запуска (`README.md`, `docs/OPERATIONS.md`, + `generator/README.md`) ссылаются на runbook. + +## Notes + +- Опирается на спеку `docs/specs/2026-06-14-generator-model-time-and-startup-history.md`, + разделы «Манифест стартовой истории» и «Повторяемая проверка в ClickHouse». +- Спека уже упоминала будущий runbook «проверка генератора на стенде» — этот + issue его и закрывает, расширяя до полного цикла «генерация — сохранение — + восстановление». +- Откуда экспорту брать события — решить при реализации и зафиксировать в + спеке/runbook. Кандидаты: писать файл артефакта прямо при backfill (вторая + копия рядом с публикацией в Kafka), вычитать топики событий (учесть retention) + или выгрузить из STG (следить за точностью формата сообщений). Критерий + выбора: артефакт должен байт в байт воспроизводить сообщения топиков. +- Рекомендуемый режим ревью по coordinator-loop: **гейт** (state, сериализация, + формат данных, правка спеки — всё из порогов риска). +- Связано с `08-migrate-course-from-archive-seed.md`: миграция уроков идёт после + этой задачи и будет ссылаться на runbook отсюда (номера отражают порядок, + переставлены 2026-07-04). + +## Идеи интерфейса — решения (2026-07-04) + +Бывший раздел «на будущее, не решено» разобран с пользователем. Судьба идей: + +- **Громкий отказ при несовместимом state** — включён в эту задачу + (см. What to build и критерии). +- **Глаголы / длительность / профили** — отдельная задача + `11-generator-launch-verbs-and-profiles.md`, делать **после этой и до + DAG-пульта**: чистый интерфейс «под капотом» делает DAG тонкой обёрткой с + простыми и понятными параметрами. +- **Airflow-DAG как пульт генератора** — приоритет поднят (пользователь, + 2026-07-04): это будущий основной человеческий интерфейс стенда — «слишком + сложно» лечится формой в веб-UI, а не только runbook'ом. Отдельная задача + `12-generator-control-dag.md`, делать после задачи 11. +- **Доливка прошлого кусочком** — отдельная задача + `13-backfill-top-up-from-snapshot.md`, без приоритета. + +## Blocked by + +- `.scratch/generator-model-time-startup-history/issues/05-startup-history-backfill-to-clickhouse.md` +- `.scratch/generator-model-time-startup-history/issues/06-generated-history-as-analytics-source.md` diff --git a/.scratch/generator-model-time-startup-history/issues/08-migrate-course-from-archive-seed.md b/.scratch/generator-model-time-startup-history/issues/08-migrate-course-from-archive-seed.md new file mode 100644 index 0000000..03501cc --- /dev/null +++ b/.scratch/generator-model-time-startup-history/issues/08-migrate-course-from-archive-seed.md @@ -0,0 +1,78 @@ +Status: ready-for-agent + +# Миграция учебных материалов с архивного сида на генерацию + +## Parent + +`.scratch/generator-model-time-startup-history/PRD.md` + +## Why + +После перевода штатного аналитического контура на стартовую историю генератора +часть учебных материалов всё ещё описывает `data/*.jsonl` как основной источник +данных стенда. Это нельзя править внутри issue 06: потребуется пройти уроки и +сохранить понятный учебный путь. + +Развилка «отдельный урок про генератор vs скрытая инфраструктура» закрыта +(2026-07-04, `docs/course/PRD.md` §7): **отдельного урока не будет, генератор — +скрытая инфраструктура**. Устройство генератора — это разработка бэкенда и +математика, не инженерия данных; в цели курса не попадает. Уроки адаптируем, +не вводя марковские цепи и сложный Python в путь менти. + +## What to build + +Обновить курс и связанные материалы (тест-план) так, чтобы основной путь был: + +```text +startup-history/backfill -> Kafka -> STG -> ODS -> DDS -> DM -> Superset +``` + +Архивный `data/*.jsonl` оставить только как временную фактуру генератора. +Генератор в уроках подаётся как готовый источник данных стенда («откуда берутся +данные»), без погружения в его устройство. + +## Acceptance criteria + +- [ ] `docs/course/` больше не ведёт ученика через `make data` или `kafka_load` + как основной путь получения аналитических данных. +- [ ] Уроки явно объясняют, что `data/*.jsonl` пока остаётся кладовкой значений + для генератора, а не источником аналитического контура. +- [ ] Уроки не вводят устройство генератора (марковская модель, внутренний + Python) в путь менти: генератор упоминается только как готовый источник данных. +- [ ] Тест-план согласован с новым штатным путём запуска. +- [ ] Если для уроков нужны новые скриншоты или ручная оценка dashboard, это + вынесено в HITL-приёмку. + +## Notes + +Реальный объём больше, чем кажется: `make data` вплетён во **все** уроки 00–05, +а не только в урок 06 (проверка 2026-07-04, `grep -rn "make data" docs/course/`): + +- `docs/course/README.md` — быстрый старт через `LIMIT=50 make data`; +- `lessons/00_kafka_intro.md` — `make data` играет роль трекера, на нём построен + весь разбор партиций и offset'ов; +- `lessons/01–05` — `LIMIT=50 make data` в запуске, «полном сбросе» и таблицах + проверок; +- `docs/TEST_PLAN.md` — сценарии на старом пути. + +Тонкое место — урок 00: там ручная заливка используется как учебный приём +(наглядно видно сообщения в топике). Решить при миграции, чем её заменить, не +потеряв наглядность; критерий приёмки запрещает `make data` как **основной путь +аналитики**, а не как локальный демонстрационный приём внутри урока. + +Схема потока в `docs/course/PRD.md` §1 уже обновлена (поправка 2026-07-04) — PRD +дополнительно править не нужно. + +Демо-материалов в скоупе нет: демо-употребление стенда устарело (демо выросло в +отдельный проект), шпаргалки удалены из репозитория 2026-07-04 (см. поправку в +шапке `docs/course/PRD.md`). + +## Blocked by + +- Жёстких блокеров нет: штатный путь (`make generated-history-analytics`) уже + существует, уроки можно вести через него. +- Мягкая зависимость от + `07-startup-history-portable-artifact-and-usage-docs.md`: runbook из issue 07 + изменит команды запуска и восстановления стенда, а уроки будут на него + ссылаться. Делать эту задачу после него, иначе уроки придётся править дважды + (номера уже отражают порядок: 07 -> 08, переставлены 2026-07-04). diff --git a/.scratch/generator-model-time-startup-history/issues/08-startup-history-portable-artifact-and-usage-docs.md b/.scratch/generator-model-time-startup-history/issues/08-startup-history-portable-artifact-and-usage-docs.md deleted file mode 100644 index 470e32c..0000000 --- a/.scratch/generator-model-time-startup-history/issues/08-startup-history-portable-artifact-and-usage-docs.md +++ /dev/null @@ -1,96 +0,0 @@ -Status: needs-triage - -# Портативный артефакт стартовой истории и runbook по стенду - -## Parent - -`.scratch/generator-model-time-startup-history/PRD.md` - -## Why - -Сейчас стартовая история персистится только в Kafka compact-топиках -(`generator_state`, `generator_startup_history_manifest`) и в ClickHouse. Чистая -пересборка стенда (`make generated-history-analytics` делает `down -v`) каждый раз -**заново генерирует** backfill. Портативного файла-артефакта, который можно -сгенерировать один раз и быстро залить на чистый ClickHouse без запуска -генератора, нет. - -Из-за этого неудобно: раздать готовое демо, мгновенно сбросить стенд, держать -длинную стартовую историю (2+ суток, чтобы суточная волна повторялась на графике) -без повторной генерации. Сейчас «дёшево» только live-возобновление из слепка и -перезапуск без `down -v`; полный сброс требует регенерации. - -Этот пункт работает на главную цель: если стенд поднимается одной командой и есть -короткий runbook, генератор становится скрытой инфраструктурой и менти не нужно -знать его устройство. Связано с открытым вопросом курса про отдельный урок по -генератору (см. `docs/course/PRD.md`, §7). - -## What to build - -- Экспорт стартовой истории в портативный файл-артефакт: события плюс слепок - состояния плюс манифест — один связный набор, чтобы не смешать `GEN_SEED`, - `T0`, `T_end` и настройки генерации. -- Импорт: залить артефакт на чистый ClickHouse и Kafka без прогона генерации; - live-режим продолжает с `T_end`. -- Runbook «как пользоваться стендом на генерации»: как сгенерировать, сохранить, - восстановить, выбрать длительность стартовой истории; что дёшево - (live-возобновление, перезапуск без чистки), а что требует регенерации. - -## Acceptance criteria - -- [ ] Есть команда экспорта: backfill -> портативный файл-артефакт - (события + слепок + манифест). -- [ ] Есть команда импорта: артефакт -> чистый ClickHouse без запуска генератора; - контрольные числа манифеста и ClickHouse совпадают с исходной генерацией. -- [ ] Сохранено антисмешивание: импорт отвергает артефакт, несовместимый по - манифесту (`GEN_SEED`, `T0`, `T_end`, настройки генерации, версия state). -- [ ] Runbook описывает генерацию один раз, дешёвое восстановление, выбор - длительности и то, что переживает перезапуск, а что требует регенерации. -- [ ] Документы запуска (`README.md`, `docs/OPERATIONS.md`, - `generator/README.md`) ссылаются на runbook. - -## Notes - -- Опирается на спеку `docs/specs/2026-06-14-generator-model-time-and-startup-history.md`, - разделы «Манифест стартовой истории» и «Повторяемая проверка в ClickHouse». -- Спека уже упоминала будущий runbook «проверка генератора на стенде» — этот - issue его и закрывает, расширяя до полного цикла «генерация — сохранение — - восстановление». -- Связано с `07-migrate-course-from-archive-seed.md`: удобный стенд упрощает выбор - «адаптировать уроки», а не писать тяжёлый урок про генератор. - -## Идеи интерфейса (на будущее, не решено) - -Запуск сейчас недружелюбный: поведение собирается из ~10 связанных env-переменных, -`T_end` задаётся абсолютной меткой вместо длительности, а несовпадение настроек при -live-продолжении даёт тихий «свежий старт» (warning в лог, общее сообщение, без -указания разошедшегося поля — `service.py:217-220`). Идеи, как сделать удобнее: - -- **Глаголы вместо матрицы флагов:** явные `backfill` / `continue` / `reset`, а не - комбинация `GEN_RUN_MODE` + `GEN_STATE_RESET`. -- **Длительность как длительность и профили:** `HISTORY_DURATION=2d` вместо ручного - расчёта `T_end`; именованные профили вместо повторения блока из ~10 переменных. -- **Громкий и адресный отказ при несовпадении (пересмотр решения спеки).** Сейчас - при `GEN_STATE_RESET=false` несовместимый по настройкам state молча ведёт к чистому - старту (`service.py:217-220`) — это сознательный выбор спеки ради устойчивости. - Предложение: различать два случая. Нет состояния или оно повреждено -> чистый старт - с предупреждением (как сейчас, оставить). Состояние есть и читается, но настройки - несовместимы при `GEN_STATE_RESET=false` (оператор намерен продолжить) -> **жёсткое - падение** с указанием разошедшихся полей (`seed`/`T0`/`timezone`/`speed`) и подсказкой - выставить `GEN_STATE_RESET=true`, если новый мир нужен осознанно. Меняет правило - спеки «несовместимо -> чистый старт», поэтому правка идёт вместе с обновлением - `docs/specs/2026-06-14-generator-model-time-and-startup-history.md`. -- **Доливка прошлого кусочком:** backfill, продолжающий слепок от `T_end` (сейчас - backfill всегда стартует с чистого состояния от `T0`, `service.py:178-185`). -- **Airflow DAG как пульт запуска (идея пользователя, 2026-06-14):** обернуть операции - генератора в параметризованный DAG (params: режим, `T0`, длительность, скорость, - seed) — UI, валидация настроек против манифеста до запуска, повторные попытки, - наглядность. Хорошо ложится на ограниченный backfill/доливку (конечная задача); - непрерывный live — это долгоживущий сервис compose, DAG его скорее стартует/останавливает, - чем держит внутри таска. Бонус: такой DAG сам по себе учебный (тема урока 4 — - оркестрация Airflow), что ближе к цели курса, чем устройство генератора. - -## Blocked by - -- `.scratch/generator-model-time-startup-history/issues/05-startup-history-backfill-to-clickhouse.md` -- `.scratch/generator-model-time-startup-history/issues/06-generated-history-as-analytics-source.md` diff --git a/.scratch/generator-model-time-startup-history/issues/11-generator-launch-verbs-and-profiles.md b/.scratch/generator-model-time-startup-history/issues/11-generator-launch-verbs-and-profiles.md new file mode 100644 index 0000000..2e5be8c --- /dev/null +++ b/.scratch/generator-model-time-startup-history/issues/11-generator-launch-verbs-and-profiles.md @@ -0,0 +1,58 @@ +Status: ready-for-agent + +# Глаголы, длительность и профили запуска генератора + +## Parent + +`.scratch/generator-model-time-startup-history/PRD.md` + +## Why + +Запуск генератора недружелюбный: поведение собирается из ~10 связанных +env-переменных, а смысл запуска — из их комбинации (`GEN_RUN_MODE` + +`GEN_STATE_RESET`). Конец истории задаётся абсолютной меткой `GEN_MODEL_T_END`, +которую оператор считает в уме от `T0`. + +Задача — дать чистый интерфейс «под капотом» перед DAG-пультом +(`12-generator-control-dag.md`): если команды простые и говорящие, DAG +становится тонкой обёрткой с понятными параметрами, а не переводчиком +формы в матрицу переменных (решение пользователя, 2026-07-04). + +## What to build + +- **Глаголы вместо матрицы флагов:** явные команды `backfill` / `continue` / + `reset` (make-цели или аргументы запуска), а не комбинация + `GEN_RUN_MODE` + `GEN_STATE_RESET`. Старые переменные могут остаться как + низкоуровневый механизм, но документированный путь — глаголы. +- **Длительность вместо абсолютной метки:** задавать конец истории как + длительность от `T0` (например, `2d`), расчёт `T_end` — внутри. +- **Именованные профили** вместо повторения блока переменных: минимум два — + быстрый проверочный (6 часов, текущий дефолт CI) и «с суточной волной» + (2+ суток). + +## Acceptance criteria + +- [ ] Стартовую историю на 2 суток можно получить одной командой с глаголом и + длительностью/профилем, без ручного расчёта `T_end` и без выставления + `GEN_RUN_MODE`/`GEN_STATE_RESET` вручную. +- [ ] Глаголы не меняют семантику режимов: за `backfill`/`continue`/`reset` + стоит тот же контракт модельного времени и state, что в спеке + `docs/specs/2026-06-14-generator-model-time-and-startup-history.md`. +- [ ] Профили покрывают быстрый проверочный прогон и прогон с суточной волной; + выбранный профиль виден в логах/манифесте. +- [ ] Runbook (из задачи 07) и документы запуска переведены на глаголы и + профили; старый способ через переменные упомянут как низкоуровневый. +- [ ] Существующие тесты генератора проходят; поведение по умолчанию + (CI-профиль) не изменилось. + +## Notes + +- Это интерфейсный слой над существующей механикой: генерацию, state и + антисмешивание не менять. +- Вместе с глаголами не забыть команды экспорта/импорта из задачи 07 — они + уже в стиле глаголов, привести всё к одному стилю. + +## Blocked by + +- `07-startup-history-portable-artifact-and-usage-docs.md` — runbook и команды + экспорта/импорта появляются там; эта задача переводит их на единый стиль. diff --git a/.scratch/generator-model-time-startup-history/issues/12-generator-control-dag.md b/.scratch/generator-model-time-startup-history/issues/12-generator-control-dag.md new file mode 100644 index 0000000..c788d8f --- /dev/null +++ b/.scratch/generator-model-time-startup-history/issues/12-generator-control-dag.md @@ -0,0 +1,55 @@ +Status: needs-triage + +# Airflow-DAG — пульт управления генератором + +## Parent + +`.scratch/generator-model-time-startup-history/PRD.md` + +## Why + +Даже с runbook и глаголами управление генератором остаётся консольным. Идея +(пользователь, 2026-06-14; приоритет поднят 2026-07-04): параметризованный DAG +в Airflow как основной человеческий интерфейс стенда — форма в веб-UI, где +выбираются режим, длительность/профиль, seed, скорость. Плюсы: валидация +настроек против манифеста ещё до запуска, повторные попытки, наглядный статус. + +Учебный бонус: такой DAG сам по себе учебный материал — живой пример +параметризованной оркестрации (тема урока 4), что ближе к цели курса, чем +устройство генератора. + +## What to build + +Черновой контур (уточнить после задач 07 и 11): + +- Параметризованный DAG с операциями: создать стартовую историю (backfill), + экспортировать артефакт, импортировать артефакт, сбросить мир. +- Валидация параметров против манифеста **до** запуска операции; при + несовместимости — понятная ошибка в UI, а не тихий новый мир. +- Конечные операции (backfill, экспорт, импорт, сброс) — таски DAG. + Непрерывный live — долгоживущий сервис compose: DAG его стартует и + останавливает, но не держит внутри таска. +- Под капотом DAG вызывает глаголы из задачи 11, а не собирает env-матрицу. + +## Acceptance criteria (черновые, дооформить после 07 и 11) + +- [ ] Стартовую историю выбранной длительности можно создать из веб-UI Airflow, + не выставляя переменных окружения вручную. +- [ ] Несовместимые параметры отклоняются до запуска с указанием разошедшихся + полей. +- [ ] Импорт/экспорт артефакта доступны как операции DAG. +- [ ] Runbook дополнен разделом «пульт в Airflow» как основным путём. + +## Notes + +- Проверить API параметров DAG (params/Datasets) через MCP Context7 по правилу + репозитория: спорные API Airflow сверять с актуальной документацией. +- DAG должен остаться понятным менти: это витрина оркестрации, не место для + хитрой логики. Сложность — в глаголах генератора (задача 11), не здесь. + +## Blocked by + +- `07-startup-history-portable-artifact-and-usage-docs.md` — операции + экспорта/импорта появляются там. +- `11-generator-launch-verbs-and-profiles.md` — DAG оборачивает глаголы и + профили; без них он превращается в переводчик формы в env-матрицу. diff --git a/.scratch/generator-model-time-startup-history/issues/13-backfill-top-up-from-snapshot.md b/.scratch/generator-model-time-startup-history/issues/13-backfill-top-up-from-snapshot.md new file mode 100644 index 0000000..1c9fee7 --- /dev/null +++ b/.scratch/generator-model-time-startup-history/issues/13-backfill-top-up-from-snapshot.md @@ -0,0 +1,37 @@ +Status: needs-triage + +# Доливка стартовой истории кусочком от слепка + +## Parent + +`.scratch/generator-model-time-startup-history/PRD.md` + +## Why + +Сейчас backfill всегда стартует с чистого состояния от `T0` +(`service.py:178-185`): удлинить существующую историю нельзя — есть 2 суток, +нужно 7, генерируй все 7 заново. Идея — «долить» продолжение от сохранённого +слепка `T_end`. + +Приоритет низкий (решение 2026-07-04): с портативным артефактом +(задача 07) длинную историю можно сгенерировать один раз и переиспользовать, +так что потребность в доливке может и не возникнуть. Вернуться, если возникнет. + +## What to build + +- Режим backfill, продолжающий от слепка: новая порция истории от `T_end` до + нового `T_end'`, манифест обновляется. + +## Acceptance criteria (черновые) + +- [ ] Доливка продолжает мир слепка: без дублей и смешения на границе. +- [ ] Однородность визитов, переживших границу доливки, — включая per-event + браузерные поля (`dds.event`), см. дефект + `09-seam-browser-fixture-not-preserved.md`: доливка создаёт новые стыки, + тот же механизм восстановления. +- [ ] Манифест после доливки отражает новый `T_end'`; антисмешивание работает. + +## Blocked by + +- `09-seam-browser-fixture-not-preserved.md` — доливка тиражирует стыки + восстановления; сначала починить фактуру на стыке, иначе дефект размножится.