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

120 lines
9.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Ревью, раунд 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 | строки 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-модули не подключены; веб-стек мёртв.