DarkRiDDeR13 мин

Полевой журнал продуктовой метрики: evidence до решения

МетрикиПроцессы

Самая дорогая ошибка в продуктовой метрике часто происходит не в SQL и не в графике. В review остаётся фраза «conversion вырос», но не остаётся периода, cohort, definition и guardrail. Через неделю никто не может повторить расчёт или объяснить, почему выпуск состоялся. Цена ошибки — повторная работа, спор об owner и решение, которое нельзя защитить evidence.

Причина — результат отделён от решения. Dashboard хранит число, а контекст живёт в сообщениях и памяти участников. Проверка — собрать короткий decision record до discussion: изменение, causal hypothesis, event contract, denominator, cohort/period, guardrail, evidence и limitation. Действие — отправить на human decision только карточку без red flags; остальные остановить и вернуть владельцу измерения.

Карточка решения должна помещаться в review

Fixed synthetic decision record
ПолеЗначениеВопрос reviewer
Decisionleave / hold после human reviewкакой риск принимаем?
Hypothesisформа без ожидания помогает пройти confirmкакое звено наблюдаем?
Attributionsame subject and requestкак confirm связан с вариантом?
Window2025-07-14одинаков ли период cohort?
Local metricconfirmed unique subjects / opened unique subjectsкаков denominator?
Guardrailrender_failed / openedчто останавливает выпуск?
Limitationfixed synthetic onlyчего evidence не доказывает?
Цикл evidence для product decision: определить change и hypothesis, зафиксировать event contract, проверить cohort-period-denominator и guardrail, затем создать human decision record либо HOLD с причиной ремонта.
Decision loop специально заканчивается человеком и ограничением. Рисунок не превращает один metric delta в автоматический ship.

Карточка хранит условия решения, а не красивый итог

Cohort — это группа с одним вариантом, attribution — правило связи попытки и подтверждения, denominator — множество открывших, guardrail — отдельное ограничение на ущерб. В field record они нужны не для терминологической полноты, а чтобы reviewer увидел, какое поле надо вернуть владельцу измерения. Если отсутствует хотя бы одно, фраза «conversion вырос» не становится решением.

Здесь нет настоящего пользователя, записи сессии или telemetry: subject и requestId — fixed synthetic labels. Они показывают место для связи, но не советуют хранить реальный идентификатор. Модуль создаёт только decision hand-off или HOLD; он не запрашивает dashboard и не выпускает вариант.

Как выглядит полезный negative path

В этой теме остановка — результат, а не исключение. Если checkout_confirmed пришёл без requestId, отчёт не должен гадать, к какому открытию его отнести. Если в treatment попал следующий день, отчёт не должен выровнять его средним. Если denominator стал all-events, расчёт не должен сохранять прежнее название conversion. Каждая ветка возвращает короткую причину и владельца ремонта: instrumentation owner, query owner или experiment owner.

import { createFixedProductMetricInput, inspectFixedProductMetric, prepareFixedProductDecision } from './upgrade-2025-07.mjs';

const report = inspectFixedProductMetric(
  createFixedProductMetricInput('fixed-mixed-period-v1'),
);
console.log(prepareFixedProductDecision(report));
// Expected: stop-before-product-decision with mixed-cohort-or-period.
// The input is fixed in-memory synthetic data; nothing is published or sent.

Такой путь полезен на review: вместо «данных мало» он говорит, какое именно условие нарушено. Вызов не исправляет cohort и не меняет production. Он только не разрешает перейти к решению. Это важно для ответственности: владелец интерфейса не обязан чинить SQL, а владелец metric contract не обязан объяснять UX-гипотезу. Карточка связывает их по явному полю, а не по догадке.

