Full audit of the project (93 findings) plus the review record for rounds 1-5: P0 release blockers,65482e8,42dfe2c, the v0.1.1 candidate verdict, and the review of the previously unreviewed OAuth/wizard/quota work. Includes the remediation task with acceptance criteria that42eddb3was verified against. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
9.4 KiB
Ревью, раунд 4: вердикт по кандидату v0.1.1
Отчёт исполнителя описывает 8314d46. Фактический origin/main — 3aae1a8, на 3 коммита впереди.
Проверка проводилась по фактическому HEAD.
Вердикт: ⛔ тег v0.1.1 не выпускать. Заявленное в отчёте сделано и подтверждено, но на текущем HEAD релизный гейт падает, а публичный фид обновлений указывает на несуществующий пакет.
1. Заявленное в отчёте — подтверждаю
| Пункт | Проверка | Итог |
|---|---|---|
Канонический .cs: EnsurePythonDependencies |
installer/HermesHubSetup.cs:89 — проверка импорта → ensurepip → pip → фолбэк на uv → повторная верификация |
✅ |
Канонический .cs: копирование assets |
строки 263–269, три целевых каталога (install dir, плагин, hermes home) | ✅ |
| Post-install smoke test | строка 303, HERMES_HUB_IMPORT_OK, проверяется ExitCode и наличие маркера |
✅ |
| M1 — dev-bypass | allow_dev_local по умолчанию False, оба продакшен-вызова передают False явно (:130, :187) |
✅ |
| M2 — счётчик гейта | 16/16 в заголовке и в сообщении согласованы |
✅ |
| M3 — кэш настроек | mtime-кэш + invalidate_settings_cache() при сохранении |
✅ |
| Публичный фид | HTTP 200, манифест валидный, v0.1.1 |
✅ |
Блокер раунда 3 (исправление P0-1 не в каноническом установщике) закрыт.
2. ⛔ Блокер 1: релизный гейт падает на текущем HEAD
Отчёт цитирует [RELEASE GATE: PASSED] — это результат для 8314d46. На 3aae1a8 фактически:
[RELEASE GATE: FAILED] One or more checks failed. Release blocked.
Причина — новый tests/test_codex_opencode_wizard.py из коммита 3aae1a8 импортирует customtkinter на уровне модуля без pytest.importorskip, и сбор всей сессии прерывается:
ERROR tests/test_codex_opencode_wizard.py
!!! Interrupted: 1 error during collection !!!
1 skipped, 3 deselected, 1 error
Падают пункты гейта 2, 3 и 4. Это возврат ровно того дефекта, который закрывался как S8 в раунде 2: отсутствие опциональной UI-зависимости должно давать skip, а не обрывать прогон. Остальные три тестовых модуля (test_ui_refinement, test_p0_release_gate, test_oauth_lifecycle) importorskip содержат — забыли только в новом.
Без этого файла суite зелёный: 57 passed, 4 skipped, 3 deselected. Исходный код, который тестируется (CodexOAuthSession, enable_clipboard_shortcuts, HubEntry, extract_jwt_identity), на месте.
Оговорка: на машине, где customtkinter установлен, гейт пройдёт. Но инвариант «отсутствие UI-зависимости не ломает прогон» нарушен — а это ровно тот сценарий, ради которого существует P0-1.
Правка: одна строка pytest.importorskip("customtkinter") в новом файле.
3. ⛔ Блокер 2: фид обновлений указывает на несуществующий пакет
Манифест живой и отдаёт HTTP 200, но пакет из него — нет:
package_url: https://github.com/ochenstarik-ui/hermes-hub-releases/releases/download/v0.1.1/hermes-hub-0.1.1.zip
-> HTTP 404
gh release list --repo ochenstarik-ui/hermes-hub-releases -> пусто
Пункт гейта 7 проверяет только наличие полей version и package_url в манифесте, но не достижимость самого пакета — поэтому печатает [LIVE STATUS] Public update manifest live. Формально верно, по существу — обновление скачать нельзя.
Сейчас это не проявится (манифест объявляет 0.1.1, приложение 0.1.1 → «обновлений нет»), но как только выйдет 0.1.2, пользователь получит ошибку загрузки.
Правка: опубликовать релизный ассет с заявленным sha256, а в check_production_update_feed добавить HEAD-запрос по package_url.
4. Артефакт релиза непроверяем из репозитория
Отчёт приводит SHA256 собранного установщика 1D41B9D6…. Проверить его нельзя:
файлов dist/ в git: 0 (dist/ в .gitignore)
локальный dist/HermesHubSetup.exe: 7e2531… (сборка от 20.08 00:16, устаревшая)
dist/checksums.txt: содержит старую сумму 7E2531…
Собранный установщик существует только на машине исполнителя. Любой, кто клонирует репозиторий, установщика не получает, а checksums.txt вводит в заблуждение. Для релиза артефакт должен попасть в GitHub Release (там же, где ассет обновления), а checksums.txt — обновляться сборочным скриптом.
Заявленный clean-install тест в изолированном venv я подтвердить не могу — воспроизвести его без артефакта нечем. Код установщика при этом проверен и выглядит корректно (см. раздел 1).
5. Отчёт отстал от кода на 2097 строк
После 8314d46 в main влиты три коммита, которых отчёт не касается:
0d9005f fix(oauth): eliminate ERR_CONNECTION_REFUSED, immediate listener binding, single session reuse
249a888 feat(oauth): Cockpit Tools model, manual callback fallback, race protection
3aae1a8 feat(wizard): Codex OAuth/API Key & OpenCode Go with clipboard UX
+2097 / −232 строк: новый codex_oauth.py (296), переработанный profile_oauth.py (+296), add_account_wizard.py (+880), components.py (+83), два новых тестовых модуля.
Это функциональная разработка, а не закрытие замечаний, и она не отревьюирована. Беглая проверка на утечки: в codex_oauth.py и profile_oauth.py токены и коды в логи не пишутся — логируются только source и HTTP-код. Полноценного ревью этих коммитов не проводилось.
Вердикт по релизу не может покрывать неотрецензированный код. Либо тег ставится на 8314d46 (после закрытия блокера 2), либо новые коммиты идут на отдельное ревью.
6. Условия выпуска v0.1.1
- Добавить
pytest.importorskip("customtkinter")вtests/test_codex_opencode_wizard.py; убедиться, что гейт зелёный в окружении без UI-зависимостей. - Опубликовать релизный ассет
hermes-hub-0.1.1.zipс суммой из манифеста; расширить проверку 7 HEAD-запросом поpackage_url. - Положить
HermesHubSetup.exeв GitHub Release и обновитьdist/checksums.txtсборочным скриптом. - Определиться с областью тега:
8314d46либо отдельное ревью коммитов0d9005f…3aae1a8.
Пункты 1 и 2 — блокирующие. 3 и 4 — обязательны для честного релиза, но могут быть закрыты процедурно.
7. Остаточное из прошлых раундов (не блокирует)
- Комментарии в
router_profiles.yamlстираются при сохранении. model_timeout_seconds,monitoring_interval_seconds,auto_monitoringсохраняются, но не читаются (работают 4 настройки из 7).tests/test_installer.pyпо-прежнему пишет в Start Menu иHKCUпри запуске с-m installer._CM_LOCKна всё время subprocess; глобальная записьgemini:antigravityбез восстановления; session affinity без TTL;router_state.jsonбез межпроцессной блокировки; roadmap-модули не подключены; веб-стек мёртв.