Приватность и отчёт «State of CI Failures»
Как Exlogare готовит ежеквартальный публичный отчёт о причинах падений CI — что попадает в агрегаты, что мы никогда не публикуем и как отключить участие.
Exlogare ежеквартально публикует открытый отчёт State of CI Failures — YYYY Qn о главных причинах падений CI у наших клиентов. Отчёт собирается автоматически из тех же RCA, которые питают ваш дашборд, но с жёсткими правилами приватности, зашитыми в pipeline агрегации.
Эта страница описывает, что туда попадает, что — никогда, и как отказаться от участия.
Что мы публикуем
В каждом выпуске State of CI Failures:
- Топ первопричин — представительная формулировка root cause, число команд, у которых эта причина встречалась (
k), суммарные хиты и severity. - Топ провайдеров CI — количество падений по каждому провайдеру (
github_actions,gitlab,bitbucket,circleci,jenkins,drone,teamcity,generic, …), чтобы видеть концентрацию. - Narrative-секция, которую пишет человек из команды Exlogare и где разбирает тренды и даёт ссылки на product docs.
Черновики генерируются автоматической квартальной задачей и проходят ручной review до публикации. В тело черновика попадают только агрегаты — человек добавляет интерпретацию, но не дополнительные строки.
Чего мы не публикуем никогда
В pipeline агрегации зашиты три жёстких правила. Их нельзя обойти ручной правкой.
- Opt-out проверяется в момент агрегации, не в момент публикации. Если команда выключила Делиться анонимной статистикой, она исключена из следующего квартального прогона. Проверка делается по живому значению
tenants.share_anonymized_stats; мы не кэшируем флаг. - k-anonymity = 5. Кластер попадает в отчёт, только если его видели минимум 5 разных команд. Всё, что ниже этого порога, просто отбрасывается. Этот же порог неявно действует и для топа провайдеров через ту же выборку.
- Никаких идентификаторов. Агрегатор никогда не отдаёт tenant id, project id, путь проекта, имя репозитория, имя ветки, commit SHA, email пользователя или URL пайплайна. Падения группируются по SHA-1 от нормализованного root cause + severity — fingerprint считается в момент анализа.
Fingerprint — односторонний хэш. Даже сотрудник Exlogare не может восстановить исходный текст первопричины из fingerprint, не имея доступа к самому ряду анализа в вашем tenant.
Как работает агрегация
Квартальная задача запускается в 10:00 UTC 2-го января, апреля, июля и октября. Она агрегирует предыдущий календарный квартал (≈92 дня) строк failure_clusters у tenant’ов с share_anonymized_stats = true. На выходе — два ряда BlogPost: state-of-ci-YYYY-qN для lang=en и lang=ru, оба с published_at = NULL.
Если черновик с этим slug уже существует, задача его не перезаписывает — повторный запуск идемпотентен.
Как отключить
- В дашборде: Settings → Приватность → выключить Делиться анонимной статистикой.
- Через API:
PATCH /api/tenants/me/privacyс телом{"share_anonymized_stats": false}. Доступно любому аутентифицированному участнику команды.
Изменение применяется сразу. Если выключить в середине квартала, вы исключены из ближайшей квартальной агрегации и всех последующих, пока флаг не будет включён обратно. Уже опубликованные отчёты не пересобираются (это markdown-строки в блоге), но в них и так никогда не было идентификаторов вашей команды.
Зачем нужен баннер
Когда пользователь из вашей команды впервые открывает дашборд после введения этого флага, на странице Overview появляется баннер с просьбой подтвердить или отключить участие. Любое из действий — Оставить включённым, Отключить или X — фиксирует выбор и проставляет share_anonymized_stats_acknowledged_at. Баннер больше не появляется.
Audit-трейл
Каждое переключение флага приватности записывается в audit log команды под action’ом tenant_privacy_updated — с email актора и предыдущим / новым значениями. Audit log живёт в дашборде в Settings → Журнал событий (нужна роль admin) и экспортируется в CSV.
Ссылки
- Кластеры падений — откуда берутся per-team
countиfingerprint_hash. - API-токены — для PATCH
/api/tenants/me/privacyтокен с scopereadне нужен, используются обычные сессионные учётные данные.