# Слепок и его доставка Резолюция развилки [«Генератор слепков: где живёт и чем связан с событиями»](https://git.dementev.space/ddmitry/clickstream-data-platform/issues/71). **Запуск.** Третья команда того же пакета — `snapshot --day D [--days N]`, свой приёмник, топик `orders`. Два источника — два запуска: трекер и бэкенд видны глазами как два производителя, каждый со своим топиком. Один прогон с двумя выходами отклонён: экономии он не даёт (со сдвигом отправки окно слепка и сыгранный день не пересекаются вовсе), а правило «приёмник выбирается тем, что для него назвали» ломает. Отклонены также: *отдельный пакет и образ* — библиотека на двоих ради одной команды; *генератор пишет слепок файлом, в топик льёт даг* — второй путь доставки и второй сериализатор; *слепок едет топиком `hits`* — убивает два режима приёма. **Сборка окна.** Слепок дня D несёт заказы, рождённые в дни D−6…D, и собирается переигровкой этих семи дней: заказы дня — производная всей воронки дня, дешёвого пути к ним нет. Цена — семь проигрышей дня (~14 с) на слепок; у начала оси окно усекается само. Отклонено: *кэш заказов на томе* — состояние между прогонами; *окно держит хранилище* — топик перестаёт нести слепок; *K = 1* — это страховочный срез 1 мастер-спеки, он в резерве. **Отправка.** Слепок **снимается на границе суток, а отправляется следующим прогоном**: даг, играющий день D, отправляет слепок дня D−1 — ночная выгрузка бэкенда за вчера, как в бою. Содержимое слепка — чистая функция (зерно, D), от момента отправки не зависит. Следствия: - живой день перестаёт быть особым случаем: своего дага у него нет, слепок живого дня отправит следующий прогон; - пропущенный день лечится окном: слепок переснимается и даёт те же байты, отдельного механизма самовосстановления нет; - покупки текущего дня в сверке всегда `awaiting_order` — сюжет «вчера не сходилось, сегодня сошлось», ради которого мастер-спека этот класс завела; - цена — один лишний проигрыш дня на прогон (окно и сыгранный день не пересекаются, проигрышей всегда восемь). На старте оси дня −1 нет, поэтому прогон дня 0 не отправляет ничего; первый слепок — дня 0 — уезжает прогоном дня 1 ([исследование формата](../../research/2026-08-16-order-snapshot-wire-format.md)). **Случайность.** Судьбу заказов бросает свой подпоток, ветвящийся по дню рождения заказа: слепок несёт семь дней рождения сразу, и судьбу каждого заказа обязан читать из его собственного дня. Вся судьба решается при рождении, поэтому слепок любого дня — чтение готовой судьбы, а не накопление состояния. Отклонено: *дописывать броски в конец `COMMERCE`* — правка заказа и правка торгового поведения стали бы одним рычагом; *бросать состояние в подпотоке дня слепка* — траектория заказа зависела бы от того, какие слепки снимали. ## Запись на проводе Контракт провода — на заказ один JSON-документ: деньги строками с двумя знаками, времена RFC 3339 в UTC с миллисекундами, `items` обычным массивом — целиком описан мастер-спекой (раздел 2); основания, отклонённые варианты и проверка разбора — в [исследовании формата](../../research/2026-08-16-order-snapshot-wire-format.md) (резолюция развилки [«Форма записи слепка на проводе»](https://git.dementev.space/ddmitry/clickstream-data-platform/issues/81)). Сверх контракта здесь живёт одно правило: **порядок строк внутри слепка — порядок рождения заказов, он же возрастание `order_id`**. Детерминизм даёт его даром, а хешу слепка в описи нужен именно названный порядок.