Commit Graph
4 Commits
Author SHA1 Message Date
ddadminandClaude Opus 5 b2fcc7e593 feat(generator): заказы дня — проекция покупок с деньгами магазина
- Зачем:
  - тикет #90: второй источник должен смотреть на торговую половину дня
    глазами бэкенда — заказ есть проекция покупки, а не второе порождение;
    учебный результат — два источника согласованы по построению, а не
    сверкой.
- Что:
  - `commerce` отдаёт вторым выходом покупки дня: номер заказа, корзину,
    выручку клиента, промокод и человека за кукой; новых бросков в
    подпоток `COMMERCE` не добавилось, события дня не сдвинулись.
  - заведена заказная сторона: подпоток `ORDERS` на позиции 2 дерева зерна
    (прежнее мёртвое имя `DISCREPANCIES`), ветвление — по дню рождения
    заказа; `LATECOMERS` не тронут, его наполнит этап 6.
  - новый модуль `orders.py`: деньги заказа целыми копейками —
    `items_total` из корзины, `discount` по таблице «код → скидка»
    (округление вниз), `delivery` броском по таблице весов на полную длину
    дня, `total` = `items_total` − `discount` + `delivery`.
  - план состава завёл `person_id` — последним броском когорты, после
    паспортов: вторая кука пары повторяет ID своего человека, заказ
    показывает его как `user_id`, в событие Метрики он не попадает.
  - `world`: окно изменяемости `ORDER_WINDOW_DAYS` = 7 рядом с D0 и поясом,
    черновая таблица стоимости доставки.
  - слепок дня в тестах сторожит обе половины: заказы сравниваются наравне
    с потоком событий.
  - доки: имя подпотока заказной стороны и состав денег заказа записаны в
    `docs/architecture/orders`, README генератора знает про новый модуль.
- Проверка:
  - из `generator/`: make lint, make typecheck, make test (417 тестов);
    в корне — make lint.
  - опись мира не покраснела: байты восьми дней те же, заказная сторона
    события не сдвинула.

Closes #90

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-18 12:30:13 +03:00
ddadminandClaude Opus 5 d17bd4e876 fix(generator): правки по линии ревью Кодекса — зёрна, словарь, сторожа
- Зачем:
  - третья линия ревью (Кодекс, другое семейство моделей) нашла дыру в
    стороже неизменности когорты, отставший словарь и тест, который
    сторожил не тот адрес дерева зёрен.
- Что:
  - когорта отдаётся видом на замороженный массив: флаг только для
    чтения вызывающий мог снять и испортить память, которой пользуются
    все дни окна. Граница защиты названа в докстроке — от случайности,
    не от умысла.
  - CONTEXT.md и комментарий `RETURN_TAIL_DAYS`: окно активности — от
    первого визита человека, общее на обе куки (спека это уже говорила,
    словарь отстал).
  - сторож предыстории сверял день −N с днём N, а сталкиваются −N и
    N−1; тем же классом слепоты страдали сторожа независимости состава
    и дня и различия компонентов — все три переписаны на сверку со всем
    куском адресов, куда подпоток мог бы попасть.
- Проверка:
  - make test (297), make lint, make typecheck;
  - батарея из 17 мутантов по plan/world/seeds — выживших нет; гоняется
    с PYTHONDONTWRITEBYTECODE=1: цикл правки и отката внутри одной
    секунды оставлял устаревший .pyc, и тесты шли по старому байт-коду.
- Отклонено с доводом:
  - перепроверка настаивала, что сторож неизменности не закрыт: через
    `.base` вида владелец данных размораживается. Верно фактически, но
    закрывающего состояния у находки нет — владелец памяти в numpy
    размораживается всегда, а копия когорты на каждый вызов меняет 2 мс
    на 16 МиБ копирования и убивает смысл запоминания.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-02 13:13:41 +03:00
ddadminandClaude Opus 5 2502f906a8 fix(generator): правки по двум линиям ревью плана состава
- Зачем:
  - ревью нашло два места, где код и документы говорили неправду, и
    несколько мест, где имена или комментарии вводили в заблуждение.
- Что:
  - обещание докстроки `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>
2026-08-02 12:33:27 +03:00
ddadminandClaude Opus 5 abac6afe18 feat(generator): план состава мира — зерно, приток, двухкуковые пары
- Зачем:
  - тикет #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>
2026-08-02 12:20:48 +03:00