Skip to content

Бэктест модели риска закрытия — июль 2026

Замер выполнен в сессии #152 по задаче closure-risk-score-is-anti-predictive. Данные — собственные закрытия проекта, а не синтетика: 374 закрытые задачи с записанным риск-скором, из них 56 сбежавших (на задачу указывает defect_of более поздней задачи — то же определение, которым пользуется backend_defect_escape) и 318 чистых.

Метод: пермутационный тест на разность средних (20000 итераций, seed зафиксирован — повтор даёт тот же p) и AUC как мера различающей силы. AUC = 0.5 — монета; выше — оценка направлена верно; ниже — направлена обратно.

Что мерили и что получили

Композит: дело не в знаке, дело в отсутствии сигнала

величиназначение
средний риск сбежавших0.2931
средний риск чистых0.3174
разность−0.0243
пермутационный p0.3848
AUC0.4820

Инверсия, с которой началась задача, статистически незначима (p = 0.38). Но вывод из этого не «всё в порядке». AUC 0.4820 означает, что композит не разделяет закрытия, из которых дефект сбежал, и те, из которых не сбежал. Два средних показывали разрыв, не говоря, разделяет ли он хоть что-нибудь, — и именно поэтому число с нулевой различающей силой читалось как «слегка инвертированное».

Пофакторно: веса были назначены априорно и никогда не проверялись

факторвесAUCpвердикт
gate_coverage0.250.4090.0098значимо ИНВЕРТИРОВАН
test_delta0.200.4950.7666сигнала нет
ac_evidence0.200.4990.5287сигнала нет
security_hits0.200.4670.2515сигнала нет
code_churn0.150.6170.0098единственный верно направленный

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

Инверсия gate_coverage — не сложность в маскировке

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

стратаnсбежалоAUC gate_coveragep
simple11780.5021.0000
medium193350.4440.2020
complex40110.2930.0170

У всех 11 сбежавших complex-задач gate_coverage = 0.0000, то есть гейты отработали полностью, против 0.2069 у чистых.

Механизм не установлен и здесь не утверждается. n = 11. Правдоподобное объяснение — полное покрытие даёт уверенность, а уверенность заменяет внимание — не измерялось, и записывать его как вывод было бы ровно той ошибкой, которую эта задача исправляет.

Риск слеп к сложности, а сложность — сильнейший доступный предиктор

сложностьnсредний рискдоля побегов
simple1170.33306.8%
medium1930.290518.1%
complex400.314727.5%

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

Главное число замера:

Одна сложность как предиктор даёт AUC 0.6327 (p = 0.0016) — против 0.4820 у всей пятифакторной формулы. Поле, которое модель игнорирует, работает лучше модели.

complexity_understated двигает оценку вниз

31 закрытие помечено детектором занижения сложности.

помеченныеостальные
доля побегов25.8%14.0%
средний риск0.24640.3198

Самый частый предвестник побега не просто невидим формуле — он двигает её оценку вниз. Это конкретный механизм наблюдаемой анти-корреляции, а не догадка.

Что с этим сделано

Композит понижен до описательного. Он по-прежнему считается и хранится (факторы диагностически полезны, а история закрытий не пересчитывается задним числом), но перестал подаваться как доказательство качества: строка при закрытии теперь называет его тем, что он есть.

Триггер обязательного L3-ревью на high оставлен. Он шумный, но асимметрия цен в его пользу: шумное требование посмотреть внимательнее стоит времени, шумное заверение в безопасности стоит дефектов.

Перевзвешивание не делалось, и это осознанный отказ. При 56 сбежавших и двух значимых факторах подгонка весов на тех же данных дала бы красивый коэффициент и ту же слепоту; удержанной выборки, на которой это можно проверить честно (AC6), такой объём не даёт. Вводить сложность в формулу как фактор — по той же причине преждевременно: сначала нужна выборка, на которой перевзвешивание можно фальсифицировать.

tausik metrics теперь печатает рядом со средними AUC композита и AUC одной сложности, чтобы статус числа был виден там, где его читают, а не только здесь.