Files
clickstream-ch-kafka-supers…/.scratch/handoffs/2026-07-04-generator-chain-review.md
T
ddadmin 549ce0c00d docs(handoff): добавлен независимый ревью-проход в handoff цепочки
- Зачем:
  - следующий шаг handoff — независимый ревью диапазона c672ed0..HEAD;
    результат нужно зафиксировать для продолжения в новой сессии.
- Что:
  - добавлен раздел «Независимый ревью-проход» (свежий взгляд, без субагентов):
    вердикт, прогнанные тесты 172+5, находки по задачам, косметические мелочи.
  - обновлены «Открытые риски» и «Следующий шаг»: остаётся HITL-приёмка и
    решение по задаче 13.
- Проверка:
  - git show --stat HEAD; ревью-раздел читается в handoff.
2026-07-04 23:58:09 +03:00

186 lines
13 KiB
Markdown

# Handoff: цепочка генератора 12 -> 14 -> 09 -> 10 -> 08
Дата: 2026-07-04.
Жанр: одноразовый handoff по ADR-0003.
Источник: `.scratch/generator-model-time-startup-history/coordinator-journal.md`.
## Статус
Цепочка `12 -> 14 -> 09 -> 10 -> 08` завершена через `coordinator-loop`.
Финальный chain review закрыт `APPROVED`; правки финального review
закоммичены в `f8b419d`.
Все issue текущей очереди имеют `Status: done`; в PRD фичи осталась только
дальнейшая задача 13 (`needs-triage`).
## Коммиты
- `dd4af82``feat(airflow): добавлен пульт управления генератором`.
- `200bb82``docs(issues): закрыта задача 12 по пульту генератора`.
- `9d1bcc4``feat(generator): ускорен учебный профиль daily-wave`.
- `0cbfe9b``docs(issues): закрыта задача 14 по быстрому профилю`.
- `e2d0684``fix(generator): сохранена фактура визита при восстановлении`.
- `0f435d7``docs(issues): закрыта задача 09 по фактуре визита`.
- `0c80e24``fix(superset): заменена нечитаемая гео-карта`.
- `de938ed``docs(issues): закрыта задача 10 по гео-графику`.
- `d76c036``docs(course): переведены уроки на стартовую историю`.
- `3d4e13c``docs(issues): закрыта задача 08 по миграции курса`.
- `f8b419d``docs(generator): закрыты находки финального ревью цепочки`.
## Что построено
- `airflow/dags/generator_control_dag.py` — ручной Airflow-пульт
`backfill/import/check`, без Docker socket, с ожиданием `etl_pipeline`.
- `generator/src/clickstream_generator/airflow_control.py` — общая логика
env, предпроверок чистого стенда и сверки manifest для DAG-пульта.
- `docker-compose.yml` / `Makefile``make up` не автостартует live-генератор;
live запускается явно через `make generator-continue`.
- `generator/src/clickstream_generator/launch.py``daily-wave` переведён на
`speed=60`, `tick=1`; `ci` сохранён.
- `generator/src/clickstream_generator/runtime.py` и `state.py` — state v3
хранит `base_click_id`, восстановление визита берёт ту же per-event фактуру.
- `scripts/check_generated_analytics.sh` — стыковочная проверка browser/source и ODS
device/os/geo включается в режиме `auto` после live-строк.
- `superset/create_dashboard.py` — гео-блок заменён на `Top Countries by Events`
(`echarts_timeseries_bar`) с tooltip, легендой и единицами.
- `docs/course/` и `docs/TEST_PLAN.md` — учебный путь переведён с архивного
сида на `startup-history/backfill -> Kafka -> STG -> ODS -> DDS -> DM -> Superset`.
## Ревью по issue
- Issue 12: обычный режим. Worker `medium` был запущен до уточнения уровней,
проверка кода сначала `medium`, повторный прогон `high`. Первая проверка нашла
отсутствие подсказки `make clean` на грязных Kafka-топиках; повторный прогон
`APPROVED`.
- Issue 14: обычный режим. Worker `medium`, проверка кода `high`; `APPROVED`.
- Issue 09: гейт. Worker `high`; проверка задачи `high` и проверка кода `high`.
Первый круг нашёл ODS-проверку device/os/geo, потерю 1 мкс в timestamp offset
и ложнозелёный `generated-history-check`; второй круг `APPROVED`.
- Issue 10: обычный режим. Worker `medium`, проверка кода `high`.
Проверка нашла рассинхрон Superset export/layout, ложнозелёный тест и риск дубля
при rename; узкие повторные прогоны закрыты, итог `APPROVED`.
- Issue 08: обычный режим. Worker `medium`, проверка кода `high`.
Проверка нашла старый путь отката в стандарте уроков и несогласованность урока 06
вокруг `superset-dashboard`; повторный прогон `APPROVED`.
## Финальное ревью
Финальное ревью цепочки шло на усиленном уровне `xhigh`.
До обновления скилла повторные прогоны запускались свежими сессиями ревьюеров:
`Bernoulli`, `Noether`, `Banach`, `Curie`, `Sartre`, `Bacon`.
Это отклонение от обновлённого процесса зафиксировано как дорогой вариант.
После обновления скилла проектные doc-находки чинил отдельный worker для правок
`Raman` (`medium`), а повторный прогон выполнял тот же ревьюер `James` через
`send_input`.
Закрытые классы находок:
- PRD фичи больше не `Draft` и не держит закрытые 12/09/10/14/08 в остатке.
- Все `Status: done` issue фичи без пустых `[ ]`.
- Superset docs/course/artifacts/code не содержат старые `World Map/world_map`
маркеры рядом с новым `Top Countries`.
- `docs/OPERATIONS.md`, `docs/course/PRD.md`, `docs/ARCHITECTURE.md`,
`docs/REPO_MAP.md` и `CONTEXT.md` согласованы со startup-history-путём и
`generator_control`.
## Отклонения процесса
- Ранние повторные прогоны ревью запускались свежими субагентами, а не продолжением
того же ревьюера. После обновления `coordinator-loop` точечные повторные прогоны
нужно делать через `send_input` тому же ревьюеру.
- До обновления скилла координатор сам правил часть project docs по финальному
ревью. После обновления project docs правил worker для правок; процессные файлы
`.scratch/...` остались зоной координатора.
- Визуальная приёмка Superset и живой проход Airflow UI не выполнялись в этой
цепочке. Это не скрыто: все такие пункты вынесены в HITL/риски.
## Открытые риски
- Нужен кросс-линейный ревью-проход другой родословной по фактическим изменениям
`c672ed0..HEAD`. Особый фокус: issue 12 Airflow-пульт, issue 09 state v3 и
стыковочная проверка, issue 10 Superset export/layout, issue 08 учебный путь.
- Нужна ручная HITL-приёмка:
- Airflow UI: `generator_control` backfill/import/check на чистом стенде.
- Superset: кадр `Top Countries by Events` целиком и кадр с tooltip.
- Курс 00-06: проход через новый startup-history-путь.
- Задача 13 (`backfill-top-up-from-snapshot`) остаётся `needs-triage`; после
фикса issue 09 её можно дооформлять отдельно.
## Быстрые проверки, которые уже проходили
- `uv run --with-requirements generator/requirements.txt pytest generator/tests -q`
— PASS на issue 12 и 09.
- `make generator-test` — PASS на issue 14.
- `uv run --with pytest pytest tests/test_superset_dashboard_config.py` — PASS
на issue 10.
- Поисковые проверки курса на старые `make data`/`kafka_load`/фиксированные
сид-ожидания — PASS на issue 08.
- Финальные `rg`-проверки по PRD, чекбоксам, Superset-маркерам и
startup-history-дрифту — PASS перед `f8b419d`.
## Независимый ревью-проход (2026-07-04, свежий взгляд)
Кто и как: Claude, свежим взглядом по диапазону `c672ed0..HEAD`, без субагентов
(правило проекта: «свежим взглядом» = без субагентов). Читались реальные диффы
всех пяти задач и сверялись с текстами issue; тесты прогонялись заново, а не со
слов handoff.
Вердикт: цепочка выполнена на уровне кода и тестов; правок для приёмки не нужно.
Доказательства (прогонял сам):
- `generator/tests` — 172 passed (в том числе контрактный тест DAG и тесты пульта).
- `tests/test_superset_dashboard_config.py` — 5 passed.
- Грепы: старых маркеров `world_map`/`Geography Map` в коде и доках нет (остались
только законный историч. след в спеке, `previous_slice_names` и тест
переименования); во всех done-issue 0 пустых чекбоксов; `state v2` в отгруженном
коде не осталось.
- `etl_pipeline` действительно принимает `conf` `full_refresh` (`Param(True,
type="boolean")`) — имя параметра из `TriggerDagRunOperator` пульта совпадает.
По задачам:
- Issue 09 (гейт): донор `base_click_id` хранится в state; восстановление громко
падает на неизвестном доноре (тихие `.get`-fallback'и убраны); запасная ветка
рождения сделана восстановимой и провалидирована. Отдельная реальная находка —
µs-фикс `_timestamp_to_state_offset` (целочисленная арифметика вместо
`total_seconds()*1e6`). Тесты бьют прямо в критерии приёмки.
- Issue 12 (пульт): `retries=0`, `is_paused_upon_creation`, join после ветвления
через `NONE_FAILED_MIN_ONE_SUCCESS`, `wait_for_completion=True`, env до
`Config()`, предпроверка пустоты Kafka и STG. Compose-профиль `live-generator`
оставляет `make up` чистым; явные пути включают профиль по имени сервиса.
- Issue 14: `daily-wave` speed 1→60, tick 60→1; `ci` не тронут; пер-тиковые INFO
приглушены до DEBUG.
- Issue 10: `echarts_timeseries_bar` с tooltip, легендой и единицами; дедуп дублей
при переименовании; экспорт-JSON защищён тестами и от рассинхрона с конфигом, и
от дрейфа раскладки.
- Issue 08: доки, старый путь `make data`/`kafka_load` убран как основной, грепы
чисты.
Мелочи (косметика, не блокеры):
- `test_default_version` (`test_state.py`): docstring говорит «версии 2», а ассерт
уже `"3.0"`.
- `build_control_env` для `import` тоже зовёт `build_launch_env("backfill", …)` —
безвредно (важен только «мир»-env), но может смутить читателя.
- `tooltipTimeFormat: "smart_date"` на категориальной оси — рудиментарный
параметр, безвреден.
## Открытые риски (обновление 2026-07-04)
- Кросс-линейный проход *другой родословной* (иная модель/агент) не выполнялся:
этот ревью сделан Claude свежим взглядом без субагентов. Для кода и тестов
этого достаточно; если нужна ещё одна родословная — отдельный шаг.
- Ручная приёмка (HITL) остаётся, код к ней честен (пропуски печатаются):
- Airflow UI: `generator_control` backfill/import/check на чистом стенде.
- Superset: кадр `Top Countries by Events` целиком и кадр с tooltip.
- Курс 00-06: проход по новому startup-history-пути.
- Задача 13 (`backfill-top-up-from-snapshot`) — `needs-triage`; предпосылка
(исправный restore из issue 09) выполнена, можно дооформлять.
## Следующий шаг
Независимый ревью кода и тестов пройден. Осталось: ручная HITL-приёмка (Airflow
UI, Superset-кадры, проход курса) и отдельное решение по задаче 13.