Два движка, один аудит
Почему вторая модель, читающая тот же код, меняет результат аудита и как объединить два отчёта, не удвоив шум.
· Чтение: 5 мин · Lina Source LLC
Дайте один и тот же pull request двум опытным ревьюерам — получите два разных списка. Один заметит, что идентификатор из URL ни разу не сверяется с сессией; другой — что цикл повторов при каждой ошибке оставляет открытым соединение с базой. Ни один не ошибается и ни один не полон. Языковые модели ведут себя так же и по той же причине: что ревьюер замечает, зависит от того, что он видел раньше.
Согласие — это сигнал
Одна модель сообщает свою уверенность. Это число чего-то стоит, но оно самооценочное: модель проверяет собственную работу. Когда две модели, обученные разными лабораториями, на разных данных и с разными слабостями, независимо приходят к одной и той же слабости в одном и том же файле, это согласие — свидетельство извне модели. Ближе к второму мнению автоматическая проверка не подходит.
Обратное важно не меньше. Находка, о которой сообщил только один движок, не становится от этого ложной, а отбросив её, вы выкинете именно те баги, которые одиночный ревьюер находит хорошо. Её нужно показать и подписать источником, чтобы взвесили вы сами.
Где один движок молчит
На практике движки сильнее всего расходятся на классах багов, где нужно рассуждение, а не сопоставление шаблонов:
- Логические дефекты: скидка, применённая дважды; конечный автомат, принимающий возврат после возврата; проверка владения, выполненная над не тем объектом.
- Авторизация, специфичная для фреймворка: middleware защищает группу маршрутов, но не API-обработчик, подключённый рядом.
- Утечки ресурсов и памяти: слушатели, таймеры и соединения, открываемые на каждый запрос и освобождаемые только на счастливом пути.
- Промпт-инъекции, спрятанные в комментариях или фикстурах: они читаются как безобидный текст, если их не искать.
Как два отчёта становятся одним
Слияние — это место, где второй движок либо окупается, либо удваивает шум. Правила, на которых мы остановились:
- Находки сопоставляются по тому, что определяет баг, а не по формулировке: по классу CWE и файлу, где он живёт.
- Совпадение показывается один раз и с более строгой из двух оценок: действовать стоит по безопасному прочтению.
- Остаётся тот текст, с которым разработчик может работать: более подробное доказательство, конкретный патч, упорядоченные шаги.
- Подтверждённая находка получает высокую уверенность и метку обоих движков.
- Находка, которую увидел только один движок, сохраняется с указанием нашедшего движка.
Оба движка читают один и тот же исходник одновременно, поэтому аудит не длится вдвое дольше; он вдвое дороже в исполнении — поэтому он и относится к тарифу Pro. Если второй движок недоступен или вернул непригодный ответ, аудит завершается на первом, а не падает.
Ничто из этого не делает отчёт истинным. Два движка могут согласиться и оба ошибиться; цитата кода под каждой находкой существует именно для того, чтобы вы проверяли, а не доверяли. Подтверждение даёт порядок: когда пришло сто находок, а у вас есть полдня, начните с тех, которые увидели оба независимых ревьюера.