docs: review document for #658

Issue: #658
User-Visible: no
This commit is contained in:
claude[bot]
2026-09-27 11:13:18 +00:00
parent bdac4b4fdc
commit ac8eac6034
+162
View File
@@ -0,0 +1,162 @@
# CODE-REVIEW-658-r1
Материал раунда: `git log --oneline origin/dev..HEAD` / `git diff origin/dev...HEAD`,
SHA `bdac4b4fdc88c7c3a48604163636a3c031830b63` (рабочая копия на нём). Заход r1,
блокирующих циклов израсходовано 0 из 4.
## Скоуп
Issue #658, класс B (`.github/workflows/*.yml`, `test/**`,
`scripts/workflow-jobs.mjs`) + C (`docs/DEVELOPMENT.md`, `PROCESS.md`,
`docs/TESTING.md`). Три хрупких места CI-обвязки:
1. `ubuntu-latest` → `ubuntu-24.04` во всех job на раннере (аудит: 43 места,
issue называет 44 — расхождение в самом тексте issue, не в коде; итоговый
коммит верно пишет «43»).
2. `timeout-minutes` на 26 job, у которых его не было.
3. Cron-расписания `_nightly`, `mutation-gate`, `process-metrics` (и заодно
`performance.yml`) сдвинуты с круглых минут; `_nightly` получил шаг
предупреждения о сдвиге старта > 60 мин.
Один squash-коммит `bdac4b4f`, трейлеры `Issue: #658` и `User-Visible: no`
корректны (изменение не видно пользователю продукта — чисто инфраструктурное).
При `User-Visible: no` правка обоих changelog не требуется — не сделана,
верно.
## Как проверялось
Зелёный Validate уже подтверждён на этом SHA
(https://github.com/Matysh/houseplan-card/actions/runs/36314264957), поэтому
`npx tsc --noEmit`, `npm test` целиком и `npm run build` со сверкой бандла не
перегонялись — они там уже прошли на этом материале. Диф не трогает `src/**`,
`node scripts/check-docs.mjs` не требуется.
Прогнано лично в этом раунде (диф — чисто CI-обвязка + тесты обвязки; ни один
из штатных смоук/golden/backend/invariants-гейтов не применим, так как diff не
трогает `src/**`, `custom_components/**/*.py` и геометрию):
- `node --test test/workflow-hygiene.test.mjs` — все 5 тестов зелёные.
- Свойство «тест умеет падать» проверено мутацией **в памяти**, без изменения
файлов репозитория (через прямой вызов `parseJobSettings` на модифицированном
тексте `validate.yml`):
- вернул `runs-on: preflight` на `ubuntu-latest` → тест «образ закреплён»
находит `floating: ['preflight']`;
- убрал `timeout-minutes: 15` у `preflight` → тест «у каждой job есть
timeout» находит `missing: ['preflight']`.
Обе мутации красят соответствующую проверку — доказательство не голословно.
- Прочитан код `parseJobSettings` (`scripts/workflow-jobs.mjs:134-165`):
разбирает только объявленные job-уровневые скаляры на отступе 4 после
`jobs:`, комментарии и содержимое шагов (`run: |`) корректно исключены
(`isBlank` фильтрует строки с `#`, отступ шагов больше 4). Проверено чтением,
не исполнением, для полноты покрытия всех 19 файлов workflow — сам разбор
подтверждён мутацией выше.
- Прочитан и вручную протрассирован bash-шаг «Сдвиг старта ночи против
расписания» (`_nightly.yml`): для входа `SCHEDULE='17 2 * * *'`,
`NOW_EPOCH` в районе 07:47 UTC даёт `lag=330` и警告; при пересечении полуночи
(`NOW` вскоре после 00:00, план вечера предыдущих суток) корректно вычитает
сутки. Это же покрыто автотестом `test/workflow-hygiene.test.mjs:99-125`,
который реально исполняет скрипт через `bash -c`, а не пересказывает его —
запуск подтверждён (см. выше, все 5 тестов ok).
- Сверены количества: `git diff … | grep -c '^+.*timeout-minutes:'` = 26,
`grep -c '^-.*timeout-minutes:'` = 0 — ровно 26 добавленных таймаутов без
удалений, как заявлено в AC2.
- Проверено `grep -rn "runs-on:.*ubuntu-latest"` по всем `.github/workflows/`
после диффа — совпадений нет (одно вхождение строки `ubuntu-latest` в
`_process.yml:946` — исторический комментарий про поведение установщика
Claude Code, не значение `runs-on`).
- Числа таймаута release-гейта прослежены до источника: `release-gate.mjs`
(`waitForGreenWorkflow`, `timeoutMs = 60 * 60 * 1000` — 60 мин, вызывается
дважды: Validate и `performance.yml`) и `e2e-gate.mjs`
(`VALIDATE_APPEAR_MS + VALIDATE_TOTAL_MS` = 3 + 45 = 48 мин, в комментарии
округлено до «45» — округление в консервативную сторону, неравенство
60+60+48=168 < 180 всё равно верно).
- Сверены упоминания времени вне workflow-файлов: `PROCESS.md` и
`docs/TESTING.md` обновлены с «01:00 UTC» на «00:43 UTC» синхронно с
`mutation-gate.yml`; `test/mutation-gate.test.mjs` AC1 обновлён на новый
cron той же строкой. Остальные упоминания старых времён (`docs/reviews/
CODE-REVIEW-513-*`, `CODE-REVIEW-637-*`) — исторические документы прошлых
раундов, не подлежат правке.
- Заголовок `## Moving the runner image (#658)` в `docs/DEVELOPMENT.md:482`
сверен посимвольно с regex теста
(`/^## Moving the runner image \(#658\)$/m`) — совпадает.
## AC · чем доказан · чем краснеет
| AC | Чем доказан | Чем краснеет |
|---|---|---|
| 1. Единый `ubuntu-24.04` во всех job, тест по тексту, запись в DEVELOPMENT.md | `test/workflow-hygiene.test.mjs` тест 2 (образ закреплён, один на все workflow, заголовок раздела найден) | Мутация «вернуть `ubuntu-latest` у одной job» → `floating` непусто (проверено выше в памяти) |
| 2. `timeout-minutes` на 26 job, тест «у каждой есть» | `test/workflow-hygiene.test.mjs` тест 3 | Мутация «убрать одну строку timeout-minutes» → `missing` непусто (проверено выше) |
| 3. Cron на некруглых минутах + предупреждение о сдвиге > 60 мин | `test/workflow-hygiene.test.mjs` тесты 4 и 5 (второй реально исполняет bash-шаг) | Тест 4: мутация cron на `30 2 * * *` регексом `% 15 === 0` красит `round`; тест 5 явно проверяет границу 60/61 мин (assert on/off) и переход через полночь |
Все три AC — защитные по духу (гарды против регресса инфраструктуры), таблица
заполнена по каждому с named-мутацией и результатом, пустых столбцов нет.
## Находки
Нет. High: 0, Medium: 0, Low: 0.
Отдельно отмечено (не находка, а расхождение исходного текста issue, не
кода): issue называет 44 места с `ubuntu-latest`, фактический аудит и
итоговый коммит — 43; расхождение не влияет на полноту исправления (сошлись
все места, что нашёл grep по факту).
## Что проверено и корректно
- Все 19 файлов `.github/workflows/*.yml` без плавающего `ubuntu-latest` в
`runs-on` (кроме одного текстового упоминания в комментарии, не влияющего
на исполнение).
- 26 добавленных `timeout-minutes`, без удалений; значения по ориентирам из
issue где они менялись (frontend 40, backend 30, golden 45, preflight 15,
proof 10, релиз/паблиш 20–30) — совпадают; там, где ориентир не совпадает
(например `smoke` шард — 20, а не рекомендованные 45), это уже
существовавшее до этой задачи значение, issue называет их «ориентирами», не
жёстким контрактом, и не требует их менять.
- Таймаут `gate` в `release.yml` (180 мин) арифметически больше суммы
собственных ожиданий (60+60+48), с чем ссылается комментарий в коде.
- Шаг обнаружения сдвига старта ночи корректно обрабатывает переход через
полночь и границу 60/61 мин, что подтверждено исполнением реального
bash-кода в тесте.
- Тонкие вызывающие workflow (`process.yml`, `process-reconcile.yml`,
`process-resume.yml`) корректно не входят в проверку `runs-on`/
`timeout-minutes` — это `uses:`-обёртки без job на раннере, фильтр
`!job.uses` в тесте это учитывает верно.
- Числа синхронизированы вне workflow-файлов: `PROCESS.md`, `docs/TESTING.md`,
`test/mutation-gate.test.mjs` — один источник (сам `mutation-gate.yml`) и
везде отражено одно и то же новое время.
- Не-скоуп соблюдён: пересъёмки golden/скриншотов и `performance.yml` на
зеркалах (#656 п.4) в диффе нет — и не должно быть.
## Чего не проверял
- Полные `npx tsc --noEmit`, `npm test` (весь набор), `npm run build` +
сверку трёх копий бандла — не перегонял лично; засчитан зелёный Validate на
этом же SHA (см. ссылку выше), это ровно то, что просит §8 при подтверждённом
зелёном прогоне на материале.
- Смоки, `golden:verify`, `pytest tests_backend`, `npm run invariants` —
сознательно не прогонял: диф не трогает `src/**` в части рантайма, рендера,
Python или геометрии, а `smoke-select.mjs` по такому диффу (только
`.github/workflows`, `test/`, `scripts/workflow-jobs.mjs`, `docs/*.md`) не
даёт релевантных прямых совпадений — гейты вне применимости диффа, не
пропущенный гейт.
- Performance-профили (`performance.yml` полностью) — в AC не названы,
сознательно не прогонял.
- Реальный прогон изменённых workflow на GitHub Actions (сработает ли новый
cron, действительно ли `ubuntu-24.04` доступен раннерам, реальный тайминг
job) — по определению недоступен ревьюеру до мержа; риск принят как
стандартный для инфраструктурных PR такого рода, дополнительно снижен тем,
что `ubuntu-24.04` — текущий образ (не новый), т.е. runs-on меняется на уже
используемый ярлык, а не на непроверенный.
---
<!-- material-anchors: сгенерировано конвейером (#414) -->
## Материал раунда
- Ветка: `issue/658-ci-hygiene`, коммит `bdac4b4fdc88` — ребейз его осиротит, и это нормально: ниже якоря, которые ребейз не меняет.
- Дерево материала: `4e64019b42ae355cda84b020a188621551b5783a`
```
git log --all --format='%H %T' | grep 4e64019b42ae
```
- Тело issue: `0549b5bbf10a565d31c5ec6d826d7c35dc07fdbadf8f56b04f2a29f3eb11189a`
- Вердикт конвейера: `green` · High 0