- Зачем:
- в docs/labs/ будет много заданий; номер ступени и номер задания в имени
делают папку оглавлением программы и избавляют от поиска по README (#230).
- Что:
- шесть ТЗ переименованы через git mv: 1-1…1-5 для ступени 1,
2-1-superset-chart.md для ступени 2; факультатив superset-dashboard.md
остался без номера.
- обновлены ссылки в docs/labs/README.md, 2-1-superset-chart.md,
docs/architecture/dds/session.md и пути в dags/homework_check.py.
- правило имен для docs/labs/ в AGENTS.md переписано под S-N-slug.
- Проверка:
- make lint; скрипт обхода относительных ссылок в docs/ и AGENTS.md —
битых нет.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
- Зачем:
- менти строит витрины DM сам, от DDL по правилу зерна до задачи в
конвейере; стенду нужны ТЗ с образцом и обратная связь по каждой
витрине (#159, резолюция #135).
- Что:
- docs/labs/: README и пять ТЗ — events_enriched_v, top_pages_daily,
session_overview, dq_errors_daily, utm_effectiveness; каждое ТЗ
называет урок, состав колонок, форму по зерну и самопроверку.
- dags/homework_check.py: ручной даг, задача на витрину, красная без
витрины или при расхождении; проверки — шесть файлов sql/dq/ с
инвариантами против DDS и ODS, без золотых констант; в dq_summary
не пишет.
- docs: dm.md называет homework_check и снимает «Остается нарезке»,
§7 и §10 мастер-спеки согласованы с лабами, dds/session.md указывает
на ТЗ, AGENTS.md пополнен правилом имен docs/labs/.
- Проверка:
- make lint; make smoke 21/21, make check-clickhouse 10/10,
make check-services 7/7.
- на свежем стенде все пять задач homework_check красные и называют
ТЗ; черновик каждой витрины по тексту ТЗ зеленит свою задачу,
после сноса — снова красная; строк от самопроверки в dq_summary нет.
Co-Authored-By: Claude Fable 5 <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>
Зачем: развилка #134 карты #127 — чем и когда гоняются трансформации DDS
и витрины-таблицы, пока спека числила etl_pipeline за этапом 5.
Что: дока docs/architecture/etl.md — даг etl_pipeline рождается этапом 4:
дёргает dds_transform и dm_transform последовательно (DQ — будущее звено);
живой день зовёт его с ожиданием после установки позиции, после разгона
пачкой менти запускает рукой, world_initialize — последним шагом; параметров
нет, объём выводится из world_position и состояния слоёв; первый шаг —
ожидание хвоста hits; механика REPLACE PARTITION — этап 4, этапу 5 —
партиционная переобработка. Указатели в доках заказа, сессии, README слоя
и ретро-пометки в ADR 0008/0009 переведены на новую доку.
Проверка: вычитка; резолюция и доводы — в тикете #134.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- Зачем:
- согласованная модель нужна для пакетной реализации DDS и понятного публичного интерфейса слоя.
- Что:
- описаны физическая карта идентичностей, полный пересчёт и отказ от first_matched_at.
- унифицирован публичный контракт _v для событий, заказов, сессий и карты.
- синхронизированы мастер-спека, имена объектов и граница доступа.
- Проверка:
- git diff --cached --check.
- Зачем:
- развилка #132 карты #127: витринам DM и сборке сессий нужен контракт
события на языке бизнес-модели, первый пример правила «слой — это
контракт, а не обязательно копия данных».
- Что:
- создан docs/architecture/dds/event.md: представление над ods.event_v,
имена модели (event_id, event_time в поясе счётчика, event_date
переименованием), расшифровка device_category, скрыты VisitID, Sign,
ecommerce и служебные колонки.
- в README карта модели ведёт на event.md, развилка убрана из открытых
решений; session.md ссылается на резолюцию судьбы VisitID.
- Проверка:
- вычитка; относительные ссылки в docs/architecture/dds/ ведут на
существующие файлы.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Зачем: две находки горячего ревью #131 уровня решения, принятые владельцем.
Что: в «Движок и наполнение» — следствие совпадения ключа шардирования с
событиями: сессионизация локальна по природе, капкан смены ключа у сессий
не стреляет; в «Сверку с эталоном» — зацепка для развилки #132: VisitID
нужен сверке, но не сборке, его дом решает контракт dds.event_v.
Проверка: вычитка; утверждение о локальности сверено с разделом
«Раскладка по шардам» доки хранилища.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Зачем: горячее ревью резолюции #131 перед мержем PR #142.
Что: поправлена фраза про торговые события (они держат сессию, а не
«рвут»), метка времени названа явно (UTCEventTime), убрано задвоение
про «цели» между составом строки и списком расхождений, у счётной
сверки честно назван предел — взаимная компенсация ошибок внутри
куки за день счёту не видна.
Проверка: повторная вычитка; утверждения сверены с CONTEXT.md, спекой
(разделы 1, 6, 7) и докой хранилища.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Зачем: развилка #131 карты #127 — зерно и правила сборки dds.session;
резолюция переносится в доки слоя тем же PR.
Что: дока docs/architecture/dds/session.md — зерно «один визит», нарезка
по правилу визита самим стендом (стенд в роли сессионизатора), session_id
как детерминированный хеш, состав строки по образцу визита Метрики без
денег и целей, MergeTree с заменой дневной партиции, сборка одним дневным
батчем после слепка, счётная DQ-сверка с VisitID (кука × день); в README
слоя сессия переведена из открытых решений в карту модели.
Проверка: вычитка доки; ссылки на разделы спеки и соседние доки сверены
с текстом.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>