diff --git a/PROCESS.md b/PROCESS.md index 0723ebe2..f316e37c 100644 --- a/PROCESS.md +++ b/PROCESS.md @@ -193,6 +193,35 @@ S1-new → S2-analysis → S3-spec → S4-spec-review ⟲ → S5-ready → кода отвечает на вопрос «оно вообще работает»: каждый AC либо доказан автотестом — и ревьюер убедился, что **тест умеет падать**, — либо разобран по коду с явной записью «проверено чтением, не исполнением». +- **Защитный AC доказывается таблицей «чем краснеет» (#435).** Для каждого AC, + заявляющего защиту — валидация, гард, лимит, отказ, инвариант, — в документе + ревью обязательна строка из трёх столбцов: **AC · чем доказан** (точная + команда или имя теста) **· чем краснеет** — мутация, снятая защита или + отрицательная проба, с результатом прогона. Пустой третий столбец — находка + Medium, а не примечание. + + «Тест умеет падать» без названной мутации и её вывода доказательством не + является. Аудит v1.71.0-beta.1 нашёл пять контрактов #51 и #423, где тест + оставался зелёным на снятой защите; все пять прошли код-ревью как доказанные, + а два теста были записаны в закрытие coverage-ratchet под именами, обещавшими + то, чего они не проверяли (#430). + + Мутант в `scripts/mutation-gate.mjs` обязателен, когда защита живёт в + продуктовом коде и проверяется дорогим гейтом (смок, бэкенд, golden): там + ревьюер не воспроизведёт отрицательный прогон второй раз. Для чистых юнитов + достаточно прогона со снятой защитой, приведённого в документе. + + Считаются **защитные AC без названного свидетеля**, а не мутанты на + подсистему: у #421 мутанты были, и дыра всё равно проехала. «Сколько мутантов + принесла задача» остаётся признаком — у #423 их ноль, и именно у #423 нашёлся + тест, спрашивавший регулярку, находит ли она подстроку, которую сам же и + вырезал. + + Правило не распространяется на AC, не заявляющие защиту (расположение, текст, + формат вывода): там свидетель — обычное сравнение ожидаемого с фактическим, и + третий столбец превратился бы в ритуал. И не отменяет «проверено чтением»: + тогда во втором столбце стоит «чтением», а не имя теста, и читатель ревью + видит разницу. - **High блокируют.** Medium **в скоупе задачи** чинится в текущем issue: без High это жёлтый вердикт и возврат автору, фикс проходит повторный цикл. Medium **вне скоупа** — отдельный issue (#202).