Files
clickstream-ch-kafka-supers…/.scratch/generator-model-time-startup-history/issues/13-backfill-top-up-from-snapshot.md
T
ddadminandClaude Fable 5 98be722808 docs(generator): диагноз флаки-гейта в задаче 20, задача 13 разблокирована
- Зачем:
  - Codex-диагноз нашёл корень нестабильности runtime-гейта: гонка
    остановки live-генератора, batch публикуется по топикам без
    атомарности, seam-SQL маскирует непарные строки под смену фактуры;
  - попутно закрыт второй открытый вопрос задачи 13 - запасная ветка
    рождения визита уже хранит донора (фикс задачи 09).
- Что:
  - задача 20: диагноз с судьбой трёх гипотез, направление фикса
    (управляемая остановка live + precheck непарных строк), статус
    ready-for-agent;
  - задача 13: вопрос про fallback-ветку закрыт, статус ready-for-human
    (осталось решение по развилке реализации).
- Проверка:
  - утверждение про донора перепроверено по generation.py:194-209;
    эмпирика диагноза - в логах прогонов, пути в задаче 20.

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

7.3 KiB

Status: ready-for-human

Глагол 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 чистого стенда переиспользуются. Ручной триггер — для урока, расписание — для «жизни».

Развилка реализации (решить до реализации)

Интерфейс next-day одинаков для двух начинок, начинку можно менять, не трогая то, чему учим:

  1. Резать готовый артефакт на дневные порции. История сгенерирована одним прогоном (задача 07), швов нет вообще — границы дней внутри одного мира естественные. Дёшево, если механизм импорта умеет подавать историю частями (см. «Открытые вопросы»). Ограничение: горизонт равен длине артефакта.
  2. Доливка от слепка T_end. Настоящая генерация продолжения. Нужна, когда жизнь стенда должна быть неограниченной. Каждый батч добавляет шов; restore-механизм общий с рестартом и закалён задачей 09, но открыт хвост про запасную ветку рождения визита (см. критерии).

Разумный путь: вариант 1 как MVP, вариант 2 — когда упрёмся в конец артефакта (возможно, отдельной задачей).

Открытые вопросы (блокируют ready-for-agent)

  • Умеет ли текущий импорт артефакта (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 (для учебного сценария этого достаточно).
  • Для варианта 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

  • Открытые вопросы выше (статус needs-info до их закрытия).
  • Исторические блокеры закрыты: 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'и. Прежняя редакция этой задачи называлась «Доливка стартовой истории кусочком от слепка».