Зачем: читателю ступеней 1–4 нужно проследить выбор дней, расчет строки
и публикацию результата без расшифровки метафор.
Что: согласованы справочники DM, сессий, ETL и два раздела хранилища
с комментариями шести SQL-примеров. Уточнены ограничения повторного
запуска и выбора атрибутов при равном времени событий.
Проверка: make lint, git diff --check, локальные Markdown-ссылки и якоря.
SQL без комментариев совпадает; AST Python без строк документации совпадает.
Исторические разделы и материалы вне границ задачи сохранены.
Refs: #249
- Зачем:
- справочники читает человек со стороны, а «пульт мира», «опись мира»,
«работник» и «сырьё» звучали шуткой или калькой времён разработки
(тикет #214, выбор владельца).
- Что:
- CONTEXT.md: статьи «Паспорт мира», «Даги модельного времени»,
«Шаговый даг», «Сырые данные», старые слова в строках «Избегать»;
пометки в ADR 0005, 0008, 0009 без переписывания решений.
- замены по README, справочникам, путеводителю, лабам, спекам,
комментариям дагов и SQL, тегу дага и панели Grafana; имена в коде
не тронуты.
- world.md и stand.md: 35 находок вычитки внесены, регистр выровнен.
- Проверка:
- make config-test; make lint в корне и в generator/; make test в
generator/ (437 passed); скрипт ссылок из #212 пуст; grep старых
слов вне ADR, research и CONTEXT.md пуст.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014QBCtU38qSHg5DvgtnKXcW
- Зачем:
- параллельный DQ выгружал деловые ключи в Python и исчерпывал 640 МиБ планировщика.
- Что:
- четыре сверки агрегируют дневные итоги и ограниченную диагностику в ClickHouse.
- коробка планировщика поднята до 1,5 ГиБ, локальные пределы задач удалены.
- измерения и граница между SQL и Python записаны в документации.
- Проверка:
- make lint, make config-test, make smoke, make check-clickhouse, make check-services.
- полный etl_pipeline, красный и восстановительный прогоны dq_check.
- Зачем:
- конвейеру нужна публикуемая сводка текущего качества с красным завершением при нарушении договоров.
- Что:
- добавлены DDL, публичное представление и пять сверок на естественном деловом зерне.
- даг dq_check встроен после DM и публикует полные дневные партиции до именованных утверждений.
- параллелизм DDS, DM и DQ приведён к измеренному лимиту памяти планировщика.
- Проверка:
- make lint; make config-test; make rebuild-storage.
- make smoke; make check-clickhouse; make check-services.
- три семейства проверок покрашены искусственными расхождениями и восстановлены повторным полным прогоном.
- Зачем:
- верхние смещения можно получить тем же административным клиентом без одноразового Consumer и фиктивной группы.
- Что:
- чтение хвоста переведено на AdminClient.list_offsets с OffsetSpec.latest.
- назначение system.one названо рядом с запросом, а документация и запись проверок сокращены и переставлены по смыслу.
- Проверка:
- make config-test; make lint.
- живые проверки готового и отсутствующего разделов Kafka; полный etl_pipeline.
Зачем:
- Один запуск должен одинаково работать из жизненного цикла, вручную после разгона и повторно после отказа.
Что:
- Добавлена последовательная сцепка DDS и DM с ожиданием каждого слоя.
- DDS дожидается смещений Kafka и очереди доставки ClickHouse за общий срок.
- ETL встроен в создание мира и живой день; документация приведена к новому графу.
Проверка:
- make config-test; make lint.
- make smoke: 21/21; make check-clickhouse: 10/10; make check-services: 7/7.
- make rebuild-storage, живой и пакетный дни, искусственный отказ и ручное восстановление ETL.
- Зачем:
- реализованы требования issue #153 к мосту между кукой и пользователем.
- Что:
- добавлены физическая карта, точное представление и полный пересчёт через GLOBAL JOIN.
- задача identity_map поставлена после сборки заказов в dds_transform.
- устройство и живые проверки карты записаны в документации хранилища.
- Проверка:
- make lint, make smoke, make check-clickhouse, make check-services.
- три запуска dds_transform: 4770 физических строк и 1590 уникальных пар в _v.
- Зачем:
- ярлык snapshot_date выжившей строки доставался жребием, а объём
пересборки DDS держался на константе окна с двумя несверяемыми копиями
(ADR 0014, развилка #163).
- Что:
- ods.order_rep переведена на ReplacingMergeTree(snapshot_date): выживает
строка позднейшего слепка, ярлык стал правдивым.
- order_scope.sql выводит окно из дней последнего слепка; ORDER_WINDOW_DAYS
и параметр window_days сняты со стенда, мёртвая защита краем источника
убрана.
- документы и комментарии SQL приведены к ADR 0014: роль ODS, условие
«одна дата — один слепок», объём прогона и слепые пятна конвейера.
- Проверка:
- make lint; make rebuild-storage, затем make smoke, make check-clickhouse,
make check-services — зелёные.
- после двух слепков snapshot_date всех 1917 строк ods.order_v равен
последнему слепку заказа, расхождений ноль; деловые поля построчно
совпали с эталоном argMax по updated_at из сырья.
- dds_transform без K: первый прогон 06-01…06-07, после нового дня мира
06-02…06-08, повтор прогона содержимого не изменил.
Closes#165
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Зачем:
- Дать слою расчётную сущность, которой в потоке нет: стенд режет визиты сам,
а VisitID генератора остаётся эталоном самопроверки.
- Отделить прожитый день от живого — иначе визит, начатый в 23:50, замёрз бы
обрезанным навсегда: пересобирать замёрзший день слой не станет.
Что:
- Добавлены dds.session_rep/_dist, двойник-донор dds.session_stage_rep/_dist и
публичный договор dds.session_v.
- Нарезка стоит на двух окнах: первое ставит шов там, где пауза длиннее
тридцати минут, второе считает нарастающий итог швов — номер визита. Границу
суток держит разбиение окна, отдельной проверки ей не нужно.
- Порядок в окнах полный, по метке времени и event_id: сортировок две, и при
равных метках они разошлись бы, разорвав сессию надвое.
- Объём прогона считается от первой дыры в слое по последний прожитый день;
прожитый день выводится из позиции мира и первого дня событий. Собирать
нечего — группа задач пропускается, а не зеленеет впустую.
- В dds_transform появилась группа session рядом с заказом; зависимости по
данным между ними нет.
- Потолок max_active_tasks: размноженная замена без него выносит планировщика
за отведённые ему 640 МиБ.
- parallel_distributed_insert_select у сессий не назначается вслух — ключ
шардирования у источника и цели один по контракту ко-локации.
- Записано, что позиция отвечает за «прожит», а не за «доехал»: сторож хвоста
потока приезжает отдельным тикетом.
Проверка:
- make lint
- make smoke (21 проверка), make check-clickhouse (10), make check-services
- Стартовый мир, пересобранный с нуля: 79367 сессий за восемь дней;
расхождение с uniqExact(VisitID) по паре «кука × день» — ноль; все 401185
событий ровно в одной сессии; session_id уникальны.
- Ни одной паузы длиннее тридцати минут внутри сессии и ни одной пары соседних
визитов куки, разделённой меньшим промежутком.
- Повтор после DROP PARTITION ALL: те же session_id и то же содержимое строк.
- Снесённая руками партиция 2026-06-04: следующий прогон взял хвост от неё,
дни до дыры не тронуты.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Зачем:
- Полный разбор урока про идемпотентность стоял дважды, предупреждение про
окно K — трижды; внимание менти конечно, и каждый пересказ списывается
с этого счёта.
Что:
- Докстринг dds_transform сокращён до одной фразы с указателями: полный разбор
остался в шапке DDL, механика подмены — в order_replace.sql.
- Комментарий про ORDER_WINDOW_DAYS в даге сведён к указателю на compose,
где число объявлено и где записан риск расхождения.
- Прорежен повтор одного риторического приёма «это не X» — оставлен там,
где различие и есть суть.
Проверка:
- make lint, make config-test
- Прогон dds_transform зелёный, слой сходится с ods.order_v: 1917 заказов,
8 дней.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Зачем:
- Дать слою первую физическую сущность и показать идемпотентность, устроенную
иначе, чем в приёме: заменой партиции, а не колонкой версии.
- Родить механику дневной пересборки на кластере — образец для сессий и витрин.
Что:
- Добавлены dds.order_rep/_dist, двойник-донор dds.order_stage_rep/_dist и
публичный договор dds.order_v с разбором позиций в три массива.
- Добавлены запросы объёма прогона, сборки в двойник и замены партиции по дню.
- Добавлен даг dds_transform: группа задач order, замена — размноженной задачей.
- Окно изменяемости K пришло на сторону стенда якорем compose; владелец числа
остаётся у генератора.
- Объём считается от позднейшего дня заказа и первого недостающего дня: ярлыки
доставки ODS для этого непригодны, а максимум собранного дня прячет дыры.
- Записано, чего конвейер о себе не знает, и адресовано контуру DQ.
Проверка:
- make lint
- make smoke, make check-clickhouse, make check-services
- Прогон по стартовому миру: 1917 заказов, счёт равен ods.order_v, каждый заказ
на шарде своего cityHash64(order_id), сумма позиций равна items_total.
- Повтор без нового слепка: содержимое то же, _load_id новый; после слепка
пересобрано окно, день за окном не тронут.
- Снесённая руками партиция 2026-06-01 восстановлена побайтово.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>