From bdf53dc482dda07adba00188d5bb16ddeb89c081 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 3 Sep 2026 10:58:12 +0300 Subject: [PATCH] =?UTF-8?q?docs:=20=C2=A72.7=20=D1=82=D1=80=D0=B5=D0=B1?= =?UTF-8?q?=D1=83=D0=B5=D1=82=20=D1=82=D0=B0=D0=B1=D0=BB=D0=B8=D1=86=D1=83?= =?UTF-8?q?=20=C2=AB=D1=87=D0=B5=D0=BC=20=D0=BA=D1=80=D0=B0=D1=81=D0=BD?= =?UTF-8?q?=D0=B5=D0=B5=D1=82=C2=BB=20=D1=83=20=D0=B7=D0=B0=D1=89=D0=B8?= =?UTF-8?q?=D1=82=D0=BD=D1=8B=D1=85=20AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit §2.7 уже требовал нужного: ревьюер обязан убедиться, что тест умеет падать. Требование было, артефакта у него не было — в документе ревью ничто не заставляло назвать, чем именно проверка краснеет, и «убедился» писалось по впечатлению от чтения теста. Цена известна по факту. Аудит v1.71.0-beta.1 нашёл пять защитных контрактов #51 и #423, где снятие защиты не покраснило ни один тест (#430). Все пять прошли код-ревью как доказанные; два теста попали в закрытие coverage-ratchet под именами, обещавшими то, чего они не проверяли. Теперь у защитного AC три столбца: чем доказан, и отдельно — чем краснеет, с результатом прогона. Пустой третий столбец — Medium. Считаются защитные AC без свидетеля, а не мутанты на подсистему: у #421 мутанты были, и дыра всё равно проехала. Число мутантов остаётся признаком — у #423 их ноль, и именно там нашёлся тест, спрашивавший регулярку, находит ли она подстроку, которую сам же и вырезал. Границы записаны явно, чтобы правило не стало ритуалом: AC без заявки на защиту его не касаются, а «проверено чтением» остаётся законным — только это видно во втором столбце. Гейты: npm test 1791 tests, 1790 pass, 0 fail. Issue: #435 User-Visible: no --- PROCESS.md | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) 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).