ADR 0089 — analytics и delivery-metricas становятся скриптом отчёта
- Статус: Принят
- Дата: 2026-08-16
- Контекст: решение владельца продукта заранее ввести две роли
целевой модели (
docs/fluxo.yml), не дожидаясь органического триггера - Родственная часть: ADR 0085
(
docs/fluxo.yml); прямой прецедент ФОРМЫ:apps/api/scripts/medir-execucao.ts(Фаза 13b)
Контекст
docs/fluxo.yml уже описывал две роли целевой модели как
status: proposto, у каждой из которых уже был записан недостающий
критерий разделения для перехода в active:
analytics(Analytics Engineer, метрика ПРОДУКТА) — «поглощенаmedicao(которая покрывает только метрику ВЫПОЛНЕНИЯ)», с критерием «день, когдаmetricas-de-produtoстанет обязательным входом PO»;delivery-metricas(Delivery Manager, поток — DORA) — «поглощенаmedicao(частично)», с критерием «никогда не становится агентом; становится ОТЧЁТОМmedicao(lead time, deployment frequency, MTTR, change failure rate, извлечённые из event log +gates.yml)».
Ни один из двух триггеров не сработал органически. Владелец продукта решил
всё равно заранее построить: воронка сессия → commit → PR → merge и
реальный срез DORA (lead time, deployment frequency) уже
извлекаемы из данных, которые продукт уже записывает, — proposed_actions.execution_result
для трёх git-действий, которые производит dev agent
(apps/api/src/domain/git/git-action-execution-result.ts), и
docs/gates.yml для gate backmerge. Ожидание органического триггера
отложило бы отчёт, который уже возможен.
Решение
Обе роли становятся status: active в docs/fluxo.yml, а материализует
их ОДИН скрипт — apps/api/scripts/analise-funil.ts
(pnpm --filter api analise:funil -- --projeto <uuid> [--json]) — в
ТОМ ЖЕ формате, что apps/api/scripts/medir-execucao.ts:
NestFactory.createApplicationContext(AppModule), обязательный аргумент
--projeto <uuid>, чистое чтение через Drizzle, ноль записи в
базу, вывод Markdown по умолчанию и --json для программного потребления.
Это не новая функция продукта: это форма, которую сам
docs/fluxo.yml уже предписывал для обеих ролей, только построенная
до предусмотренного триггера. Ни GenServer, ни агента LLM, ни нового
HTTP-маршрута.
Что скрипт измеряет ПО-НАСТОЯЩЕМУ
- Настоящая воронка (
calcularFunil): сколько сессий произвели хотя бы одинexecutedgit_commit,pr_openиgit_merge, и коэффициент конверсии между последовательными этапами. Считает СЕССИИ, а не действия. - Настоящий lead time (
calcularLeadTimes): от первогоexecutedgit_commitдо первогоexecutedgit_mergeтой же сессии, используяupdated_at— момент, когдаExecuteGitActionUseCaseпо-настоящему записалexecution_result, а не когда действие было предложено. - Настоящая deployment frequency (
deploymentFrequencyPorDia):executedgit_merge, чейtargetBranchнаходится вPROTECTED_BRANCHES, сгруппированные по дням. Сопоставляется по ССЫЛКЕ с gatebackmerge(docs/gates.yml) — его доказательство — CI (.release/gate.json), вне досягаемости скрипта, который лишь читает базу, поэтому никакого соединения данных нет, лишь тот же срез ветки.
Что скрипт ОБЪЯВЛЯЕТ отсутствующим и почему это не «недостающие данные»
Три метрики остаются в разделе вывода «Не измерено, намеренно», и решение оставить их так постоянно, пока не изменятся предусловия ниже, — это не пробел, который нужно закрыть в следующем раунде:
- Полная продуктовая воронка (идея → commit). У
sessionsнетstoryId— RN-230 уже объявляет этот пробел во вкладке Criativo (apps/web/src/routes/ProjectSessionsTab.tsx). Его закрытие потребовало бы новой схемы (новый столбец, возможно migration вsessionsили связующая таблица), вне охвата этого направления по принципу: никаких migrations в этом раунде. - Доказательство принятия по функции. В отличие от первого, это не данные, которые не хватает СОБРАТЬ: это возможность, у продукта для которой сегодня нет никакого ПУТИ. Brabo не инструментирует проекты, которые он СТРОИТ, — не существует конвейера телеметрии использования, выходящего из сгенерированного кода, ни продуктового решения о том, как бы он существовал. Объявить «отсутствует» здесь следовало тому же принципу, что ADR 0042 для оценки модели и ADR 0077 (RN-210) для «идеального» рейтинга: никогда не приближать числом, которое казалось бы настоящим.
- MTTR и change failure rate. Оба требуют сигнала ИНЦИДЕНТА
реального production, та же зависимость, которую
docs/fluxo.ymlуже фиксирует для ролейsecops-runtime/platform(status: proposto/planned, включение синхронизировано сDEPLOY_ENABLED). Это работа другого направления, не этого.
Последствия
docs/fluxo.yml:analyticsиdelivery-metricasпереходят изstatus: propostoвstatus: active, сsaidas_alvo, переписанным вsaidas(то, что реально сегодня), плюс явное полеlacunas(то, что остаётсяstatus: lacuna, без удаления объявления).apps/api/package.json: новая запись"analise:funil".- Ни migration, ни нового HTTP-маршрута, ни нового экрана.
- RN-320..322 в
docs/business-rules.mdпокрывают форму скрипта (RN-320), семантику воронки и lead time (RN-321) и deployment frequency плюс три объявленных отсутствия (RN-322).
Рассмотренные альтернативы
Ждать органического триггера каждой роли. Это был стандартный план
docs/fluxo.yml, и он остаётся поведением модели команды по умолчанию
для остальных ролей proposto. Отвергнуто здесь лишь потому, что владелец
продукта явно решил ввести заранее, — это не прецедент для заблаговременного ввода
остальных ролей proposto без эквивалентного решения.
Агент LLM analytics, читающий базу и пересказывающий воронку.
Отвергнуто по самому критерию разделения, который docs/fluxo.yml уже
объявлял для delivery-metricas («никогда не становится агентом») и который это
решение распространяет на analytics: отчёт детерминирован — суммирует,
группирует, фильтрует по статусу — и не нуждается в модели для интерпретации.
Агент здесь был бы расходом на LLM без прироста информации.
Приблизить три отсутствующие метрики через прокси (напр.: считать
chat.message прокси «использования» или время до следующего commit —
прокси MTTR). Отвергнуто: прокси, который выглядит как настоящая метрика и
не является ею, — это ошибка, которую ADR 0042 уже назвал для оценки модели, — лучше
«—» с записанной причиной, чем число, которое учит неправильному.
Ссылки
docs/fluxo.yml(блокиid: analytics,id: delivery-metricas)apps/api/scripts/analise-funil.ts/apps/api/scripts/medir-execucao.ts(прецедент формы, Фаза 13b)apps/api/src/domain/git/git-action-execution-result.tsdocs/gates.yml(gatebackmerge)- RN-230 — пробел идея → commit, уже объявленный во вкладке Criativo
- ADR 0042 — принцип никогда не притворяться, что существуют несуществующие данные
- ADR 0077 — тот же отказ, применённый к «идеальной модели»