Назад к блогу

Поток баг-репортов от LLM: как мейнтейнеры ядра справляются с лавиной уязвимостей

Поток баг-репортов от LLM: как мейнтейнеры ядра справляются с лавиной уязвимостей

Поток баг-репортов, который LLM-агенты обрушили на мейнтейнеров ядра Linux, заставил пересмотреть и правила приёма отчётов, и сам процесс выпуска обновлений. Разбираем, как мейнтейнеры отличают полезный вклад от шума, по каким правилам маршрутизируются уязвимости и почему Canonical перешла на новую схему SRU.

Автоматизированный поиск ошибок большими языковыми моделями и ИИ-агентами породил поток отчётов, который обрушился на списки рассылки ядра Linux. Разбираем, как устроена механика фильтрации этого потока: что мейнтейнеры считают security-багом, как отчёт маршрутизируется к нужным людям, какие требования к формату зафиксированы в документации и что показывают замеры LLM-агентов на реальных уязвимостях.

Позиция мейнтейнеров: отчёты от ИИ считаются публичными

Официальная позиция мейнтейнеров ядра состоит в том, что отчёт об ошибке, найденной с помощью ИИ, следует считать публичным: если для выявления бага привлекался ИИ, к нему нужно относиться как к публичному. При этом публично делиться воспроизводителем запрещено, так как это может причинить вред: можно лишь упомянуть, что он есть, а мейнтейнеры могут запросить его приватно, если он им нужен.

Документация security-bugs фиксирует конкретные требования к таким отчётам:

  • отчёт должен начинаться с чёткого резюме проблемы и всех критических деталей — файлов, версий, влияния — чтобы важное было видно сразу;
  • отчёт должен быть простым текстом без Markdown-разметки;
  • оценка влияния опирается только на проверяемые факты, без перечисления спекулятивных последствий;
  • ИИ-инструмент обязан предоставить воспроизводитель и тщательно его протестировать — если воспроизводитель не работает или отсутствует, обоснованность отчёта ставится под серьёзное сомнение;
  • если исправление нельзя протестировать из-за редкого оборудования или почти исчезнувших сетевых протоколов, проблема, вероятно, не является security-багом.

Линус Торвальдс поднял эту тему в сообщении к релиз-кандидату. Его претензия — не к самому факту использования ИИ, а к качеству результата: в списки рассылки попадает слишком много отчётов, найденных одними и теми же AI-инструментами, которые часто дублируют уже известные или исправленные проблемы. Если человек просто пересылает найденный нейросетью отчёт, не понимает проблему и не проверяет, была ли она уже разобрана, это не помогает разработке ядра: мейнтейнеры тратят время на сортировку сообщений, перенаправление их нужным людям и объяснение, что проблема уже обсуждалась или исправлена. Ядру нужны не случайные отчёты, а полезный вклад — лучше присылать патчи, устраняющие проблему. При этом Торвальдс не выступил против AI-инструментов как таковых: они могут быть полезны для повышения безопасности ПО, включая ядро Linux, если действительно помогают находить и исправлять ошибки. Проблема начинается там, где вместо улучшения процесса появляется поток однотипных сообщений и иллюзия полезной работы.

Масштаб лавины и реакция Canonical

Масштаб потока виден по бюллетеням дистрибутивов: один выпуск бюллетеня Ubuntu для ядра Azure от 22 сентября перечислял более 1400 исправленных CVE, а другие обновления того же дня содержали десятки и сотни записей. При этом риск нельзя оценивать одним количеством идентификаторов: часть ошибок не затрагивает конкретные конфигурации, тогда как отдельные проблемы Linux уже используются в реальных атаках.

Canonical связывает ускорение прежде всего с резким ростом числа CVE, вызванным автоматизацией поиска ошибок большими языковыми моделями и специализированными ИИ-агентами. Второй фактор — с февраля 2024 года kernel.org получил статус CVE Numbering Authority и начал самостоятельно присваивать идентификаторы потенциальным проблемам ядра. Из-за роли ядра почти любая ошибка теоретически может затронуть безопасность, даже если путь эксплуатации не очевиден в момент исправления, что резко увеличило число записей для разбора дистрибутивами.

