Files
clickstream-ch-kafka-supers…/.scratch/generator-model-time-startup-history/issues/13-backfill-top-up-from-snapshot.md
T
ddadminandClaude Fable 5 515d5ef73b docs(generator): решена развилка задачи 13, handoff сессии
- Зачем:
  - диагноз задачи 20 снял страх швов (генератор на стыке не ломает),
    и пользователь выбрал вариант реализации next-day;
  - сессия завершается - нужен handoff для продолжения.
- Что:
  - задача 13: выбран вариант 2 (генерация следующего дня от слепка),
    вариант нарезки артефакта отклонён с обоснованием; статус
    ready-for-agent, blocked by задача 20;
  - handoff сессии в .scratch/handoffs/ - итоги проверки пути менти,
    состояние трекера, план (фикс 20 -> задача 13 -> HITL).
- Проверка:
  - чтение задачи 13 и handoff; git status чистый после коммита.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-07 22:40:29 +03:00

95 lines
7.4 KiB
Markdown

Status: ready-for-agent
# Глагол next-day: собрать следующий модельный день
## Parent
`.scratch/generator-model-time-startup-history/PRD.md`
## Why
Рамка пересмотрена 2026-07-07 (обсуждение с пользователем). Было: «удлинить
готовую историю» (2 суток -> 7) — этот мотив закрыл портативный артефакт
(задача 07), приоритет был низкий. Стало: **режим кормления стенда порциями**.
Ценность не в длине истории, а в дискретности подачи:
- **Урок.** Менти триггерит «следующий день» -> в Kafka падает батч за новый
модельный день -> прогон `etl_pipeline` -> витрины и дашборды сдвинулись.
Полный цикл DWH виден за один шаг; повторяемо и управляемо, в отличие от
непрерывного live.
- **Имитация жизни.** Тот же механизм по расписанию (`@daily` или чаще) —
стенд «живёт»: мониторинги бегут, метрики копятся, нагрузка видна.
- Удлинение истории остаётся как частный случай (несколько next-day подряд).
## Интерфейс
Новый глагол `next-day` в существующем DAG `generator_control`
(`airflow/dags/generator_control_dag.py`), не отдельный DAG: менти уже знает,
где ручки генератора; pause-check `etl_pipeline` и guard чистого стенда
переиспользуются. Ручной триггер — для урока, расписание — для «жизни».
## Развилка реализации — решена (пользователь, 2026-07-07)
**Выбран вариант 2: генерация следующего дня от слепка `T_end`.**
Обоснование. Диагноз задачи 20 показал, что генератор на стыке ничего не
ломает — красный гейт был гонкой в самой проверке. Страх «швов» был страхом
перед артефактом верификатора. При этом оба варианта одинаково требуют
цепочку манифестов и расширение проверок, а вариант 1 сверх того требует
новый режим среза в импорте («всё или ничего» сейчас). То есть вариант 2 не
дороже, честнее (жизнь стенда не ограничена длиной артефакта) и переиспользует
уже закалённый restore-механизм (задача 09: донор в state, громкие ошибки,
детерминированная запасная ветка).
Отклонено: вариант 1 (резать готовый артефакт на дневные порции) — не даёт
неограниченной жизни и требует своей новой механики импорта.
## Открытые вопросы (блокируют ready-for-agent)
- [x] Умеет ли текущий импорт артефакта (`startup-history-import`) подавать
историю частями? **Нет, «всё или ничего»** (проверено 2026-07-07):
скрипт требует чистый стенд (`import_startup_history_artifact.sh:50`,
`assert_stand_clean.sh`), CLI артефакта воспроизводит все топики целиком и
не имеет опций среза, а валидация жёстко связывает manifest и state
(`startup_history_artifact.py`, `_validate_manifest_state`). Для варианта 1
нужен новый режим импорта: срез по модельному дню, цепочка manifest'ов
вместо «manifest равен state», и ослабление guard'а чистого стенда для
последующих порций (граница по манифесту вместо пустоты). Нюанс: артефакт
хранит один state на конец полной истории, поэтому live-продолжение
возможно только после последней порции; промежуточные дни — batch-only
(для учебного сценария этого достаточно).
- [x] Для варианта 2 — решение по запасной ветке рождения визита: **уже
закрыто фиксом задачи 09** (проверено по коду 2026-07-07 при диагнозе
задачи 20): ветка хранит донора (`generation.py:194-209`) и громко падает
на неполных locations, восстановление воспроизводит её детерминированно.
## Acceptance criteria (черновые)
- [ ] Глагол `next-day` в `generator_control`: батч ровно за один следующий
модельный день от текущей границы манифеста.
- [ ] Идемпотентность: повторный триггер того же дня — громкий отказ по
манифесту, а не второй мир и не дубли.
- [ ] Манифест двигает `T_end` атомарно; антисмешивание работает на **цепочке**
границ (30 батчей = 30 границ), проверки
(`scripts/check_generated_analytics.sh` и родня) расширены с одной границы
на цепочку.
- [ ] Учебный цикл целиком: после `next-day` прогон `etl_pipeline` даёт новые
строки в DM-витринах; проверка повторяемая, не разовая.
- [ ] Для варианта 2: визиты, пережившие границу батча, однородны по всем
per-event полям (браузер, referer, utm) — тот же класс проверки, что в
задаче 09.
## Blocked by
- `20-flaky-runtime-seam-check.md` — доверенный стабильный гейт стыка нужен
до навешивания на него цепочки границ; фикс 20 идёт первым.
- Исторические блокеры закрыты: `15-world-boundary-after-cross-review.md`
(граница миров) и `17-trusted-checks-startup-history-superset.md`
(доверенные проверки) — done.
Исторический контекст: `09-seam-browser-fixture-not-preserved.md` — шов
рождается при любом прохождении мира через сериализованный state (рестарт,
сбой, доливка — один код восстановления); фикс 09 положил донора фактуры в
state и закрыл тихие fallback'и. Прежняя редакция этой задачи называлась
«Доливка стартовой истории кусочком от слепка».