Reality-audit — свидетельствование: потрать хвост на то, что шипится
Свидетельство имплементации легко собрать с неверной поверхности: скретч-сборка, разовый прогон интерпретатора, тест в обход публичной границы, правдоподобный печатный вывод. Этот терминальный протокол решает, было ли поведение, которое шипится, действительно испытано.
Это вторая ступень сверки — свидетельствование мира, — и её несёт свидетель, не автор. Гнездо: санскр. sākṣin (साक्षिन्) — свидетель-сознание: присутствует при опыте, но не действовало в наблюдаемом; образ традиции — лотос, не смоченный водой. Овеществивший (kartṛ) видит не сущее, а ābhāsa — отражение собственной интенции; потому фальсификатор называется до взгляда (Поппер: какое наблюдение опровергло бы?), а наблюдение берётся заново. 中 驗 yàn — испытание на деле (驗證 yànzhèng — проверка-удостоверение); лат. testis — «третий стоящий»: свидетельство надёжнее, когда его несёт не сторона. Говоря «проверено», называй ступень: чтение записанного (граф — инструмент наблюдения, не мир) утверждение о поведении не закрывает.
Загружай после последней содержательной правки имплементации, до слов verified, done, `green», «работы не осталось» — и снова после поправки владельца или воспроизведённого фальсификатора, обесценившего прежнее свидетельство. Не на входе в задачу, и никогда не прерывай имплементацию граф-моделированием ради подготовки к нему.
Пропорциональность. Когда правка не меняет публичного контракта — ни нового/изменённого экспортируемого символа, формата вывода, формы конфига/схемы, документированного поведения — лестница сжимается до шагов 1–2 по тронутому пути: пересобери канонический деливерабл, испытай изменённый путь один раз с утверждённым ожиданием, запиши команду и код выхода одной строкой. Полная таблица утверждений оценена под поведенческую работу, не под правки класса опечатки. Сомневаешься, менялся ли контракт, — менялся.
1. Заморозь только несущие утверждения
Читай принятый источник, не итоговый пересказ имплементатора. Старшинство контракта:
- последняя поправка владельца;
- принятое требование или спецификация;
- устоявшийся публичный API, схема и канонические тесты целевой версии;
- пересказ имплементатора — свидетельство об исполнении, никогда не контракт.
Записывай только утверждения, чей провал меняет приёмку. Точный вывод, порядок, ошибка, сериализация или пример команды — исполняемые утверждения, даже записанные прозой. Каждый нормативный пример воспроизводи точно; более простой представительный случай его не разряжает.
2. Назови носитель и фальсификатор до прогона
По каждому утверждению — одна компактная строка:
| Поле | Требуемый ответ |
|---|---|
| Утверждение | Что именно должно держаться? |
| Канонический носитель | Какой именно бинарь, пакет, экспортируемый символ, API-маршрут, UI, схему, генерируемый артефакт или задеплоенный путь потребят пользователи? |
| Наблюдаемое | Что должен увидеть внешний наблюдатель? |
| Исполняемый фальсификатор | Какая команда, запрос, assertion или тест доказали бы ложность? |
Граничные слова — классы эквивалентности, не одна удобная фикстура. Для empty, none, missing, malformed, default перечисли различимые представления, которые публичный парсер может получить (ноль байт vs пустая запись, пустой массив vs отсутствующее поле, опущенный флаг vs его явный дефолт), и пробей каждое, которое принятая формулировка приравнивает. Для минимума, максимума, порога, окна, счётчика, гейта версии — принятая граница плюс ближайшее значение с иным поведением с каждой стороны; дефолт, поставляющий границу, тестируется и опущенным, и явным. Парсер, валидатор или хелпер, переиспользованный со строжайшего соседнего пути, получает независимую проверку предусловий: унаследованный страж не должен отвергать вход, который новый публичный контракт принимает.
Назови канонический путь до пробы. Скретч-сборка, локальный скрипт, mock-only-вызов, тест в обход публичной границы — provisional, если только это не и есть точный публичный деливерабл. Авторство не решает: свежий black-box-тест свидетельствует, когда пересобирает и исполняет канонический носитель с точным фальсификатором; одноавторский мок или внутренний тест — нет. Когда запуститься могло несколько артефактов — докажи, который побежал: путь плюс свежесть (mtime, digest, версия, маркер сборки). Печатный вывод — наблюдение, не пасс, пока исполняемый assertion не проверил ожидаемое значение и код выхода.
3. Прогони терминальную лестницу свидетельств
После последней содержательной правки, в этом порядке:
- Собери/упакуй/задеплой канонический деливерабл — прежде чем тестировать любую скретч-копию.
- Испытай именно изменённый путь на его публичной границе. Утверди ожидаемое наблюдаемое и поведение отказа; не «осмотри правдоподобный вывод».
- Перегони точный прежний фальсификатор. Опровергнутое утверждение остаётся опровергнутым, пока тот же случай — или строго более сильный — не пройдёт против свежего деливерабла.
- Перегони затронутые старые требования в коде. Сначала приёмочные случаи по изменённому общему коду; широкая сюита — только после прогона точного нового пути.
Любая содержательная правка артефакта после шага 1 обесценивает хвост: пересобери и повтори задетые пробы. Никогда не давай уборке, граф-работе или нарративу съесть бюджет пробы нового пути.
Граф идёт после свидетельства и никогда не входит в него. Сначала заморозь вердикты и заверши все содержательные правки артефактов; затем максимум одно терминальное обновление — и только когда устойчивая поправка или противоречие изменит решение позднего агента. Поздний содержательный патч делает то обновление преждевременным: его поведенческая уверенность provisional, пока задетое публичное свидетельство не перегнано и узел не пере-удостоверен. Граф — не мид-аудитный черновик, и состояние графа никогда не аргумент вердикта: запрещена подмена ступени, не чтение графа — но здесь, в терминале, читается мир.
Код выхода — вердикт (канонический локус правила — этот скилл; writing указывает сюда). Совмещённое терминальное свидетельство фейл-клоузд с первой команды (set -euo pipefail или платформенный эквивалент); ожидаемый код отказа ловится и утверждается локально, затем фейл-клоузд восстанавливается. Утверждение не verified, пока его команда-свидетельство выходит ненулём: зелёные субтесты, строки passed в stdout, поздний посторонний ноль не перекрывают записанный код — читай его из результата тула, не выводи из выбранного вывода; чистит только перегон того же случая (или строго более сильного) против свежего деливерабла. Обёртка, сознательно гоняющая все подгруппы, накапливает провалы и выходит ненулём при провале любой обязательной. Перед финальным нарративом сведи каждое заявление passed/green с записанными кодами выхода и сводкой упавших подгрупп.
4. Дай один правдивый вердикт на утверждение
- verified — свежий канонический носитель произвёл требуемое наблюдаемое, и исполняемый фальсификатор был успешно исполнен;
- provisional — свидетельство есть, но скретч-only, mock/внутреннее, print-only, несвежее или мимо точной публичной границы;
- contradicted — воспроизведённый контрпример всё ещё падает;
- blocked — поверхность свидетельства недоступна; процитируй блокер буквально и назови только то утверждение, чью проверку он не даёт.
Доложи компактную таблицу «утверждения × вердикты» с каноническим путём и свидетельством команды/теста — только реальная телеметрия, никогда оценённые токены, цена, длительность или покрытие. Зелёное перенесённое подмножество, опускающее падающий случай, — отсутствие наблюдения, не починка. Структурное здоровье графа — отдельный факт, поведенческий вердикт оно не повышает.
Классы из Ceiling Reality-таблицы репо — с записанным «достижимого наблюдения нет» — никогда не возвращаются verified: их потолок — provisional, как бы ни прошла проба; честная эпистемика такого рода — anumita или схождение независимых свидетельств.
Обязательная работа закрывается, только когда каждое обязательное утверждение verified — или владелец сознательно принял названное исключение. Provisional, contradicted и blocked — состояния передачи, не синонимы «готово».