docs(generator): проведён триаж бэклога фичи, задачи 01-06 закрыты

- Зачем:
  - follow-up задачи после ревью 2026-06-14 лежали без триажа; решения по
    артефакту, громкому отказу и интерфейсу приняты 2026-07-04 и должны
    попасть в задачи до передачи исполнителю.
- Что:
  - задачи 07 (миграция курса) и 08 (артефакт) поменяны местами — номера
    отражают порядок; ссылки обновлены.
  - 07 (артефакт + runbook) дооформлен: импорт строго через Kafka (напрямую
    в ClickHouse не пишет), громкий отказ при несовместимом state с правкой
    спеки, граница runbook «использование, не устройство»; ready-for-agent.
  - 08 дооформлен: устройство генератора вне пути менти, реальный объём
    (make data во всех уроках 00-05), демо вне скоупа; ready-for-agent.
  - новые задачи: 11 глаголы/длительность/профили (после 07, до 12),
    12 Airflow-DAG как пульт (приоритет поднят), 13 доливка (после 09).
  - задачи 01-06 переведены в done (стояли ошибочные ready-for-human);
    PRD фичи дополнен списком задач 7-13 с порядком и зависимостями.
- Проверка:
  - head -1 .scratch/generator-model-time-startup-history/issues/*.md;
    grep по старым именам файлов ничего не находит вне handoff.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-04 16:39:40 +03:00
co-authored by Claude Fable 5
parent 7d54e5fc1f
commit 85f076e205
14 changed files with 372 additions and 143 deletions
@@ -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 по сквозному инварианту времени:
@@ -1,4 +1,4 @@
Status: ready-for-human
Status: done
# Контракт модельного времени и стартовой истории
@@ -1,4 +1,4 @@
Status: ready-for-human
Status: done
# Модельное время до ClickHouse
@@ -1,4 +1,4 @@
Status: ready-for-human
Status: done
# ×K и дневной коэффициент по модельному времени
@@ -1,4 +1,4 @@
Status: ready-for-human
Status: done
# Восстановление state v2 от модельной точки
@@ -1,4 +1,4 @@
Status: ready-for-human
Status: done
# Стартовая история до ClickHouse
@@ -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`
— миграция учебных материалов с архивного сида на генерацию.
## Риски и что не проверено
@@ -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`.
@@ -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`
@@ -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` вплетён во **все** уроки 0005,
а не только в урок 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/0105``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).
@@ -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`
@@ -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 и команды
экспорта/импорта появляются там; эта задача переводит их на единый стиль.
@@ -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-матрицу.
@@ -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` — доливка тиражирует стыки
восстановления; сначала починить фактуру на стыке, иначе дефект размножится.