Именно поэтому Canonical переводит стабильные ядра на новую схему SRU: вместо четырёхнедельного цикла обычных обновлений и отдельного двухнедельного цикла безопасности остаётся единый двухнедельный процесс. Двухнедельные циклы запускаются с интервалом в неделю и перекрываются, что позволяет новым стабильным ядрам выходить каждую неделю при полном двухнедельном пути каждого из них.

Что считается security-багом и что нет

Документация относит к security-багам только те проблемы, что дают атакующему возможность, которой у него не должно быть на правильно настроенной production-системе, и легко эксплуатируются, представляя непосредственную угрозу многим пользователям. Баг, который невозможно воспроизвести, по определению не эксплуатируем и потому security-багом не является.

Большинство же сообщаемых багов — обычные баги, ошибочно квалифицированные как security из-за непонимания модели угроз Linux-ядра. Публичная обработка рекомендуется потому, что закрытые обсуждения малым кругом участников реже дают наилучшее исправление — есть риск упустить допустимые сценарии использования, а возможности тестирования ограничены. Поэтому важно, чтобы большинство багов обрабатывались публично с привлечением максимально широкой аудитории.

Значительная доля отчётов об ошибках, приходящих в security-команду, на деле является результатом code review с помощью AI-инструментов. Это создаёт перегрузку мейнтейнеров, которые иногда вынуждены игнорировать такие отчёты из-за их низкого качества или точности. На приоритизацию это влияет прямо: отчёты, не прошедшие проверку по требованиям, рискуют быть проигнорированными. Отправка обычных ошибок в security-список не ускоряет их обработку и расходует ресурсы триажа, нужные другим отчётам. Если затронутый файл не менялся более года и поддерживается одним человеком, нет нужды тратить время мейнтейнера на неважный отчёт.

Маршрутизация отчёта: как найти правильных мейнтейнеров

Получателей определяет скрипт get_maintainer.pl: при передаче имени файла он ищет его путь в файле MAINTAINERS и строит иерархический список релевантных мейнтейнеров. Первый вызов с самым узким уровнем фильтрации чаще всего возвращает короткий список сопровождающих конкретного файла, и именно им следует направлять сообщение.

Состав вывода управляется флагами. Флаг --no-l отключает вывод списков рассылки, --no-r — вывод рецензентов, так что в выводе остаются только мейнтейнеры. Флаг --pattern-depth 1 ограничивает глубину сопоставления шаблонов одним уровнем: с ним находятся только мейнтейнеры конкретного драйвера, без него — мейнтейнеры всей подсистемы, включая записи с пометкой [GENERAL]. Флаг --no-git-fallback отключает резервный поиск по истории git. Флаг --no-substatus убирает из вывода подстатус, а --no-rolestats — статистику по ролям.

$ ./scripts/get_maintainer.pl --no-l --no-r --pattern-depth 1 \
  drivers/example.c
Developer One <[email protected]> (maintainer:example driver)

Выбор «первого, самого специфичного» мейнтейнера выполняется вручную: достаточно взять первых, самых специфичных, а при длинном списке можно сформировать разделённый запятыми список адресов для поля To:.

Если команда не возвращает ничего, значит затронутый файл относится к более широкой подсистеме, и фильтрацию следует ослабить — вызвать скрипт без сужения по глубине. Более узкий вызов с --pattern-depth 1 возвращает только [email protected], [email protected], а широкий вызов без него — четыре адреса: [email protected], [email protected], [email protected], [email protected]. Если всё ещё трудно определить нужных сопровождающих, и только в этом случае, можно отправить отчёт только команде безопасности ядра Linux.

ИИ разрешено использовать для поиска мейнтейнеров только как часть обязательной процедуры: ассистент должен прочитать документацию security-bugs и The Linux Kernel threat model, следовать процедуре из AI Coding Assistants и в конце определить мейнтейнеров через get_maintainer.pl. То есть поиск выполняет скрипт, а не ИИ произвольно. Ассистент при этом должен работать на актуальном mainline-дереве с указанием commit ID, проверить реальность бага, написать фикс, собрать его без предупреждений и чисто по checkpatch, закоммитить с тегом Fixes и только затем определить мейнтейнеров.

Отчёты, затрагивающие несколько частей ядра, следует отправлять отдельными сообщениями, даже если проблемы довольно похожи, потому что сопровождающие не все будут работать над ними одновременно. Исключение — когда проблема касается тесно связанных частей, поддерживаемых одним и тем же подмножеством сопровождающих, и эти части предполагается исправить сразу одним коммитом.

