14 KiB
SPEC-REVIEW-481-r2
Issue: #481 «changed_mutants: журнал пойманных свидетелей вместо суда по диапазону»
Этап: ТЗ на ревью (PROCESS.md §2.4). Трек: small — ТЗ в теле issue, файл
docs/specs/481-*.md не создан (проверено: ls docs/specs/ | grep -i 481 — пусто).
Заход: r2 · блокирующих циклов израсходовано 1 из 2 (r1 был жёлтым и потратил цикл;
зелёный вердикт цикла не образует, #227).
Скоуп
Предмет ревью — тело issue #481 на текущий момент, целиком, но разбор — по дельте между r1 и r2 (PROCESS.md §2.10): полностью переразобраны только два места, которых касалась правка автора; остальное (AC1–AC5, AC7, ссылки, оценка, список файлов) унаследовано из r1 без повторной проверки по существу, с точечной сверкой фактов, которые дёшево перепроверить (см. «Унаследовано из r1»).
Как проверялось
- Найден вердикт r1 — комментарий в issue (жёлтый, High: 0, Medium: 2) и документ
docs/reviews/SPEC-REVIEW-481-r1.md(коммит2f65a184,git show 2f65a184:docs/reviews/SPEC-REVIEW-481-r1.md). Блок «Материал раунда» в конце r1-документа несёт пустой SHA ветки («Ветка: dev, коммит `` — ... Якоря снять не удалось: ветки задачи нет, материал читался по dev»). По PROCESS.md §2.10 это прямо названо нормальным случаем, а не находкой: «если SHA не резолвится — это не находка, а обычное дело»; находкой было бы только SHA, мёртвое уже на момент публикации — здесь SHA просто не указано, а не указано неверно. Дельту поэтому объявляю не по коду, а по тексту: r1-документ дословно цитирует то, что было в теле issue на момент r1 (формулировки находок 1 и 2 ниже), и комментарий автора после r1 прямо перечисляет, что изменено. Оба источника сверены с текущим телом issue построчно. - Дельта = добавленный
### 6. Откатвнутри «Решение» + переписанная колонка «Доказательство» строки AC6 в таблице критериев. Больше правок в теле issue между r1 и r2 нет (сверено построчно с текстом, процитированным в r1-документе и с комментарием автора). - По каждой из двух Medium-находок r1 — сверено дословное совпадение предложенного в r1 исправления с тем, что появилось в issue (см. таблицу ниже).
- AC1–AC5, AC7 дельта не затрагивает — не переразбирались по существу. Дёшево
сверено: файл
docs/specs/по-прежнему отсутствует; названные в AC7 идентификаторы свидетелей (ledger-records-escaped,ledger-version-sensitive,ledger-written-at-end-only) и тесты#481 AC1…#481 AC5по-прежнему существуют в коде ветки (grepпоscripts/mutation-gate.mjs,test/mutation-gate.test.mjs,test/validate-workflow.test.mjs) — спецификация не разошлась с уже существующей реализацией на ветке задачи. Это не код-ревью (реализация по существу не оценивалась), а та же перекрёстная сверка реализуемости, что делал r1. - Числа в комментарии автора после r1 (132/134 отобрано, 132 пропущено, 113/113 без
изменения отпечатка) — не доказательство (AC6 явно это оговаривает), поэтому не
перепроверялись побитово; но сами исторические SHA, на которые они ссылаются,
проверены на существование и соответствие описанию:
052549fa— «test: accept golden baselines after #471 and #476»,f2e38e48— «build: prepare v1.73.0-beta.2 candidate»,5d281171— «ci: shard changed mutants before release»,04f4cd10— «docs: refresh screenshot source fingerprint». Все существуют, ни один не выдуман, описание соответствует содержимому коммитов. - Гейты (typecheck/test/build) не гонялись — по прецеденту r1 и по существу этапа: материал spec-review — текст ТЗ, а не диапазон кода; их прогон принадлежит код-ревью (§2.7).
Закрытие раунда r1
| Находка r1 | Чем закрыта | Где видно |
|---|---|---|
| Medium 1: отсутствует обязательный раздел «откат» (шаблон §5) | Добавлен ### 6. Откат внутри «Решение», текст почти дословно повторяет формулировку, предложенную r1 («ревёрт коммита… readLedger трактует отсутствующий, битый или чужой по схеме файл как пустой журнал… старое поведение восстанавливается без ручных действий») |
Тело issue #481, раздел «Решение» → «### 6. Откат» |
| Medium 2: AC6 доказывается способом вне таксономии §2.5 («замер при реализации, числа в issue» — запрещено правилом 18) | Колонка «Доказательство» строки AC6 переписана на «ревью кода (иллюстративные числа — комментарий автора в issue, не доказательство)» — выбран путь (b) из двух предложенных r1; критерий AC6 сформулирован как структурное утверждение, проверяемое чтением кода (отбор по диффу не изменён, сужение только через splitByLedger, версия-инвариантность — следствие AC1), а не как конкретное число мутантов |
Тело issue #481, таблица «Критерии приёмки», строка AC6 |
| Low 3: влияние на perf/touch не названо явно словом «нет» (снято r1 без правки, с запиской) | Закрыто попутно тем же новым разделом: «Влияние на perf/touch/UX — нет: затронуты только скрипты, workflow и тесты» | Тело issue #481, конец «### 6. Откат» |
Унаследовано из r1
Документ: docs/reviews/SPEC-REVIEW-481-r1.md (коммит 2f65a184; материал раунда —
dev на момент r1, SHA ветки в документе не резолвлен — по §2.10 это нормальный
случай, не находка).
Принято без повторной проверки по существу:
- AC1–AC5 и AC7 однозначны, проверяемы, попадают в разрешённую таксономию доказательств (unit / контрактный тест воркфлоу / отрицательные прогоны свидетелей); на ветке задачи для них есть реальные автотесты, различающие правильное и сломанное поведение.
- Ссылки на #475, #480, #472, #388 точны и соответствуют описанию автора.
- Технические факты не домысел:
guardFiles()экспортирована,visualFingerprintи нормализация версии существуют вscripts/source-fingerprint.mjs, структураMUTANT_DEFINITIONSсоответствует описанию. - Раздел «Что не меняется» корректно ограничивает скоуп (полный прогон,
--check,--idжурнал не читают). actions/cache/save … if: always()— осознанное обоснованное отступление от соседнего success-only паттернаperformance_smoke.- Трек
smallобоснован: критерии §5 выполняются одновременно; файлаdocs/specs/481-*.mdнет. - «Затронутые файлы» — верно, всё класса B/C, ни одного класса A; подтверждено
дополнительно и в этом раунде:
git diff --statс момента r1-документа (коммит2f65a184) по текущий HEAD2c50e736трогает ровно перечисленные файлы (scripts/mutation-gate.mjs,scripts/source-fingerprint.mjs,.github/workflows/validate.yml,test/mutation-gate.test.mjs,test/validate-workflow.test.mjs,docs/TESTING.md) плюс служебныйdocs/images/screenshots.json(отпечаток скриншотов, механика докс-гейта, не продуктовый файл) — класс A по-прежнему не задет.
Находки нового раунда
Нет. High: 0, Medium: 0.
Что проверено и корректно (в этом раунде)
- Текст нового раздела «Откат» точно соответствует поведению
readLedger, независимо подтверждённому ещё в r1 чтением кода ветки: отсутствующий, битый или несовпадающий по схеме файл трактуется как пустой журнал. - AC6 больше не привязан к нефальсифицируемому числу и не требует ручного «замера»: формулировка проверяема чтением кода, а поле доказательства явно в разрешённой таксономии §2.5 и не нарушает правило 18 (числа помечены как иллюстрация, не доказательство).
- Названные в комментарии автора исторические SHA (
052549fa,f2e38e48,5d281171,04f4cd10) существуют и соответствуют описанным событиям (релизный кандидат, шардирование, докс-коммит) — иллюстрация не построена на выдуманных ссылках, хотя сама она и не является доказательством AC6. - Открытых продуктовых вопросов в тексте нет; догадок, выданных за решённое поведение, не найдено — как в дельте, так и в унаследованной части (перепроверено r1, не оспаривается).
Чего не проверял
- Гейты (
tsc --noEmit,npm test,npm run build) не гонялись: на этапе spec-review материал — текст ТЗ, а не диапазон кода; тот же выбор сделал r1 для этой же задачи по той же причине.node scripts/check-docs.mjsне запускался по той же причине — этот этап не проверяет состояниеsrc/**. - Не пересчитывал побитово иллюстративные числа из комментария автора (132 из 134 отобранных пропущено по журналу; 113 из 113 без изменения отпечатка на бампе версии) — они явно помечены как не-доказательство, реальный прогон на историческом диапазоне и фиксация команды/результата — задача код-ревью (вариант (b) из находки r1 №2 прямо поручает это код-ревьюеру).
- Не переоценивал по существу реализацию на ветке
issue/481-mutation-ledger— это предмет код-ревью (§2.7), не этого этапа; использовал код только как перекрёстную проверку (не домысел ли текст ТЗ), как и в r1.
Вердикт
Зелёный. High: 0, Medium: 0. Обе Medium-находки r1 закрыты текстом issue дословно по предложенным вариантам исправления, Low закрыт попутно. Статус — «Готово к разработке».
Материал раунда: тело issue #481 на момент r2; предыдущий документ —
docs/reviews/SPEC-REVIEW-481-r1.md (коммит 2f65a184); HEAD ветки на момент
этого разбора — 2c50e736 (detached, origin/issue/481-mutation-ledger).
Материал раунда
- Ветка:
issue/481-mutation-ledger, коммит2c50e7367100— ребейз его осиротит, и это нормально: ниже якоря, которые ребейз не меняет. - Дерево материала:
3d4c141fe31c1bad1f12948956a3246c678eec0cgit log --all --format='%H %T' | grep 3d4c141fe31c