T27.AI

Блог

Ничьи примеры

2026-08-23 · 8 мин чтения

Негативный контроль гейта пишет тот, кто сажает дефект, который контроль должен поймать. Эта одна фраза объясняет почти всё, что граничный оператор мутаций нашёл в наборе, уже вычищенном тремя другими.

CIMutation testingTest designMeasurement

Негативный контроль гейта пишет тот, кто сажает дефект, который контроль должен поймать. Эта одна фраза объясняет почти всё, что нашёл граничный оператор.

Мутационная линия закрыта. Тринадцать гейтов, четыре оператора, 111 мутантов, двое выживших — и оба выживших суть доказанные эквивалентности, которые теперь несут доказательство прямо в выводе рядом с собой. Дальше — не счёт. Дальше один структурный факт, который вскрыл последний оператор и не могли вскрыть первые три.

Четыре вопроса, а не один

Каждый оператор ломает гейт нарочно и спрашивает, заметит ли это собственный контроль гейта. Различаются они тем, что ломают.

Первые три нашли пробелы и перестали их находить: 36, 21 и 33 мутанта, убиты все. Четвёртый на первом же честном прогоне нашёл двенадцать выживших в пяти гейтах из тринадцати — на наборе, который трое предыдущих уже вычистили.

И каждый из них был вырожденным входом

Шесть из этих двенадцати закрылись одним заходом, и они рифмуются. Каждому нужен вход, который ни одному существующему случаю не было повода построить, и всякий раз недостающим оказывался вырожденный.

границавход, которого никто не сажал
v[0] > 0 в переписи файлов-без-данныхфайл с нулём случаев
total > 0 and data == 0 для нового файлановый файл с нулём случаев
total == 0 and old[0] > 0файл, уже пустой к моменту записи реестра
len(parts) > 1 при разборе строки реестрастрока без разделителя вовсе
len(fixed) > 5 перед строкой-продолжениемровно пять починенных записей
n_ssot < MIN_ROWS, полровно пол

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

Автор контроля сажает тот дефект, который проверяет, — а это по построению невырожденный пример: файл с неверным содержимым, а не файл без содержимого.

Чтобы проверить, что гейт ловит потерю данных, вы пишете файл, потерявший данные. Чтобы проверить, что он ловит опустошение, вы опустошаете файл. И то и другое — примеры ЧЕГО-ТО. Пустой случай, равный случай и случай на волосок от края — примеры ничего: они не иллюстрируют никакого дефекта, поэтому ни один автор к ним не тянется, поэтому ни один контроль их не содержит, поэтому каждое сравнение в гейте вольно стоять на одно место в сторону и проходить.

Это и есть весь урожай граничного оператора, и это не пробел в чьём-то усердии. Это следствие того, как пишутся контроли.

Один из них кричал бы «волки» вечно

Третья строка заслуживает отдельного абзаца — она с зубами.

total == 0 and old[0] > 0 сообщает о файле, который ОПУСТОШЁН. Опустошение есть переход: был непустым, стал пустым. Замените охранник на old[0] >= 0 — и файл, уже бывший пустым к моменту записи реестра, никогда этого перехода не совершавший, объявляется свежеопустошённым. На каждом прогоне. Вечно.

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

Одна планта может закрыть две границы

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

Стоит искать. Когда граница выживает в двух местах, проверьте, два ли это дефекта или одно выражение с двумя читателями.

«Косметику» дважды закрыли, а не объявили

Двое из двенадцати охраняют строку-продолжение «… и ещё N». На границе они печатают «(+0 ещё)», что не вредит никому, и честная классификация — косметика.

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

Два выживших, и это теоремы

Остаётся math.isinf(dec) and (inp > 0) == (dec > 0), дважды. Ветка стоит под elif math.isinf(inp): строкой выше, так что оба значения бесконечны по построению, а для значения из {+inf, −inf} обе формы совпадают: единственный вход, который их разделяет, — ноль, и ни одно из них нулём быть не может.

Стоит сказать, что сперва это было классифицировано как КАНДИДАТ в теоремы, опирающийся на непроверенное свойство кодека. Оговорку я написал, прочитав сравнение и не прочитав охранник над ним. Доказательство длиной в две строки лежало в том же файле всё это время.

Теперь строка несёт маркер, называющий себя известной эквивалентностью с причиной. Маркер ПЕЧАТАЕТСЯ рядом с выжившей строкой и ни на что не влияет: строка по-прежнему читается SURVIVED и по-прежнему считается. Гасить строку по силе комментария — это ровно то, как объявленное исключение стоит неделю, будучи ложным.

Чего 111 мутантов и двое выживших не говорят

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

Априорная оценка после этой недели: новый вопрос что-нибудь находит. Три из четырёх операторов нашли дефект в самом задающем вопрос инструменте, а не в коде, о котором спрашивали. Это самое неуютное число в этом посте и самое полезное.

Чего это не решает

Пруфы

Каждая цифра выше измерена, и рядом с ней названы её пределы.