Формат и содержание отчёта

Обязательный минимум для отчёта об ошибке безопасности — четыре пункта:

  • описание проблемы — подробное, с трейсами, показывающими проявление, и объяснением, почему наблюдаемое поведение считается проблемой ядра;
  • воспроизводитель — способ вызвать проблему и способ подтвердить, что она происходит; он должен иметь малую сложность зависимостей (исходный код, shell-скрипт, последовательность инструкций, образ файловой системы), бинарные исполняемые файлы не принимаются;
  • условия — если ошибка зависит от конфигурационных опций, sysctl, прав, таймингов, модификаций кода;
  • затронутая версия или commit ID.

Дополнительно крайне желательны предполагаемое расположение ошибки (имена файлов и функций) и предложенное исправление, а также меры по смягчению. Отчёт отправляется исключительно по электронной почте, предпочтительно простым текстом без вложений: в теле нужно описать проблему и влияние, перечислить шаги воспроизведения и затем предложить исправление — всё в plain text.

Почему plain text без вложений и MIME

Требование связано с необходимостью дать разработчикам ядра возможность читать и комментировать изменения прямо в почтовом клиенте. Разработчикам нужно уметь «цитировать» изменения стандартными почтовыми инструментами, чтобы комментировать конкретные части кода. Поэтому патч нельзя прикреплять как MIME-вложение: многие популярные почтовые приложения не всегда передают такое вложение как простой текст, что делает комментирование кода невозможным. Вложение к тому же требует от Линуса немного больше времени на обработку, что снижает вероятность принятия изменения. Для отчётов об ошибках безопасности аналогично: труднее вести обсуждение сложного вопроса с цитированием контекста, если все детали скрыты во вложениях. Форматированный текст (Markdown, HTML, RST) особенно не одобряется — его трудно читать людям, и он подталкивает к использованию сторонних просмотрщиков, иногда онлайн, что неприемлемо для конфиденциального отчёта об уязвимости.

Теги в патчах

Тег Reported-by даёт признание людям, нашедшим и сообщившим об ошибках, и предназначен именно для ошибок, а не для запросов функций; его следует сопровождать тегом Closes:, указывающим на отчёт, либо Link:, если патч исправляет лишь часть проблемы. Tested-by указывает, что патч был успешно протестирован указанным лицом в некотором окружении, и служит информированию мейнтейнеров о проведённом тестировании и признанию заслуг тестировщиков. Reviewed-by — это заявление о мнении, что патч является подходящей модификацией ядра без оставшихся серьёзных технических проблем; оно сопровождается Reviewer's Statement of oversight, где рецензент подтверждает проведение технического обзора, сообщение о проблемах автору, удовлетворённость ответом и отсутствие гарантий работоспособности. Suggested-by указывает, что идея патча предложена указанным лицом. Fixes указывает, что патч исправляет ошибку в предыдущем коммите, помогает определить источник проблемы и определить, какие стабильные версии ядра должны получить исправление, но не отменяет правил stable-процесса и требования Cc: [email protected]. Assisted-by требует указания при использовании любых продвинутых инструментов кодирования при создании патча, а невыполнение этого может помешать принятию работы. Co-developed-by упоминается в разделе о тегах, но его процедурное значение не раскрыто.

Все теги, кроме Cc:, Reported-by: и Suggested-by:, требуют явного разрешения указанного лица. Для этих трёх достаточно неявного разрешения, если лицо участвовало в ядре Linux под этим именем и адресом согласно архивам lore или истории коммитов, а для Reported-by: и Suggested-by: — если сообщение или предложение было публичным. bugzilla.kernel.org является публичным местом в этом смысле, но используемые там адреса приватны, поэтому их не следует раскрывать в тегах, если лицо не использовало их в более ранних вкладах.

Ссылка на исходный отчёт

Ссылка на исходный отчёт оформляется тегом Closes: с URL, указывающим на отчёт в архивах списка рассылки или в публичном баг-трекере:

Closes: https://example.com/issues/1234

Перед отправкой нужно проверить, что ссылка действительно работает и ведёт к соответствующему сообщению. При этом объяснение должно быть понятным и без внешних ресурсов — следует кратко изложить ключевые моменты обсуждения, приведшего к патчу. Частные баг-трекеры и недействительные URL запрещены. Некоторые баг-трекеры умеют автоматически закрывать issue при применении коммита с таким тегом, а некоторые боты в списках рассылки отслеживают такие теги и выполняют определённые действия.

