fix: the guard says why it refused, in the issue

A review label promises work. When the guard declined it wrote the reason to the
run log and nothing else, so the issue sat in a status nobody was acting on and
nobody could tell. #123 showed it: an outside reporter's issue was walked up to
S4-spec-review, the guard refused in nine seconds because only the owner's issues
enter the process, and the issue itself said not a word.

Refusals that a human can act on now become a comment: wrong author, blocked,
review-4. Only when a stage was actually recognised, so an unrelated label change
stays silent.

This is the same defect as the merge conflict that left the label untouched, seen
from the other side. The pattern is worth naming: doing nothing quietly is the
most expensive thing a pipeline can do.

Issue: #114
User-Visible: no
This commit is contained in:
Matysh
2026-08-13 20:36:25 +03:00
parent 948f2848dd
commit 4e539b02df
+23 -6
View File
@@ -77,19 +77,36 @@ jobs:
-q "[.comments[] | select(.body | test(\"Вердикт:\")) | select(.body | test(\"$marker\"))] | length")
fi
# Отказ обязан быть виден в issue, а не только в логе прогона.
# Ревьюшная метка обещает работу; если конвейер её не начал и промолчал,
# задача стоит в этом статусе бесконечно и никто об этом не узнаёт.
# Так и вышло на #123: чужой issue довели до S4-spec-review, guard
# отказался за 9 секунд, и в issue не было ни слова.
#
# Пишем только когда пытались запустить ревью, то есть stage опознан.
# Иначе комментарий уходил бы на каждую смену любой метки.
refuse() {
echo "$1"
gh issue comment "$NUM" --repo "${{ github.repository }}" --body \
"Конвейер ревью не запущен: $2
Метка \`$LABEL\` обещает работу, которая не начнётся, поэтому статус лучше вернуть в предыдущий — иначе задача простоит здесь бесконечно. [Прогон](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }})."
stage=""
}
# В процесс идут только issue, созданные владельцем: репозиторий
# публичный, чужие отчёты бывают невалидны и статусов не несут.
if [ -z "$stage" ]; then
:
elif [ "$AUTHOR" != "Matysh" ]; then
echo "issue от $AUTHOR, не от владельца — пропуск"
stage=""
refuse "issue от $AUTHOR, не от владельца — пропуск" \
"issue создан пользователем \`$AUTHOR\`, а в процесс идут только issue владельца (PROCESS.md §9). Чтобы взять задачу в работу, владельцу нужно завести свой issue со ссылкой на этот."
elif [ "$BLOCKED" = "true" ]; then
echo "стоит blocked — конвейер не запускается"
stage=""
refuse "стоит blocked — конвейер не запускается" \
"на issue стоит \`blocked\` — задача ждёт внешнего решения. Снять метку, когда решение принято."
elif [ "$EXHAUSTED" = "true" ]; then
echo "стоит review-4 — решение за владельцем"
stage=""
refuse "стоит review-4 — решение за владельцем" \
"на issue стоит \`review-4\`: лимит циклов ревью исчерпан, дальше решает владелец — разделить задачу, отклонить или арбитраж (PROCESS.md §4)."
elif [ "$done_cycles" -ge "$limit" ]; then
echo "циклов этапа $stage пройдено $done_cycles из $limit — лимит исчерпан"
gh issue edit "$NUM" --repo "${{ github.repository }}" --add-label review-4