Тема: Часть 22. Практический зачёт: полный цикл SDD Data от спецификации до отчёта ревьюера
Уровень сложности: Средний
Расчётное время изучения: 3–4 часа самостоятельной работы (с учётом написания спецификации, реализации модели и подготовки отчёта ревьюера)
Предварительные требования: Уверенное владение SQL (агрегации, оконные функции, JOIN)
Базовое знакомство с dbt (модели, тесты, sources, schema.yml)
Понимание концепции data contracts и SDD Data (Specification-Driven Development for Data)
Знание принципов работы с PII (Personally Identifiable Information)
Опыт работы с git и командной строкой
Понимание разницы между staging, intermediate и mart слоями
Цели обучения: Критически оценивать спецификации данных и находить в них минимум 10 слабых мест до начала SQL-реализации
Переписывать слабые ТЗ в полноценные SDD Data-спецификации с разделами grain, PII, контракт, приёмочные факты
Проектировать dbt-модель mart-слоя с гарантией grain «одна строка на ключ» и покрытием обязательных тестов
Разделять роли автора и ревьюера, формировать отчёт ревьюера с разделением фактов, допущений и открытых подтверждений
Проводить ретроспективу SDD Data и определять, какую фазу следующей фичи нужно сузить или подробнее описать
Обзор: Финальная часть курса проверяет не память о синтаксисе dbt, а способность удержать обещание дата-продукта от спецификации до отчёта ревьюера. Зачёт специально стартует с плохой спецификации вида «сделать полезную витрину», чтобы проверить, остановит ли студент слабое задание до SQL. Зачёт состоит из четырёх блоков: 12 быстрых письменных вопросов на понимание терминологии SDD Data; задание найти проблемы в намеренно слабой спецификации; переписать её в правильном SDD Data-формате; и, наконец, реализовать витрину mart_customer_risk_summary в dbt с полным пакетом доказательств — спецификация до SQL, тесты, влияние на контракт, отчёт ревьюера и ретроспектива. Зачёт можно проходить в одиночку или в паре (автор + ревьюер) — парный формат показывает, что ревью — это активная инженерная роль, а не пассивное чтение SQL. Работа оценивается по 25-балльной рубрике: 21+ балл означает готовность процесса к переносу на реальный дата-продукт.
Ключевые концепции: Grain (гранулярность): Источник истины для grain — это спецификация модели или контракт дата-продукта, а не SQL. Grain фиксирует, что каждой строке выходной витрины соответствует ровно один бизнес-объект (например, customer_id). Изменение grain всегда требует подтверждения человека, даже если SQL собирается «чисто».
Odps vs odcs: ODPS (Open Data Product Specification) описывает продукт и его потребителей: зачем витрина, кто её читает, какие вопросы она закрывает. ODCS (Open Data Contract Standard) — это технический контракт: схема, SLA, формат, владелец, версионирование. SDD Data использует оба: ODPS для продуктового смысла, ODCS для технического обещания.
Dbt-тесты vs контракт данных: dbt-тесты (not_null, unique, accepted_values, relationships) проверяют только часть формы и частичные свойства данных. Они не доказывают полноту спецификации, корректность методологии расчёта метрик и не заменяют продуктовый контракт. Зелёный dbt build — это гигиена, а не обещание.
Политика pii и запрещённые поля: Список запрещённых прямых PII (ФИО, email, телефон, паспортные данные) должен быть зафиксирован в спецификации модели, в AGENTS.md и в чек-листе ревьюера. По возможности он превращается в singular-тест или в макрос, сканирующий итоговую схему. Это превращает политику из лозунга в проверяемый артефакт.
Дрейф контракта (contract drift): Расхождение между контрактом/спецификацией и фактически реализованной моделью. Дрейф появляется, когда автор «маленького улучшения» молча меняет grain, добавляет поле, ослабляет тест или переименовывает сущность. Поймать дрейф до релиза — главная задача ревьюера.
Ломающие изменения: Изменение grain, переименование или удаление поля контракта, изменение семантики метрики, изменение PII-политики, изменение SLA. Добавление nullable-колонки обычно не ломающее, но может стать ломающим, если downstream-системы интерпретируют её как новую бизнес-метрику или она меняет grain.
Разделение ролей автора и ревьюера: Ревьюер должен проверять догадки автора, а не защищать их. Поэтому автор и ревьюер — разные роли (в парном зачёте — два разных студента). Ревьюер не редактирует файлы автора, а готовит отчёт с замечаниями к контракту, SQL, тестам и процессу отдельно.
Что доказывает dbt build: dbt build доказывает только исполнимость DAG и прохождение заявленных тестов на текущих данных. Он не доказывает полноту спецификации, корректность методологии, достаточность тестов и соответствие контракту потребителей.
Schema manifest vs спецификация модели: Schema Manifest (или schema.yml) описывает наблюдаемый источник: реальные колонки, типы, тесты. Спецификация модели описывает обещанную витрину: grain, потребитель, методология, PII-политика, приёмочные факты. Они связаны, но не взаимозаменяемы.
Raw-данные и «починка» под зелёный build: Raw-слой сохраняет вход как есть и не «чинится» ради зелёного dbt build. Семантика пустых значений и null решается в staging или явно прописывается в спецификации. Иначе вы прячете плохое качество данных за валидной моделью.
Проверочный факт (acceptance fact): Это артефакт, который должен содержать четыре элемента: команду (SQL/dbt/ручной шаг), ожидаемый результат, статус выполнения и того, кто его подтвердил. Без этих четырёх элементов «проверка» — это просто комментарий.
Подтверждение человеком (human confirmation): Требуется при изменении grain, политики PII, SLA, полей контракта или методологии расчёта риск-метрик. Это список ситуаций, в которых AI-ассистент не должен принимать решение сам, а должен остановиться и попросить подтверждение.
Важные даты: Этап 1 — спецификация до sql: Создание specs/models/mart_customer_risk_summary.md и приёмочных фактов до любого изменения кода
Этап 2 — заметка о влиянии на контракт: Фиксация того, является ли витрина новым дата-продуктом или расширением существующего, до реализации
Этап 3 — реализация и проверка: Написание dbt-модели, обновление models/schema.yml, запуск dbt build --profiles-dir .
Этап 4 — отчёт ревьюера: Парный ревью запускает data-contract-review и формирует отчёт с разделением фактов, допущений и подтверждений
Этап 5 — ретроспектива: Заполнение шаблона ретроспективы с оценкой того, что спецификация описала хорошо и что пришлось уточнять после SQL
Практические упражнения: Название: Блок 1. Письменные ответы на 12 быстрых вопросов SDD Data
Проблема: Ответьте письменно, без помощи AI-ассистента, на 12 вопросов: (1) Что является источником истины для grain? (2) Чем ODPS отличается от ODCS? (3) Почему dbt-тесты не заменяют контракт данных? (4) Где должен быть описан список запрещённых PII? (5) Что такое дрейф контракта? (6) Когда добавление nullable-колонки может быть ломающим изменением? (7) Почему автор и ревьюер должны быть разными ролями? (8) Что доказывает dbt build, а чего он не доказывает? (9) Чем Schema Manifest отличается от спецификации модели? (10) Почему raw-данные не нужно «чинить» ради зелёного dbt build? (11) Что должен содержать проверочный факт? (12) Когда требуется подтверждение человеком?
Решение: Эталонные ответы: (1) Спецификация модели или контракт дата-продукта, не SQL. (2) ODPS описывает продукт и потребителей; ODCS — технический контракт. (3) dbt-тесты проверяют часть формы/данных, но не весь продуктовый смысл. (4) В спецификации, AGENTS.md, чек-листе ревьюера и, по возможности, singular-тесте. (5) Расхождение между контрактом/спецификацией и фактической моделью. (6) Если она выглядит как новая бизнес-метрика, меняет grain или API ниже по цепочке. (7) Ревьюер должен проверять догадки автора, а не защищать их. (8) dbt build доказывает исполнимость DAG/тестов, но не полноту спецификации. (9) Манифест описывает наблюдаемый источник; спецификация модели описывает обещанную витрину. (10) Raw сохраняет вход; семантика пустых значений и null решается в staging/спецификации. (11) Команду, SQL или ручной шаг ревьюера, ожидание и статус. (12) При изменении grain, политики PII, SLA, полей контракта или методологии риска.
Сложность: intermediate
Название: Блок 2. Найдите 10+ проблем в слабой спецификации
Проблема: Дана намеренно слабая спецификация. Проанализируйте её и найдите все слабые места. Текст спецификации: «# Сводка риска клиента. Сделать полезную витрину риска клиентов. ## Данные. Использовать customer_360 и платежи. Добавить нужные поля риска. ## Проверка. Проверить, что данные корректные и нет персональных данных.»
Решение: Пошаговый разбор: 1) Не указано имя витрины — невозможно сослаться на артефакт в контракте. 2) Не указан потребитель — невозможно проверить полезность. 3) Не указана гранулярность (grain) — невозможно доказать уникальность строк. 4) «Полезную» — слово непроверяемо, не является критерием приёмки. 5) «Нужные поля» не определены — потребитель не сможет понять, что он получит. 6) Нет обязательных показателей — нечего тестировать. 7) Политика PII не превращена в тест по списку запрещённых полей — это лозунг, а не проверка. 8) Не описано влияние на контракт — невозможно понять, расширение это или новый продукт. 9) Нет списка входных моделей в виде источников — нечего валидировать в DAG. 10) Нет dbt-команд — нет воспроизводимой проверки. 11) Нет ручных фактов для ревьюера — нет доказательной базы. 12) Не сказано, является ли это новым продуктом или расширением — невозможно оценить риск изменения.
Сложность: intermediate
Название: Блок 3. Перепишите спецификацию в SDD Data-формате
Проблема: Перепишите слабую спецификацию из Блока 2 в полноценный SDD Data-формат с разделами: Назначение, Потребитель, Grain, Входы, Выходные поля, Политика PII, Влияние на контракт, Приёмочные факты, Открытые подтверждения. Ограничения: grain — одна строка на customer_id; входы — mart_customer_360 и mart_payment_risk_signals; поля — customer_id, risk_event_count, large_amount_event_count, last_risk_event_date; без прямых PII; проверки — customer_id not_null/unique, риск-счётчики not_null; существующий контракт mart_customer_360 не менять.
Решение: Образец переписанной спецификации:
# Спецификация модели: mart_customer_risk_summary
## Назначение
Витрина агрегированных риск-сигналов по клиенту для команд скоринга и антифрода. Не используется для маркетинга.
## Потребитель
Команда риск-моделирования, downstream-дашборд в BI; вторичный потребитель — антифрод-алерты.
## Grain
Одна строка на customer_id. Изменение grain запрещено без подтверждения владельца продукта.
## Входы
- mart_customer_360 — справочник клиентов, контракт зафиксирован, не меняется.
- mart_payment_risk_signals — события риск-признаков платежей.
## Выходные поля
- customer_id (PK, BIGINT, NOT NULL, UNIQUE)
- risk_event_count (INT, NOT NULL) — общее число риск-событий за 90 дней.
- large_amount_event_count (INT, NOT NULL) — число событий с суммой выше порога.
- last_risk_event_date (DATE, NULLABLE) — дата последнего события; NULL допустим, если событий нет.
## Политика PII
Запрещены прямые PII: ФИО, email, телефон, паспорт, адрес. Используется только customer_id как квазиидентификатор. Список запрещённых полей проверяется singular-тестом no_pii_columns на схему итоговой модели.
## Влияние на контракт
Новый дата-продукт, не расширение существующего. Контракт mart_customer_360 не меняется. Зависимости downstream: BI-дашборд риска начинает читать mart_customer_risk_summary вместо ad-hoc SQL.
## Приёмочные факты
1. dbt run на модели mart_customer_risk_summary — успех.
2. dbt test на not_null + unique customer_id — успех.
3. dbt test на not_null риск-счётчиков — успех.
4. singular-тест no_pii_columns — успех.
5. Ручной факт ревьюера: визуальная проверка 5 случайных customer_id через BI — соответствие.
## Открытые подтверждения
- Порог large_amount: требует подтверждения владельца риск-модели.
- Окно 90 дней: требует подтверждения потребителя BI-дашборда.
Сложность: intermediate
Название: Блок 4. Итоговый проект — реализация mart_customer_risk_summary
Проблема: Добавьте новую витрину mart_customer_risk_summary в dbt-проект. Требования: grain «одна строка на customer_id»; входы — mart_customer_360 и mart_payment_risk_signals; поля — customer_id, risk_event_count, large_amount_event_count, last_risk_event_date; без прямых PII; dbt-тесты; спецификация модели и проверочные факты; заметка о влиянии на контракт; отчёт ревьюера. Следуйте процессу из 10 шагов: от рабочего дерева до ретроспективы.
Решение: Пошаговое решение по процессу:
- Создайте чистую ветку git: git checkout -b feat/mart-customer-risk-summary.
- Создайте файл specs/models/mart_customer_risk_summary.md со спецификацией из Блока 3 — это происходит до любого SQL.
- До SQL опишите приёмочные факты: список dbt-команд, ручных шагов и ожиданий. Например: «dbt test -m mart_customer_risk_summary ожидает 4 зелёных теста».
- Опишите влияние на контракт: «Новый дата-продукт, расширения mart_customer_360 нет, downstream BI-дашборд переключается на новую витрину».
- Реализуйте модель models/marts/mart_customer_risk_summary.sql. Пример SQL:
{{ config(materialized='table') }}
with payments as (
select customer_id, event_date, amount, is_risk_event
from {{ ref('mart_payment_risk_signals') }}
),
agg as (
select
customer_id,
count(*) filter (where is_risk_event) as risk_event_count,
count(*) filter (where is_risk_event and amount > 100000) as large_amount_event_count,
max(event_date) filter (where is_risk_event) as last_risk_event_date
from payments
group by 1
)
select c.customer_id, a.risk_event_count, a.large_amount_event_count, a.last_risk_event_date
from {{ ref('mart_customer_360') }} c
left join agg a using (customer_id)
- Обновите models/schema.yml: добавьте модель, описание, тесты not_null и unique на customer_id, not_null на риск-счётчики.
- Запустите dbt build --profiles-dir . — все тесты должны быть зелёными.
- Подготовьте отчёт ревьюера (партнёр по парному зачёту): разделите замечания на факты (что проверено), допущения (что принято на веру) и открытые подтверждения (что требует владельца продукта).
- Запишите в specs: меняет ли витрина существующие контракты (в данном случае — не меняет, mart_customer_360 остаётся как был).
- Если ревьюер нашёл дрейф (например, last_risk_event_date стал NOT NULL вместо NULLABLE) — исправьте спецификацию или SQL до мержа.
Сложность: intermediate
Кейсы: Название: Кейс 1: Витрина риска клиента — новый дата-продукт с нуля
Сценарий: Команда риск-моделирования в финтех-компании просит data-инженера собрать витрину агрегированных риск-сигналов по клиенту. До этого BI-дашборд собирал данные ad-hoc SQL прямо поверх mart_customer_360 и сырых платежей. Витрина должна заменить ad-hoc запросы и стать источником для антифрод-алертов.
Задача: Первоначальная спецификация от аналитика звучала как «сделать полезную витрину риска клиентов». Не было указано: имя витрины, потребитель, grain, обязательные поля, PII-политика, влияние на существующий контракт mart_customer_360, критерии приёмки. Риск: data-инженер делает «удобную» модель с джойном, которая технически собирается, но не отвечает на вопрос риск-команды и ломает BI-дашборд.
Решение: Инженер остановил работу до SQL. Совместно с владельцем продукта и аналитиком зафиксировали: grain = одна строка на customer_id; три обязательных поля (risk_event_count, large_amount_event_count, last_risk_event_date); список запрещённых PII (ФИО, email, телефон, паспорт, адрес) превращён в singular-тест no_pii_columns; влияние на контракт — новый дата-продукт, mart_customer_360 не меняется; приёмочные факты включают как dbt-тесты, так и ручную проверку 5 случайных customer_id в BI. После утверждения спецификации написана модель, прогнан dbt build, ревьюер подготовил отчёт с разделением фактов и допущений.
Результат: Витрина внедрена в прод за один спринт. BI-дашборд переключился на новую витрину, ad-hoc SQL-скрипты выпилены. Антифрод-алерты стали стабильнее, так как исчезла вариативность ad-hoc запросов. Зачёт по рубрике: 23/25 баллов — потеря 2 балла на разделе «приёмочные факты» (в первой итерации ручной шаг ревьюера не был описан).
Извлечённые уроки: Слабая спецификация — это нормальная стартовая точка; задача инженера — остановить её до SQL и превратить в полноценный SDD Data-артефакт
Запрещённый список PII должен превращаться в исполняемый singular-тест, а не оставаться лозунгом в чате
Ручные приёмочные факты (визуальная проверка в BI) обязательны — dbt-тесты не покрывают продуктовый смысл
Разделение «новый продукт» vs «расширение существующего» — это контрактное решение, а не техническое
Связанные концепции: Grain как источник истины
ODPS vs ODCS
Политика PII и singular-тест
Приёмочные факты (команда + ожидание + статус + подтверждающий)
Влияние на контракт: новый продукт vs расширение
Название: Кейс 2: Дрейф контракта при «маленьком улучшении»
Сценарий: В существующей витрине mart_customer_360 автор добавил nullable-колонку date_of_birth в рамках задачи «обогатить профиль клиента для аналитики оттока». Автор не остановился и не согласовал изменение с владельцем продукта, потому что колонка nullable и «ничего не ломает».
Задача: Через неделю команда антифрода построила дашборд, который фильтровал клиентов по date_of_birth. Это нарушило политику PII (компания запрещает обработку даты рождения вне KYC-контура). Дрейф не был пойман, потому что: (а) в спецификации не было списка запрещённых PII с проверкой; (б) ревьюер проверял только SQL, а не контракт; (в) dbt-тесты прошли — формально всё зелёное.
Решение: Постфактум: колонку удалили, добавили singular-тест no_pii_columns во все витрины marts, обновили AGENTS.md списком запрещённых полей, пересмотрели процесс ревью так, чтобы ревьюер сверялся со спецификацией и политикой PII до мержа. В следующей итерации аналогичное «маленькое улучшение» было поймано ревьюером на этапе спецификации.
Результат: Инцидент привёл к формальному запрету добавлять поля в существующие витрины без подтверждения владельца продукта. Процесс ревью расширен обязательной сверкой с политикой PII и ODCS-контрактом. После доработок аналогичные попытки дрейфа ловились до релиза в 100% случаев за следующие 3 месяца.
Извлечённые уроки: Nullable-колонка может быть ломающим изменением, если downstream начинает её использовать как бизнес-метрику или нарушает PII-политику
dbt build зелёный ≠ контракт цел
Список запрещённых PII должен быть исполняемым артефактом, а не документом в Confluence
Ревьюер проверяет догадки автора, а не SQL — это активная роль
Связанные концепции: Дрейф контракта
Ломающие изменения
Что доказывает dbt build
Разделение ролей автора и ревьюера
PII-политика как исполняемый тест
Название: Кейс 3: Парный зачёт — опыт разделения ролей автора и ревьюера
Сценарий: Два junior-инженера проходят парный зачёт по SDD Data. Студент А — автор витрины mart_marketing_attribution; студент Б — ревьюер. Оба только что прошли курс и впервые применяют методологию на практике.
Задача: Автор склонен «доработать напильником» SQL без возврата к спецификации. Ревьюер склонен одобрять правки «по мелочи», чтобы не тормозить процесс. Оба рискуют свести зачёт к формальному прогону dbt build без реальной проверки контракта.
Решение: Перед стартом зачёта пара зафиксировала правила: ревьюер не редактирует файлы автора; все замечания пишутся в отчёт с разделением на блоки «Контракт», «SQL», «Тесты», «Процесс»; автор после первой витрины меняется ролью с ревьюером для второй. Ревьюер использует чек-лист data-contract-review: сверяет фактическую схему со спецификацией, прогоняет singular-тест PII, проверяет, что приёмочные факты выполнены. Автор после первой итерации увидел в отчёте ревьюера три дрейфа: (1) добавлена колонка region без согласования; (2) не описан метод расчёта attribution_window; (3) тесты покрывают только not_null, нет accepted_values для атрибуционных каналов.
Результат: Первая витрина получила 18/25 — не дотянула до «можно переносить в прод», но дала материал для ретроспективы. После смены ролей вторая витрина получила 23/25 — оба студента отметили, что роль ревьюера дала гораздо больше, чем роль автора, потому что заставляет формализовать свои критерии приёмки.
Извлечённые уроки: Парный формат снимает иллюзию, что ревью — пассивное чтение SQL
Смена ролей автор↔ревьюер помогает понять, какие критерии приёмки реально работают
Отчёт ревьюера должен отделять факты, допущения и открытые подтверждения — иначе это просто комментарии
Ретроспектива после зачёта — это не отписка, а вход для следующей фазы: если «что пришлось уточнять после SQL» больше 3 пунктов, фазу надо сузить
Связанные концепции: Разделение ролей автора и ревьюера
Отчёт ревьюера (факты, допущения, подтверждения)
Ретроспектива SDD Data
Рубрика 25 баллов
Парный формат зачёта
Советы по изучению: Не пытайтесь «перескочить» к SQL — пишите спецификацию и приёмочные факты строго до кода. Это самая частая причина низких баллов по рубрике.
Сделайте чек-лист из 12 быстрых вопросов Блока 1 на карточке и проходите его перед каждой фичей — это займёт 5 минут и сэкономит часы переделок.
Заведите шаблон спецификации в specs/models/ и не правьте его «по мелочи» без возврата к владельцу продукта. Любое изменение спецификации = изменение контракта.
Превращайте политику PII в singular-тест no_pii_columns сразу, в той же итерации. Лозунг «у нас нет PII» без проверки = дрейф, который случится на следующей неделе.
Договоритесь с коллегой/напарником о парном формате. Если напарника нет, попросите AI扮演 роль ревьюера через сценарий /clear + data-contract-review, но финальный отчёт всё равно покажите человеку.
Ведите журнал «открытых подтверждений» в спецификации — это снижает шанс, что Qwen Code «угадает» методологию и сделает необратимое предположение.
Запускайте dbt build с --profiles-dir . и фиксируйте вывод в артефакт — это ваш первый приёмочный факт. Скриншот/лог храните вместе со спецификацией.
После зачёта не пропускайте ретроспективу. Если в разделе «что пришлось уточнять после SQL» больше 3 пунктов, следующую фичу уменьшайте или описывайте подробнее.
Используйте рекомендованные Qwen-сценарии (создание спецификации → реализация → ревью) как буквальный скрипт: /clear + контекст + явный запрет писать код на первом шаге.
Помните: 21+ балла по рубрике — это «можно переносить на реальный дата-продукт». Если вы набрали 16–20 — это не провал, но проверку и ревью нужно усилить до переноса в прод.
Дополнительные ресурсы: Open data product specification (odps): Спецификация для описания продукта и потребителей дата-продукта — bitol.io/odps или актуальная версия на сайте bitol.io. Используется как шаблон раздела «Назначение» и «Потребитель».
Open data contract standard (odcs): Технический контракт дата-продукта — bitol.io/odcs. Используется как шаблон раздела «Выходные поля» и «Влияние на контракт».
Dbt documentation — tests: Документация по dbt-тестам (not_null, unique, accepted_values, relationships, singular). Источник для раздела «dbt-проверки» в спецификации.
Dbt documentation — contracts: Документация по dbt contracts — enforce_schema, enforce_not_null. Полезно для раздела «Влияние на контракт» в спецификации модели.
Agents.md в корне проекта: Файл, в котором фиксируется политика PII, запрещённые поля, стек, ограничения. Должен читаться AI-ассистентом до любых предложений по коду.
Qwen code — сценарий data-contract-review: Внутренний сценарий ревью в Qwen Code. Запускается после реализации и проверяет изменение против спецификации, политики PII, тестов и приёмочных фактов без редактирования файлов автора.
Шаблон ретроспективы sdd data: Markdown-шаблон с разделами «Что спецификация описала хорошо / Что пришлось уточнить после SQL / Какие проверки поймали ошибку / Где Qwen Code пытался угадать смысл / Что усилить перед переносом в боевой контур». Должен заполняться после каждого зачёта и крупной фичи.
Резюме: Часть 22 «Практический зачёт» — это финальная проверка не знания dbt-синтаксиса, а способности удержать обещание дата-продукта от спецификации до отчёта ревьюера. Ключевая мысль: зачёт начинается с намеренно слабой спецификации («сделать полезную витрину»), и хороший инженер должен остановить её до SQL. Зачёт состоит из четырёх блоков: 12 письменных вопросов на терминологию SDD Data (grain, ODPS vs ODCS, дрейф контракта, PII, dbt build, проверочные факты, человеческое подтверждение); задание найти 10+ проблем в слабой спецификации; переписать её в полноценный SDD Data-формат; реализовать витрину mart_customer_risk_summary с полным пакетом доказательств — спецификация до SQL, dbt-тесты, влияние на контракт, отчёт ревьюера, ретроспектива. Парный формат показывает, что ревью — это активная роль. Оценка по 25-балльной рубрике: 21+ балл — процесс можно переносить на боевой дата-продукт; 16–20 — результат полезен для обучения, но проверку и ревью нужно усилить; ниже 16 — фаза слишком большая или спецификации не удерживают смысл. Главный практический вывод: если в ретроспективе «что пришлось уточнить после SQL» больше трёх пунктов, следующую фичу надо уменьшить или описать подробнее до реализации.