Жизненный цикл уязвимости: от отчёта до фикса

Сначала репортёр готовит отчёт с обязательными пунктами и отправляет его по электронной почте простым текстом без вложений. Далее security team и мейнтейнеры почти всегда запрашивают дополнительные сведения и полагаются на активное сотрудничество репортёра для дальнейшего тестирования — проверки версий, опций конфигурации, митигаций или патчей. Поэтому репортёр должен быть доступен для объяснений, обсуждений и дополнительных тестов. Отчёт должен быть отправлен мейнтейнерам; если получателей два или меньше, нужно также Cc: команду безопасности ядра Linux, которая поможет доставить сообщение нужным людям и проверить отчёт.

После разработки надёжного фикса начинается процесс релиза: фиксы для публично известных багов выпускаются немедленно. Для ещё не раскрытых багов публикация может быть отложена по просьбе репортёра или затронутой стороны до 7 календарных дней с начала процесса релиза, с исключительным продлением до 14 календарных дней, если согласовано, что критичность бага требует больше времени. Единственная допустимая причина отсрочки публикации фикса — учесть логистику QA и крупномасштабных развёртываний, требующих координации релиза.

Режим эмбарго

эмбарго означает, что информация об уязвимости может передаваться доверенным лицам для разработки исправления, но не публикуется без разрешения репортёра. Даже после снятия эмбарго вся прочая информация, отправленная в security list, и последующие обсуждения отчёта остаются конфиденциальными навсегда. Репортёру рекомендуют не контактировать с рассылкой linux-distros до тех пор, пока исправление не принято мейнтейнерами затронутого кода, поскольку политики трёх списков различаются: у команды безопасности ядра эмбарго начинается с момента доступности исправления, а у linux-distros — с первоначального сообщения в список независимо от доступности исправления.

Назначение CVE

Назначением CVE для ядра Linux занимается отдельная команда — kernel CVE assignment team, а не security-команда ядра. Security-команда ядра не назначает CVE и не требует их для отчётов или исправлений, поскольку это может без необходимости усложнить процесс и задержать обработку ошибки. Если репортёр хочет получить идентификатор CVE для подтверждённой проблемы, он может обратиться в kernel CVE assignment team. Security-команда ядра сосредоточена исключительно на исправлении ошибок, тогда как другие группы занимаются исправлениями в дистрибутивах и координацией раскрытия информации между производителями операционных систем. Координация обычно осуществляется через список рассылки linux-distros, а раскрытие — через публичный список oss-security.

Практика: примеры AI-найденных уязвимостей

CVE-2025-37778: use-after-free в ksmbd на пути Kerberos

Уязвимость возникает так: в krb5_authenticate при состоянии сессии SMB2_SESSION_VALID освобождается sess->user, но указатель не обнуляется, и код полагается на то, что ksmbd_krb5_authenticate либо заново инициализирует sess->user, либо после возврата -EINVAL к sess->user больше не обращаются. Это допущение ошибочно: можно заставить ksmbd_krb5_authenticate не переинициализировать sess->user и затем обратиться к уже освобождённому sess->user, даже когда krb5_authenticate возвращает -EINVAL. Другой путь — smb2_session_logoff: там sess->state переводится в SMB2_SESSION_EXPIRED, а затем при наличии sess->user вызывается ksmbd_free_user(sess->user) и sess->user = NULL. Предложенный фикс добавляет обнуление указателя сразу после освобождения в krb5_authenticate:

- if (sess->state == SMB2_SESSION_VALID)
+ if (sess->state == SMB2_SESSION_VALID) {
      ksmbd_free_user(sess->user);
+     sess->user = NULL;
+ }

CVE-2024-50264: UAF на virtio_vsock_sock

Прерывание системного вызова connect() POSIX-сигналом запускает цепочку: ядро вызывает vsock_assign_transport(), которая переключает виртуальный сокет на новый транспорт svm_cid и освобождает ресурсы предыдущего vsock-транспорта. В ходе этой процедуры virtio_transport_close() закрывает старый vsock-транспорт, а virtio_transport_destruct() освобождает объект virtio_vsock_sock. Из-за ошибочного состояния сокета TCP_CLOSING функция virtio_transport_close() инициирует дальнейший обмен данными, для обработки которого ядро пробуждает поток kworker, обращающийся к освобождённой памяти в virtio_transport_space_update() — это и есть UAF.

