fix: отделить delimiter результата ревью от JSON (#551)

Issue: #551
User-Visible: no
This commit is contained in:
Sergey Matyunin
2026-09-13 14:34:17 +03:00
parent 23f48829c2
commit 62e0eff219
3 changed files with 26 additions and 5 deletions
+5 -5
View File
@@ -1212,11 +1212,11 @@ jobs:
(.verdict == "green" or .verdict == "yellow" or .verdict == "red")
and (.high | type == "number") and (.medium | type == "number")
and (.summary | type == "string")' "$dir/verdict.json" >/dev/null
{
echo 'structured_output<<EOF_RESULT'
cat "$dir/verdict.json"
echo 'EOF_RESULT'
} >> "$GITHUB_OUTPUT"
printf 'structured_output<<EOF_RESULT\n' >> "$GITHUB_OUTPUT"
cat "$dir/verdict.json" >> "$GITHUB_OUTPUT"
# structured_output не обязан оканчиваться LF: delimiter команды
# GitHub должен начинаться с отдельной строки.
printf '\nEOF_RESULT\n' >> "$GITHUB_OUTPUT"
# Ревьюер пишет только в docs/reviews/. Что именно попадёт в коммит,
# решает этот шаг, а не модель: всё остальное откатывается.
+11
View File
@@ -7869,6 +7869,17 @@ const MUTANT_DEFINITIONS = [
replace: ' printf \'%s\' "$OUT" | jq -e \'true\' > "$RUNNER_TEMP/verdict.json" # mutant: boolean payload',
}],
},
{
id: 'review-integration-delimiter-follows-json-without-newline',
guard: 'node --test --test-name-pattern="#551" test/review-doc-guard.test.mjs',
because: '#551: structured verdict записан через printf без финального LF; GitHub output '
+ 'delimiter обязан начинаться с новой строки, иначе integration падает после зелёной модели',
patches: [{
file: '.github/workflows/process.yml',
find: ' printf \'\\nEOF_RESULT\\n\' >> "$GITHUB_OUTPUT"',
replace: ' printf \'EOF_RESULT\\n\' >> "$GITHUB_OUTPUT" # mutant: delimiter glued to JSON',
}],
},
{
id: 'review-integration-skips-evidence-checksum',
guard: 'node --test --test-name-pattern="#551" test/review-doc-guard.test.mjs',
+10
View File
@@ -779,6 +779,16 @@ test('#551: gates, модель и интеграция имеют незави
'jq валидирует сохранённый объект, не записывает boolean предиката вместо него');
assert.doesNotMatch(seal, /jq -e '[\s\S]*> "\$RUNNER_TEMP\/verdict\.json"/,
'stdout предиката jq не становится payload интеграции');
const resultOutput = integrate.slice(
integrate.indexOf('- name: Проверить полноту и происхождение результата'),
integrate.indexOf('- name: Опубликовать документ ревью'),
);
assert.match(resultOutput,
/cat "\$dir\/verdict\.json" >> "\$GITHUB_OUTPUT"[\s\S]*printf '\\nEOF_RESULT\\n' >> "\$GITHUB_OUTPUT"/,
'закрывающий delimiter начинается с новой строки даже у JSON без финального LF');
assert.doesNotMatch(resultOutput,
/cat "\$dir\/verdict\.json"\n\s+echo 'EOF_RESULT'/,
'cat без гарантированного LF не приклеивает delimiter к JSON');
assert.match(model, /ref: \$\{\{ needs\.prepare\.outputs\.material_sha \}\}/,
'модель получает exact material, а не подвижную ветку');