hermes-hub/agents/inbox/2026-08-21-truthful-data-and-release-readiness.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

87 lines
8.7 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.

# Задание: Правдивость данных и готовность к релизу v0.1.1
## Дата поступления
2026-08-21
## Контекст
По итогам ревью раунда 5 (`0d9005f…0c511cd`, +6970 строк) выявлены два блокирующих дефекта одного класса: **пользователю показываются правдоподобные, но выдуманные данные**. Тесты и релизный гейт при этом зелёные — дефекты не детектируются существующими проверками.
Ветка `main` = `0c511cd`. Тег `v0.1.1` снят с `origin` и локально (указывал на `65482e8` без исправления P0-1).
**Просьба: на время выполнения этого задания заморозить `main` для новой функциональности.** За два предыдущих ревью в ветку влилось ~7300 строк, из-за чего вердикт устаревал к моменту выдачи.
---
## Область задачи (Scope)
### P0-1. Сборщик квот не должен выдавать выдуманные числа за данные провайдера
`src/antigravity_provider/router/quota_collector.py` не делает ни одного сетевого вызова (`urlopen`: 0), но возвращает 17 захардкоженных `used_percent` и помечает снапшоты источниками `antigravity_api`, `codex_usage_api`, `opencode_api`, `claude_oauth_usage_api`, `xai_task_usage_api`. Эти значения выводятся в карточке аккаунта (`ui/views/accounts_view.py:168`).
Выбрать один из путей:
**Путь А (предпочтительный) — реальный сбор.** Запрашивать потребление у провайдера там, где есть API; при успехе оставлять источник `*_api`, при неудаче — переключаться на путь Б.
**Путь Б — честная маркировка.** Если данные вычисляются локально:
- источник снапшота — `estimated` или `baseline`, но **не** `*_api`;
- в UI рядом с корзиной квоты — явный признак оценки (значок/подпись «оценка», не проверено у провайдера);
- значения не должны выглядеть как измерение: либо диапазон, либо «нет данных» вместо `9%`.
Смешанный вариант (А с фолбэком на Б) допустим и желателен.
### P0-2. Убрать тихий фолбэк на поддельный код авторизации
`router/codex_oauth.py:103112` и `router/grok_oauth.py:9194` при недоступности эндпоинта провайдера генерируют локальные `user_code` (`CDX-…`, `GRK-…`) и `device_code`/`device_auth_id`. По RFC 8628 их выдаёт сервер авторизации; локально сгенерированные ему неизвестны, поллинг гарантированно завершается таймаутом через 15 минут, а пользователь всё это время видит правдоподобный код.
Требуется:
- в обычном режиме при неудаче запроса кода — **немедленная ошибка** с текстом причины в мастере, без запуска поллинга;
- фолбэк на локальную сессию — только под явным `HERMES_HUB_DEV_MODE=1` (по образцу `update_manager.is_allowed_update_host`), с видимой пометкой в UI, что сессия тестовая;
- проверить остальные OAuth-модули (`claude_oauth.py`, `profile_oauth.py`) на такой же паттерн.
### P1-3. Распространить решение по OAuth-клиентам на новых провайдеров
`docs/OAUTH_CLIENT.md` описывает только Google. В коде появились ещё три заимствованных клиента:
```
codex_oauth.py:31 app_EMoamEEZ73f0CkXaXp7hrann (OpenAI)
grok_oauth.py:30 b1a00492-073a-47ea-816f-4c329264a828 (xAI)
claude_oauth.py клиент Claude
```
Добавить их в документ с той же структурой: тип клиента, модель угроз, обоснование по RFC 8252/7636, явное указание происхождения.
### P1-4. Определить судьбу `gui_server.py`
Файл вырос ещё на 112 строк, но `run_gui_server` не вызывается ниоткуда (проверено по `.py`, `.bat`, `.ps1`, `.cs`). Либо подключить, либо вынести в `legacy/`, либо удалить вместе с `gui_cockpit.html`. При удалении — убрать `fastapi`/`uvicorn` из обязательных зависимостей `pyproject.toml`.
### P1-5. Организационные пункты релиза (из раунда 4)
1. Опубликовать GitHub Release в `ochenstarik-ui/hermes-hub-releases`: ассет `hermes-hub-0.1.1.zip` с суммой, совпадающей с `sha256` в `update_manifest.json` (сейчас `package_url` → HTTP 404).
2. Положить туда же `HermesHubSetup.exe`; `dist/checksums.txt` обновлять сборочным скриптом, а не вручную.
3. Тег `v0.1.1` ставить только на коммит, прошедший ревью. Если локальный тег остался на машине исполнителя — удалить: `cd <repo>; git tag -d v0.1.1`.
### P2-6. Долг, накопленный за пять раундов (в обычную очередь)
- `capability_matrix`, `lifecycle_supervisor`, `skill_registry`, `deepseek_adapter` — не подключены ни к одному кодовому пути; подключить либо пометить экспериментальными.
- Комментарии в `router_profiles.yaml` стираются при сохранении.
- `model_timeout_seconds`, `monitoring_interval_seconds`, `auto_monitoring` сохраняются, но не читаются (работают 4 настройки из 7).
- `tests/test_installer.py` при `-m installer` пишет в Start Menu и `HKCU`.
- `_CM_LOCK` удерживается на всё время subprocess `agy`; глобальная запись `gemini:antigravity` перезаписывается без восстановления.
- `health_tracker`: запись атомарна, но межпроцессной блокировки нет (last-writer-wins между GUI и Hermes).
---
## Критерии приёмки
Ревью будет проверять ровно это, исполнением:
1. `grep -c urlopen quota_collector.py` > 0 **либо** ни один снапшот с локально вычисленными значениями не имеет источник `*_api`. Проверяется вызовом сборщика и чтением поля `source`.
2. В UI карточки аккаунта для оценочных данных присутствует визуальный признак оценки.
3. При недоступности эндпоинта устройства (мокируется исключением в `_post_json`) и **без** `HERMES_HUB_DEV_MODE`: `start()` возвращает ошибку, `status != "pending"`, поток поллинга не стартует.
4. С `HERMES_HUB_DEV_MODE=1` фолбэк работает и помечен в UI.
5. `docs/OAUTH_CLIENT.md` содержит разделы по OpenAI, xAI и Claude.
6. `run_gui_server` либо вызывается, либо файла нет в `src/`.
7. `curl -I <package_url из манифеста>` → HTTP 200, sha256 совпадает.
8. Регрессия не внесена: полный `pytest tests/` зелёный **в окружении без UI-зависимостей** (проверка инварианта `importorskip`), релизный гейт PASSED.
9. Новые тесты на P0-1 и P0-2, падающие на текущем `0c511cd`.
## Что НЕ входит в задание
Новая функциональность. Задание закрывает дефекты и готовит релиз; любые новые возможности — после тега.