Для расширения окна гонки исследователь вызывал timerfd_create(CLOCK_MONOTONIC, 0), создавал 8 дочерних процессов, в каждом 100 раз вызывал dup() для timerfd и 500 раз epoll_create(), включал отслеживание событий на всех копиях timerfd через epoll_ctl() и настраивал timerfd так, чтобы прерывание случилось в нужный момент работы потока kworker. Такой приём увеличил окно состояния гонки примерно в 80 раз. Ограничением стало /proc/sys/fs/epoll/max_user_watches: при превышении лимита epoll_ctl() завершается с ошибкой, и на Ubuntu Server 24.04 с 2 ГиБ памяти это значение составляет 431838, что позволило 8 × 500 × 100 = 400000 отслеживаний.

Ограничения эксплойта CVE-2024-50264 и их обход

Ограничения таковы: уязвимый клиентский объект virtio_vsock_sock создаётся вместе с серверным, и их выделение в одном слэбе не позволяет провести кросс-кэш-атаку; состояние гонки воспроизводится очень нестабильно; запись в освобождённый объект происходит в kworker спустя всего несколько микросекунд после kfree(), чего недостаточно для кросс-кэш-атаки; после UAF-записи происходит разыменование нулевого указателя; через VSOCK_CLOSE_TIMEOUT (восемь секунд) в kworker возникает ещё одно разыменование нулевого указателя; kworker зависает в spin_lock_bh(), если поле virtio_vsock_sock.tx_lock ненулевое.

При включённом CONFIG_SLAB_BUCKETS=y ядро создаёт набор отдельных слэб-кэшей для объектов с пользовательскими данными, а при CONFIG_RANDOM_KMALLOC_CACHES=y — несколько копий слэб-кэшей, и kmalloc() выбирает одну из них в зависимости от адреса кода, что не даёт выполнить heap spraying и расположить нужный объект на месте освобождённого в том же слэбе. Для обхода используется кросс-кэш-атака, а для msg_msg — техника с восстановлением m_list: почти полностью заполняют очередь сообщений (MSGMNB=16384 байт) двумя большими сообщениями-пустышками по 8191 байт с mtype=1, затем создают целевые msg_msg с mtype=2 через msgsnd() из отдельных pthread-потоков, выполняют UAF-запись, повреждая m_list, m_type и m_ts, после чего вызывают msgrcv() для сообщений-пустышек, освобождая место, и ядро пробуждает потоки, восстанавливая поле m_list.

Как сравнивали и что получилось

Стенд и методология бенчмарка o3 на CVE-2025-37778

Использовалась модель o3, запускавшаяся через инструмент llm с системным промптом и несколькими файлами .prompt. Входной код — обработчик команды подготовки сессии SMB вместе со всеми вызываемыми функциями до глубины вызовов 3, а также код функций чтения из сети, парсинга запроса, выбора обработчика и завершения соединения; весь код уместился примерно в 3,3 тысяч строк (около 27 тысяч токенов) и был выложен в едином файле, созданном с помощью files-to-prompt. Обвязка выполняла команды N раз, в этом эксперименте N=100, и сохраняла результаты. В промпте автор просил искать use-after-free, дал краткое описание ksmbd, его архитектуры и модели угроз, а также пытался запретить ложноположительные срабатывания.

Результаты o3

СценарийНашла багЛожноотрицательныеЛожноположительные
Только код обработчика подготовки сессии (около 27 тысяч токенов)8 из 10066 из 10028 из 100
Все обработчики команд (около 12 тысяч строк, примерно 100 тысяч токенов)1 из 100——

При передаче всех обработчиков команд o3 нашла ту же уязвимость лишь в 1 из 100 прогонов — существенное падение показателей, но ей всё равно удалось её найти. Для инструмента указано соотношение «сигнал-шум» примерно 1:50.

Стенд и методология эксперимента с Claude-агентом для Python-пакетов

