Зачем: оставить только необходимые ориентиры для автора учебного текста.
Что: раздел сокращен до трех согласованных абзацев, ссылки на оба образца сохранены.
Проверка: git diff --check прошел; проверен diff единственного измененного файла.
Зачем: убрать механические повторы в итогах и избежать ложных расхождений при проверке графика Superset.
Что: уточнены правила итоговых списков и название задания о проверках заказов. В разборе событий разделены учет повторных доставок и выбор событий ODS для сравнения. Первый график Superset и проверочный SQL используют весь период витрины.
Проверка: git diff --check, локальные ссылки и переходы к измененным заголовкам прошли. Блоки кода и таблицы требований сохранены. Согласованность периода графика с SQL проверена по тексту; повторный проход через интерфейс Superset не выполнялся.
Зачем: помочь менти понять действия, проверить результат и оценить освоенное умение.
Что: вычитаны 13 заданий основной программы и общий индекс. Итоговые списки обращены к учащемуся, убраны история разработки и повторы. Правила учебного текста записаны в программе, из AGENTS.md добавлена ссылка.
Проверка: git diff --check, локальные ссылки и ссылки на измененные заголовки прошли. Блоки кода и таблицы требований совпадают с исходными. Упражнения на стенде повторно не выполнялись: изменен только текст.
Зачем: дать менти два самостоятельных задания по BI после ступени 2.
Что: обновлено ТЗ дашборда, добавлен опыт с объектом на одной ноде, уточнены программа и индекс. Формулировки обращены к учащемуся.
Проверка: локальные ссылки и git diff --check прошли. На ClickHouse 26.3.17.56 воспроизведены ошибка чтения со второй ноды и исправление; учебный объект удален. Полный проход через интерфейс Superset не выполнялся.
- Зачем:
- расположение файла должно отличать задания основной программы от факультативов.
- Что:
- существующее ТЗ Superset перенесено в `docs/labs/optional/`, ссылки обновлены.
- правило размещения записано в `AGENTS.md`.
- выбор формы витрин объяснен учебной целью стенда.
- Проверка:
- `git diff --check`.
- проверены все упоминания `superset-dashboard` и относительные ссылки.
- Зачем:
- справочники читает человек со стороны, а «пульт мира», «опись мира»,
«работник» и «сырьё» звучали шуткой или калькой времён разработки
(тикет #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
- Зачем:
- раздел 9 отсылал к открытому тикету #203; решение принято, указатель
должен вести на итог, а не на вопрос.
- Что:
- фраза «докуда ведет карта #182» заменена итогом: карта закрыта приемкой
спеки, исполнение ведет карта #206.
- Проверка:
- вычитка раздела 9 файла docs/specs/2026-09-01-labs-program.md.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- Зачем:
- термины спеки перейдут в задания, а «хребет», «ветки» и «точка
прицепа» с калькированными заголовками сюжетов смущали бы студентов.
- Что:
- хребет → основная программа, шаги → ступени, ветки → факультативы,
«точка прицепа» заменена формулой «открывается после ступени N»;
- заголовки разделов и сюжетов переписаны из позиции студента
(«Почему выручка не сходится», «Куда попадают битые строки»);
- переносы выровнены по ~80 колонок по всему файлу.
- Проверка:
- текст без учета пробелов не изменился на шаге переносов (SHA-256);
решения, состав и порядок программы не менялись.
- Зачем:
- тикет #202 карты #182: собрать из инвентаризации #201 программу лаб
целиком — состав, порядок, формы и судьбу идей-кандидатов.
- Что:
- создан docs/specs/2026-09-01-labs-program.md: хребет из семи
обязательных шагов и пять тематических разделов необязательных лаб;
- узаконены границы вычитания по потокам и поименные резолюции идей
#143, #145, #148, #149, #186, #187, #188;
- записаны отклоненные варианты оси прогрессии и границы спеки (#203).
- Проверка:
- вычитка владельцем (спека принята), слепое ревью фактов против
инвентаризации и доков — все находки закрыты.
Зачем: раздел 10 выносил все лабы v2 в отдельную работу учебного пути,
делая исключение только для домашек DM, — необязательная лаба Superset
из #197 формально в него не попадала.
Что: исключение расширено фразой про лабу «свой дашборд в Superset» с
меркой владельца: домашки DM и эта лаба продуманы до готовых ТЗ,
остальные лабы пока на уровне идей.
Проверка: вычитка; решение владельца репозитория из обсуждения #197.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- Зачем:
- семь мест обещали калибровку черновых долей «при пересборке
эталонного мира (этап 7)», а пересборки не будет (#192); числа
сверены замером и зафиксированы (#194, хвост этапа 7 — #9).
- Что:
- замер на каноническом мире (28 дней, без транспорта): все доли в
пределах ориентиров; пометки «черновое» сняты, наблюдаемые доли
вписаны в комментарии world.py, fate.md и запись «Что проверено»;
- потеря purchase: наблюдаемых 1,78% при броске 3% — вычеты штатные
(пары склейки, приоритет отмены), принято решением владельца;
ориентир класса B в мастер-спеке различает бросок и наблюдаемую долю;
- веса мира и опись не тронуты: правки world.py — только комментарии.
- Проверка:
- cd generator && make lint && make typecheck && make test (437 passed);
- git diff по data/world-inventory.json пуст; grep «черновое|калибровка»
по generator/src и docs/architecture/orders пуст.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- Зачем:
- у дней 8-13 описи не нашлось читателя: обещание эталона в 14 дней
снято решением владельца 2026-08-30 (#192, этап 7 — #9).
- Что:
- резолюция перенесена в обе спеки, докстринг описи и словарь CONTEXT.md;
- добавлен тест: проигранный через CLI день совпадает с хешем описи;
- сняты замеры: пересборка описи 20,5 с, снимок 460,7 МБ, make test
176,5 с — записаны в карту проверок и таблицу бюджетов.
- Проверка:
- cd generator && make lint && make typecheck && make test (437 passed);
- git diff по data/world-inventory.json пуст.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- Зачем:
- спека разрослась до 1058 строк, а журнал решений в разделе 9 читался
только целиком; агентам и людям нужен дешевый адресный заход к
основаниям решений генератора.
- Что:
- заведены ADR 0015 (пояс счетчика), 0016 (паспорт куки) и 0017 (номер
заказа); четыре адресные ссылки на «раздел 9» перешиты на них.
- раздел 9 пересобран в 11 тематических подразделов с датами и тикетами
у каждого решения и закрыт пометкой о заморозке; устаревшие
промежуточные замеры свернуты до указателей на актуальные.
- строка статуса в шапке отмечает закрытие спеки как документа этапа 2.
- Проверка:
- wc -l docs/specs/2026-08-01-generator.md (951, было 1058);
rg -n 'раздел[а-яё]* 9|разделы 8 и 9' docs -g '*.md' — 18 попаданий,
все классифицированы; разделы 1-8 нетронуты (сверка хешем).
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>
- Зачем:
- конвейеру нужна публикуемая сводка текущего качества с красным завершением при нарушении договоров.
- Что:
- добавлены 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; меры сверены с прямыми агрегатами.
- Зачем:
- описание вело нового читателя через историю исправления вместо действующего
контракта слоёв.
- Что:
- прямо описаны версия заказа, границы пакетного приёма и расчёт окна 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>
Зачем:
- Показать слой 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 после ревью.
- Зачем:
- согласованная модель нужна для пакетной реализации DDS и понятного публичного интерфейса слоя.
- Что:
- описаны физическая карта идентичностей, полный пересчёт и отказ от first_matched_at.
- унифицирован публичный контракт _v для событий, заказов, сессий и карты.
- синхронизированы мастер-спека, имена объектов и граница доступа.
- Проверка:
- git diff --cached --check.
- Зачем:
- свежий 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`.
- Зачем:
- дашборды нужны точками наблюдения на приёмке этапов 4-8, а зависимость
у них формально только от этапа 1: «в хвосте» было выбором, не
необходимостью.
- Что:
- раздел 9: дашборды строятся параллельно этапам 4-8, состав не меняется.
- назван хвост этапа: runbook keeper/DDL, system.text_log, правила
оповещения, урок «посмотрели - сломали - вернули».
- записано правило: панели порогов и цветовых вердиктов не несут, красное
и зелёное живёт в проверках.
- Проверка:
- тикеты этапа нарезаны по этому раскрою: #114-#117 под #11.
- Зачем:
- ODS должен показывать сущность заказа, а не способ её доставки слепком.
- Что:
- физические таблицы и представление переведены на имена `order_*`.
- SQL загрузки, DAG и документация приведены к тому же словарю.
- Проверка:
- `make config-test`, `make lint`.
- `make clean && make up`, `make smoke`, `make check-clickhouse`, `make check-services`.
Зачем: ревью в три линии нашло настоящий дефект. Девятая проверка кластера
звала dictGet('dds.products', …) — объекта после переноса не существует, и
make check-clickhouse падал. Промах вырос из недосчёта: упоминания dds.products
я искал с фильтром по расширениям, .sh туда не попал, и в ADR уехало «четыре
упоминания» вместо семи.
Что: проверка переведена на dic.products и сверяет цену, умножив её обратно на
сто, — так утверждается ещё и точность приведения к Decimal. Раздел 3
мастер-спеки и список пользователей README догнали перенос: оба описывали
отменённое устройство. В ADR 0012 добавлено условие пересмотра для дома — для
него его не было, хотя ради дома тикет и заводился; недосчёт записан в
«Что проверено» как урок. Разнобой обозначений сведён: карта таблиц в доке
хранилища перешла на имена баз строчными, таблица мастер-спеки — на заголовок
«Где», зону всюду зовут зоной, а не слоем. Термин «Справочник» переписан без
метафоры и уложен в формат глоссария. Вычтено лишнее: комментарии DDL
сократились вдвое, из ADR 0006 и 0007 убраны самооправдание и дублирующие
абзацы, отраслевой образец получил честную оговорку о непроверяемости.
Проверка: make config-test, make lint, make smoke и make check-clickhouse —
все зелёные, десять проверок кластера из десяти.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Зачем: горячее ревью поймало ошибку в трёх местах сразу. Было записано, что
после правки каталога ноды расходятся до тридцати секунд — число взято из
ширины окна LIFETIME(MIN 60 MAX 90). Ширина тут ни при чём: каждая нода ждёт
правки от нуля до верхней границы окна, фазы у них независимы, поэтому
расходиться они могут почти на все полторы минуты.
Что: исправлены ADR 0012, опорная точка мастер-спеки и комментарий DDL. Заодно
уточнено, что LIFETIME(0) неатомарность не предотвращал, а сжимал до разброса
исполнения SYSTEM RELOAD DICTIONARY ON CLUSTER, и что витрина выручки пока
спроектирована, а не построена.
Проверка: рассуждением, замером не подтверждалось — прежнее число тоже было
выведено, а не измерено. Замер в ADR (116 секунд на окне MIN 60 MAX 120)
относится к другому утверждению: что словарь обновляется сам.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Зачем: место словаря в dds было унаследовано от первого объекта, а не решено.
Справочник читают несколько слоёв, а производит его в хранилище ни один —
прописка внутри одного из потребителей приписывала DDS владение, которого у
него нет.
Что: заведена база dic вне цепочки STG → ODS → DDS → DM, dds.products переехал
в dic.products. Под словарём появилась подложка dic.products_file на движке
File — намеренное усложнение ради урока: в бою источник словаря приезжает
процессом, а не лежит файлом у сервера. Источник объявлен формой query и
приводит цену из целых копеек каталога в Decimal(18, 2), как у денег бэкенда.
Обновление — окном LIFETIME(MIN 60 MAX 90) вместо ручной перезагрузки, ценой
заявленной неатомарности между нодами. У словаря свой беспарольный
пользователь dict с единственным правом на чтение dic. Суффикс _file добавлен
в конвенцию имён ADR 0006. Решение, отвергнутые варианты и условия пересмотра
— ADR 0012.
Проверка: make clean && make up на собранном заново стенде — зелено, make smoke
20 проверок и 0 ошибок, make lint чисто. Словарь LOADED со 180 строками, цена
Decimal(18, 2) и точна на копейках: 188990 → 1889.90. Пользователь bi читает
словарь dictGet-ом со второй ноды, analyst — подложку соединением, база dds
пуста. Минимальное право на движок замерено тремя пользователями: достаточно
GRANT FILE ON *.*, хотя отказ называет TABLE ENGINE ON File.
Closes#105
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
- Зачем:
- потребителю ODS нужна точная актуальная версия события без знания о FINAL.
- Что:
- создано ods.event_v над распределённой таблицей событий с FINAL.
- сверка стартового мира переведена на новое представление.
- документация различает физические версии ODS и бизнес-представление DDS.
- Проверка:
- make config-test.
- make check-clickhouse.
Зачем: черновик этапов держал DDS заказа в этапе 3, а принятый набор
docs/architecture/orders/ оставляет модель DDS проектированию этапа 4
(ingestion.md «Не входит», тикет #85 перевешен на #6) — расхождение
всплыло на холодном ревью нарезки этапа (#89).
Что: в разделе 9 этап 3 сужен до STG/ODS и дага приёма, модель DDS
заказа названа работой этапа 4.
Проверка: чтение; нарезка этапа 3 (#90–#96) согласована с этой строкой.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Зачем: датированная спека — событие истории, а устройство компонента — живой
документ; большое полотно плохо грузится и агентом, и человеком (ADR 0011).
Что: вычитание #84 слито с переустройством формы: набор
docs/architecture/orders/ — индекс README и семь файлов по частям устройства
(нарезка по правилу «семь плюс-минус два»); датированные файлы удалены,
ссылки перенацелены, AGENTS.md дополнен правилом подпапки. Приёмка
владельцем #88 пройдена, черновой статус снят из README.
Проверка: холодная сверка миграции свежим тредом — потерь решений нет;
обход относительных ссылок набора — битых нет.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Зачем: решения развилок #70–#74, #80, #81 карты #69 разошлись по резолюциям
тикетов — цельная картина второго источника нужна в одном месте.
Что: черновик спеки заказов docs/specs/2026-08-16-orders.md и спека приёма
docs/specs/2026-08-16-order-ingestion.md; согласующие правки соседних
документов; правки горячего ревью и двух слепых холодных линий — дефекты
сборки закрыты, назван порядок строк внутри слепка.
Проверка: перепроверка находок теми же ревьюерами — ALL_CLOSED.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- Зачем:
- документация не должна обещать постоянные числа для движущегося мира.
- Что:
- уточнено появление опоздавших заказов в слепках.
- опись ограничена неизменяемым выходом и счётчиками с читателем.
- счётчик пар оставлен плану, но исключён из описи.
- Проверка:
- CONTEXT.md перечитан целиком; git diff --check.
Зачем: взгляд владельца на генератор жил только в разговорах, и каждый
следующий агент восстанавливал его заново или не восстанавливал вовсе.
Без него решения по генератору принимаются не по тому критерию: внутренняя
стройность вместо правдоподобия данных на выходе.
Что: новый раздел «Чем меряется генератор» сразу после «Зачем» — пять
утверждений рамки. Генератор меряется выходом, а не устройством; менти
внутрь не смотрит, поэтому конструкция оправдана только наблюдаемым
эффектом; повторимы эффекты, а не числа, и хеши описи обещают видимость
сдвига, а не постоянство чисел; цена ошибки мала, поэтому оборона дороже
ошибки не заводится; сложность изолирована службой ради дешевизны правки.
Рамка шире этапа 2, поэтому спеки следующих этапов ссылаются на неё, а не
копируют.
Проверка: правка только текстовая, кода не касается.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Зачем: модельный день прогоняется только руками, и владельцу нечем
проверять процессы стенда вживую. Этап 3 без дага не существует вовсе
(ADR 0008), поэтому форму пульта и способ вызова генератора надо решить
раньше кода.
Что: ADR 0009 — работники без расписания (`world_next_day` пачкой,
`world_live_day` в темпе) и выключатель `world_live` без своей работы,
ждущий дочерний прогон триггером, а не сенсором; генератор зовётся
`DockerOperator` в каноническом контейнере, потому что в образе Airflow ему
не жить (Python 3.14 против 3.13); позиция ставится как «последний сыгранный
+ 1» — правило вместо сторожа, и его мягкий худший исход назван. Плата за
сокет докера снята замером: доступ открывается добавлением GID в контейнер,
правка прав на хосте не нужна, а сам GID — локальная настройка в `.env`.
Пакетная автоматика отложена, не отвергнута. Расхождения внесены в спеку
генератора: позицию ставит сыгравший, у живого дня появился выключатель.
В словарь добавлен «пульт мира».
Проверка: `make config-test` зелёный; API Airflow 3.3 (пауза и ручной
запуск, ожидание триггера по идентификатору прогона, привязка сенсора к
логической дате, `DockerOperator`) сверено через MCP Context7; версия
Python в образе и права сокета — замером.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
- Зачем:
- читателю нужна честная граница между учебными ролями и боевой защитой.
- Что:
- README описывает пользователей, роли и место хранения паролей.
- мастер-спека явно откладывает эксплуатационные меры защиты.
- устаревшие комментарии Compose и пробника приведены к реализации.
- Проверка:
- make config-test, make lint.
- Зачем:
- развилка этапа 3 стояла нерешённой прямо в разделе 7 мастер-спеки: нужен
ли слепку слой сырья и как заказы попадают из топика в хранилище (#70).
- Что:
- заведён ADR 0008 — байтовый чтец без матвью, слой сырья у заказов
остаётся, в ods.order_snapshot пишет шаг Airflow заменой партиции; топик
orders в одну партицию, чтец на clickhouse-01 без ON CLUSTER.
- мастер-спека приведена в соответствие, разделы 6, 7, 9, 11, 12: сравнение
двух приёмов переписано на «поток против слепка», сенсор дневного батча
снят, первый даг переехал с этапа 5 на этап 3.
- в CONTEXT.md заведены «слепок», «окно изменяемости», «пакетный забор».
- Проверка:
- решение сверено по документации ClickHouse через MCP Context7 12 августа
2026 года; что осталось замерить на стенде — списком в конце ADR 0008.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
- Зачем:
- корневые цели смешивали два уровня: пять из шестнадцати начинались с cd generator.
- цель, названная общерепозиторной, охватывала 31 файл Python из 34: даги и Superset не видел ни линт, ни типы.
- Что:
- lint, typecheck, test, docs и inventory переехали в новый generator/Makefile.
- корневой lint заведён по коду стенда — dags и infra/superset — с явными путями и закреплённой версией ruff.
- заведён корневой ruff.toml: тот же список правил, target-version по младшему Python в образах стенда.
- цели корня сгруппированы по использованию, осталось двенадцать.
- два файла дагов переформатированы под новую проверку.
- карта проверок, оба README, спека генератора и AGENTS.md приведены к двум дверям.
- Проверка:
- make lint; make config-test — зелёные.
- make -C generator lint; typecheck; test — зелёные, 407 тестов.
- ruff check --show-files: из корня ровно три файла стенда, из generator/ — только его.
- цена корневого lint замерена (0,4 с) и вписана в карту проверок.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
- Зачем:
- конвенция #63 записана, а код её не достиг: колонки времени стояли без
пояса, и сходилось всё лишь потому, что пояс сервера — UTC.
- Что:
- UTCEventTime объявлен DateTime('UTC'), служебные метки _load_ts и
kafka_timestamp — DateTime64(3, 'UTC') в STG и ODS.
- parseDateTimeOrNull получил третьим аргументом 'UTC': маска сверяет
суффикс Z как букву, зоны из строки не берёт вовсе.
- контракт схемы и описание выгрузки несут тип с поясом; имя пояса
Europe/Samara встало рядом со смещением в world.py, сходимость сверяет
тест.
- учебный комментарий о линзе — у первой колонки с явным поясом.
- Проверка:
- make lint, make typecheck, make test (408 тестов)
- make clean && make up && make check-clickhouse — 9 из 9
- замер тикета повторён: под session_timezone='Europe/Samara' колонка
показана 2026-05-31 23:37:00, как и без настроек
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Зачем: формулировка в спеке дублировала строку карты проверок и делала это
хуже оригинала. «make up работает» следует из зелёных проверок и потому
пусто; настоящее условие — «с нуля» — в спеке не проговаривалось. Заодно
гигиеническая планка носила имя приёмки этапа, хотя про предмет этапа она
молчит: дашборд может быть не нарисован, а все три цели зелены. Тот же промах
разобран в ADR 0004 — там он случился с числовым порогом.
Что: раздел 9 спеки отсылает к карте проверок вместо своей формулировки и
называет вещь своим именем — гигиена, а не приёмка. Копия строки убрана из
семи карт этапов и карты #1 в трекере: одна вещь — одно место.
Проверка: правка документная. grep по docs, README и AGENTS — других копий
формулировки нет.
Зачем: этап 2 принят прогоном с нуля, и два его следа должны остаться в
доках — иначе решение «не проверяем» станет забытым долгом, а цена цели
разойдётся с замером.
Что:
- в спеке v2 раздел 11 больше не держит Kafka Engine на двух нодах: дубли и
раскладку партиций между прогонами решено не проверять — дубль возможен по
устройству движка, окно разобрано в доке хранилища, в ODS его схлопывает
ReplacingMergeTree. Половина, которую показал #37, названа;
- в карте проверок цена check-services 44 с -> 59 с и абзац с замерами
приёмки: clean+up 2 м 58 с, смоук 9 с, check-clickhouse 8 с, test 71 с.
Причина подорожания не выдумывается — названа неизвестной.
Проверка: make clean && make up, затем make smoke, make check-clickhouse,
make check-services, make lint, make typecheck, make test — всё зелёное
7 августа 2026 года.