- Зачем:
- владелец на ревью PR #175 отметил кальку в подсказках; читать их
будет менти, и язык здесь — часть продукта.
- Что:
- переписаны подсказка формы days, докстринги работников, строки
журнала remember_played, абзац README и пункт в etl.md; смысл
не менялся.
- Проверка:
- make lint, make config-test.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- Зачем:
- оператор принимал служебную logical_date Airflow за дату мира (#111),
а документацию читают реже, чем форму запуска.
- Что:
- у параметра days появилась подсказка description_md, а в докстринги
работников добавлена фраза: день определяет world_position, служебные
поля Airflow к оси мира отношения не имеют.
- remember_played пишет в журнал сыгранные дни и новую позицию.
- README дополнен абзацем про служебные поля за «Advanced Options»;
из etl.md сняты устаревшие стыки на закрытые #7 и #2.
- Проверка:
- make lint, make config-test; ручной прогон world_next_day зелёный,
позиция 9 -> 10, в журнале «сыграны дни 9–9, позиция теперь 10».
Co-Authored-By: Claude Fable 5 <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>
- Зачем:
- параллельный 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.
Зачем:
- Показать два ритма пересборки агрегатов на готовых витринах DM.
Что:
- Добавлены физические модели и публичные договоры revenue_daily и daily_traffic.
- Добавлен dm_transform с оконной заменой выручки и полным пересчетом трафика.
- Отрицательный опыт локального соединения через публичные _v зафиксирован; выбран явный GLOBAL LEFT JOIN.
- Замены партиций сериализованы после подтвержденного OOM при трех одновременных задачах.
- Обновлены архитектурные документы и мастер-спека.
Проверка:
- make lint, make config-test, make smoke, make check-clickhouse, make check-services.
- Чистая сборка world_recreate, dds_transform и dm_transform; меры сверены с прямыми агрегатами.
- Зачем:
- реализованы требования issue #153 к мосту между кукой и пользователем.
- Что:
- добавлены физическая карта, точное представление и полный пересчёт через GLOBAL JOIN.
- задача identity_map поставлена после сборки заказов в dds_transform.
- устройство и живые проверки карты записаны в документации хранилища.
- Проверка:
- make lint, make smoke, make check-clickhouse, make check-services.
- три запуска dds_transform: 4770 физических строк и 1590 уникальных пар в _v.
- Зачем:
- описание вело нового читателя через историю исправления вместо действующего
контракта слоёв.
- Что:
- прямо описаны версия заказа, границы пакетного приёма и расчёт окна DDS.
- ответственность ODS, DDS и конвейера разделена без ссылок на прежние
ошибки как на основной довод.
- исторический вывод исследования помечен до устаревшего абзаца, а ссылки
ведут к отдельным решениям и контрактам.
- Проверка:
- make lint.
- make config-test.
- Зачем:
- ярлык 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>
Зачем:
- Дать слою первую физическую сущность и показать идемпотентность, устроенную
иначе, чем в приёме: заменой партиции, а не колонкой версии.
- Родить механику дневной пересборки на кластере — образец для сессий и витрин.
Что:
- Добавлены 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>
- Зачем:
- Закрепить реалистичную границу доступа BI и убрать двусмысленность для неизвестных кодов.
- Что:
- Пояснены доступ к ODS, пояс счётчика и порядок DDL.
- Проверка равенства строк отделена от размера конкретной загрузки.
- Проверка:
- `git diff --check`.
- `make config-test` не стартовал: Snap требует работающий `snapd.apparmor`.
Зачем:
- Показать слой DDS как договор данных, которому не нужна физическая копия.
- Сохранить простой учебный стенд без отдельного маршрута ради узких прав.
Что:
- Добавлено кластерное представление dds.event_v с явными 44 колонками.
- Роли bi_reader разрешено чтение ODS, DDS и DM при договоре чтения через _v.
- Согласованы мастер-спека, ADR, справочники архитектуры и живые тикеты этапа.
- Зафиксировано исследование поведения DEFINER поверх Distributed.
Проверка:
- make config-test
- make smoke
- make check-clickhouse
- Приёмочные запросы: равенство ODS/DDS, состав колонок, коды устройств и права bi.
- Зачем:
- сверка с описью подглядывает внутрь генератора: у настоящего магазина
такого оракула нет, и выдавать её за учебный урок DQ нельзя (развилка
из комментария к #157).
- Что:
- в dm.md проверка счётчиков классов помечена технической, её обещание
сужено честно: до витрин доехал рождённый мир; верно ли мир рождён,
проверка не видит — опись считает тот же генератор.
- в §8 мастер-спеки читатель счётчиков «самопроверка лабы сверки»
заменён на техническую проверку classes_vs_inventory звена DQ.
- словарь: короткий термин «Техническая проверка» в CONTEXT.md — только
язык, решение живёт в dm.md; та же формулировка читателя в inventory.md.
- Проверка:
- grep -rn "лабы сверки" docs/ — упоминаний не осталось.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Зачем:
- дать описи контрольные числа для закрытых дней заказного окна;
- зафиксировать словарь наблюдаемых классов без изменения самого мира.
Что:
- посчитаны match, cancelled и amount_delta с приоритетом отмены;
- счётчики добавлены только к дням с закрытым окном;
- опись, тесты и документация приведены к новому формату.
Проверка:
- make lint;
- make typecheck;
- make test — 429 passed;
- uv run pytest tests/test_inventory.py -q — 3 passed после ревью.
- Зачем:
- после переписывания ритма пересборки в тексте остались швы прежних
формулировок и один разрыв с докой конвейера.
- Что:
- довод против дневных партиций daily_traffic заменён верным: партиция —
единица замены, а витрина заменяется только целиком (число строк тут
ни при чём, иначе довод бил бы и по dq_summary).
- в etl.md к механике REPLACE PARTITION добавлена вторая идемпотентность
конвейера — полная перезапись в ReplacingMergeTree.
- правило ритмов говорит про день, а не партицию; поправлены переносы
строк и обороты.
- Проверка:
- make config-test.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- Зачем:
- обсуждение горячего ревью показало: «окно K для всех» — ритм заказов,
натянутый на слой, а замерзание daily_traffic обесценивало витрину.
- Что:
- раздел «Объём пересборки» заменён «Ритмом пересборки»: три ритма —
хвост / окно K / целиком; daily_traffic наследует у карты полный
пересчёт в ReplacingMergeTree, дневные партиции ей не положены.
- в отклонённые добавлены замерзание за окном K и инкремент по
first_matched_at; инкремент стал идеей лабы повышенной сложности #149.
- Проверка:
- make config-test.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- Зачем:
- горячее ревью развилки #135 нашло два незакрытых решения: объём
пересборки витрин и судьба менти-витрины после постройки.
- Что:
- добавлен раздел «Объём пересборки»: одно окно K для всех витрин,
замерзание daily_traffic за окном названо решением с объяснением.
- в ТЗ менти добавлен финальный пункт — встроить витрину в dm_transform.
- поправлены мелочи: greenplum-стенд больше не зовётся предшественником,
добавлены ссылки на спеку и карту идентичностей.
- Проверка:
- make config-test.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- Зачем:
- развилка #135 карты #127 решена: форма и состав витрин DM,
контур DQ этапа 4; резолюция переносится в доки architecture.
- Что:
- создана docs/architecture/dm.md: форма по зерну, дележ витрин
между стендом и заданиями менти, dq_summary с REPLACE PARTITION,
звено DQ конвейера и даг самопроверки домашек.
- ссылки на #135 в etl.md и dds/README.md заменены на доку слоя.
- Проверка:
- make config-test.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Зачем: горячее ревью доки перед слиянием PR #146.
Что: «единственный на стенде» больше не читается как «единственный даг
стенда»; в пункте про живой день причина порядка триггера названа один раз
и по делу; конвейер дёргает работник живого дня, а не работники; в
ретро-пометке ADR 0009 расставлены кто кого дёргает.
Проверка: перечитка диффа.
Co-Authored-By: Claude Fable 5 <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 нашло шероховатости, мешающие читателю.
- Что:
- срезан дубль про event_date из «Языка модели» — факт живёт в «Форме»,
расхождений имён осталось два.
- выровнены префиксы dm. в «Читателях», распутана фраза про два слоя
DQ-сверки, ссылка на спеку — в домашнем стиле.
- Проверка:
- вычитка.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- Зачем:
- развилка #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>
- Зачем:
- горячее ревью после написания: неточности формулировок и один пропуск
в списке читаемых колонок.
- Что:
- уточнено, что дом набора выбран развилкой #130, а не «первой развилкой
карты» (первыми шли research-тикеты);
- сверке добавлен order_date в перечень читаемых колонок (спека, §7:
колонка order_day);
- мастер-спека слинкована при первом упоминании; пояснена роль резолюции
#128 в «Связанных решениях».
- Проверка:
- только документы; ссылки сверены с деревом docs/.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- Зачем:
- развилка #130 карты #127: заказу нужен объект в DDS — зерно, состав,
движок и судьба служебных колонок; резолюции этапа 4 нужен дом в git.
- Что:
- создан набор docs/architecture/dds/ по ADR 0011: README с картой
модели и правилами слоя, order.md с моделью заказа — зерно «заказ в
текущем состоянии», позиции массивами, MergeTree с заменой партиций,
свои _load_id/_load_ts вместо ярлыков ODS (закрывает наследство #85);
- указатели на модель добавлены в orders/README.md, orders/ingestion.md
и storage.md.
- Проверка:
- только документы; относительные ссылки сверены с деревом docs/.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- Зачем:
- правки #137 дважды рассказывали одно и то же: механика капкана жила и в
storage.md, и у вставок, а цифры замеров — и в прозе, и в леджере;
у читателя это спрашивает больше внимания, чем даёт.
- Что:
- комментарии у вставок order_parse.sql сжаты до довода с указателем на
storage.md; из капкана в storage.md цифры ушли в «Что проверено»;
в ingestion.md замеры перенесены из прозы в свой раздел «Что проверено».
- Проверка:
- рендер order_parse.sql по-прежнему делится ровно на два запроса
(из комментария убрана точка с запятой, по которой оператор делит файл).
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
- Зачем:
- проверка #137 показала: у заказа, не менявшегося несколько дней, версию
выбирает только updated_at, и какая из одинаковых строк переживёт
схлопывание — не обещано; snapshot_date выжившей строки означал не то,
что обещала документация (у 86 заказов стартового мира выжил серединный
день наблюдения).
- Что:
- в docs/architecture/orders/ingestion.md записано: snapshot_date, _load_id
и _load_ts выжившей строки — координаты одного из наблюдений версии, не
обязательно последнего; допущение «уточнение поднимает updated_at»
названо допущением с границей применимости.
- та же оговорка — в комментарии DDL ods.order_rep.
- Проверка:
- замеры на живом стенде: во всех 3034 парах строк с равным updated_at
деловые поля совпали побайтово; монотонность updated_at по слепкам —
без нарушений; ods.order_v сошёлся с эталоном argMax из сырья построчно.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
- Зачем:
- заводское parallel_distributed_insert_select = 2 исполняло вставку из
Distributed в Distributed локально на каждом шарде, минуя ключ цели:
1189 из 1662 заказов задвоились на обоих шардах, а ReplacingMergeTree
через границу шарда дубли не схлопывает.
- Что:
- в обе вставки sql/ods/order_parse.sql добавлено явное
parallel_distributed_insert_select = 0 с доводом комментарием.
- в docs/architecture/storage.md описан капкан «INSERT из Distributed в
Distributed при несовпадающих ключах» и записана проверка (#137).
- Проверка:
- межшардовые дубли по ods.order_rep дают 0 (было 1189), каждый шард
держит только свои ключи; uniqExact(order_id) не изменился.
- после прожитого дага world_next_day новый слепок принят, дублей
по-прежнему 0.
- make smoke, make check-clickhouse.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
- Зачем:
- при холодном старте GET уже видел DAG, пока POST запуска ещё считал его устаревшим.
- Что:
- точный стартовый ответ 404 повторяется до двадцати раз с паузой три секунды.
- прочие ответы и сетевые ошибки завершают команду без риска двойного запуска.
- граница повторов объяснена в коде и документации проверок.
- Проверка:
- выполнены `bash -n scripts/run-dag.sh`, `make config-test` и изолированные сценарии ответов API.
- выполнены холодный `make up`, `make lint` и `make smoke` (21/21).
- Зачем:
- свежий main добавил мониторинг и проявил устаревшие доводы, мёртвые настройки и слишком короткий тайм-аут DDL.
- Что:
- документация приведена к текущему жизненному циклу мира и составу стенда;
- удалены лишняя проверка и неиспользуемый YAML-якорь;
- ожидание ClickHouse возвращено к 300 секундам, а отказы и параметры DockerOperator пояснены.
- Проверка:
- `make config-test`;
- `make lint`;
- `make smoke` — 21/21.
- Зачем:
- границы владения Compose и Airflow должны быть видны менти из одного источника истины.
- Что:
- добавлены спека и ADR жизненного цикла мира;
- обновлены README, архитектурные справочники и прежние решения;
- правило полной очистки записано как явное и проверяемое требование к агенту.
- Проверка:
- документация вычитана через `ai-text-lint` и `writing-for-agents`;
- выполнена литературная вычитка русского текста;
- `git diff --check`.
- Зачем:
- второй круг ревью нашёл, что текст спорит с собственной приёмкой: окно
держалось доводом «слияния за минуту-две», а замер даёт двадцать секунд;
довод панели ошибок опирался на отказ по памяти, которого ADR 0004 на этом
стенде не обещает.
- Что:
- «Части» сортируются по таблице: сортировка по числу частей разводила две
ноды одной таблицы, как только между ними вставала чужая.
- у «Слияний» столбик шириной в минуту, иначе редкие события выходили
волосяной линией; из заголовка убран «слой» — фильтр отсекает журналы
сервера, а не выбирает слои.
- в cluster.md исправлены довод за окно, ложное «времени в system.parts нет»,
счёт панелей без нод (их две, не одна) и разрешение, в котором снят замер
процессора.
- панель ошибок и её запись в ADR 0002 переписаны под проверенное: отказ на
шарде воспроизведён принудительным пределом памяти.
- из queries.md убран абзац про SELECT 1 — он объяснял пол удалённой панели.
- Проверка:
- make config-test; make smoke 21/21; make check-clickhouse 10/10.
- все десять панелей отвечают через /api/ds/query в окнах на полчаса, час и
шесть часов; шаг столбика слияний проверен отдельным запросом.
- Зачем:
- слияния в верхних строках показывали только журналы самого сервера, а
предел в 15 строк рвал пару нод пополам: панели отвечали не на свой вопрос.
- Что:
- «Слияния» стали столбиками по слоям: журналы сервера отделены, ряды ods и
stg видны своими.
- «Части» показывают все таблицы слоёв целиком, без предела и без обрезанных
пар.
- у «Запросов» убран «Поток запросов» — его пол составляли пробники
состояния; у «Кто спрашивает» убрана лишняя колонка.
- ряд «коробка» назван «отведено» — как в заголовке панели.
- доводы дописаны в cluster.md и queries.md, отступления от ADR 0002
записаны в сам ADR.
- Проверка:
- make config-test; make smoke 21/21; make check-clickhouse 10/10.
- все десять панелей отвечают через /api/ds/query в окнах на полчаса, час и
шесть часов.
- Зачем:
- ADR 0002 обещает три дашборда; собран был один, а симптом инфраструктуры
как следствие решения человека показать было негде.
- Что:
- cluster.json — семь панелей: процессор, память с пределом коробки, диски,
части по таблицам, слияния, keeper, очередь распределённых DDL.
- queries.json — четыре панели поверх system.query_log: тяжёлые запросы,
поток запросов, аппетит по пользователям, ошибки.
- системные таблицы читаются через clusterAllReplicas; очередь DDL — без
обёртки, она живёт в keeper и у обеих нод одна.
- устройство обоих дашбордов записано в docs/architecture/monitoring/,
правило про пороги поднято из data.md в README набора.
- Проверка:
- make config-test; make smoke 21/21; make check-clickhouse 10/10.
- все одиннадцать панелей отвечают через /api/ds/query.
- Зачем:
- «что скребёт Prometheus» — калька со scrape, по-русски звучит коряво;
рядом нашлись ошибка падежа и пара фраз, которые читаются с запинкой.
- Что:
- заголовок набора и раздел названы по-русски: «за чем следит» и «кого
опрашивает Prometheus».
- «Единицы общие — сообщений за интервал» исправлено на именительный падеж.
- разбиты две перегруженные фразы: про место диагностики версий и про то,
что читать на панели сходимости.
- Проверка:
- make config-test.
- Зачем:
- проход на вычитание: каталог дашбордов появился в этом же PR, и абзац
«что здесь есть» стал называть «Данные» второй раз.
- Что:
- вводный абзац отсылает к каталогу, а имя дашборда и состав панелей
остались только в самом каталоге.
- Проверка:
- make config-test.
- Зачем:
- таблица панелей дублировала заголовки из data.json и уже правилась
дважды; заголовок раздела называл запрещённое действие вместо нужного;
довод про отвергнутые способы счёта сходимости стоял в двух местах.
- Что:
- в таблице панелей остались только источники, вопрос панели читается с её
заголовка на экране.
- раздел про чтецов Kafka назван по тому, что панели делают, опасность
kafka_commit_on_select осталась внутри как причина.
- из записи о приёмке убран пересказ довода, замер оставлен.
- Проверка:
- make config-test; make lint.
- Зачем:
- в общем разделе «Что проверено» лежали два разных прогона, пола и
дашборда; следующие дашборды копили бы там осадок.
- Что:
- запись о приёмке дашборда «Данные» перенесена в data.md, в README.md
осталась приёмка самой зоны.
- Проверка:
- make config-test.
- Зачем:
- половина справочника была про один дашборд «Данные», а этап приносит ещё
два дашборда и правила оповещения: описание самой зоны утонуло бы.
- Что:
- заведён набор docs/architecture/monitoring/ по ADR 0011: README.md — зона
и каталог дашбордов, data.md — устройство дашборда «Данные».
- обе входящие ссылки перенацелены: README.md репозитория и ADR 0002.
- Проверка:
- make config-test; ссылки из README.md и ADR 0002 открываются.
- Зачем:
- две линии ревью нашли, что колонки панели брака читаются как
непересекающиеся кучи, «вовремя ли» из ADR 0002 не считается вовсе, а
отказ от ряда «против вчерашнего» нигде не записан рядом с решением.
- Что:
- в панели брака столбец назван «Из них в брак»: брак — часть приехавшего,
а не соседняя куча.
- панель слепка считает паузу после прошлого слепка — это и есть «вовремя
ли» из ADR 0002; пустая пауза у самого раннего слепка держится
обнуляемым типом.
- отказ от ряда «против вчерашнего» записан в ADR 0002 и в monitoring.md с
доводом: сдвиг на модельные сутки прописал бы ускорение мира в JSON.
- в monitoring.md сказано, почему свежесть читает физическую _dist, а не
ods.*_v, и почему панель слепка не знает окна; довод про сломанный JSON
оставлен у кода, а не задвоен в доке.
- README больше не утверждает, что панелей нет.
- у разбора дашбордов убран флаг -e: он обещал утверждение, которого нет.
- Проверка:
- make config-test (краснеет на нарочно сломанном JSON дашборда), make lint,
make smoke 21/21, make check-clickhouse 10/10; все шесть панелей отвечают
через /api/ds/query. Опыты приёмки и их следы — monitoring.md,
«Что проверено».
- Зачем:
- главный дашборд ADR 0002 отвечает на вопрос «с потоком всё в порядке?»;
три его вопроса — свежесть, брак и сходимость — у предшественника не
заданы вовсе, и в этом весь смысл экрана.
- Что:
- добавлен infra/grafana/provisioning/dashboards/data.json: свежесть, поток,
брак, сходимость, отставание чтения из Kafka и дневной слепок заказов;
порогов и цветовых вердиктов на панелях нет.
- в monitoring.md записано устройство дашборда: почему слои у панелей разные
и как считается сходимость — с доводом и двумя отвергнутыми способами.
- make config-test разбирает JSON дашбордов тем же доводом, что и файлы
дагов: сломанный файл Grafana молча оставляет прежнюю версию.
- Проверка:
- make config-test; на живом стенде make smoke 21/21 и make check-clickhouse
10/10; все шесть панелей отвечают через /api/ds/query.