mirror of
https://github.com/Matysh/houseplan-card
synced 2026-09-29 03:09:36 +00:00
@@ -0,0 +1,165 @@
|
||||
# SPEC-REVIEW-511-r2
|
||||
|
||||
- Issue: #511 — «release-gate: судить по последнему завершённому прогону на SHA, отменённые не блокируют»
|
||||
- Этап: ТЗ на ревью (PROCESS.md §2.4), лёгкий трек (`small`)
|
||||
- Заход: r2 · блокирующих циклов израсходовано 1 из 2 (этот раунд — зелёный, бюджет не тратится, #227)
|
||||
- Вердикт: **зелёный**
|
||||
|
||||
## Скоуп раунда и объявление дельты
|
||||
|
||||
Предыдущий вердикт — r1, жёлтый, документ `docs/reviews/SPEC-REVIEW-511-r1.md`,
|
||||
опубликован коммитом `6842b69e` (текущий `HEAD`, дерево между раундами не
|
||||
менялось вовсе — задача лёгкого трека, ТЗ живёт в теле issue, кода ещё нет).
|
||||
Материал раунда r1 сам называл SHA пустым («ребейз его осиротит» — якорь не
|
||||
резолвился, ветки задачи не было, читали по `dev`); в r2 сверка проще: между
|
||||
раундами не было ни одного коммита, только правка тела issue.
|
||||
|
||||
Дельта объявлена через историю правок issue (`userContentEdits` GraphQL,
|
||||
единственный способ увидеть точный до/после тела issue, раз обычный
|
||||
`git diff` тут неприменим — ТЗ не файл). Правка сделана 2026-09-09T14:20:49Z,
|
||||
через 17 секунд после публикации вердикта r1 (14:20:32Z). Точный diff:
|
||||
|
||||
```diff
|
||||
- AC3. `docs/performance/README.md`/`docs/TESTING.md` — одна фраза о семантике «последний завершённый».
|
||||
+ AC3. `docs/DEVELOPMENT.md` (канонический документ релиза; строка «A missing, failed, cancelled or one-hour-timed-out Validate withholds the asset» становится неверной) описывает новую семантику: «последний завершённый прогон, `cancelled` не считаются»; `demo/performance/README.md` — та же фраза рядом с требованием Full Performance для stable. Доказательство AC2 — `release.yml` без диффа; доказательство AC3 — grep этих фраз в тесте `release-gate.test`.
|
||||
+
|
||||
+ ## Откат
|
||||
+
|
||||
+ Revert одного коммита; данных и форматов нет.
|
||||
```
|
||||
|
||||
«Проблема», «Решение владельца», AC1, AC2 — байт в байт без изменений.
|
||||
Дельта локальна по всем критериям §2.10: не ребейз, не смена контракта
|
||||
поведения, не новая подсистема, объём — одна строка AC плюс один
|
||||
трёхстрочный раздел. Разбор ограничен дельтой; AC1/AC2 наследуются из r1
|
||||
без повторного вывода алгоритма.
|
||||
|
||||
## Закрытие раунда r1
|
||||
|
||||
| Находка r1 | Чем закрыта | Где это видно |
|
||||
|---|---|---|
|
||||
| **Medium** — AC3 указывал на несуществующий `docs/performance/README.md` и топически неподходящий `docs/TESTING.md`; реальная строка `docs/DEVELOPMENT.md:360` не была названа | AC3 переписан: целевой файл — `docs/DEVELOPMENT.md`, с точной цитатой строки, которая станет неверной; `docs/performance/README.md`/`docs/TESTING.md` убраны | Тело issue #511, раздел AC, пункт AC3 (см. diff выше); подтверждено чтением `docs/DEVELOPMENT.md:359-360` — цитата совпадает дословно (перенос строки в исходнике не меняет фразу) |
|
||||
| **Low 1** — раздел «откат» отсутствовал в теле issue дословно | Раздел `## Откат` добавлен в тело: «Revert одного коммита; данных и форматов нет» | Тело issue #511, последний раздел |
|
||||
| **Low 2** — AC2/AC3 не называли явно способ доказательства | Дописано прямым текстом: «Доказательство AC2 — `release.yml` без диффа; доказательство AC3 — grep этих фраз в тесте `release-gate.test`» | Тело issue #511, конец пункта AC3 |
|
||||
|
||||
Все три находки r1 закрыты содержательно, не декларативно — по каждой указана
|
||||
конкретная строка текста, а не заявление автора.
|
||||
|
||||
## Унаследовано из r1
|
||||
|
||||
Без повторной проверки принято из `docs/reviews/SPEC-REVIEW-511-r1.md`
|
||||
(материал: `dev`, документ опубликован коммитом `6842b69e`, тем же, что и
|
||||
текущий `HEAD`, — дерево кода между раундами идентично):
|
||||
|
||||
- **AC1** полностью и однозначно описывает алгоритм: `cancelled` исключаются
|
||||
целиком, из оставшихся берётся хронологически последний
|
||||
(`run_started_at`/`created_at`); все шесть пар вход/выход в тексте
|
||||
взаимно непротиворечивы. Текст AC1 не менялся дельтой — переверять нечего.
|
||||
- **AC2** структурно подтверждён чтением `release.yml` (оба вызова
|
||||
`release-gate.mjs` идут через общую `classifyValidateRuns`, третьего места
|
||||
с отдельной логикой нет). Текст AC2 не менялся дельтой.
|
||||
- Продуктовая рамка: задача не расширяет скоуп, не трогает `src/**`, не
|
||||
создаёт новый UX-контракт, `User-Visible: no` подразумевается верно.
|
||||
- Отсутствие догадок, выданных за решение: «Решение владельца» — прямая
|
||||
цитата ретроспективы 09.09, п.5, алгоритм AC1 полностью выводится из неё.
|
||||
- Продуктовых вопросов владельцу не требуется — весь материал технический.
|
||||
- Трек `small` выбран корректно (одна поверхность класса B — `scripts/**` +
|
||||
`test/**`, риск 2/10, нет конфига/i18n/перфа/touch).
|
||||
|
||||
## Что проверено заново в этом раунде
|
||||
|
||||
- **Цитата в AC3 для `docs/DEVELOPMENT.md`.** Прочитан файл, строки 359–360:
|
||||
«*A missing, failed, cancelled or one-hour-timed-out Validate withholds the
|
||||
asset*» — фраза реальна, совпадает с цитатой в AC3 дословно (в источнике
|
||||
перенесена по мягкому переносу markdown между «failed,» и «cancelled», это
|
||||
не меняет содержание). `grep -n` подтверждает построчно (359, 360).
|
||||
- **Путь `demo/performance/README.md`.** Файл существует
|
||||
(`ls demo/performand/README.md` → есть), в отличие от использованного в r1
|
||||
ошибочного `docs/performance/README.md` (`docs/performance/` не существует
|
||||
вовсе — перепроверено `ls docs/performance` → «No such file or directory»).
|
||||
Так что сама подмена пути — реальное исправление, не косметика.
|
||||
- **Смысл «та же фраза» для `demo/performance/README.md`.** Проверил
|
||||
построчно (`grep -n -i "exact-SHA|stable release|withhold|asset"`) — в этом
|
||||
файле **нет** существующей фразы вида «A missing, failed, cancelled...»,
|
||||
которая «становится неверной»; единственное релевантное место — строки
|
||||
122–124 («Stable release assets require both exact-SHA `Validate` and
|
||||
exact-SHA `Full Performance`»), и это утверждение остаётся истинным после
|
||||
AC1 (требование «нужен зелёный Validate» не меняется, меняется только то,
|
||||
как это «зелёный» вычисляется). Прочитав AC3 целиком («описывает новую
|
||||
семантику: «последний завершённый прогон, `cancelled` не считаются»; …
|
||||
та же фраза…»), нахожу более естественным прочтение «та же фраза» = та же
|
||||
**новая** поясняющая фраза, добавляемая в оба файла, а не тождественная
|
||||
старая формулировка, которую надо «исправить» во втором файле (там
|
||||
исправлять нечего — искажённого утверждения там сейчас нет). Это не
|
||||
единственно возможное прочтение, но при этом чтении AC3 однозначно
|
||||
выполнимо и проверяемо (grep новой фразы в обоих файлах), а
|
||||
неоднозначность — не о продукте (не «что видит пользователь», а «в какой
|
||||
документ разработки идёт вспомогательное предложение») и не годится для
|
||||
эскалации владельцу по правилу §7.1. Не блокирую: пограничная
|
||||
формулировка, а не фактическая ошибка или неисполнимость — граница между
|
||||
«дефект» и «стилистика», по-моему, здесь пройдена в пользу автора, потому
|
||||
что оба чтения ведут к одному и тому же безопасному действию разработчика
|
||||
(добавить/поправить одну поясняющую фразу в названном месте) и к
|
||||
проверяемому тесту.
|
||||
- **Тест-цель `release-gate.test`.** `test/release-gate.test.mjs` существует
|
||||
уже сегодня (класс B, правится в этой же задаче), текущие тесты
|
||||
(`release gate fails closed for red, cancelled and skipped runs`, `one red
|
||||
duplicate blocks a green duplicate for the same SHA`) кодируют именно
|
||||
старую семантику, которую AC1 переворачивает, — подтверждает, что задача
|
||||
не вакуумна и есть что менять и проверять. Новых assert'ов на grep
|
||||
docs-файлов в тесте пока нет (ожидаемо — реализации ещё нет), но
|
||||
добавление такого теста ничем не блокировано: `docs/DEVELOPMENT.md` и
|
||||
`demo/performance/README.md` — обычные текстовые файлы, `readFileSync` +
|
||||
`includes` тривиален.
|
||||
- **Раздел «Откат».** «Revert одного коммита; данных и форматов нет» —
|
||||
точно для скоупа (правка одного CI-скрипта, одного теста и двух
|
||||
документационных файлов, без миграций, без хранимого состояния, без
|
||||
config-полей). Проверено чтением, не исполнением (откатывать нечего —
|
||||
кода ещё нет).
|
||||
|
||||
## Чего не проверял
|
||||
|
||||
- Продуктовые команды (`typecheck`/`test`/`build`) не гонял — на этапе ТЗ
|
||||
кода нет, гонять нечего (наследуется из r1, ситуация не изменилась).
|
||||
- Историческую точность инцидента 09.09 (конкретные ID прогонов) — факт
|
||||
прошлого CI, не проверяемый чтением репозитория; для ревью ТЗ достаточно,
|
||||
что баг воспроизводится логикой текущего `classifyValidateRuns` (принято
|
||||
в r1, дельта этого не касалась).
|
||||
- Не открывал `docs/CHANGELOG.md`/`.ru.md` — `User-Visible: no`, оба
|
||||
changelog не требуются (наследуется из r1).
|
||||
- Не проверял, действительно ли задача подходила бы под инфраструктурный
|
||||
обход без спецификации (AGENTS.md, «ни одного файла класса A» — она бы
|
||||
подошла, `scripts/**` + `test/**` только класс B). Это выбор автора/
|
||||
аналитика идти полным лёгким треком, а не нарушение процесса — необязателен
|
||||
к проверке ревьюером ТЗ.
|
||||
|
||||
## Итог
|
||||
|
||||
Все три находки r1 (1 Medium, 2 Low) закрыты конкретным текстом, не
|
||||
заявлением. Дополнительная проверка второй половины переписанного AC3
|
||||
(`demo/performance/README.md`) не вскрыла блокирующего дефекта — формулировка
|
||||
пограничная, но исполнима и проверяема при разумном прочтении, последствия
|
||||
обеих трактовок безопасны и совпадают в действии. High-находок нет,
|
||||
новых Medium/Low не заводится. AC1/AC2 наследуются из r1 без повторной
|
||||
проверки алгоритма — дельта их не касалась. Вердикт — зелёный; переход в
|
||||
`S5-ready`.
|
||||
|
||||
---
|
||||
|
||||
<!-- material-anchors: заполняется конвейером -->
|
||||
|
||||
## Материал раунда
|
||||
|
||||
- Ветка/дерево: `dev`, коммит `6842b69eed1a6530d7475f4427132b4a1b501e49` (код не менялся с r1; дельта — только тело issue).
|
||||
- Материал ТЗ: тело issue #511 на момент вывода вердикта; правка зафиксирована `userContentEdits` (GraphQL), `editedAt: 2026-09-09T14:20:49Z`, editor `Matysh`.
|
||||
- Вердикт: `green` · High 0 · Medium 0
|
||||
|
||||
---
|
||||
|
||||
<!-- material-anchors: сгенерировано конвейером (#414) -->
|
||||
|
||||
## Материал раунда
|
||||
|
||||
- Ветка: `dev`, коммит `` — ребейз его осиротит, и это нормально: ниже якоря, которые ребейз не меняет.
|
||||
- Якоря снять не удалось: ветки задачи нет, материал читался по `dev`.
|
||||
- Вердикт конвейера: `green` · High 0
|
||||
Reference in New Issue
Block a user