diff --git a/docs/specs/454-review-round-counter.md b/docs/specs/454-review-round-counter.md index 730f7f39..b5af2921 100644 --- a/docs/specs/454-review-round-counter.md +++ b/docs/specs/454-review-round-counter.md @@ -59,13 +59,19 @@ spent=$(… "$blocking | length") | 14:46 | spec, жёлтый, «заход r1» | нет | | 14:56 | spec, жёлтый, «заход r2» | да | | 15:17 | spec, зелёный, «заход r3» | да | -| 16:01 | code, красный, «заход r1» | нет | +| 16:01 | code, красный, «заход r1» | да, но случайно | `docs/reviews/SPEC-REVIEW-449-r1.md` имеет две ревизии: `1ce62613` — 223 строки, заголовок «заход r1»; `070c276e` — 226 строк, заголовок «**заход r2**». Файл -`…-r2.md` (`b39f99b3`) содержит третий раунд. Красный вердикт код-этапа от 16:01 -маркера не содержит, поэтому дефект повторится на первом же возврате #449 в -`S7-code-review`. +`…-r2.md` (`b39f99b3`) содержит третий раунд. + +Красный вердикт код-этапа от 16:01 маркер содержит — но не в строке «Документ:», +а внутри прозаической фразы «путь соберёт шаг публикации, `CODE-REVIEW-449-r1`». +Проверено исполнением тем же выражением, что и в `process.yml`: сегодня guard +видит на #449 два спек-вердикта из трёх (`attempt=3`, верно случайно) и один +код-вердикт из одного (`attempt=2`, верно). То есть счёт спасён тем, что +ревьюер два раза из четырёх упомянул имя файла в свободном тексте. Это и есть +предмет задачи: корректность зависит от прозы, а не от факта. Недосчёт был осознанным решением (`process.yml:88-93`: «Недосчёт даёт лишний заход, перерасчёт остановил бы работу досрочно: из двух ошибок выбрана @@ -96,7 +102,13 @@ spent=$(… "$blocking | length") гейт: обсуждается в «Принятых предположениях», но в реализацию не берётся — оно возвращает зависимость от прозы, ради ухода от которой задача и заведена. - Восстановление затёртого документа `SPEC-REVIEW-449-r1.md`: отдельная ручная - операция владельца, к механизму не относится. + операция владельца, к механизму не относится. Отсюда следствие, важное для + чтения AC2: жёлтый вердикт первого спек-раунда #449 утрачен безвозвратно — + его файл перезаписан тем самым дефектом, который чинится, а его комментарий + маркера не содержит. Ни счёт по файлам, ни страховка по комментариям его не + воскрешают, поэтому на сегодняшних данных `spent=1`, и это правильный ответ, + а не недосчёт. Исправление возвращает верным будущий счёт, а не прошлую + историю. ## Контракт поведения @@ -162,7 +174,8 @@ spent = max(spentFromFiles, spentFromComments) | AC | Критерий | Доказательство | |---|---|---| | AC1 | `attempt` берётся от максимального номера опубликованного файла этапа, а не от их количества | unit | -| AC2 | Вердикт без маркера в теле больше не занижает ни `attempt`, ни `spent`: сценарий #449 (r1 без маркера, r2 с маркером) даёт `attempt=3`, `spent=2` | unit на фикстуре реальных данных #449 | +| AC2 | Вердикт без маркера в теле больше не занижает `attempt`: фикстура «#449 как есть» (файлы `…-r1.md` с телом второго раунда, жёлтый, и `…-r2.md` с телом третьего, зелёный; три комментария, у первого маркера нет) даёт `attempt=3`, `spent=1` | unit на фикстуре, снятой с реальных файлов и комментариев #449 | +| AC2b | На той же истории, прожитой уже с исправлением, ничего не теряется: фикстура трёх файлов `r1` (жёлтый), `r2` (жёлтый), `r3` (зелёный) даёт `attempt=4`, `spent=2` | unit на реконструированной фикстуре | | AC3 | Имя документа никогда не повторяет уже существующее на ветке | unit + мутант | | AC4 | Зелёный вердикт цикла не тратит (#227 не сломан) | unit | | AC5 | Вердикт чужого этапа не влияет на счёт (#89 не сломан) | unit | @@ -174,8 +187,11 @@ spent = max(spentFromFiles, spentFromComments) ## План тестирования - `test/review-doc-guard.test.mjs` — новые случаи на каждую строку таблицы - крайних случаев и на AC1–AC7; фикстура «как на #449» строится из реальных - заголовков документов и строк вердиктов. + крайних случаев и на AC1–AC7. Фикстур две, и они разные: + **«#449 как есть»** — буквальный слепок сегодняшнего состояния ветки + (два файла, три комментария), ожидание `attempt=3`, `spent=1`; + **«#449, прожитая с исправлением»** — реконструкция из трёх файлов, + ожидание `attempt=4`, `spent=2`. - Мутанты (правило «мутант на каждый защитный контракт»): - `review-round-counts-files-not-max` — `attempt` считает количество файлов вместо максимума; краснеет AC1/AC3;