chore(scratch): уборка одноразовых материалов и handoff новой фичи
- Зачем:
- после слияния feature/data-generator одноразовые материалы .scratch
(задачи 01-21, PRD, журналы, старые handoff'ы) больше не нужны:
долговечное живёт в docs/, история — в git (срез 0e312b3).
- Что:
- удалено всё содержимое .scratch (50 файлов).
- добавлен handoff 20260719-2229-mentee-path-start.md: направление
редизайна пути менти (4 задачи) и пилот GitHub Issues.
- Проверка:
- git show --stat; в .scratch остался только новый handoff.
This commit is contained in:
@@ -1,65 +0,0 @@
|
||||
# Handoff: спеки генератора готовы — передача на детальный план и реализацию
|
||||
|
||||
Дата: 2026-06-10
|
||||
Ветка: `feature/data-generator`
|
||||
Жанр: одноразовые леса́ (ADR-0003) — durable-рассуждение в спеках/ADR/CONTEXT, не здесь.
|
||||
|
||||
> Место: `.scratch/handoffs/` по [ADR-0003](../../docs/adr/0003-handoffs-in-scratch.md)
|
||||
> (перекрывает generic-дефолт скилла «temp dir»: мультимашинность + worktrees).
|
||||
> Предыдущий handoff (2026-06-09-generator-rework.md) отработал и удалён.
|
||||
|
||||
## Где остановились
|
||||
|
||||
Дизайн-этап переработки генератора **завершён**. Спека математической модели
|
||||
написана, прошла **два** адверсариальных ревью свежими агентами (второе ревью
|
||||
ловило ошибки правок первого — практика себя оправдала), все находки закрыты,
|
||||
ключевые цифры перепроверены замерами по полному сиду. Кода по-прежнему
|
||||
не трогали.
|
||||
|
||||
Разделение ролей (см. память проекта): дизайн/спеки — Fable, **детальный план
|
||||
и реализация — Codex 5.5**. Следующая сессия — скорее всего, подготовка задачи
|
||||
для Кодекса или сама реализация.
|
||||
|
||||
## Документы (источники истины, не пересказываю)
|
||||
|
||||
- **Мат-модель (главный документ для исполнителя):**
|
||||
`docs/specs/2026-06-10-generator-math-model.md` — марковская цепочка по
|
||||
страницам, формула «популяция ↔ интенсивность ↔ пауза», кулдаун, правило
|
||||
30 минут на рестарт, критерии приёмки.
|
||||
- **Форма доработки:** `docs/specs/2026-06-09-generator-rework-hierarchical.md`
|
||||
(Open questions закрыты ссылкой на мат-спеку).
|
||||
- **Почему генератор, а не реплей:** `docs/adr/0004-steady-stream-synthetic-generator.md`.
|
||||
- **Профиль сид-датасета (опора калибровки):** `CONTEXT.md`, раздел
|
||||
«Профиль сид-датасета» — измерено по полным файлам 2026-06-10.
|
||||
- **Диагноз дефекта старого кода:** `generator/KNOWN_ISSUES.md`.
|
||||
|
||||
## Ловушки (одной строкой; детали — в спеках)
|
||||
|
||||
- Ранний «факт» **«1..7 событий на визит» был неверен** (срез файла); реально
|
||||
1..27, медиана 10. Если встретишь «1..7» где-то ещё в доках/коде — это
|
||||
остатки ошибки, чинить по профилю сида.
|
||||
- **Формула паузы в мат-спеке обязательна** при смене λ/популяции; кулдаун в
|
||||
неё не прибавляется (уже учтён балансом). Вторая ревизия исправляла именно
|
||||
двойной счёт — не откатить случайно.
|
||||
- **device/geo публикуются на каждое событие** (как в сиде) — это контракт с
|
||||
ETL, не деталь.
|
||||
- `event_timestamp` событий — **запланированное** время, не момент отправки
|
||||
тика (иначе метки прилипают к сетке тиков).
|
||||
- Модель интенсивности (`_calculate_events_count`) сохраняем; дефолт
|
||||
`GEN_LAMBDA_BASE_PER_MIN` меняется 200 → 30.
|
||||
|
||||
## Следующий шаг
|
||||
|
||||
Передать пару спек Кодексу: детальный план реализации → код. Уровень спек
|
||||
сознательно «решения и инварианты, без алгоритмов» — конкретику исполнитель
|
||||
достраивает сам. Возможная подготовка: оформить задачу в `.scratch/<feature>/`
|
||||
по `docs/agents/issue-tracker.md` (скилл `to-issues`, если план дробить).
|
||||
|
||||
## Suggested skills (для следующей сессии)
|
||||
|
||||
- **`to-issues`** — если решим дробить реализацию на задачи в локальном трекере.
|
||||
- **`tdd`** — для этапа реализации (pytest-набор `generator/tests/` существует,
|
||||
но писался под старую модель — пересмотр под новую неизбежен).
|
||||
- **`adversarial-review`** / **`code-review`** — ревью реализации против
|
||||
мат-спеки перед вливанием.
|
||||
- **`conventional-commits`** — коммиты по правилам репозитория.
|
||||
@@ -1,66 +0,0 @@
|
||||
# Handoff: генератор разбит на AFK-задачи
|
||||
|
||||
Дата: 2026-06-11
|
||||
Ветка: `feature/data-generator`
|
||||
Жанр: одноразовые леса по [ADR-0003](../../docs/adr/0003-handoffs-in-scratch.md).
|
||||
|
||||
## Где остановились
|
||||
|
||||
После обсуждения с пользователем дизайн переработки steady-stream генератора
|
||||
переведён из больших спек в локальные задачи для агентов. Код генератора не
|
||||
меняли.
|
||||
|
||||
Создан каталог задач:
|
||||
|
||||
- `.scratch/feature-data-generator/issues/01-minimal-connected-visit.md`
|
||||
- `.scratch/feature-data-generator/issues/02-visit-page-path-and-monotonic-time.md`
|
||||
- `.scratch/feature-data-generator/issues/03-tick-stream-with-active-visits.md`
|
||||
- `.scratch/feature-data-generator/issues/04-user-population-and-returns.md`
|
||||
- `.scratch/feature-data-generator/issues/05-intensity-and-flow-calibration.md`
|
||||
- `.scratch/feature-data-generator/issues/06-state-v2-and-restart.md`
|
||||
- `.scratch/feature-data-generator/issues/07-service-integration-and-docs.md`
|
||||
|
||||
Все задачи имеют `Status: ready-for-agent`. Разрез сделан как последовательные
|
||||
вертикальные срезы, а не как слои архитектуры. Решение пользователя: идти по
|
||||
этому варианту.
|
||||
|
||||
## Важный контекст
|
||||
|
||||
- Старый генератор считаем слабым прототипом, а не ценным кодом для сохранения.
|
||||
Сохранять надо внешние контракты, если они полезны: топики Kafka, формат
|
||||
сообщений для текущего ETL, команды запуска, метрики, идею compact-топика
|
||||
состояния.
|
||||
- Отдельную задачу "зафиксировать внешний контракт" не создавали: контракт
|
||||
встроен в первый и последний срезы.
|
||||
- Детали модели не дублировать отсюда. Источники истины:
|
||||
- `docs/specs/2026-06-10-generator-math-model.md`
|
||||
- `docs/specs/2026-06-09-generator-rework-hierarchical.md`
|
||||
- `docs/adr/0004-steady-stream-synthetic-generator.md`
|
||||
- `CONTEXT.md`
|
||||
- `generator/KNOWN_ISSUES.md`
|
||||
- Предыдущий handoff `.scratch/handoffs/2026-06-10-generator-spec-to-codex.md`
|
||||
остаётся полезным как предыстория спек.
|
||||
|
||||
## Следующий шаг
|
||||
|
||||
Начать с задачи 01 через TDD:
|
||||
|
||||
1. написать один красный тест на публичное поведение "минимальный связанный
|
||||
визит";
|
||||
2. реализовать минимальное новое генеративное ядро без Kafka;
|
||||
3. не тащить старую плоскую модель `generate_batch()`;
|
||||
4. после зелёного теста переходить к следующему поведению, не писать все тесты
|
||||
заранее.
|
||||
|
||||
Пример запуска задачи:
|
||||
|
||||
```text
|
||||
/goal Реализовать .scratch/feature-data-generator/issues/01-minimal-connected-visit.md с использованием /tdd. Соблюдать цикл: один тест на наблюдаемое поведение → минимальная реализация → зелёный тест → остановиться и отчитаться. Не писать все тесты заранее, не реализовывать задачи 02-07.
|
||||
```
|
||||
|
||||
## Suggested skills
|
||||
|
||||
- `tdd` — для реализации каждой задачи короткими циклами red-green-refactor.
|
||||
- `adversarial-review` или `claude-team-review` — после реализации нескольких
|
||||
срезов, чтобы сверить код с мат-спекой.
|
||||
- `conventional-commits` — при фиксации следующих изменений.
|
||||
@@ -1,86 +0,0 @@
|
||||
# Handoff: ADR про модельное время генератора + отложенное ревью петли
|
||||
|
||||
Дата: 2026-06-11
|
||||
Ветка: `feature/data-generator`
|
||||
Жанр: одноразовый handoff по [ADR-0003](../../docs/adr/0003-handoffs-in-scratch.md).
|
||||
|
||||
## Зачем этот handoff
|
||||
|
||||
Сессия с Fable шла в стиле brainstorm-with-docs про **модельное время
|
||||
генератора**. Параллельно идёт эксперимент: автономная петля субагентов Кодекс
|
||||
(координатор + worker + reviewer) доделывает срез генератора (задачи 06→07).
|
||||
Эти две линии **намеренно разделены** — пересмотр времени не правит то, что петля
|
||||
строит на реал-тайм-модели. Handoff фиксирует, что уже сделано и что осталось,
|
||||
чтобы не потерять контекст в новой сессии.
|
||||
|
||||
## Что сделано в этой сессии (durable, не дублирую — см. файлы)
|
||||
|
||||
- Создан **[ADR-0005](../../docs/adr/0005-generator-model-clock.md)** «Модельные
|
||||
часы генератора, отвязанные от настенного времени». Все решения там; кратко:
|
||||
модельное время расцеплено с `now()`; режимы (живой ×1 / ускоренный ×K /
|
||||
заливка `K → ∞`) — драйверы поверх одного шва; живой стенд масштабируется ×K
|
||||
(дефолт ×1); правило 30 минут переопределяется в **модельном** времени с
|
||||
параметрическим origin возобновления; «стартовая история стенда»
|
||||
(сгенерированное прошлое + заморозка state v2) — **будущее направление, ещё не
|
||||
строим**.
|
||||
- Правки **[`CONTEXT.md`](../../CONTEXT.md)** (глоссарий): разведены три значения
|
||||
слова «сид» (`GEN_SEED` / статический сид / стартовая история стенда) и добавлен
|
||||
термин «модельное время и масштаб ×K».
|
||||
|
||||
**Эти изменения (ADR-0005 + CONTEXT.md) ещё НЕ закоммичены.** Их коммит — выход
|
||||
брейншторма пользователя, его нельзя мешать с коммитами кода от петли (06/07).
|
||||
Отдельный docs-коммит.
|
||||
|
||||
## Открытые線 для следующей сессии
|
||||
|
||||
### 1. Отложенное ревью результата автономной петли (приоритет)
|
||||
|
||||
Делать **после** того, как петля закоммитит задачу 07. Это read-only ревью.
|
||||
Измерительный лист — в памяти проекта
|
||||
`memory/ralph-loop-experiment-generator.md`. Главное:
|
||||
|
||||
- **A (главный индикатор эксперимента):** ссылочная целостность при
|
||||
`restore_state`. `_validate_v2_payload` проверяет только форму, не ссылки.
|
||||
Структурно-валидный state v2 с висячей ссылкой визит→пользователь
|
||||
(`generator/src/clickstream_generator/runtime.py:283`) или пользователь→словарь
|
||||
(`runtime.py:253/255`) проходит `from_dict_safe` и роняет `restore_state` без
|
||||
обёртки try→fresh. Прогноз: петля это **пропустит** (слепые зоны внутри одной
|
||||
линии Кодекс скоррелированы). Проверить гипотезу локально структурой с висячей
|
||||
ссылкой (как пользователь проверял оценку снимка 4.7 MB и падение на битой
|
||||
вложенности).
|
||||
- **B/D (проверено OK ранее):** кулдауны по меткам, не тикам (`runtime.py:104`);
|
||||
детерминизм компактного снимка (`_stable_event_id`, restore не жжёт ГПСЧ).
|
||||
Подтвердить, что 06→07 их не сломали.
|
||||
- **C (риск, вне скоупа 06):** всплеск досылки созревших событий с прошлыми
|
||||
метками на первом тике после рестарта — всплыл ли хоть как риск в саморевью.
|
||||
- Верхнеуровневое для 07: границы задачи, честность отметок acceptance, не
|
||||
смешаны ли 06/07, `git status`.
|
||||
|
||||
Цель ревью двойная: (1) корректность 06/07; (2) мета-вывод — **какой класс
|
||||
дефектов автономная петля систематически не видит без внешнего взгляда другой
|
||||
модели**.
|
||||
|
||||
### 2. Реконсиляция мат-спеки с ADR-0005
|
||||
|
||||
После ревью петли. Разделы «Персистентность» и «Воспроизводимость» в
|
||||
`docs/specs/2026-06-10-generator-math-model.md` написаны от настенных часов;
|
||||
привести в соответствие с ADR-0005 (модельное время, правило 30 минут в
|
||||
модельном времени). Не делать сейчас — файл смежен с тем, что петля трогала.
|
||||
|
||||
## Фон (память проекта, не дублирую)
|
||||
|
||||
- `memory/ralph-loop-experiment-generator.md` — схема Ральф-цикла + измерительный
|
||||
лист.
|
||||
- `memory/generator-full-rework.md`, `memory/fable-design-codex-implementation.md`
|
||||
— направление переработки генератора и разделение ролей Fable(дизайн)/Codex(код).
|
||||
- `.scratch/handoffs/2026-06-11-subagent-coordinator-experiment.md` — детальная
|
||||
схема эксперимента с координатором и наблюдения по циклам 05/06.
|
||||
|
||||
## Suggested skills
|
||||
|
||||
- `conventional-commits` — для отдельного docs-коммита ADR-0005 + `CONTEXT.md`
|
||||
(не мешать с кодом петли).
|
||||
- `brainstorm-with-docs` — когда вернёмся к реконсиляции спеки или к проектированию
|
||||
«стартовой истории стенда» (будущее направление из ADR-0005).
|
||||
- `handoff` — после ревью петли зафиксировать рефлексию эксперимента (что петля
|
||||
поймала/пропустила, особенно по находке A).
|
||||
@@ -1,242 +0,0 @@
|
||||
# Handoff: эксперимент с координатором субагентов
|
||||
|
||||
Дата: 2026-06-11
|
||||
Ветка: `feature/data-generator`
|
||||
Жанр: одноразовый handoff по [ADR-0003](../../docs/adr/0003-handoffs-in-scratch.md).
|
||||
|
||||
## Зачем нужен этот handoff
|
||||
|
||||
Пользователь хочет провести эксперимент: не реализовывать следующие задачи
|
||||
самому верхнеуровневому агенту, а использовать его как координатора цепочки
|
||||
субагентов. После эксперимента планируется отдельно отрефлексировать, что
|
||||
сработало, что не сработало и стоит ли закреплять такой процесс.
|
||||
|
||||
Этот документ фиксирует текущее понимание процесса перед запуском, чтобы не
|
||||
потерять договорённости в новой сессии.
|
||||
|
||||
## Текущий рабочий контекст
|
||||
|
||||
Активная линия работы — переработка steady-stream генератора кликстрима.
|
||||
Задачи лежат в `.scratch/feature-data-generator/issues/`.
|
||||
|
||||
Уже выполнены и ожидают человеческой приёмки:
|
||||
|
||||
- `01-minimal-connected-visit.md`
|
||||
- `02-visit-page-path-and-monotonic-time.md`
|
||||
- `02-5-generator-service-cleanup.md`
|
||||
- `03-tick-stream-with-active-visits.md`
|
||||
- `04-user-population-and-returns.md`
|
||||
|
||||
Оставшаяся последовательность:
|
||||
|
||||
1. `05-intensity-and-flow-calibration.md`
|
||||
2. `06-state-v2-and-restart.md`
|
||||
3. `07-service-integration-and-docs.md`
|
||||
|
||||
Задачи зависимы и, вероятно, меняют близкие файлы генератора, поэтому запускать
|
||||
их надо строго последовательно, не параллельно.
|
||||
|
||||
В рабочем дереве на момент обсуждения была незакоммиченная правка только в
|
||||
`.scratch/feature-data-generator/issues/06-state-v2-and-restart.md`: добавлен
|
||||
комментарий, что задачу 06 нельзя начинать до завершения предыдущих срезов,
|
||||
особенно задачи 05.
|
||||
|
||||
## Договорённая схема эксперимента
|
||||
|
||||
Верхнеуровневый агент не включает для себя `/goal`. Его роль — координатор и
|
||||
gatekeeper, а не непосредственный исполнитель.
|
||||
|
||||
Для каждой задачи:
|
||||
|
||||
1. Координатор запускает нового worker-субагента на ровно один issue.
|
||||
2. Задание субагенту формулируется в стиле `/goal`:
|
||||
- реализовать конкретный файл задачи;
|
||||
- работать по методике `/tdd`;
|
||||
- не реализовывать следующие задачи;
|
||||
- не коммитить;
|
||||
- не откатывать чужие изменения;
|
||||
- в конце отчитаться по изменённым файлам, тестам, проверкам и рискам.
|
||||
3. После реализации тот же субагент делает саморевью в отдельной роли:
|
||||
- остановиться;
|
||||
- проверить результат против acceptance criteria, спеки и тестов;
|
||||
- искать ошибки, лишний объём, хрупкость и нарушение учебной читаемости;
|
||||
- сначала выдать находки с важностью, не исправляя их сразу.
|
||||
4. Координатор решает, какие замечания достаточно важные.
|
||||
5. Тот же субагент исправляет только одобренные важные замечания.
|
||||
6. Координатор проверяет верхнеуровневые вещи:
|
||||
- границы задачи;
|
||||
- список изменённых файлов;
|
||||
- честность отметок acceptance criteria;
|
||||
- тесты;
|
||||
- `git status`;
|
||||
- отсутствие смешивания нескольких задач.
|
||||
7. Коммит делает координатор, не субагент.
|
||||
8. Координатор закрывает агента и переходит к следующему issue новым
|
||||
worker-субагентом.
|
||||
|
||||
Для сложных переходов, особенно после задачи 05 перед задачей 06, можно добавить
|
||||
отдельного reviewer-субагента. Это не обязательный шаг на каждую задачу, а
|
||||
контрольная мера, если есть риск, что саморевью исполнителя недостаточно.
|
||||
|
||||
## Роль координатора
|
||||
|
||||
Координатор не должен пытаться заново глубоко реализовывать или полностью
|
||||
повторять работу субагента. Его польза — в управлении процессом:
|
||||
|
||||
- держать порядок задач;
|
||||
- ограничивать область изменений;
|
||||
- читать отчёты и принимать решения;
|
||||
- запускать исправления только по существенным замечаниям;
|
||||
- делать финальный обзор diff на уровне границ и рисков;
|
||||
- выполнять проверки и коммитить.
|
||||
|
||||
Главный риск верхнеуровневого `/goal`: он может заставить координатора
|
||||
оптимизировать работу под закрытие большой цели, а не под аккуратное управление
|
||||
этапами. Поэтому для координатора `/goal` не использовать.
|
||||
|
||||
## Почему саморевью тем же субагентом допустимо
|
||||
|
||||
Пользователь отмечает, что на практике субагенты хорошо делают “ревью свежим
|
||||
взглядом” внутри уже накопленного подробного контекста задачи. Это может быть
|
||||
полезнее, чем полностью внешний поверхностный обзор координатора, которому не
|
||||
хватит деталей реализации.
|
||||
|
||||
Ожидаемая модель:
|
||||
|
||||
- субагент глубоко понимает сделанную задачу и проверяет её на несостыковки;
|
||||
- координатор не доверяет этому слепо, но оценивает адекватность выводов и
|
||||
границы изменений;
|
||||
- для особо рискованных мест можно подключить отдельного проверяющего агента.
|
||||
|
||||
## Suggested skills
|
||||
|
||||
- `tdd` — должен использовать worker-субагент при реализации каждой задачи.
|
||||
- `conventional-commits` — использовать координатору перед созданием каждого
|
||||
коммита.
|
||||
- `claude-team-review` — опционально после задачи 05 или перед задачей 06, если
|
||||
нужен дополнительный независимый взгляд на модель.
|
||||
- `handoff` — после эксперимента зафиксировать рефлексию: что получилось, что
|
||||
не получилось, какие правила стоит оставить.
|
||||
|
||||
## Возможная первая команда субагенту
|
||||
|
||||
```text
|
||||
/goal Реализовать .scratch/feature-data-generator/issues/05-intensity-and-flow-calibration.md с использованием /tdd.
|
||||
|
||||
Работай только в границах этой задачи. Не реализовывай задачи 06-07.
|
||||
Не коммить. Не откатывай чужие изменения.
|
||||
|
||||
Сначала прочитай сам issue и источники решений, указанные в нём. Работай
|
||||
вертикальными TDD-срезами: один тест на наблюдаемое поведение -> минимальная
|
||||
реализация -> зелёная проверка -> следующий тест.
|
||||
|
||||
В конце остановись и отчитайся:
|
||||
- какие файлы изменены;
|
||||
- какие тесты добавлены или изменены;
|
||||
- какие проверки запускались и с каким результатом;
|
||||
- какие acceptance criteria закрыты;
|
||||
- какие риски или спорные места остались.
|
||||
```
|
||||
|
||||
После этого координатор должен попросить того же субагента выполнить саморевью
|
||||
результата, не исправляя замечания до отдельного решения координатора.
|
||||
|
||||
## Наблюдения во время эксперимента
|
||||
|
||||
### Цикл 05: интенсивность и калибровка потока
|
||||
|
||||
Стартовая задача оказалась дорогой по обратной связи: это не локальный инвариант,
|
||||
а отладка статистической модели на длинных симуляциях. Первый worker долго
|
||||
работал без промежуточного отчёта; координатору пришлось сначала поставить
|
||||
мягкий статус-чек в очередь, затем прервать агента ради статуса. Это не сломало
|
||||
работу, но показало: для статистических задач лучше заранее задавать контрольные
|
||||
точки или ожидать длинный первый цикл.
|
||||
|
||||
Саморевью того же worker оказалось полезным. Оно нашло несколько реальных
|
||||
несостыковок:
|
||||
|
||||
- `docker-compose.yml` оставлял старую интенсивность `GEN_LAMBDA_BASE_PER_MIN=200`;
|
||||
- тест межсессионной паузы был слишком широким;
|
||||
- в тестовой конфигурации оставались старые числа;
|
||||
- README мог быть двусмысленным про `GEN_MIN/MAX_EVENTS_PER_TICK`.
|
||||
|
||||
Координаторская проверка тоже добавила ценность: после саморевью был найден
|
||||
конфликт между новым `GEN_LAMBDA_BASE_PER_MIN=30` и старым нижним пределом
|
||||
`GEN_MIN_EVENTS_PER_TICK=5`. При тике 5 секунд это давало минимум 60 событий в
|
||||
минуту и ломало критерий интенсивности. Worker исправил это отдельной точечной
|
||||
итерацией.
|
||||
|
||||
Полезная схема цикла:
|
||||
|
||||
1. worker реализует задачу;
|
||||
2. координатор прерывает только если агент слишком долго молчит;
|
||||
3. worker делает саморевью без правок;
|
||||
4. координатор выбирает, какие замечания чинить;
|
||||
5. worker чинит только выбранные пункты;
|
||||
6. координатор добавляет свой узкий sanity-check по связям между дефолтами,
|
||||
документацией и критерием задачи;
|
||||
7. координатор коммитит.
|
||||
|
||||
Результат цикла 05:
|
||||
|
||||
- коммит `8f1e997 feat(generator): откалиброван поток steady-stream генератора`;
|
||||
- полный прогон: `uv run --with-requirements generator/requirements.txt pytest generator/tests -q`
|
||||
— 96 passed;
|
||||
- `git diff --check` — без замечаний.
|
||||
|
||||
Промежуточный вывод: тот же субагент действительно хорошо использует подробный
|
||||
контекст задачи для саморевью, но координатор всё равно нужен как внешний
|
||||
проверяющий связей между настройками, обычным запуском и acceptance criteria.
|
||||
|
||||
### Reviewer-субагент между задачами
|
||||
|
||||
После задачи 06 пользователь предложил добавить отдельного reviewer-субагента
|
||||
между задачами. Это выглядит особенно полезно на границах вроде 06 -> 07, где
|
||||
следующая задача будет опираться на уже изменённые состояние, сервисный цикл и
|
||||
документацию.
|
||||
|
||||
Важное ограничение: reviewer не является источником истины. Его находки нужно
|
||||
рассматривать как гипотезы и классифицировать координатором:
|
||||
|
||||
- `чинить до коммита` — реальный дефект или риск закрытия acceptance criteria;
|
||||
- `записать как риск` — важно знать, но не блокирует текущую задачу;
|
||||
- `ложная тревога` — reviewer неверно понял код, тест или границы задачи;
|
||||
- `вне скоупа` — может быть полезно позже, но не относится к текущему issue.
|
||||
|
||||
Только находки из первой группы возвращаются worker-агенту на исправление.
|
||||
Иначе есть риск превратить reviewer-а в источник лишнего объёма и расползания
|
||||
задачи.
|
||||
|
||||
В цикле 06 это правило сразу пригодилось. Саморевью исполнителя и отдельный
|
||||
reviewer независимо нашли два существенных риска:
|
||||
|
||||
- битое state v2 с валидным ГПСЧ могло пройти `from_dict_safe`, а затем уронить
|
||||
сервис уже в `restore_state`;
|
||||
- снимок активных визитов сохранялся полными batch-словарями и на верхних
|
||||
лимитах получался порядка мегабайт, хотя спека говорит про компактное
|
||||
состояние.
|
||||
|
||||
Координатор проверил обе гипотезы локально: `restore_state` действительно падал
|
||||
на битой вложенной структуре, а оценка JSON-снимка при 200 активных визитах и
|
||||
популяции 300 дала около 4.7 MB. Эти находки классифицированы как `чинить до
|
||||
коммита` и возвращены worker-агенту. Низкие замечания про совместимость
|
||||
`generate_tick_batch` и пересечение сервиса с задачей 07 не стали правками:
|
||||
первое оказалось ложной тревогой, второе — допустимым пересечением для
|
||||
восстановления state v2.
|
||||
|
||||
После крупной переделки по замечаниям reviewer-а нужен второй круг ревью. В
|
||||
цикле 06 это подтвердилось: исправление компактного состояния само изменило
|
||||
дизайн снимка и восстановление активных визитов. Второй reviewer нашёл новый
|
||||
дефект уже в исправленной версии: формально похожий v2-state с `population=[]`
|
||||
или строковым `pending_visit_births` проходил первичную загрузку, но затем
|
||||
оставлял поток без пользователей или ронял следующий тик. Координатор
|
||||
подтвердил это локальной проверкой и вернул worker-агенту как единственный
|
||||
обязательный пункт второго круга.
|
||||
|
||||
В цикле 07 reviewer оказался полезен уже не для поиска падений, а для силы
|
||||
доказательства. Worker добавил сервисный тест с мок-публикацией, но внешний
|
||||
reviewer заметил, что один опубликованный event доказывает четыре топика и
|
||||
связи, но слабее доказывает невырожденную модель «один визит -> несколько
|
||||
событий с одним `click_id`». Координатор классифицировал это как `чинить до
|
||||
коммита`: финальный интеграционный тест должен доказывать именно уход от старой
|
||||
плоской модели, а не только факт публикации.
|
||||
@@ -1,76 +0,0 @@
|
||||
# Handoff: ADR-0006 (источник аналитики) + спека модельного времени
|
||||
|
||||
Дата: 2026-06-14
|
||||
Ветка: `feature/data-generator`
|
||||
Режим работы: дизайн (brainstorm-with-docs), не реализация кода.
|
||||
|
||||
## Что сделано в этой сессии (закоммичено)
|
||||
|
||||
Содержание не дублирую — смотри сами файлы:
|
||||
|
||||
- **ADR-0006** `docs/adr/0006-generation-as-sole-analytics-source.md` — генерация
|
||||
становится единственным источником аналитики; статический сид → архивный;
|
||||
перевод процесса на новый (сгенерированный) сид — цель работы. Коммит `49512b1`.
|
||||
- **Спека** `docs/specs/2026-06-14-generator-model-time-and-startup-history.md` —
|
||||
модельное время на практике: точка отсчёта `T0`, повторяемость, заливка
|
||||
прошлого, стартовая история, сохранение состояния, скорость ×K, проверка в два
|
||||
шага. Коммит `49512b1`.
|
||||
- **Указатели вперёд** в ADR-0004 и ADR-0005 на ADR-0006 и спеку. Коммит `49512b1`.
|
||||
- **AGENTS.md** — ужесточено правило про русский язык + добавлено правило про
|
||||
понятность и краткость документов. Коммит `c4cc01e`.
|
||||
|
||||
## Контекст и решения, которых нет в артефактах (важны для продолжения)
|
||||
|
||||
- **Роль сида = «кладовка значений» (палитра атрибутов).** Генератор сам придумывает
|
||||
структуру (иерархию, время, воронку), но фактуру (браузер/гео/устройство/utm)
|
||||
копирует из строк сида: `generator/src/clickstream_generator/generation.py`
|
||||
(строки ~202–228, `{**base_browser, …}`), индексы в `dictionary.py`. Профиль
|
||||
популяции хранится ссылкой на сид-сессию (мат-спека, §«Профиль пользователя»).
|
||||
Поэтому сид нельзя удалить, пока генератор не научится фактуре сам.
|
||||
- **Сид полностью чист** — проверено: 1000 записей × 4 файла, 0 падений в DQ
|
||||
(`ods.*_errors`). Значит вывод сида не ломает учебный путь про грязные данные.
|
||||
- **Двухшаговая проверка** (раздел «Проверка» спеки): шаг 1 — агент на чистом
|
||||
стенде сверяет числа в ClickHouse (пирамида/воронка/возвраты), детерминированно;
|
||||
шаг 2 — человек смотрит дашборды (распределение похоже на задуманное + стенд
|
||||
«дышит» на ×K). Вскрытый пробел: дашборда с распределением сгенерированных
|
||||
данных нет (Superset на сиде, Grafana показывает пропускную способность).
|
||||
- **Известные расхождения калибровки** (из прошлого ревью, не в этих артефактах):
|
||||
медиана длины визита ~8 против сидовых 10, всплеск на длине 2, нет
|
||||
bounce-визитов длины 1, доля `/confirmation` ~27%. Когда генерация станет
|
||||
источником, это станет «правдой» стенда — учесть при заполнении коридоров шага 1
|
||||
и в будущей задаче калибровки/фактуры.
|
||||
|
||||
## Очередь (следующие шаги)
|
||||
|
||||
1. Выровнять `CONTEXT.md` (раздел «три значения слова сид») под ADR-0006:
|
||||
статический сид → архивная кладовка значений, цель — полный вывод.
|
||||
2. Пометить в мат-спеке `docs/specs/2026-06-10-generator-math-model.md` разделы
|
||||
«Персистентность через рестарты» и «Воспроизводимость» как переописанные в
|
||||
модельном времени новой спекой (ссылкой, без дублирования).
|
||||
3. (Опционально) Этап 1 вживую: поднять стенд на текущем генераторе, снять
|
||||
реальные числа в ClickHouse, заполнить коридоры в разделе «Проверка». Поднимает
|
||||
docker-стек (меняет состояние) — только с согласия владельца.
|
||||
4. Черновик спеки **синтеза фактуры** — то, что позволит удалить `data/*.jsonl`.
|
||||
5. Черновик спеки **перестройки процесса** (загрузка `kafka_load_dag` → новый сид,
|
||||
Superset/витрины, уроки) — на этапе реализации, по ADR-0006.
|
||||
6. Реализация механизма (модельные часы/×K/стартовая история) — это код, зона Codex.
|
||||
|
||||
## Ограничения (продолжать соблюдать)
|
||||
|
||||
- Роль: Claude — ADR/спеки/ревью; Codex — код. Намерение, против которого
|
||||
сверяем, живёт в ADR/спеках Claude.
|
||||
- Язык: ясный русский без транслитераций (теперь зафиксировано в `AGENTS.md`).
|
||||
- Коммиты: только по просьбе; формат conventional-commits; трейлер
|
||||
`Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>`.
|
||||
- Git строго аддитивно: на ветке может параллельно писать Codex — не делать
|
||||
amend/rebase/reset чужих коммитов. В `main` — merge `--no-ff`, не тащить
|
||||
`.scratch/`.
|
||||
- Context7 для спорных/меняющихся API (особенно Airflow).
|
||||
- Публичный репозиторий — без персональных данных менти.
|
||||
|
||||
## Suggested skills
|
||||
|
||||
- **brainstorm-with-docs** — для продолжения дизайна (пункты 1, 4, 5 очереди:
|
||||
`CONTEXT.md`, спека фактуры, спека перестройки процесса).
|
||||
- **conventional-commits** — для коммитов.
|
||||
- **Context7 (MCP)** — при касании API.
|
||||
@@ -1,16 +0,0 @@
|
||||
# Handoff: экономия контекста в coordinator-loop (указатель)
|
||||
|
||||
Дата: 2026-06-14 MSK
|
||||
|
||||
Полная, авторитетная версия этого handoff перенесена **внутрь навыка**, рядом с
|
||||
handoff про наблюдаемость:
|
||||
|
||||
`~/dotfiles/agents/.agents/skills/coordinator-loop/handoffs/2026-06-14-coordinator-loop-context-economy.md`
|
||||
|
||||
Почему там: handoff про доработку навыка `coordinator-loop`, и сам навык, и его
|
||||
handoff-побратим (`2026-06-14-observability-design.md`) живут в dotfiles. Чтобы будущая
|
||||
сессия по доработке навыка нашла всё в одном месте, авторитетная версия лежит у навыка.
|
||||
|
||||
Здесь оставлен только указатель: диагностика, на которой стоит handoff, снята с прогона
|
||||
именно этого репозитория (фичи `feature-data-generator` и
|
||||
`generator-model-time-startup-history` под `/coordinator-loop`).
|
||||
@@ -1,68 +0,0 @@
|
||||
# Handoff: задачи по модельному времени и стартовой истории
|
||||
|
||||
Дата: 2026-06-14
|
||||
Жанр: одноразовый handoff по ADR-0003.
|
||||
|
||||
## Что сделано
|
||||
|
||||
Создан рабочий набор артефактов для следующей фазы работ:
|
||||
|
||||
- `.scratch/generator-model-time-startup-history/PRD.md`
|
||||
- `.scratch/generator-model-time-startup-history/issues/01-time-and-startup-history-contract.md`
|
||||
- `.scratch/generator-model-time-startup-history/issues/02-model-time-to-clickhouse.md`
|
||||
- `.scratch/generator-model-time-startup-history/issues/03-model-speed-and-day-factor.md`
|
||||
- `.scratch/generator-model-time-startup-history/issues/04-state-v2-model-resume.md`
|
||||
- `.scratch/generator-model-time-startup-history/issues/05-startup-history-backfill-to-clickhouse.md`
|
||||
- `.scratch/generator-model-time-startup-history/issues/06-generated-history-as-analytics-source.md`
|
||||
|
||||
Артефакты режут работу на 6 последовательных issue и 2 review gate. Главная
|
||||
идея: каждый кодовый срез должен подтверждаться через ClickHouse, а не только
|
||||
локальными тестами генератора. Финальная проверка дашбордов глазами остаётся в
|
||||
конце.
|
||||
|
||||
## Важные решения
|
||||
|
||||
- Координатор не берёт `/goal` на всю цепочку: один worker получает один issue.
|
||||
- Worker работает через `/tdd`, не коммитит и не реализует следующие задачи.
|
||||
- После реализации worker делает саморевью без правок.
|
||||
- Координатор классифицирует находки и коммитит сам.
|
||||
- После задачи 3 нужен review gate по сквозному инварианту времени.
|
||||
- После задачи 5 нужен review gate по распределениям и двум путям генерации.
|
||||
- Для review gate после задачи 5 нужен reviewer другой родословной; без него
|
||||
координатор останавливает цепочку и отдаёт риск человеку. Это следует из
|
||||
`docs/research/2026-06-11-subagent-coordinator-experiment.md`.
|
||||
|
||||
## Что важно не потерять
|
||||
|
||||
- В задаче 1 нужно зафиксировать durable-контракт, а не оставить решение только
|
||||
в комментарии к issue.
|
||||
- При ×K восстановление после сбоя нельзя считать простым `datetime.now()`: нужна
|
||||
сохранённая связка модельного и настенного времени.
|
||||
- Короткий или долгий простой считается по модельному времени, а не по настенным
|
||||
минутам.
|
||||
- Чистый прогон должен сбрасывать не только ClickHouse, но и Kafka-топики данных
|
||||
и состояние генератора.
|
||||
- Стартовая история должна быть парным артефактом: события, слепок состояния и
|
||||
манифест.
|
||||
- Живой и восстановленный пути не должны менять контекст внутри одного визита;
|
||||
это известная слепая зона из research.
|
||||
- Задача 6 специально сужена до штатного пути стенда и документов запуска.
|
||||
Уроки, новые панели и улучшения дашбордов уходят в follow-up, если окажутся
|
||||
нетривиальными.
|
||||
|
||||
## Suggested skills
|
||||
|
||||
- `to-issues` — если понадобится переразбить или опубликовать дополнительные
|
||||
issue.
|
||||
- `tdd` — основной режим работы worker-а над каждым кодовым issue.
|
||||
- `conventional-commits` — перед каждым коммитом координатора.
|
||||
- `claude-team-review` или другой внешний reviewer — на двух review gate.
|
||||
- `handoff` — если работа прерывается между issue или после review gate.
|
||||
|
||||
## Следующий шаг
|
||||
|
||||
Начать с
|
||||
`.scratch/generator-model-time-startup-history/issues/01-time-and-startup-history-contract.md`.
|
||||
Это HITL-задача: нужно закрепить интерфейс модельного времени, манифест
|
||||
стартовой истории, правило границы `T_end` и способ повторяемой проверки в
|
||||
ClickHouse.
|
||||
@@ -1,96 +0,0 @@
|
||||
# Handoff: независимое ревью модельного времени и стартовой истории
|
||||
|
||||
Дата: 2026-06-14
|
||||
Жанр: одноразовый handoff по ADR-0003.
|
||||
|
||||
## Контекст
|
||||
|
||||
После прогона coordinator-loop по фичам `feature-data-generator` и
|
||||
`generator-model-time-startup-history` (issues 01–06, реализация Codex) проведено
|
||||
независимое ревью результатов — другой родословной (Claude). Это в том числе
|
||||
закрыло пропущенный внешний review gate после задачи 5 из PRD: он был выполнен той
|
||||
же родословной, что и worker, а PRD требовал другую.
|
||||
|
||||
## Что проверили независимо (не по отчётам)
|
||||
|
||||
- `make generator-test` — `134 passed` (своим прогоном).
|
||||
- Код = «Рабочий контракт реализации» спеки буква в букву: настройки
|
||||
`GEN_MODEL_*`, state v2 (`model_timestamp/wall_timestamp/model_time_speed/…`),
|
||||
формула live-возобновления, полуоткрытая граница `[T0, T_end)` с
|
||||
`drain_until(include_boundary=False)`, манифест и антисмешивание.
|
||||
- Данные в ClickHouse реальные и сходятся с отчётами до цифры: 6 ч → 16 054;
|
||||
перепрогнали 1 сутки → 93 952; 2 суток → 187 087 событий / 17 397 визитов /
|
||||
2 765 пользователей.
|
||||
- Пирамида (users < visits < events), возвраты, монотонность обеих воронок,
|
||||
отсутствие архивного сида (все строки 2026 года).
|
||||
- Повторяемость суточной волны на 2 сутках: часовые числа day1≈day2
|
||||
(отношение в основном 0.9–1.1), форма «ночь–день» повторяется.
|
||||
- Стык backfill→live (live-доливка от `T_end=2026-01-03`): дублей 0, граница
|
||||
держится, device/os/гео на стыке однородны.
|
||||
- Дашборд: визуальная приёмка (шаг 2 спеки) — человеком и через Playwright.
|
||||
«Rows by Layer» (4 равных столбца = 187 312) корректен: пайплайн проносит
|
||||
событие 1:1, потерь нет, дедуп at-least-once на чистом backfill не возникает.
|
||||
|
||||
## Что нашли
|
||||
|
||||
- **issue 09 — реальный дефект стыка.** Браузерная фактура не переживает
|
||||
восстановление визита: у визитов, активных ровно на `T_end`, в live-продолжении
|
||||
меняется `browser_name`/`browser_language` (17/22 и 22/22), хотя внутри чистого
|
||||
backfill браузер постоянен (0/14556). device/гео не задеты. Нарушает заявленный
|
||||
критерий однородности задач 04/05; проверялось неполно (смотрели только поля
|
||||
`dds.click`, а не per-event браузер в `dds.event`). Масштаб ~0.13% визитов.
|
||||
- Гео-карта на дашборде нечитаема (нет легенды/подсказок/понятной шкалы) — issue 10.
|
||||
- Стартовый сид по умолчанию — 6 часов (быстрый профиль для CI); суточная волна на
|
||||
нём не видна, для просмотра нужен ≥2-суточный профиль через env.
|
||||
|
||||
## Открытые пробелы проверки (НЕ закрыты)
|
||||
|
||||
Ревью прошло по корректности кода, форме данных, стыку и дашборду, но НЕ трогало:
|
||||
|
||||
1. **×K не гоняли.** Все прогоны на `speed=1`. Ускорение модельного времени,
|
||||
событийный бюджет по модельной длительности и смена дневного коэффициента при
|
||||
×K проверены только в коде/по отчёту issue 03.
|
||||
2. **Live-crash recovery не воспроизводили.** Формула возобновления с настенной
|
||||
дельтой и закрытие просроченных визитов — только в коде. Гипотеза: дефект
|
||||
issue 09 бьёт и сюда (тот же restore-механизм), эмпирически не подтверждено.
|
||||
3. **Распределения не сверяли с коридорами мат-спеки** (`2026-06-10-generator-math-model.md`).
|
||||
Подтвердили форму (монотонность, возвраты, длина), но не попадание
|
||||
`confirmation_share` и доли коротких визитов в спроектированные коридоры.
|
||||
4. **Воспроизводимость сами не перепрогоняли** — идентичность checksum при
|
||||
повторном чистом прогоне взята из отчётов issue 03/05.
|
||||
5. **Второй review gate (после задачи 3) не делали** — систематический sweep на
|
||||
утечку настенных часов в расчёт интенсивности и сохранение состояния.
|
||||
|
||||
Помельче: не проверяли обработку повреждённого/старого state (fresh-start с
|
||||
предупреждением), `browser_user_agent` (тот же механизм, что issue 09), сам процесс
|
||||
coordinator-loop по правилам PRD.
|
||||
|
||||
## Зафиксированные follow-up (все needs-triage, на потом)
|
||||
|
||||
- `issues/07-migrate-course-from-archive-seed.md` — миграция уроков.
|
||||
- `issues/08-startup-history-portable-artifact-and-usage-docs.md` — портативный
|
||||
артефакт стартовой истории + runbook + идеи интерфейса (глаголы вместо флагов,
|
||||
длительность/профили, громкий отказ при несовпадении, доливка кусочком,
|
||||
Airflow-DAG как пульт).
|
||||
- `issues/09-seam-browser-fixture-not-preserved.md` — дефект браузерной фактуры.
|
||||
- `issues/10-dashboard-geo-map-readability.md` — читаемость гео-карты.
|
||||
- `docs/course/PRD.md` §7 — развилка «генератор как скрытая инфраструктура vs
|
||||
отдельный урок про генератор» (не грузить менти марковскими цепями).
|
||||
|
||||
## Состояние стенда
|
||||
|
||||
Поднят на 2 сутках генерации (+ несколько live-тиков от seam-проверки): ClickHouse,
|
||||
Kafka, Superset, postgres-metadata. Дашборд:
|
||||
`http://localhost:8088/superset/dashboard/ecommerce-analytics/`.
|
||||
|
||||
## Suggested skills
|
||||
|
||||
- `tdd` — для фикса issue 09 (один поведенческий тест на однородность браузера через
|
||||
стык, затем минимальная правка).
|
||||
- `conventional-commits` — перед коммитами.
|
||||
- `claude-team-review` / внешний reviewer другой родословной — на пробелы 1–5.
|
||||
|
||||
## Следующий шаг
|
||||
|
||||
Сегодня только фиксация, без правок. Дальше — приоритизировать issue 09 (баг) против
|
||||
08/10 (удобство/виз) и закрыть пробелы проверки 1–5 (особенно ×K и crash recovery).
|
||||
@@ -1,91 +0,0 @@
|
||||
# Handoff: триаж бэклога генератора и целеполагание стенда
|
||||
|
||||
Дата: 2026-07-04
|
||||
Жанр: одноразовый handoff по ADR-0003.
|
||||
|
||||
## Рабочая форма (зафиксирована сегодня)
|
||||
|
||||
С Claude — обсуждение проекта, планы, проектные документы и независимые ревью.
|
||||
Исполнение кода — Codex, предпочтительно через `/goal` или `/coordinator-loop`.
|
||||
Сохранено в памяти Claude (memory), новая сессия подхватит автоматически.
|
||||
|
||||
## Что решено и зафиксировано
|
||||
|
||||
- **Целеполагание сверено** и записано в `docs/course/PRD.md` §1 (поправка
|
||||
2026-07-04): три части трека ClickHouse (теория — внешние курсы, лабы —
|
||||
clickhouse-learning-cluster, этот стенд — интеграции «как в жизни»); иерархия
|
||||
целей: курс -> стенд-носитель -> генератор как скрытая инфраструктура.
|
||||
- **Развилка «урок про генератор» закрыта**: урока не будет, генератор — скрытая
|
||||
инфраструктура (PRD §7).
|
||||
- **Демо-употребление устарело**: `docs/DEMO_CHEATSHEET_5MIN.md` и
|
||||
`docs/DEMO_SCRIPT_10_15MIN.md` удалены, демо выросло в отдельный проект.
|
||||
- **Новая открытая развилка** в PRD §7: кластерная конфигурация ClickHouse
|
||||
(пользователь склоняется к «всё в одном», решение не принято).
|
||||
- **Конвенция трекера**: завершённая задача — `Status: done`
|
||||
(`docs/agents/issue-tracker.md`); задачи 01–06 фичи переведены в `done`
|
||||
(стояли ошибочные `ready-for-human` от глючившего координатора).
|
||||
|
||||
## Бэклог фичи `generator-model-time-startup-history`
|
||||
|
||||
Список задач и порядок — в PRD фичи (раздел «Задачи», дополнен сегодня):
|
||||
|
||||
- **07** (артефакт + runbook, `ready-for-agent`) — импорт строго через Kafka
|
||||
(напрямую в ClickHouse не пишет — решение пользователя), громкий отказ при
|
||||
несовместимом state (пересмотр правила спеки), граница runbook «использование,
|
||||
не устройство». Режим ревью — гейт.
|
||||
- **08** (миграция курса, `ready-for-agent`) — после 07; `make data` вплетён во
|
||||
все уроки 00–05, объём больше, чем кажется; тонкое место — урок 00.
|
||||
- **11** (глаголы/длительность/профили, `ready-for-agent`) — после 07, до 12.
|
||||
- **12** (DAG-пульт, `needs-triage`) — дооформить после 07 и 11; приоритет
|
||||
поднят пользователем: будущий основной человеческий интерфейс стенда.
|
||||
- **13** (доливка, `needs-triage`) — без приоритета, после фикса 09.
|
||||
- Перестановка: бывший 07 (миграция) и 08 (артефакт) поменяны местами.
|
||||
|
||||
## Следующий шаг
|
||||
|
||||
Весь бэклог готов к передаче Codex. Порядок пересмотрен (решение 2026-07-04,
|
||||
«пульт вперёд»): узкое место — время человека на ручную приёмку, поэтому
|
||||
основная цепочка теперь 07 -> 11 -> 12 (пульт появляется раньше), а миграция
|
||||
курса 08 идёт последней — её приёмку (проход по урокам) человек ведёт уже через
|
||||
пульт. 09 и 10 независимы, можно параллельно; 13 — после фикса 09. Граф и
|
||||
подробности — в PRD фичи, раздел «Задачи»; там же зафиксировано, что номер
|
||||
файла — идентификатор, а не порядок.
|
||||
|
||||
## Дооформление 09 и 10 — что изменилось против прежнего понимания
|
||||
|
||||
Сделано в этот же день, вторым заходом. 09 и 10 переведены в `ready-for-agent`;
|
||||
детали — в самих issue, здесь только сдвиги в понимании:
|
||||
|
||||
- **Гипотеза по 09 не подтвердилась.** Дело не в рассинхроне `event_index`, а в
|
||||
источнике фактуры: при рождении визита браузерные строки берутся у случайного
|
||||
«донора» из словаря, при восстановлении — у `seed_click_id` пользователя.
|
||||
Прежняя развилка «выбор по абсолютному индексу, не трогая схему state»
|
||||
оказалась нерабочей — restore не знает донора. Решение пользователя: хранить
|
||||
`base_click_id` донора в state (альтернативы и причины отказа — в issue).
|
||||
- **Дефект 09 шире браузера** (нашло ревью): per-event поля location (referer,
|
||||
utm) расходятся на стыке так же — критерии приёмки расширены, иначе частичный
|
||||
фикс «только браузер» прошёл бы приёмку. Расхождение event_id (uuid4 при
|
||||
рождении, uuid5 при restore) зафиксировано как известное и вне скоупа.
|
||||
- **По 10 сняты две мины:** пересборка по умолчанию даёт 6 часов истории, а не
|
||||
2 суток (профиль «2 суток одной командой» — это ещё не сделанная задача 11);
|
||||
legacy-виз `world_map`, похоже, вообще не умеет легенду и tooltip — основной
|
||||
путь, вероятно, смена типа визуализации, а не настройка (проверить через
|
||||
Context7 при реализации).
|
||||
- **Процессная заметка:** дооформленные issue прогнаны через тройное ревью
|
||||
(самопроверка + два свежих агента, адверсарно, с проверкой каждого утверждения
|
||||
по коду). Улов оправдал затраты — см. пункты выше; для issue с режимом «гейт»
|
||||
так стоит делать и дальше.
|
||||
|
||||
## Не забыть (вне бэклога)
|
||||
|
||||
Открытые пробелы независимого ревью от 2026-06-14 (см. handoff
|
||||
`2026-06-14-generator-model-time-verification-review.md`): ×K не гоняли,
|
||||
live-crash recovery не воспроизводили, распределения не сверяли с коридорами
|
||||
мат-спеки, воспроизводимость checksum не перепроверяли.
|
||||
|
||||
## Suggested skills
|
||||
|
||||
- `conventional-commits` — перед коммитами.
|
||||
- `tdd` — для фикса issue 09 (тест на однородность браузера через стык, затем
|
||||
минимальная правка).
|
||||
- `coordinator-loop` — на цепочки 07 -> 08 и 07 -> 11 -> 12.
|
||||
@@ -1,185 +0,0 @@
|
||||
# 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.
|
||||
@@ -1,160 +0,0 @@
|
||||
# Кросс-линейное ревью цепочки генератора 12 -> 14 -> 09 -> 10 -> 08
|
||||
|
||||
Дата: 2026-07-05 00:02.
|
||||
Жанр: одноразовый handoff по ADR-0003; отчёт кросс-прохода другой родословной
|
||||
(Claude) по диапазону `c672ed0..ec815ce`. Бриф — из
|
||||
`.scratch/handoffs/2026-07-04-generator-chain-review.md`.
|
||||
Метод: четыре параллельных адверсарных ревьюера с исполняемыми доказательствами
|
||||
(мутационные тесты на копии, эксперимент с compose-профилем на реальной версии
|
||||
Compose, зонды на реальном сиде, сверка Airflow API через Context7). Репозиторий
|
||||
не менялся.
|
||||
|
||||
## Вердикт
|
||||
|
||||
**CHANGES_REQUESTED.** Счёт: 1 critical, 5 high, 10 medium, 4 low — после
|
||||
`APPROVED` финального ревью той же линии. Третье подтверждение находки о
|
||||
родословной: внутренние ревью закрыли локальные дефекты честно, кросс-линия
|
||||
нашла сквозные сценарии.
|
||||
|
||||
## Сквозные семейства (главная ценность прохода)
|
||||
|
||||
1. **«Смешение миров» возвращается тремя дорогами.** Инвариант задачи 07
|
||||
(«чистый стенд, громкий отказ») пробит: (а) state v2 после обновления кода
|
||||
классифицируется как «повреждённый» → тихий чистый старт нового мира поверх
|
||||
истории; (б) live-генератор ушёл в compose-профиль, и `make clean`/`down`
|
||||
его больше **не убивают** — осиротевший генератор старого мира пишет в чистые
|
||||
топики и переживает перезагрузку (`restart: unless-stopped`); (в) консольные
|
||||
пути (`make generator-backfill`, `startup-history-import`) остались без
|
||||
предпроверок, которые пульту сочли обязательными.
|
||||
2. **Последствия «make up больше не стартует live» не выметены.** Алерт
|
||||
`Kafka No Messages Produced` горит весь курс на здоровом стенде; уроки 0/5
|
||||
ожидают поток; `sleep 5` в документированной проверке шва меньше времени
|
||||
старта генератора — проверка стала пустышкой.
|
||||
3. **Ложнозелёные проверки.** Superset-тесты пропускают дрейф параметров
|
||||
(top-15 → 500 строк — 5 тестов зелёные); стыковая проверка сверяет шов там,
|
||||
куда указал env, а не где он по манифесту; ODS-блок проходит на пустом ODS.
|
||||
4. **Чистый клон/свежий стенд никто не прошёл.** `uv` не заявлен в
|
||||
пререквизитах; README-быстрый старт падает без `ddl_init`; пульт вечно висит
|
||||
на запаused `etl_pipeline`; после `git pull` образ Airflow не пересобирается
|
||||
(DAG красный); центральное упражнение урока 1 физически невоспроизводимо.
|
||||
Всё это лежало ровно в вынесенной в риски HITL-приёмке.
|
||||
|
||||
## Индекс находок по issue
|
||||
|
||||
### Issue 08 (курс) — CHANGES_REQUESTED
|
||||
|
||||
- **CRITICAL** `docs/course/lessons/01_kafka_to_clickhouse.md:192-239` —
|
||||
упражнение с `kafka_msg_ts` невоспроизводимо: «перезаливка среза» заменена на
|
||||
`make generated-history-analytics && make up`, который делает `down -v` и
|
||||
накатывает эталонный DDL — добавленная менти колонка уничтожается, финальный
|
||||
SELECT падает; в тексте остался висящий `TRUNCATE` (след нестыковки).
|
||||
Нужен путь перезаливки без сброса схемы (смена `kafka_group_name` /
|
||||
`CLEAN_START=0` + повторный backfill) и проверка на стенде.
|
||||
- **HIGH** `docs/course/README.md:19-34`, `README.md:43-47` — первая команда
|
||||
курса требует `uv` на хосте; ни пререквизиты, ни quick start его не называют.
|
||||
- **HIGH** `docs/course/lessons/05_monitoring.md:254,259-262,339` — на штатном
|
||||
пути (без live) `Kafka No Messages Produced` горит постоянно; урок обещает
|
||||
«алерты не шумят»; панели описаны для потока, которого нет.
|
||||
- **MEDIUM** `00_kafka_intro.md:56-65` — служебные топики `generator_state` и
|
||||
`generator_startup_history_manifest` не объяснены (урок построен на
|
||||
разглядывании списка топиков).
|
||||
- **MEDIUM** `00_kafka_intro.md:117-122` vs `05_monitoring.md:156-161` —
|
||||
взаимоисключающие утверждения о видимости consumer lag; проверить на стенде.
|
||||
- **MEDIUM** `README.md:64-68`, `docs/OPERATIONS.md:175-199` —
|
||||
`make generated-history-check` после `PROFILE=daily-wave` падает: в check
|
||||
зашит диапазон ci, PROFILE не передаётся.
|
||||
- **MEDIUM** `docs/OPERATIONS.md:95` — источником STG первым назван архивный
|
||||
`make data`.
|
||||
|
||||
### Issue 12/14 (пульт, профиль) — CHANGES_REQUESTED
|
||||
|
||||
- **HIGH** `airflow/dags/generator_control_dag.py:227-235` +
|
||||
`etl_pipeline_dag.py:263` — `etl_pipeline` создаётся на паузе; `trigger_etl`
|
||||
(`wait_for_completion`, без `execution_timeout`) виснет навсегда,
|
||||
`max_active_runs=1` блокирует повторные запуски. В Airflow 2.10 нет
|
||||
`fail_when_dag_is_paused` (Context7). Нужна предпроверка «etl_pipeline не на
|
||||
паузе» + шаг unpause в README/runbook.
|
||||
- **HIGH** `docker-compose.yml:293-294,334`, Makefile (`down`, `clean`) —
|
||||
профильный `live-generator` не удаляется `down -v` (доказано экспериментом,
|
||||
Compose v5.1.3); `restart: unless-stopped` воскрешает его после перезагрузки.
|
||||
В `down`/`clean`/CLEAN_START нужен `--profile live-generator`.
|
||||
- **MEDIUM** `README.md:32-40` — быстрый старт без `ddl_init`: precheck падает
|
||||
сырым `UNKNOWN_TABLE`; добавить шаг и человекочитаемую подсказку.
|
||||
- **MEDIUM** `airflow/requirements.txt:9-10`, Makefile `up` — после `git pull`
|
||||
образ Airflow не пересобирается → `ModuleNotFoundError: prometheus_client`,
|
||||
DAG красный. Нужен `--build` или инструкция.
|
||||
- **MEDIUM** `docs/OPERATIONS.md:237-241` vs `kafka_io.py:161,253` — `sleep 5`
|
||||
меньше времени старта continue (≥10 с): live-строк ноль, `CHECK_LIVE_SEAM=auto`
|
||||
молча пропускает шов. Было `sleep 130` при тике 60 с.
|
||||
- **MEDIUM** `airflow_control.py:102-141` vs `run_generator.sh:56-77`,
|
||||
`import_startup_history_artifact.sh` — предпроверки только в DAG; консольные
|
||||
пути тихо смешивают миры. Вынести `assert_stand_clean` в общую точку входа.
|
||||
- **LOW** `service.py:203-215` — простой стенда ×60: ночь = +30 модельных суток
|
||||
дыры; предупредить в runbook, советовать reset/повторный импорт.
|
||||
- **LOW** — фиксация Context7-проверки Airflow API только в `.scratch/`, не в
|
||||
коде/доках (AGENTS.md требует); сами вызовы для 2.10.5 корректны.
|
||||
|
||||
### Issue 09 (state v3, фактура) — CHANGES_REQUESTED
|
||||
|
||||
- **HIGH** `state.py:236-241` → `kafka_io.py:181` → `service.py:100-102` —
|
||||
поднятие STATE_VERSION молча превращает живой стенд во «второй мир»: v2 —
|
||||
читаемый, несовместимый state, но version-гейт убивает его до семантики,
|
||||
`from_dict_safe` даёт `None`, сервис тихо стартует новый мир с `model_t0`
|
||||
поверх истории. Сверка `manifest.state_version != state.version`
|
||||
(`service.py:246`) недостижима. Спека (строки 198-204, 245-247) требует
|
||||
громкий отказ; `IncompatibleStateError` уже существует — использовать его при
|
||||
известной старой версии и `GEN_STATE_RESET=false`; миграционной заметки в
|
||||
доках нет.
|
||||
- **MEDIUM** `check_generated_analytics.sh:13,273-289,342,387-393` — проверка
|
||||
стыка сверяет шов по env-дефолту (`2026-01-01T06:00`), не по манифесту: после
|
||||
`daily-wave` голый `make generated-history-check` «доказывает» однородность
|
||||
фальшивого шва посреди backfill. LEFT JOIN `dds.click` структурно пуст; ODS-блок
|
||||
проходит на пустом ODS. Брать `model_t_end` из манифеста, требовать ненулевые
|
||||
ODS-строки.
|
||||
- **MEDIUM** `generation.py:196-209` — предпосылка issue «fallback не
|
||||
срабатывает» неверна: срабатывает у ~8% визитов (зонд, seed=4242, N=20000);
|
||||
выпуск не изменился только потому, что у всех доноров сида строки внутри
|
||||
click_id идентичны — свойство нигде не зафиксировано; при регенерации сида
|
||||
с вариативностью ~8% визитов поедет. Зафиксировать свойство сида или
|
||||
ограничить `GEN_MAX_SESSION_EVENTS` длиной максимального донора.
|
||||
- Ядро фикса крепкое (проверено исполнением): инвариант «рождение ==
|
||||
восстановление» держится, RNG не потребляется при restore, микросекунды
|
||||
чинятся честно, форма распределений не сместилась (сверка с `e2d0684^`).
|
||||
|
||||
### Issue 10 (Superset) — CHANGES_REQUESTED
|
||||
|
||||
- **MEDIUM** `tests/test_superset_dashboard_config.py:64-76` — тесты сверяют
|
||||
подмножество параметров: мутация «top-15 по убыванию» в экспорте (row_limit
|
||||
15→500, order_desc→false и др.) проходит все 5 тестов. Нужно полное сравнение
|
||||
`params` config-vs-export. Классы «возврат world_map» и «рассинхрон layout»
|
||||
закрыты честно (мутации падают).
|
||||
- **MEDIUM** issue `10-*:51-68`, `create_dashboard.py:158-185` — приёмка «по
|
||||
кадру» выполнена декларативно, чарт никем не отрисован; порядок столбцов после
|
||||
pivot не гарантирован — задать `x_axis_sort: "Events, pcs"`,
|
||||
`x_axis_sort_asc: false`; снять кадр при HITL.
|
||||
- **MEDIUM** `create_dashboard.py:505-520` — удаление дублей по глобальному
|
||||
совпадению имени: повторный прогон молча удалит одноимённый чарт менти;
|
||||
сузить по `datasource_id`, задокументировать деструктивность.
|
||||
- **LOW** `create_dashboard.py:176` — `tooltipTimeFormat` бессмыслен для
|
||||
категориальной оси; легенда дублирует ось при единственной серии.
|
||||
- **LOW** `docs/SUPERSET_DASHBOARD.md:205-211` — путь ручного импорта экспорта
|
||||
(legacy v0) ничем не проверяется.
|
||||
|
||||
## Маршрутизация (предложение)
|
||||
|
||||
- **Багфикс-цепочка Codex** (кандидат-порядок по риску): (1) семейство
|
||||
«смешение миров» — 09-HIGH + 12-HIGH-clean + разъезд предпроверок одним
|
||||
issue; (2) 12-HIGH-паузы + README/ddl_init/build — «свежий стенд» одним
|
||||
issue; (3) 08-CRITICAL урок 1 + uv + алерт урока 5 — «курс на чистом клоне»;
|
||||
(4) ложнозелёные проверки (09-MEDIUM-шов, 10-MEDIUM-тесты); (5) остальное.
|
||||
- **HITL остаётся HITL** (кадры Superset, живой проход Airflow UI, проход по
|
||||
урокам) — но пункты 08-CRITICAL и 12-HIGH показывают, что часть HITL дешевле
|
||||
заменить проверками на чистом клоне в CI-манере.
|
||||
- Отдельно: третий случай подтверждения находки о родословной — кандидат на
|
||||
датированную поправку в `references/rationale.md` скилла coordinator-loop.
|
||||
|
||||
## Что подтверждено как корректное
|
||||
|
||||
Стыковка env DAG→генератор; ветвление DAG; отсутствие потребности в Docker
|
||||
изнутри Airflow; make-цели/имена DAG/DDL-колонки/числа профилей в уроках; ядро
|
||||
state v3; замена карты в обоих источниках; 172 unit-теста зелёные.
|
||||
@@ -1,122 +0,0 @@
|
||||
# Handoff: fixes after generator cross-line review
|
||||
|
||||
Дата: 2026-07-05 22:12.
|
||||
Жанр: handoff по ADR-0003 после coordinator-loop 15 -> 16 -> 17 -> 18.
|
||||
|
||||
## Что закрыто
|
||||
|
||||
- 15: граница миров после обновления, clean/reset и host-запусков.
|
||||
Коммиты: `080d5ae`, `108053b`.
|
||||
- 16: свежий стенд и `generator_control` без неявных ручных шагов.
|
||||
Коммиты: `27947ce`, `9804d0b`.
|
||||
- 17: доверенные проверки startup-history и Superset.
|
||||
Коммиты: `00c97eb`, `6731349`.
|
||||
- 18: курс 00/01/05 проходит по startup-history на чистом стенде.
|
||||
Коммиты: `77e4fb6`, `6d64f39`.
|
||||
- Follow-up 19: отдельная задача на единые `make test` и `make lint`.
|
||||
Коммит: `2778eae`.
|
||||
- Финальный review fix: документация больше не советует обычный
|
||||
`make generated-history-check` после backfill-only пути.
|
||||
Коммит: `8e1c733`.
|
||||
- Issue 19 закрыта после внешнего Claude review: единые `make test` и
|
||||
`make lint`, подключение корневых контрактных тестов и усиление проверок
|
||||
startup-history.
|
||||
Коммит: `9b0b063`.
|
||||
|
||||
## Ключевые стыки реализации
|
||||
|
||||
- `generator/src/clickstream_generator/stand_clean.py` — общий guard чистого
|
||||
стенда для Airflow и host-путей.
|
||||
- `scripts/assert_stand_clean.sh` — host-проверка перед backfill/import/continue.
|
||||
- `airflow/dags/generator_control_dag.py` — pause-check `etl_pipeline` до
|
||||
мутирующих веток.
|
||||
- `scripts/check_generated_analytics.sh` — manifest boundary, fail-closed
|
||||
live seam, непустой ODS и fail-closed проверка DM-витрин.
|
||||
- `scripts/run_generated_history_runtime_check.sh` — bounded runtime gate для
|
||||
daily-wave + live seam.
|
||||
- `scripts/run_generator.sh` — `reset` теперь проходит clean-stand guard до
|
||||
запуска live-генератора.
|
||||
- `Makefile` — `make test`, `make lint`, `contract-test`; обычный pytest-вывод
|
||||
тихий, подробность можно включить через `PYTEST_ARGS`.
|
||||
- `generator/src/clickstream_generator/state.py` — любая версия state не `3.0`
|
||||
даёт громкий `UnsupportedStateVersionError`; `from_dict_safe` больше не
|
||||
глотает ошибку старой/неизвестной версии.
|
||||
- `generator/src/clickstream_generator/airflow_control.py` —
|
||||
`target_dag_trigger_error()` покрывает три ветки pause-check без импорта
|
||||
Airflow.
|
||||
- `superset/create_dashboard.py` — sync ограничен чартами целевого dashboard.
|
||||
- `docs/course/lessons/00_kafka_intro.md`,
|
||||
`docs/course/lessons/01_kafka_to_clickhouse.md`,
|
||||
`docs/course/lessons/05_monitoring.md` — курс согласован с startup-history,
|
||||
no-live default и consumer lag.
|
||||
|
||||
## Проверки
|
||||
|
||||
- Issue 15: `make generator-test`, `docker compose config --quiet`,
|
||||
`py_compile`, `bash -n`.
|
||||
- Issue 16: `make generator-test`, `docker compose config --quiet`,
|
||||
`py_compile`, `make clean`, `make up`, `make ddl`.
|
||||
- Issue 17: Docker target tests, `make generator-test`, `py_compile`,
|
||||
`bash -n`, `make generated-history-runtime-check`.
|
||||
- Issue 18: doc `rg`, `git diff --check`,
|
||||
`make generated-history-analytics`, `make up`.
|
||||
- Issue 19 / commit `9b0b063`: `make contract-test` — 16 passed;
|
||||
`make generator-test` — 190 passed; `make lint` — passed; `make test` —
|
||||
190 generator tests, 16 contract tests, `docker compose config --quiet`.
|
||||
- Финальный chain review `Gibbs`: initial `CHANGES_REQUESTED`, narrow rerun
|
||||
`APPROVED`.
|
||||
|
||||
## Происхождение ревью
|
||||
|
||||
- 15: gate; task reviewer `Ptolemy` high, code reviewer `Linnaeus` high;
|
||||
оба rerun `APPROVED`.
|
||||
- 16: code reviewer `Laplace` high; primary review found paused-DAG order bug,
|
||||
later reruns `APPROVED`.
|
||||
- 17: code reviewer `Bacon` high; found Superset ownership and live-seam
|
||||
defaults; bounded runtime gate rerun `APPROVED`.
|
||||
- 18: docs/code reviewer `Hume` high; found Prometheus scrape-count drift;
|
||||
rerun `APPROVED`.
|
||||
- Финал: chain reviewer `Gibbs` xhigh; found docs drift around
|
||||
`generated-history-check`; rerun `APPROVED`.
|
||||
- После `9b0b063`: внешний Claude review подтвердил закрытие всех девяти
|
||||
находок и дал `APPROVED`. Reviewer не перезапускал Docker-проверки сам, но
|
||||
сверил код, тесты и документы; фактические прогоны были выполнены
|
||||
координатором.
|
||||
|
||||
## Отклонения процесса
|
||||
|
||||
- Локальный `uv run ... pytest` у координатора падал до pytest из-за
|
||||
`snap-confine` / `cap_dac_override`. Для координаторского gate целевые тесты
|
||||
запускались через Docker-образ `generator:test`. Это вынесено в issue 19.
|
||||
- Первичный runtime gate issue 17 через полный `daily-wave` был остановлен:
|
||||
прогон был активным, но слишком долгим для коммит-гейта. После этого добавлен
|
||||
bounded `make generated-history-runtime-check`.
|
||||
- Несколько стендовых проверок чистили Docker volumes. Это ожидаемо для issue
|
||||
16-18 и зафиксировано в журнале.
|
||||
|
||||
## Что вручную проверить дальше
|
||||
|
||||
- Чистый ручной путь через Airflow UI: `make up`, `make ddl` или `ddl_init`,
|
||||
`airflow dags unpause etl_pipeline`, затем `generator_control` backfill.
|
||||
- Backfill-only путь: `make generated-history-analytics`, затем
|
||||
`CHECK_LIVE_SEAM=0 make generated-history-check`.
|
||||
- Стык backfill/live: `make generated-history-runtime-check`.
|
||||
- Superset: после готового DM открыть dashboard и сверить, что чарты созданы и
|
||||
`Top Countries by Events` читается.
|
||||
- Kafka UI: в уроке 00 должны быть понятны четыре data-топика и служебные
|
||||
`generator_state`, `generator_startup_history_manifest`,
|
||||
`generator_batch_history`.
|
||||
|
||||
## Suggested skills
|
||||
|
||||
- `triage` — если продолжать issue 13: он всё ещё `needs-triage`.
|
||||
- `brainstorm-with-docs` — если перед issue 13 нужно заново согласовать
|
||||
модель доливки истории от слепка.
|
||||
- `coordinator-loop` — только после перевода issue 13 в `ready-for-agent`.
|
||||
- `code-review` — для внешнего прохода по коммитам после ручной проверки.
|
||||
|
||||
## Открытые риски
|
||||
|
||||
- Ручная HITL-проверка после `9b0b063` ещё не выполнена пользователем.
|
||||
- Issue 13 остаётся `needs-triage`: доливка истории от слепка должна опираться
|
||||
на закрытые инварианты 15 и 17.
|
||||
@@ -1,70 +0,0 @@
|
||||
# Handoff: проверка пути менти, диагноз флаки-гейта, задача next-day
|
||||
|
||||
Дата: 2026-07-07 22:34.
|
||||
Жанр: handoff по ADR-0003 после сессии «проверка пути менти + триаж 13/20».
|
||||
|
||||
## Что закрыто
|
||||
|
||||
- Проверка пути менти двумя субагентами (читатель документации на Opus,
|
||||
прогонщик стенда на Sonnet):
|
||||
- Документация: workable-with-friction, четыре мелких находки — все
|
||||
исправлены. Коммит `900e949`.
|
||||
- Стенд с нуля: clean -> generated-history-analytics -> up -> проверки ->
|
||||
Superset (чарты с данными) -> Kafka (4 data-топика + служебные) ->
|
||||
ClickHouse (ODS/DM непустые) — всё прошло, дубликатов ноль.
|
||||
- Единственное падение: `make generated-history-runtime-check` красный
|
||||
через раз — заведена задача 20.
|
||||
- Диагноз задачи 20 (Codex, ключевой факт перепроверен по коду): генератор
|
||||
фактуру на стыке НЕ ломает; корень — гонка остановки live-генератора в
|
||||
самой проверке + seam-SQL, маскирующий непарные строки под «смену фактуры».
|
||||
Детали и направление фикса — в задаче. Коммит `98be722`.
|
||||
- Задача 13 переписана под глагол `next-day` в `generator_control`;
|
||||
оба открытых вопроса закрыты; развилка реализации решена пользователем:
|
||||
**вариант 2 — генерация следующего дня от слепка** (обоснование в задаче).
|
||||
Коммиты `a3ac4b4`, `98be722`; решение развилки — в коммите с этим handoff.
|
||||
- Созданы репо-локальные субагенты `.claude/agents/deep-reasoner.md` (Opus)
|
||||
и `fast-worker.md` (Sonnet); `.gitignore` скрывает локальное в `.claude/`.
|
||||
Коммит `984d6fc`.
|
||||
|
||||
## Состояние трекера
|
||||
|
||||
- `20-flaky-runtime-seam-check.md` — **ready-for-agent**: диагноз есть,
|
||||
направление фикса выбрано (управляемая остановка live после полного flush
|
||||
всех топиков + precheck непарных строк в seam-check). Идти первым.
|
||||
- `13-backfill-top-up-from-snapshot.md` — **ready-for-agent**, blocked by 20.
|
||||
Вариант реализации решён, критерии в задаче.
|
||||
|
||||
## Что дальше
|
||||
|
||||
1. Фикс задачи 20 по конвейеру `/claude-subagent-playbook`: постановка в
|
||||
задаче самодостаточна, свежий адверсарный взгляд на неё до реализации,
|
||||
реализация Кодексом (прямой `codex exec`, не плагин — см. handoff в
|
||||
скилле), два слепых ревью.
|
||||
2. После зелёного стабильного гейта (3+ прогона) — задача 13.
|
||||
3. Ручная HITL-проверка пути менти пользователем всё ещё не сделана
|
||||
(Airflow UI, Superset глазами, Kafka UI) — стенд остался в рабочем
|
||||
состоянии после зелёного runtime-check.
|
||||
|
||||
## Проверки этой сессии
|
||||
|
||||
- `make generated-history-runtime-check`: красный (8/19), затем зелёный —
|
||||
эмпирика флаки в задаче 20; полные логи в session-scratchpad (одноразовые,
|
||||
сводка перенесена в задачу).
|
||||
- Утверждение диагноза про запасную ветку перепроверено по
|
||||
`generation.py:194-209`.
|
||||
- Дерево чистое после каждого коммита; `.claude/settings.local.json`
|
||||
в git не попал.
|
||||
|
||||
## Отклонения процесса
|
||||
|
||||
- Прогонщик стенда дважды засыпал без отслеживаемого фонового процесса и
|
||||
в финале умер, не собрав отчёт, — вердикт собран координатором из логов.
|
||||
- Диагност через плагин codex-rescue: форвардер отчитался «finished» при
|
||||
живом фоновом вызове; результат забран напрямую из output-файла задания.
|
||||
Уроки процесса — в handoff рядом со скиллом claude-subagent-playbook.
|
||||
|
||||
## Suggested skills
|
||||
|
||||
- `claude-subagent-playbook` — для фикса задачи 20 (одна нетривиальная
|
||||
задача: постановка готова, нужен конвейер).
|
||||
- `conventional-commits` — коммиты.
|
||||
@@ -1,82 +0,0 @@
|
||||
# Handoff: задача 13 закрыта конвейером, дальше — задача про расписание и HITL
|
||||
|
||||
Дата: 2026-07-12 23:59.
|
||||
Жанр: handoff по ADR-0003 после сессии «задача 13 (глагол next-day) по
|
||||
/claude-subagent-playbook».
|
||||
|
||||
## Что закрыто
|
||||
|
||||
- **Задача 13 — done.** Полный конвейер плейбука: двойное слепое ревью
|
||||
постановки (оба CHANGES_REQUIRED, 9 решений внесены, коммит `540989d`)
|
||||
-> реализация Codex (`gpt-5.6-sol`, high, тред
|
||||
`019f57d2-ff7b-70d3-8143-3740324309d9`) -> два слепых ревью кода
|
||||
(Codex: CHANGES_REQUIRED 3 MAJOR; Claude: APPROVED_WITH_MINORS) ->
|
||||
триаж в 2 круга + узкий диагноз нулевого стыка -> перепроверки
|
||||
ALL_CLOSED у обоих -> моя приёмка. Коммит `f5dee26`.
|
||||
- Суть решений, диагноз нулевого стыка (естественный ночной провал, не
|
||||
дефект restore) и аргументы отклонений — в самой задаче
|
||||
`.scratch/generator-model-time-startup-history/issues/13-*.md`, здесь
|
||||
не дублируются.
|
||||
- Приёмка своими глазами: `make test` 204+31; `generated-history-chain-check`
|
||||
зелёный (граница 1: crossing=1, граница 2: crossing=0 с явным статусом,
|
||||
непарные — нули); регрессия `generated-history-runtime-check` задачи 20
|
||||
зелёная (19 переходящих визитов). Учебный цикл: DM 322 -> 10 026 ->
|
||||
19 196 за два next-day.
|
||||
|
||||
## Состояние
|
||||
|
||||
- Ветка `feature/data-generator`, дерево чистое после `f5dee26`
|
||||
(+ handoff-коммит следом), запушено в origin.
|
||||
- Стенд поднят, в мире 3 модельных дня (артефакт + два next-day от
|
||||
прогонов исполнителя); live-генератор остановлен.
|
||||
- Модель Codex — `gpt-5.6-sol` (high для реализации/ревью; xhigh не
|
||||
окупается). Перед каждым фоновым запуском — сообщать пользователю, что
|
||||
запускается и какой этап.
|
||||
|
||||
## Что дальше
|
||||
|
||||
1. **Завести задачу про расписание** («имитация жизни»): включение
|
||||
`next-day` по расписанию. Обязана решить: как расписание задаёт
|
||||
`operation=next-day` (дефолт DAG — `backfill`, планового запуска с
|
||||
дефолтом быть не должно) и retention/формат накопительного состояния
|
||||
манифеста (см. отклонение «полная перечитка Kafka» в задаче 13 —
|
||||
оно блокирует её по записи в тикете).
|
||||
2. **Ручная HITL-проверка пути менти** (Airflow UI, Superset глазами,
|
||||
Kafka UI) — переносится пятый handoff подряд; исполнитель задачи 13
|
||||
отметил, что Airflow UI руками не гонял (проводка next-day проверена
|
||||
контрактными тестами и реальными запусками через `run_batch.sh`).
|
||||
3. **Внести уроки в плейбук**: рефлексия по расходу контекста мастера
|
||||
проведена в конце сессии 2026-07-12/13 (см. итоговое сообщение) —
|
||||
согласовать с пользователем и записать в
|
||||
`~/.claude/skills/claude-subagent-playbook/references/lessons.md`.
|
||||
Ключевые кандидаты: ограничить раздел confirmations у ревьюеров
|
||||
(одна строка на пункт); самый большой неконтролируемый расход —
|
||||
эхо всего файла задачи в контекст мастера, когда исполнитель правит
|
||||
файл, который мастер недавно писал сам.
|
||||
|
||||
## Проверки этой сессии
|
||||
|
||||
- `make test`: 204 (генератор) + 31 (контракты корня) — прогнаны мной,
|
||||
исполнителем и ревьюерами независимо.
|
||||
- Стенд: chain-check и runtime-check зелёные (лог приёмки одноразовый в
|
||||
session-scratchpad, сводка — в задаче 13).
|
||||
- Дерево сверялось с baseline после каждого ревью/перепроверки —
|
||||
ревьюеры исходники не трогали.
|
||||
|
||||
## Отклонения процесса
|
||||
|
||||
- Перепроверка Codex принесла новую находку (MAJOR про микросекунды) —
|
||||
это не нарушение узости, штатный случай из prompt-templates.md;
|
||||
закрыта вторым кругом триажа тем же тредом исполнителя.
|
||||
- Требование «громкий отказ на нулевом стыке» из обоих ревью покраснело
|
||||
на честном стенде; решён диагнозом по данным (ветка «естественный
|
||||
провал») и сменой семантики на явный статус — класс «артефакт
|
||||
верификатора», как в задаче 20.
|
||||
|
||||
## Suggested skills
|
||||
|
||||
- `claude-subagent-playbook` — задача про расписание тем же конвейером
|
||||
(постановку писать с нуля — этапы 1–2).
|
||||
- `conventional-commits` — коммиты.
|
||||
- `research` — если для задачи про расписание понадобится фактура по
|
||||
Airflow (params при scheduled runs) — через Context7.
|
||||
@@ -1,103 +0,0 @@
|
||||
# Handoff: ручной HITL пути менти пройден — вырос в набросок редизайна
|
||||
|
||||
Дата: 2026-07-19 21:44.
|
||||
Жанр: handoff по ADR-0003 после сессии «ручная HITL-проверка пути менти»
|
||||
(долг переносился пятый handoff подряд — закрыт).
|
||||
|
||||
## Что сделано
|
||||
|
||||
- **HITL-проверка пути менти пройдена целиком, своими руками через UI.**
|
||||
Чистый стенд (`make clean` + `make up`) -> Airflow UI: `ddl_init` ->
|
||||
`generator_control` `backfill` (профиль `ci`) -> ETL -> `make superset-init`
|
||||
-> дашборд глазами -> `generator_control` `next-day` -> проверка стыка.
|
||||
Каждый шаг сверен по данным (ClickHouse, manifest, chain-check).
|
||||
- **Результат мира:** backfill `[00:00, 06:00)` = 16 054 события; после
|
||||
`next-day` = 110 602 события, визитов 10 228, пользователей 1 726;
|
||||
`boundaries` = три границы, `model_t_end` = `2026-01-02 06:00`.
|
||||
`generated-history-chain-check` — EXIT 0 (стык 06:00: 9 переходящих
|
||||
визитов, непарных 0, однородность подтверждена).
|
||||
- **9 находок + рамочная модель** — в
|
||||
`.scratch/generator-model-time-startup-history/hitl-findings.md`.
|
||||
Половина находок родилась из наблюдений менти. HITL из «проверить, что
|
||||
не сломалось» перерос в **набросок редизайна пути менти**.
|
||||
|
||||
## Ключевые выводы (кратко; подробно — в hitl-findings.md)
|
||||
|
||||
- **Рамочная модель менти:** основной режим — `import` артефакта (база),
|
||||
дальше две ветки от одного состояния: `next-day` (пакетно) и `continue`
|
||||
(живой поток). Это три разных лабораторных. `next-day` и `continue`
|
||||
не схлопывать. Подтверждено `launch.py:117-137`.
|
||||
- **F7 + замер:** опыт на 6h беден; нужен готовый артефакт из файла.
|
||||
Артефакт 6h = 49 МБ; `xz -9e` -> 1,1 МБ (48x, 13,5 с). На 3 дня ~13 МБ
|
||||
— кладётся в обычный git. Паттерн-образец: `airflow-greenplum-solution`
|
||||
(`bookings/seed/demo.sql.xz`).
|
||||
- **Решение менти:** целевой стартовый мир — **3 дня на `daily-wave`**
|
||||
(обсуждаемо). На `ci` три дня плоские — волну даёт `daily-wave`.
|
||||
- **F8:** два профиля путают. Свести к одному учебному (волна, ×60);
|
||||
`ci` (×1) — служебный для тестов. ×60 оправдан live-лабой (`continue`).
|
||||
- **F9:** `next-day` растёт O(N²) из-за полной перечитки Kafka для
|
||||
счётчиков (`service.py:591`). Параллелить не то (ломает детерминизм);
|
||||
правильно — инкрементальные счётчики (O(N), снимает риск OOM). Это и
|
||||
есть решение «новый формат состояния manifest», блокирующее расписание.
|
||||
- **F1, F5 (баги UI):** форма `generator_control` держит необязательные
|
||||
поля обязательными (`type="string"` без `null`); Airflow и Superset
|
||||
быстро разлогинивают (ротацию секрета исключил, корень TBD).
|
||||
|
||||
## Состояние
|
||||
|
||||
- Ветка `feature/data-generator`. После этого handoff в дереве останутся:
|
||||
`hitl-findings.md` + этот handoff (коммитятся), плюс **не коммитить**
|
||||
`data/ci_backfill.json` (49 МБ, побочный от backfill; `.gitignore` его
|
||||
не покрывает — риск, см. ниже).
|
||||
- Стенд **оставлен поднятым** по просьбе пользователя; в мире 1,25 суток
|
||||
(профиль `ci`), live-генератор не запущен. Выросший мир можно смотреть
|
||||
в Superset (dashboard id 1).
|
||||
|
||||
## Что дальше
|
||||
|
||||
1. **Разложить находки в постановки по плейбуку** (этапы 1-2, двойное
|
||||
слепое ревью). Ориентировочно ~4 задачи (номера 21+ в `issues/`):
|
||||
- **Ядро:** эталонный 3-дневный артефакт (`daily-wave`) как база
|
||||
менти через `import`; формат/сжатие (`xz`, нужен ли `raw_topics`);
|
||||
место хранения (git после отладки сида). Снимает F7.
|
||||
- **Профиль:** один учебный профиль, `ci` -> служебный тестовый.
|
||||
Перед слиянием проверить, не зависит ли live-тест от скорости ×1
|
||||
(F8).
|
||||
- **Расписание + retention:** беспараметрный DAG `next-day` (F1/F3),
|
||||
`schedule`, инкрементальные счётчики manifest (F9/F6). Это одна
|
||||
связка — их корень общий.
|
||||
- **Баг-фиксы:** F1 (форма) и F5 (разлогин); F4 (JS-баг Grid) низкий.
|
||||
2. **Три режима -> свои уроки/лабы** — вход в учебный контент
|
||||
(`docs/course/`). Под каждую ветку отдельная лаба: `next-day`
|
||||
(пакетная инкрементальная обработка) и `continue` (потоковый приём);
|
||||
общая база `import` — их совместное начало. Отдельно от
|
||||
инфраструктурных задач.
|
||||
3. **Мелочь по гигиене:** `data/*.json` не покрыт `.gitignore` —
|
||||
побочные артефакты backfill (49 МБ) рискуют попасть в коммит. Решить:
|
||||
правило в `.gitignore` или чистить артефакты после прогонов.
|
||||
|
||||
## Проверки этой сессии
|
||||
|
||||
- `ddl_init`: 4 слоя созданы (stg 12 / ods 8 / dds 2 / dm 6 таблиц).
|
||||
- Форма мира после backfill: пирамида 445 < 1516 < 16 054, интервал
|
||||
`[00:00, 06:00)` точный.
|
||||
- После `next-day`: 3 границы в manifest, мир до `2026-01-02 06:00`.
|
||||
- `generated-history-chain-check`: EXIT 0.
|
||||
- Длительность `next-day` (метаданные Airflow): задача `run_next_day`
|
||||
638 с (~10,6 мин); ETL `trigger_etl` 30 с — узкое место в генерации.
|
||||
- Замер сжатия: `xz -9e` 48x за 13,5 с; gzip -9 17x.
|
||||
|
||||
## Отклонения процесса
|
||||
|
||||
- Ревью субагентами не запускали: пользователь просил «свежий взгляд»,
|
||||
что по договорённости = без субагентов. Проверка проведена мной руками.
|
||||
- Обход бага F1: форму backfill/next-day заполняли значениями профиля
|
||||
`ci` целиком (пустые необязательные поля UI не пропускает).
|
||||
|
||||
## Suggested skills
|
||||
|
||||
- `claude-subagent-playbook` — разложить находки в постановки тем же
|
||||
конвейером (этапы 1-2 с нуля).
|
||||
- `conventional-commits` — коммиты.
|
||||
- `research` / Context7 — для задачи про профиль/форму (Airflow Param
|
||||
`type=["null","string"]`) и про формат артефакта.
|
||||
@@ -0,0 +1,89 @@
|
||||
# Handoff: старт редизайна пути менти — спека и пилот GitHub Issues
|
||||
|
||||
Дата: 2026-07-19 22:29.
|
||||
Жанр: handoff по ADR-0003 — точка входа в новую фичу на чистой ветке.
|
||||
|
||||
## Контекст
|
||||
|
||||
- `feature/data-generator` (146 коммитов) влита в main (`0e312b3`) и
|
||||
запушена. Перед слиянием закрыта задача 21: баг F1 (необязательные поля
|
||||
формы `generator_control` требовались как обязательные) починен через
|
||||
`Param(None, type=["null", "string"])`, `.gitignore` покрыл артефакты
|
||||
`data/*.json`, доки (`ARCHITECTURE.md`, `REPO_MAP.md`) догнали код.
|
||||
`make test` (205 + 31) и `make lint` зелёные.
|
||||
- `.scratch` очищен целиком (решение пользователя 2026-07-19): задачи
|
||||
01–21, PRD, журналы и старые handoff'ы — одноразовые материалы, всё
|
||||
долговечное перенесено в `docs/` (ADR 0004–0006, спеки, runbook
|
||||
`startup-history`). История доступна в git: см. состояние на `0e312b3`,
|
||||
ключевой файл находок —
|
||||
`.scratch/generator-model-time-startup-history/hitl-findings.md@0e312b3`.
|
||||
|
||||
## Направление работ: редизайн пути менти
|
||||
|
||||
Рамочная модель (из ручного HITL 2026-07-19, подтверждена по
|
||||
`launch.py`): основной режим менти — **`import` готового артефакта**
|
||||
(база), от одного восстановленного состояния две ветки-лабы:
|
||||
**`next-day`** (пакетно добавить сутки) и **`continue`** (живой поток,
|
||||
оправдывает скорость ×60). `backfill` в целевой модели — инструмент
|
||||
мейнтейнера для сборки артефакта, не первый шаг менти.
|
||||
|
||||
Ориентировочно 4 задачи:
|
||||
|
||||
1. **Ядро: эталонный 3-дневный артефакт** на профиле `daily-wave` как
|
||||
база менти через `import`. Факты: артефакт 6h = 49 МБ raw; `xz -9e`
|
||||
жмёт 48× (1,1 МБ за 13,5 с); 3 дня ≈ 13 МБ сжатого — кладётся в
|
||||
обычный git. Паттерн-образец: `airflow-greenplum-solution`
|
||||
(`bookings/seed/demo.sql.xz`). Открыто: нужен ли артефакту
|
||||
`raw_topics` или хватит компактного `state`.
|
||||
2. **Один учебный профиль**: `daily-wave` (волна, ×60) — учебный,
|
||||
`ci` (×1, плоский) — служебный для тестов; форма не должна
|
||||
подсовывать `ci` первым. Перед слиянием проверить, не зависит ли
|
||||
runtime-seam-тест от скорости ×1.
|
||||
3. **Расписание + инкремент**: беспараметрный DAG `next-day` (удобство
|
||||
менти и пригодность к `schedule`) + инкрементальные счётчики manifest:
|
||||
сейчас `next-day` перечитывает всю Kafka-историю с нуля — O(N²) по
|
||||
дням и рост RAM (риск OOM); замер: день 2 = 638 с, узкое место —
|
||||
генерация+пересчёт, не ETL (30 с). Параллелить нельзя (детерминизм),
|
||||
правильный рычаг — накопленное состояние счётчиков в manifest/state.
|
||||
4. **Баг-фиксы**: F5 — быстрый разлогин Airflow и Superset (ротация
|
||||
секрета исключена; копать время жизни сессии/cookie); F4 — JS-ошибка
|
||||
авто-refresh в Airflow Grid (косметика, низкий приоритет).
|
||||
|
||||
Отдельная линия (после инфраструктуры): три режима → свои лабы в
|
||||
`docs/course/` (`import` — общая база; `next-day` — пакетная
|
||||
инкрементальная обработка; `continue` — потоковый приём).
|
||||
|
||||
## Пилот GitHub Issues (решение пользователя 2026-07-19)
|
||||
|
||||
Новый процесс для этой фичи:
|
||||
|
||||
- Спека редизайна — файлом в репозитории (материал — hitl-findings из
|
||||
истории git, см. выше).
|
||||
- Тонкий корневой issue на GitHub со ссылкой на спеку и чекбоксами на
|
||||
дочерние issues; дочерние — полноценные самодостаточные постановки.
|
||||
- Triage-метки — пять канонических ролей из `docs/agents/triage-labels.md`
|
||||
как настоящие метки GitHub.
|
||||
- В том же заходе поправить контракт: AGENTS.md и
|
||||
`docs/agents/issue-tracker.md` сейчас говорят «GitHub Issues не
|
||||
используются» — заменить на правила пилота. Старые задачи не
|
||||
мигрировать (архив в истории git).
|
||||
|
||||
## Что дальше (порядок)
|
||||
|
||||
1. Спека редизайна пути менти в `docs/specs/` (из hitl-findings).
|
||||
2. Обновить контракт трекера (AGENTS.md, `docs/agents/issue-tracker.md`).
|
||||
3. Корневой issue + 4 дочерних на GitHub, метки.
|
||||
4. Работа по задачам конвейером `claude-subagent-playbook`.
|
||||
|
||||
## Состояние стенда
|
||||
|
||||
Стенд поднят: мир 1,25 суток на профиле `ci`, `model_t_end` =
|
||||
`2026-01-02 06:00`, live-генератор не запущен, дашборд — Superset id 1.
|
||||
Для новой работы, скорее всего, понадобится чистый прогон (`make clean`).
|
||||
|
||||
## Suggested skills
|
||||
|
||||
- `claude-subagent-playbook` — конвейер задач.
|
||||
- `conventional-commits` — коммиты.
|
||||
- `research` / Context7 — фактура для спеки (формат артефакта, Airflow
|
||||
`schedule`).
|
||||
Reference in New Issue
Block a user