- Зачем:
- world_next_day перечитывал всю историю топиков Kafka ради
накопительных счётчиков — время прогона росло с возрастом мира
(issue #5, находка F9).
- Что:
- счётчики засеваются при import из уже прочитанного артефакта и при
backfill из потока; next-day продвигает их только событиями нового
дня, полного чтения Kafka больше нет;
- катящаяся контрольная сумма — сумма SHA-256 событий по модулю 2^256
(инкремент равен полному пересчёту), старый формат артефакта
принимается без изменений;
- точные множества click_id/user_domain_id вынесены из manifest в
цепочку контент-адресуемых фрагментов (<=10 000 ID, SHA-256-цепочка,
отдельный топик counter_chunks) — потолок сообщения Kafka не грозит,
предел 900 000 байт проверяется явно с понятной ошибкой;
- порядок записи всюду: фрагменты -> manifest -> state; старое локальное
состояние отклоняется с подсказкой перезапустить import;
- документация manifest/state обновлена (ARCHITECTURE, OPERATIONS,
runbook startup-history).
- Проверка:
- make test (216+31) и make lint зелёные;
- живая приёмка на чистом стенде: import 235 с; три прогона
world_next_day — 716/718/716 с (плоское время, O(нового дня));
мир 3->6 дней, 561 942 события; make generated-history-chain-check —
все порции и стыки однородны;
- тест равенства инкремента и полного пересчёта:
test_incremental_counters_equal_full_recompute.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- Зачем:
- режим кормления стенда порциями: менти триггерит «следующий день»,
видит полный цикл DWH за один шаг (задача 13, вариант 2 — генерация
от слепка T_end).
- Что:
- новый ограниченный режим next-day: восстановление мира из state,
генерация ровно [T_end, T_end+24h), публикация данные -> state ->
манифест (манифест — точка фиксации, автоотката нет).
- операция next-day в DAG generator_control: своя предпроверка границы
вместо clean-guard, идемпотентность через параметр expected_t_end.
- цепочка границ — накопительное поле boundaries в манифесте, старый
формат читается как [T0, T_end]; импорт не изменён.
- новая проверка цепочки (make generated-history-chain-check): непарные
счётчики и однородность по каждой границе, явный статус нулевого
стыка, хвост за границей по всем четырём топикам, литералы в UTC
с микросекундами.
- документация OPERATIONS.md: глагол, предпроверка, восстановление
после сбоя, ограничение retention; в задаче 13 — решения двух слепых
ревью постановки и кода с аргументами отклонений.
- Проверка:
- make test: 204 теста генератора + 31 контракт корня, зелёные.
- make generated-history-chain-check: зелёный, 2 внутренние границы,
непарные счётчики нулевые; учебный цикл: DM 322 -> 10026 -> 19196
за два next-day подряд.
- make generated-history-runtime-check (регрессия задачи 20): зелёный.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- Зачем:
- старый state и ручной live-генератор могли тихо писать события в новый мир данных.
- Что:
- добавлена общая проверка чистого стенда для Airflow и host-путей.
- защищены backfill, import, continue и clean-start сценарии live-generator.
- описан миграционный отказ старого state.
- Проверка:
- make generator-test; docker compose config --quiet; py_compile; bash -n.
- Зачем:
- визит после восстановления не должен менять браузер и источники перехода внутри одного click_id.
- Что:
- добавлен base_click_id в state v3 для восстановления донора фактуры.
- исправлено восстановление timestamp offset без потери микросекунд.
- расширены тесты и стыковая проверка browser/source и device/os/geo.
- Проверка:
- uv run --with-requirements generator/requirements.txt pytest generator/tests -q.
- bash -n scripts/check_generated_analytics.sh.
- git diff --cached --check.
- Зачем:
- суточная волна должна быть видна на занятии за минуты, а не за сутки работы стенда.
- Что:
- профиль daily-wave переведён на speed 60 при тике 1 секунда.
- приглушены подробные live-логи успешного тика без изменения сохранения state.
- обновлены тесты, спека и инструкции запуска быстрого профиля.
- Проверка:
- make generator-test.
- git diff --cached --check.
- Зачем:
- стенду нужна повторяемая история с живым продолжением от модельной границы без дублей и разрыва визитов.
- Что:
- добавлен backfill-режим с `GEN_MODEL_T_END`, manifest и state на `T_end`.
- live-запуск восстанавливается из manifest без настенной дельты и проверяет совместимость state.
- добавлены SQL-проверки формы данных, повторяемости и стыка backfill с live.
- Проверка:
- make generator-test.
- два чистых ClickHouse-прогона backfill дали одинаковые manifest checksums и digest.
- reviewer gate issue 05 пройден после исправлений state/manifest.
- Зачем:
- рестарт генератора должен продолжать поток от модельной точки без дублей и смешивания state разных настроек.
- Что:
- state v2 хранит модельную и настенную метки, скорость, timezone, T0 и seed.
- live-восстановление считает модельную точку по настенной дельте и проверяет совместимость config.
- добавлен путь восстановления от T_end и тесты короткого и долгого простоя.
- Проверка:
- make generator-test.
- ClickHouse-сценарии короткого и долгого восстановления state.
- reviewer gate issue 04 пройден после исправления совместимости state.
- Зачем:
- ускоренный стенд должен проходить больше модельного времени и давать соответствующий событийный бюджет.
- Что:
- расчёт интенсивности переведён на модельную длительность тика.
- добавлена устойчивая выборка бюджета при больших λ.
- усилены тесты ×K, дневного коэффициента и независимости от настенного часа.
- Проверка:
- make generator-test.
- review gate после issue 03 пройден после исправления underflow Poisson.
- Зачем:
- генератор должен писать события от модельной точки T0 и проверяться повторяемо в ClickHouse.
- Что:
- добавлены настройки модельного времени и передача модельной точки в live-тик.
- дневной коэффициент считается по модельному времени и часовому поясу.
- обновлены проверки, compose, документация и статус issue 02.
- Проверка:
- make generator-test.
- два чистых ClickHouse-прогона с GEN_STATE_RESET=true дали одинаковые контрольные числа.
- Зачем:
- после калибровки потока и state v2 генератор нужно принять как рабочий steady-stream источник, а не как исторически сломанный прототип.
- Что:
- добавлен сервисный тест multi-event визита с мок-публикацией во все четыре Kafka-топика.
- compose позволяет переопределять демо-параметры генератора без правки файла, сохраняя внутренние контейнерные адреса.
- README, OPERATIONS, KNOWN_ISSUES и карточка задачи синхронизированы с новой моделью и state v2.
- Проверка:
- uv run --with-requirements generator/requirements.txt pytest generator/tests -q.
- git diff --check.
- GEN_STATE_RESET=true GEN_POPULATION_MAX=123 docker compose config.
- Зачем:
- генератор должен переживать рестарт без потери популяции пользователей и коротко прерванных активных визитов.
- Что:
- добавлен компактный state v2 для популяции, активных визитов и остатка бюджета рождений.
- сервис генератора переведён на единый тиковый поток с сохранением и восстановлением состояния.
- добавлена безопасная деградация для старого state v1 и битого state v2.
- покрыты короткий и долгий простой, reset состояния и валидация вложенного state.
- Проверка:
- uv run --with-requirements generator/requirements.txt pytest generator/tests -q.
- git diff --check.
- Удалён класс InMemoryBatchHistory и вся fallback-логика
- Упрощён KafkaBatchHistory: убраны _initialized, get_stats(), обработка ошибок
- Обновлена документация (generator/README.md, docs/OPERATIONS.md)
- Упрощены тесты, удалены тесты для удалённого функционала
- Код стал честнее: без Kafka генератор падает при старте
Ревьюер: Prometheus даёт достаточно visibility, fallback избыточен
- Зачем:
- ревью rev5: ClickHouse-интеграция была проблемной (порт 9000 native vs HTTP,
неработающий fallback, отсутствие DDL для базы meta)
- архитектурно чище: генератор остаётся pure Kafka producer,
история доступна для аналитики через стандартный ingestion
- Что:
- удален ClickHouseBatchHistory, clickhouse-connect зависимость
- добавлен KafkaBatchHistory с записью в топик generator_batch_history
- добавлен BatchRecord.to_dict() для JSON-сериализации
- добавлен рабочий fallback: Kafka → InMemory при недоступности
- удален pytest-asyncio (не использовался)
- добавлены тесты test_kafka_history.py (15 тестов) и test_service.py (6 тестов)
- обновлена документация: топик вместо таблицы ClickHouse
- Проверка:
- make generator-test: 44/44 тестов пройдено
- docker-compose валиден, генератор не зависит от clickhouse