- Зачем:
- спека отвечает «почему», а жанра «как пройти устройство по коду»
не было (#48); черновик в generator/README.md ждал выверки.
- Что:
- новый набор docs/architecture/generator/: индекс с целевой картиной
и mermaid-схемой плюс шесть поддокументов по темам тикета.
- демо-модуль и цель make demo: канонический D0, все стадии цепочки
на одном экране; тест-сторож проверяет стадии без прибитых чисел.
- раздел «Как это работает» в generator/README.md сжат до ссылки
на путеводитель, черновая врезка снята.
- Проверка:
- из generator/: make lint, make typecheck, make test (430 passed),
make demo; два слепых ревью и узкая перепроверка — находки закрыты.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
62 lines
3.9 KiB
Markdown
62 lines
3.9 KiB
Markdown
# Дерево зерен и порядок бросков
|
||
|
||
Этот документ отвечает на вопрос, почему место подпотока стабильно, а порядок
|
||
бросков внутри него менять нельзя.
|
||
|
||
## Два порядка
|
||
|
||
[`seeds.cohort_stream`](../../../generator/src/clickstream_generator/seeds.py)
|
||
и [`seeds.day_stream`](../../../generator/src/clickstream_generator/seeds.py)
|
||
находят ветвь по позиции `SeedSequence(entropy, spawn_key)`. Поэтому результат
|
||
ветви не зависит от того, какую соседнюю ветвь вычислили раньше.
|
||
|
||
Внутри найденной ветви живет один `Generator`. Каждый его вызов забирает
|
||
следующие значения. Поэтому порядок вызовов меняет результат: прежний
|
||
пятый бросок после вставки становится шестым и достается другому свойству
|
||
мира.
|
||
|
||
Дерево целиком описано в модуле
|
||
[`seeds`](../../../generator/src/clickstream_generator/seeds.py), а
|
||
[`seeds.Component`](../../../generator/src/clickstream_generator/seeds.py)
|
||
задает его нижний уровень — четыре подпотока дня:
|
||
|
||
```text
|
||
корневое зерно
|
||
├── состав мира
|
||
│ ├── ось событий → номер дня → когорта
|
||
│ └── предыстория → глубина → когорта до D0
|
||
└── дни
|
||
└── номер дня
|
||
├── TRAFFIC
|
||
├── COMMERCE
|
||
├── ORDERS
|
||
└── LATECOMERS — место будущей событийной стороны
|
||
```
|
||
|
||
Отрицательному дню нельзя отдать отрицательную позицию, поэтому предыстория
|
||
получила отдельную ветвь. Компоненты дня тоже занимают позиции, а не получают
|
||
зерна в порядке запуска.
|
||
|
||
## Что ломает вставка
|
||
|
||
Новый бросок в середине функции сдвигает все последующие значения этого
|
||
подпотока. Код продолжает работать, но тем же свойствам достается другая
|
||
случайность. Соседние подпотоки остаются прежними, а измененная часть
|
||
канонического мира проявляется в описи и побайтовом сравнении.
|
||
|
||
Какое обещание воспроизводимости это защищает, записано в
|
||
[спеке генератора](../../specs/2026-08-01-generator.md), раздел 2. Здесь важно
|
||
различать два свойства: `SeedSequence` стабилизирует адрес ветви, но порядок
|
||
бросков внутри `Generator` стабилизирует только сам код.
|
||
|
||
## Броски последними
|
||
|
||
Новое свойство продолжает существующий подпоток после прежних бросков. Такой
|
||
бросок не отнимает значения у уже рассчитанных свойств. В
|
||
[`plan.cohort`](../../../generator/src/clickstream_generator/plan.py) паспорт
|
||
куки был дописан после состава и назначенных заказов, а личность человека —
|
||
после паспорта. Поэтому прежние ряды остались прежними.
|
||
|
||
Почему паспорт вообще принадлежит этой ветви, разобрано отдельно в
|
||
[документе о паспорте куки](cookie-passport.md).
|