Набор состоял из более чем 100 популярных Python-пакетов, охватывающих разные области — от численных вычислений и парсинга до баз данных. Агент запускался на каждом пакете, и собирались все сгенерированные баг-репорты. Из 984 баг-репортов вручную выбрали 50 для ревью, после чего Opus 4.1 оценил все отчёты. На втором этапе запустили агента с Sonnet 4.5 на 10 важных пакетах, а также использовали агента-оценщика на Sonnet 4.5 и оплатили работу трёх экспертов для проверки корректности багов высокой серьёзности. Для окончательной проверки выбрали пять особенно интересных случаев и вручную отправили их в GitHub-репозитории вместе с предложенным патчем.

Результаты по Python-пакетам

Из 50 отобранных вручную отчётов 56% описывали реальные баги, а 32% — реальные баги, о которых авторы также стали бы сообщать мейнтейнерам. Среди баг-репортов с максимальными оценками 86% были реальными, а 81% — одновременно реальными и достойными отправки мейнтейнерам.

Подтверждённые примеры:

  • numpy.random.wald иногда возвращает отрицательные числа — это баг, так как значения распределения Вальда должны быть только положительными; ошибку отследили до катастрофической потери точности и предложили более численно устойчивую формулу, которая, как показали мейнтейнеры NumPy, даёт относительную ошибку почти на десять порядков ниже;
  • slice_dictionary() в aws-lambda-powertools возвращает первый фрагмент из-за отсутствия инкремента итератора;
  • item_hash() в cloudformation-cli-java-plugin выдаёт одно и то же значение hash(None) для всех списков из-за in-place метода .sort();
  • в tokenizers в EncodingVisualizer.calculate_label_colors() не хватает закрывающей скобки, из-за чего возвращается невалидный HSL-код;
  • в python-dateutil easter() для некоторых лет возвращает дату не на воскресенье при юлианском календаре, но мейнтейнеры признали это ожидаемым поведением, и issue был признан невалидным.

Оговорки

Результаты бенчмарка o3 могут быть не идентичны при повторении: перед написанием поста автор удалил файл с кодом для анализа и сгенерировал его заново, повторно эксперимент не проводил. Весь системный промпт спекулятивен — автор не проводил достаточного количества проверок, чтобы определить, помогает это или мешает, и считает его скорее молитвой, чем чем-то научным или инженерным.

Оценка «нашёл баг» и «предложил корректный фикс» в источниках не разделяются как отдельные метрики: для пяти случаев баг-репорты отправляли вместе с предложенным патчем, но отдельных precision/recall по патчам не приводится.

Что из этого следует на практике

  • Отчёт от ИИ публичен по умолчанию. Если баг найден с помощью ИИ, скрывать сам факт его существования нельзя, но воспроизводитель публично не выкладывается — только упоминание о его наличии. Это меняет расчёт репортёра: рассчитывать на длительное эмбарго для AI-найденной проблемы не приходится.
  • Воспроизводитель — критерий допуска, а не пожелание. Без работающего воспроизводителя обоснованность отчёта ставится под сомнение, а невоспроизводимая проблема по определению не считается security-багом. ИИ-инструмент обязан предоставить воспроизводитель и протестировать его.
  • Формат влияет на выживание отчёта. Отчёт, не прошедший проверку по требованиям, рискует быть проигнорированным; обычные баги, отправленные в security-список, не ускоряются, а расходуют ресурсы триажа. Plain text без вложений и MIME — не стилистическое предпочтение, а условие того, что отчёт вообще можно цитировать и обсуждать в почтовом клиенте.
  • Маршрутизация — ручная работа поверх скрипта. get_maintainer.pl строит иерархический список, но выбор «первого, самого специфичного» делает человек. Если скрипт ничего не вернул, файл относится к более широкой подсистеме, и фильтрацию нужно ослабить; отправка только команде безопасности — крайняя мера.
  • Разделение труда по CVE. Security-команда ядра не назначает CVE и не требует их — она фокусируется на исправлении. Идентификатор выдаёт отдельная kernel CVE assignment team, а координация раскрытия идёт через linux-distros и oss-security, у которых свои правила отсчёта эмбарго.
  • Цифры LLM-агентов пока скромные. На узком контексте o3 находила реальную уязвимость в 8 из 100 прогонов при 28 ложноположительных, а на широком контексте — в 1 из 100 при соотношении «сигнал-шум» примерно 1:50. Для Python-пакетов 56% отобранных вручную отчётов описывали реальные баги, а среди отчётов с максимальными оценками по рубрике — 86%. Это означает, что автоматический поток требует фильтрации, а не принимается как есть.

Источники

Похожее