Status: needs-triage # Runtime-проверка стыка нестабильна: фактура меняется через раз ## Parent `.scratch/generator-model-time-startup-history/PRD.md` ## Что нашли Два подряд прогона `make generated-history-runtime-check` на одном и том же стенде (2026-07-07, проверка пути менти) дали разный результат: - Прогон 1 (20:18–20:20): **красный** — `Ошибка: per-event фактура меняется на стыке: 8/19` (у 8 из 19 визитов, переживших границу backfill->live, поменялась per-event фактура). При этом `duplicate_events=0`, events=2776. - Прогон 2 (21:5x, та же команда, без изменений кода): **зелёный** — «runtime-проверка startup-history/live seam прошла», конфликтов 0, events=2815. Конфигурация проверки: `GEN_LAUNCH_PROFILE=daily-wave`, `GEN_HISTORY_DURATION=1h`, `GEN_MODEL_T_END=2026-01-01T01:00:00+00:00` (зашита в `scripts/run_generated_history_runtime_check.sh`). ## Почему это важно - Это гейт, которому мы доверяем стык backfill->live (задача 17); флаки-гейт ничего не гарантирует: красный пугает зря, зелёный ничего не доказывает. - Смена фактуры на стыке — класс дефекта задачи 09, который считается закрытым (донор фактуры сохранён в state, тихие fallback'и заменены на ошибки). Либо фикс неполон, либо есть второй источник расхождения. - Задача 13 (глагол next-day) навешивает на этот же механизм цепочку границ — ей нужен доверенный, стабильный гейт. ## Гипотезы (проверить при диагнозе) 1. **Тихая запасная ветка рождения визита** (`generation.py`, ветка без донора-кандидата): при истории в 1 час словарь визитов маленький, донора с достаточным числом событий может не найтись. Задача 09 требовала «молча оставить как есть нельзя» — проверить, что сделал фикс. 2. Недетерминизм live-части: реальное время тиков решает, какие визиты пересекут границу; сам факт «через раз» указывает на зависимость от wall-clock, а не от сида. 3. Проверочный SQL: убедиться, что сравнение полей не цепляет поля, легитимно различающиеся (по образцу исключения `event_id` в задаче 09). ## Acceptance criteria (черновые) - [ ] Причина расхождения 8/19 найдена и названа (код, не догадка). - [ ] Либо генератор починен (фактура на стыке стабильна при любом профиле), либо проверка исправлена (если ловила легитимные различия) — с объяснением. - [ ] `make generated-history-runtime-check` стабилен: N подряд прогонов зелёные (N >= 3), зафиксировано в задаче. - [ ] Если срабатывает запасная ветка рождения — она стала громкой или воспроизводимой при восстановлении (наследие задачи 09 и открытый вопрос задачи 13 закрываются согласованно). ## Blocked by - Нет. Диагноз можно начинать сразу; стенд воспроизводит через раз. Связано: `09-seam-browser-fixture-not-preserved.md` (класс дефекта и решение про донора), `13-backfill-top-up-from-snapshot.md` (нуждается в доверенном гейте на цепочке границ), `17-trusted-checks-startup-history-superset.md` (появление этого гейта).