hermes-hub/agents/inbox/2026-08-20-review-round4-verdict.md
Hermes Team 46a185395c docs(review): add independent audit, five review rounds, and remediation task
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 that 42eddb3 was verified against.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-20 22:22:57 +07:00

9.4 KiB
Raw Permalink Blame History

Ревью, раунд 4: вердикт по кандидату v0.1.1

Отчёт исполнителя описывает 8314d46. Фактический origin/main3aae1a8, на 3 коммита впереди. Проверка проводилась по фактическому HEAD.

Вердикт: тег v0.1.1 не выпускать. Заявленное в отчёте сделано и подтверждено, но на текущем HEAD релизный гейт падает, а публичный фид обновлений указывает на несуществующий пакет.


1. Заявленное в отчёте — подтверждаю

Пункт Проверка Итог
Канонический .cs: EnsurePythonDependencies installer/HermesHubSetup.cs:89 — проверка импорта → ensurepippip → фолбэк на uv → повторная верификация
Канонический .cs: копирование assets строки 263269, три целевых каталога (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

  1. Добавить pytest.importorskip("customtkinter") в tests/test_codex_opencode_wizard.py; убедиться, что гейт зелёный в окружении без UI-зависимостей.
  2. Опубликовать релизный ассет hermes-hub-0.1.1.zip с суммой из манифеста; расширить проверку 7 HEAD-запросом по package_url.
  3. Положить HermesHubSetup.exe в GitHub Release и обновить dist/checksums.txt сборочным скриптом.
  4. Определиться с областью тега: 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-модули не подключены; веб-стек мёртв.