Порядок полевой проверки

  1. Сначала прочитать решение. Если нельзя закончить фразой «оставить или остановить вариант при таких условиях», метрика ещё не выбрана.
  2. Затем проверить событие. Имя, subject, cohort, period и ключ attribution должны быть записаны до query.
  3. Разложить ratio. Отдельно вывести unique numerator и unique denominator; не подменять субъект строкой telemetry.
  4. Посмотреть guardrail тем же срезом. Если у него другой период или population, назвать ограничение, не сравнивать молча.
  5. Прогнать один отрицательный вход. Missing attribution, mixed period или wrong denominator обязан привести к HOLD.
  6. Зафиксировать evidence. Ссылка на definition, запрос, owner и следующий check делают результат воспроизводимым.

Что делать, когда local metric двигается

Сначала не объявлять успех. Сверить, что метрика использует тот же event schema и что набор субъектов не менялся. Затем показать guardrail и diagnostic split: отдельно cohorts, period и numerator/denominator. Только после этого reviewer решает, нужно ли расширять наблюдение, повторять запуск или менять реализацию. Этот порядок короче бесконечного dashboard tour, потому что каждый шаг отвечает на отдельный риск.

Статья о metric pitfalls предупреждает, что другой состав выборок может исказить направление delta, а потеря telemetry может быть одним из источников bias. Это подтверждает необходимость проверки, но не создаёт готовый pipeline. В конкретном проекте нужно отдельно проверить privacy, retention, идентификаторы и задержку событий. Synthetic requestId здесь лишь показывает место связи; он не является советом хранить реальный идентификатор пользователя.

Ограничение и следующий проверяемый шаг

Полевой журнал не обещает, что команда научится доказывать все product effects. Он делает неизвестное явным: какую связь мы наблюдаем, какое ухудшение не принимаем и чего не хватает для решения. В этом пакете нет реальных пользователей, денег, инцидентов, SQL, сети или production query. Поэтому его fixture проверяет только deterministic stop branches и отсутствие side effect.

Следующий шаг: добавьте к одному существующему review ровно четыре строки — decision, denominator, guardrail и limitation. Затем попросите другого инженера восстановить query только по карточке. Если он не может понять cohort или period, не улучшайте визуализацию: сначала исправьте event contract. Ожидаемый результат — спор о выпуске превращается в список проверяемых условий.

Историческая граница июля 2025

Источники ограничены материалами, существовавшими до 31 июля 2025: Microsoft Research 2017/2019 и OpenTelemetry v1.31.0. Их утверждения отделены от нашего процесса: они поддерживают ценность раздельных metric roles, документированного события и проверки состава выборки. Формат журнала, synthetic literals и решение HOLD — практическая схема автора, а не обещание framework.

Проверяемые источники

  • OpenTelemetry Semantic Conventions v1.31.0, events (immutable commit c01aa89, 11 March 2025) — версия: tag v1.31.0; immutable commit c01aa89d9a13042e56536c60975139c50e764796, 2025-03-11. Событие имеет уникальное имя; структура события и применимые attributes должны быть документированы, а dynamic values не должны становиться частью имени. Граница: Это соглашение о семантике telemetry. Оно не определяет продуктовую метрику, causal effect, выбор denominator или критерий ship.
  • Microsoft Research: Safe Velocity with Controlled Rollouts (ICSE-SEIP 2019) — версия: ICSE-SEIP 2019 author version, published 2019; HTTPS checked 2026-07-31. Работа различает local feature, success и guardrail metrics; guardrail нужен, чтобы выпуск не ухудшал важные показатели, а local metric помогает объяснить движение более общей метрики. Граница: Это описание controlled rollouts Microsoft. Оно не доказывает, что любое изменение local metric вызвало пользовательский результат в другом продукте.
  • Microsoft Research: A Dirty Dozen Metric Interpretation Pitfalls (KDD 2017) — версия: KDD 2017 author version, published 2017; HTTPS checked 2026-07-31. Работа показывает, что разные наборы наблюдений в treatment и control делают metric delta недостоверной; рекомендует разбирать numerator и denominator и отслеживать telemetry loss. Граница: Пример относится к controlled experiments. Он не заменяет дизайн эксперимента, расчёт мощности, privacy policy или проверку конкретного pipeline.