- Зачем:
- ревью нашло два места, где код и документы говорили неправду, и
несколько мест, где имена или комментарии вводили в заблуждение.
- Что:
- обещание докстроки `seeds.py` подкреплено тестом: адрес в дереве
даёт тот же подпоток, что цепочка `spawn`.
- в тесте гарантии пар убран сторож-тавтология, вместо него проверка,
что заказы назначены с двух разных кук.
- `Cohort.visitors_on` — «кто пришёл в день D» спрашивается у когорты,
а не собирается снаружи из четырёх её массивов.
- имена: `CLIENT_ID_LIMIT`, `_RETURN_*_CUMULATIVE`, `first_of_day`,
`WEEKLY_PROFILE_PERCENT` — профиль недели один на весь мир, по нему
же пойдёт трафик дня-функции (#39).
- спека: в дерево зёрен внесена ветвь предыстории; окно активности —
от первого визита человека, общее на обе куки (иначе загляд назад
ленивой формы удваивается); оценка накопленной аудитории больше не
спорит с измерением.
- CONTEXT.md: «подпоток» и «конфигурация мира».
- Проверка:
- make test (296), make lint, make typecheck; мутации перепроверены
после переноса среза дня в `Cohort`.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
- Зачем:
- тикет #38: состав мира должен быть чистой функцией зерна, а счётчики
будущего манифеста — известны до генерации хоть одного события.
- Что:
- `world.py` — конфигурация мира одним модулем чистых данных: приток,
недельная волна, профиль возвратов, доли покупателей и пар, D0.
- `seeds.py` — иерархия подпотоков на `SeedSequence`: состав мира
(ось и предыстория) отдельно от дней и их компонентов.
- `plan.py` — ленивый план состава: когорта дня, аудитория дня из
окна возвратов, гарантированные заказы пар, счётчики горизонта.
Случайность — только целыми числами.
- спека, раздел 1: вторая кука пары рождается по затухающему профилю
возвратов; раздел 9: измеренные числа канонического мира, оценка
накопленной аудитории поправлена с ≈60 до 68 тыс.
- CONTEXT.md: термин «когорта дня»; README генератора — новые модули.
- Проверка:
- make test (295 тестов), make lint, make typecheck;
- тесты проверены мутациями: 12 подмен в плане и конфигурации,
каждая роняет ровно свой тест.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
- Зачем:
- тикет #38 требует решить и внести в спеку генератора числа притока,
D0 и формат конфигурации мира до реализации плана состава.
- Что:
- раздел 1 спеки: ленивый план по когортам дня, предыстория с полкой
от D0, гарантия двухкуковых пар назначенными заказами (единица —
человек), пять отклонённых вариантов с доводами.
- раздел 9: приток 3 800 кук/день, окно активности 90 дней (решение
владельца), доля покупателей 5% людей, D0 = 2026-06-01,
конфигурация мира — модуль чистых данных; шапка Proposed → Accepted.
- CONTEXT.md: термины «план состава», «приток», «хвост возвратов»,
«предыстория»; «состав мира» уточнён, словарь очищен от решений.
- Проверка:
- двойное слепое ревью правок (Codex + Claude), все 20 находок
закрыты; арифметика чисел пересчитана ревьюерами независимо.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
- Зачем:
- запрет был лишним: dds.v_event по разделу 7 мастер-спеки эти имена и
берёт, так что синоним не всегда ошибка.
- Что:
- в статье «Нормализованное имя» снята строка _Избегать_; различие
с именем атрибута в модели данных осталось в теле статьи.
- Проверка:
- вычитка.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
- Зачем:
- контракт вёл себя как хозяин чужого слоя: поле называлось dds_name, в
описании стоял столбец «Имя в DDS», а два теста прибивали имена
гвоздями. Спека же задала вид имени (snake_case), а не список: имена
атрибутов складывает модель данных DDS, и решать это не трекеру.
- Что:
- поле контракта и столбец описания стали нормализованным именем: имя
источника в нашем стиле. В описании и в докстринге сказано прямо, что
слой DDS называет атрибуты по своей модели.
- сняты оба теста на имена — копия имён DDS и конспект состава по
мастер-спеке. Они не проверяли верность имени, только неизменность, а
неизменность и так сторожит пересборка описания: молчаливой правки
контракта не бывает, она всплывает диффом документа.
- остались проверки формы: 47 колонок, уникальность, стили имён,
заполненность, согласие типов numpy и ClickHouse, порядок групп.
- спека генератора (раздел 3) и CONTEXT.md согласованы тем же
коммитом: уточнение внесено как расхождение, найденное при исполнении.
- Проверка:
- make test (248 тестов), make lint, make config-test;
- make docs, затем git diff --exit-code docs/ — пусто.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
- Зачем:
- этап 2 начинается с формы: контракт схемы — источник истины и для
генерации событий, и для DDL хранилища, а имена пакета и модулей
задают границы всем следующим тикетам этапа.
- Что:
- заведён uv-проект generator/ (pyproject.toml и uv.lock в git; numpy,
pytest и ruff), пакет clickstream_generator.
- schema.py — контракт: чистые данные о 47 колонках выгрузки (имя
Метрики, тип ClickHouse, тип numpy, имя для DDS, группа); порядок
несёт сам кортеж COLUMNS, отдельного поля с номером нет намеренно.
- schema_doc.py собирает из контракта описание выгрузки
docs/formats/clickstream-event.md — по нему пишется сторона
хранилища; документ руками не правится.
- тесты: инварианты контракта (состав, уникальность, заполненность,
согласие типов и порядок групп) и свежесть описания выгрузки.
- цели make lint, make test и make docs; README, AGENTS.md и
CONTEXT.md дополнены генератором, форматами и словарной статьёй.
- Проверка:
- make test (248 тестов), make lint, make config-test;
- make docs, затем git diff --exit-code docs/ — пусто.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
- Зачем:
- владелец сознательно вывел DWH из списка избегаемых (синоним
хранилища), а правка по холодному ревью вернула его по старому
комментарию тикета #32 — откат к воле владельца.
- Что:
- в статье «Хранилище» список «_Избегать_» снова: склад, склад данных.
- Проверка:
- вычитка CONTEXT.md.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
- Зачем:
- холодное ревью (Fable, свежая сессия) нашло невыполненный хвост
тикета #32 и места, где доводы резолюций сжались до непонятности.
- Что:
- мастер-спека 1.1: «склад» заменён на «хранилище» (хвост #32);
CONTEXT.md: DWH в избегаемых, отдельная статья «Пакетный режим».
- спека: восстановлены доводы «на маке и в WSL тоже» и «менти упрётся
в красный чек манифеста»; обещания про diff привязаны к манифесту;
темп ×60 и расчёт порога согласованы с числами разделов; заголовок
притока честен про затухание; выход за мандат оговорён в «Зачем».
- раздел 9: добавлены числа притока и календарная дата-константа D0;
заметка исследования: у Faker единицы «значений/с», не «строк/с».
- Проверка:
- вычитка; решения развилок не пересматриваются, правки текстовые.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
- Зачем:
- вычитка спеки на приёмке нашла дыру: состав мира читался как
замкнутая труппа без новых посетителей — неправдоподобный магазин.
- Что:
- раздел 1: состав не замкнут — план задаёт календарь появления кук,
доля одноразовых высока; приток — часть плана, не мутация.
- раздел 6: «Faker» ослаблен до «посточные фейкеры (Faker, mimesis)»,
выбор библиотеки — этапу 2; там же оговорка про таблицы-литералы.
- раздел 9: к интерфейсу запуска добавлены вопросы «кто зовёт
генератор (даги world_init/next_day)» и «в каком контейнере живёт».
- CONTEXT.md: в «Состав мира» добавлен календарь появления.
- Проверка:
- вычитка; правки точечные, решения развилок не пересматриваются.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
- Зачем:
- этап 2 нельзя нарезать на тикеты без единой картины генератора,
а решения четырёх развилок карты #26 жили только в тикетах трекера.
- Что:
- новая спека docs/specs/2026-08-01-generator.md: функциональный мир,
детерминизм до байта (SeedSequence сверен через Context7), контракт
схемы, канонический сериализатор, числа и порог производительности;
отклонённые варианты записаны с доводами.
- мастер-спека согласована тем же коммитом: 1.4 — data contract вместо
автогенерации DDL, 8 — в git только манифест, 11 — числа вместо
«зафиксировать требования»; мелкие согласования в 7 и 9.
- CONTEXT.md пополнен терминами модели мира и вывода генератора.
- Проверка:
- вычитка; относительные ссылки спек указывают на существующие файлы
в docs/specs/ и docs/research/.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>