diff --git a/scripts/mutation-gate.mjs b/scripts/mutation-gate.mjs index cca30760..03766e8c 100644 --- a/scripts/mutation-gate.mjs +++ b/scripts/mutation-gate.mjs @@ -7880,6 +7880,19 @@ const MUTANT_DEFINITIONS = [ replace: ' printf \'EOF_RESULT\\n\' >> "$GITHUB_OUTPUT" # mutant: delimiter glued to JSON', }], }, + { + id: 'process-canon-says-review-replaces-testing-across-line-break', + guard: 'node --test --test-name-pattern="#553" test/review-doc-guard.test.mjs', + because: '#553: запрет старой формулировки обязан переживать перенос строки; ' + + 'дословный откат прежнего абзаца не должен проходить regression-тест', + patches: [{ + file: 'PROCESS.md', + find: '- **Ревьюер отвечает за полноту доказательств AC, а не заменяет их исполнение.**', + replace: '- **Ревьюер отвечает за полноту доказательств AC, а не заменяет их исполнение.**\n' + + ' Код-ревью не пропускается\n' + + ' никогда — именно оно в этом процессе заменяет тестирование.', + }], + }, { id: 'review-integration-skips-evidence-checksum', guard: 'node --test --test-name-pattern="#551" test/review-doc-guard.test.mjs', diff --git a/test/review-doc-guard.test.mjs b/test/review-doc-guard.test.mjs index bddf7477..28fe637d 100644 --- a/test/review-doc-guard.test.mjs +++ b/test/review-doc-guard.test.mjs @@ -754,7 +754,7 @@ test('#553: канон разделяет review и исполнение тес const agents = read('AGENTS.md'); const status = read('docs/STATUS.md'); - assert.doesNotMatch(process, /ревью[^\n]{0,80}заменяет тестирование/i); + assert.doesNotMatch(process, /ревью[\s\S]{0,120}заменяет тестирование/i); assert.doesNotMatch(agents, /review[^\n]{0,80}stands in for testing/i); assert.doesNotMatch(process, /получает\s+нормальный файл ТЗ/i); assert.match(process, /полное ТЗ в теле issue по §7\.1/);