docs(task): A8 and B7 — defects found during the first live run
The owner used the product and the router proved itself: the log shows a real failover chain codex-orch -> ag-orch-fallback -> opengo-3 driven by actual quota errors. Everything around that core failed. Hub stopped launching because customtkinter vanished from the Hermes venv, most likely wiped by that app's repair-install; pythonw swallows the traceback, so it looks like the window never opens. The wizard offers five providers while the router config defines profiles for three, so find_free_slot returns a non-existent claude-orch. The test action still reaches the agy subprocess, which opens a browser on expired credentials. The routing "configure" button only raises a toast about drag-and-drop. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
8cddc9fee2
commit
20078f5ff6
2 changed files with 240 additions and 0 deletions
135
agents/inbox/2026-08-22-A8-antigravity-deployment-and-doctor.md
Normal file
135
agents/inbox/2026-08-22-A8-antigravity-deployment-and-doctor.md
Normal file
|
|
@ -0,0 +1,135 @@
|
||||||
|
# Задание A8 (Antigravity): запуск, развёртывание, самопроверка
|
||||||
|
|
||||||
|
## Дата поступления
|
||||||
|
2026-08-22
|
||||||
|
|
||||||
|
## База
|
||||||
|
Проверочный HEAD: **`8cddc9f`**, `origin/main` = `8cddc9f`. `git fetch`, зафиксировать `BASE_SHA`.
|
||||||
|
|
||||||
|
## Ветка
|
||||||
|
`antigravity/deployment-doctor`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Что принято по A7
|
||||||
|
|
||||||
|
Проверено исполнением: лизы объединены (`engine.leases is LeaseManager.get()` → `True`, снапшот показывает `{'codex-orch': 1}`), CPU прогревается (первое измерение 25.0 вместо нуля), сеть стала скоростью `net_speed_mbps`. Прогон: headless 195, с UI-зависимостями 249, ruff чисто, гейт PASSED.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Контекст: владелец впервые эксплуатировал Hub
|
||||||
|
|
||||||
|
Вчера и сегодня продукт запускали вживую. Результат: **роутер работает, оболочка — нет**. В журнале зафиксирован настоящий каскад отказоустойчивости:
|
||||||
|
|
||||||
|
```
|
||||||
|
20:07:10 Переключение роли 'orchestrator': сбой 'codex-orch' — Insufficient quota
|
||||||
|
20:07:10 Успешное переключение: резервный профиль 'ag-orch-fallback'
|
||||||
|
20:07:10 Переключение: сбой 'ag-orch-fallback' — Individual quota reached
|
||||||
|
20:07:10 Успешное переключение: резервный профиль 'opengo-3'
|
||||||
|
```
|
||||||
|
|
||||||
|
Это первое доказательство, что ядро делает то, ради чего создавалось. Всё остальное, о чём сообщил владелец, — дефекты вокруг ядра.
|
||||||
|
|
||||||
|
## P0-1. Hub перестал запускаться: зависимость живёт в чужом окружении
|
||||||
|
|
||||||
|
Симптом: «программа запускается и сразу закрывается». Причина воспроизведена:
|
||||||
|
|
||||||
|
```
|
||||||
|
ModuleNotFoundError: No module named 'customtkinter'
|
||||||
|
```
|
||||||
|
|
||||||
|
Лаунчер запускает `pythonw.exe` — без консоли, поэтому трейсбек уходит в никуда и окно просто не появляется. Ещё в 09:41 Hub стартовал нормально; пакет исчез между 09:41 и вечером. Наиболее вероятная причина — кнопка «Repair install» в диалоге ошибки Hermes: она пересоздаёт venv агента и стирает всё доустановленное.
|
||||||
|
|
||||||
|
Я вернул пакет вручную, Hub снова импортируется. Но проблема архитектурная: **Hub держит свои зависимости в venv чужого приложения, которое их периодически сносит.**
|
||||||
|
|
||||||
|
Требуется:
|
||||||
|
|
||||||
|
1. **Самолечение при запуске.** Перед созданием окна проверять импорт `customtkinter`, `PIL`, `psutil`, `yaml`. Если чего-то нет — доустановить в venv Hermes и повторить, либо показать понятное окно с одной кнопкой «Установить зависимости».
|
||||||
|
2. **Ошибка запуска должна быть видимой.** Сейчас любой сбой до создания окна = тишина. Писать трейсбек в `logs/startup.log` **до** импорта UI и, при падении, показывать нативное окно с текстом ошибки и путём к логу. Файл уже есть, но пишется слишком поздно.
|
||||||
|
3. Оценить переход на собственный venv Hub рядом с `%LOCALAPPDATA%\Programs\HermesHub\`, чтобы обслуживание Hermes не ломало Hub. Если решение — остаться в venv Hermes, записать это как осознанный выбор с обоснованием.
|
||||||
|
|
||||||
|
## P0-2. Мастер предлагает провайдеров, для которых нет профилей
|
||||||
|
|
||||||
|
Симптом владельца: «завершить не нажимается, пишет что всё исчерпано, но нет».
|
||||||
|
|
||||||
|
Причина: мастер предлагает пять провайдеров, а в конфигурации роутера профили есть только для трёх.
|
||||||
|
|
||||||
|
```
|
||||||
|
antigravity 10 профилей
|
||||||
|
openai-codex 3 профиля
|
||||||
|
opencode-go 3 профиля
|
||||||
|
claude НЕТ НИ ОДНОГО
|
||||||
|
grok НЕТ НИ ОДНОГО
|
||||||
|
```
|
||||||
|
|
||||||
|
`AutoAssigner.find_free_slot` перебирает `claude-orch`, `claude-worker-1`… не находит их в конфиге, пропускает все и возвращает `candidates[0]` — то есть **несуществующий** `claude-orch`. Дальше мастер сохраняет авторизацию в слот, которого нет, назначение роли отвечает «профиль не найден», завершение не проходит.
|
||||||
|
|
||||||
|
Требуется: профили для `claude` и `grok` во встроенной конфигурации и в шаблоне `router_profiles.example.yaml`, по образцу существующих, с ролями в цепочках. И `find_free_slot` не должен возвращать идентификатор, отсутствующий в конфиге, — при отсутствии свободных слотов возвращать `None` с внятной причиной.
|
||||||
|
|
||||||
|
**Тест:** для каждого провайдера, который предлагает мастер, `find_free_slot` возвращает либо существующий профиль, либо `None`.
|
||||||
|
|
||||||
|
## P0-3. Кнопка «Тест» открывает окно авторизации
|
||||||
|
|
||||||
|
Симптом: «при тесте открывается опять окно авторизации и ничего».
|
||||||
|
|
||||||
|
В журнале: `Ошибка теста ag-orch-fallback (gemini-3.7-flash): Antigravity error: agy error: authentication failed or timed out`.
|
||||||
|
|
||||||
|
Проверка учётных данных в `do_test_profile` выполняется, но затем вызывается адаптер, а он запускает `agy` — и **этот подпроцесс сам открывает браузер**, когда токен просрочен. Требование «тест никогда не запускает OAuth» стоит в проекте с первого аудита и нарушено на уровне подпроцесса.
|
||||||
|
|
||||||
|
Требуется: запускать `agy` в неинтерактивном режиме, чтобы при невалидных учётных данных он возвращал ошибку, а не открывал окно. Если у CLI нет такого флага — проверять валидность токена до вызова и не доходить до подпроцесса. Результатом теста в этом случае должно быть «Авторизация истекла, требуется повторный вход», а не молчаливое окно браузера.
|
||||||
|
|
||||||
|
**Тест:** просроченные учётные данные дают ошибку авторизации без попытки интерактивного входа.
|
||||||
|
|
||||||
|
## P0-4. Установка должна быть зеркалом, а не наслоением
|
||||||
|
|
||||||
|
`HermesHubSetup.cs:279` делает `CopyDirectoryRecursive` — только копирует, никогда не удаляет. Развёрнуто у владельца 51 файл от 19 августа против 70 в репозитории, и среди них четыре модуля, удалённых нами как мёртвый код:
|
||||||
|
|
||||||
|
```
|
||||||
|
router/capability/
|
||||||
|
router/skills/skill_registry.py
|
||||||
|
router/supervisor/lifecycle_supervisor.py
|
||||||
|
router/gui_server.py
|
||||||
|
```
|
||||||
|
|
||||||
|
Сами по себе инертны, но однажды уже ввели в заблуждение: тесты подхватывали `runtime.py` из развёрнутой копии.
|
||||||
|
|
||||||
|
Требуется точное зеркало источника: удалять файлы, которых нет в источнике, исключать `__pycache__`. **Тест:** развернуть, удалить файл из источника, развернуть снова, убедиться, что в цели его нет.
|
||||||
|
|
||||||
|
## P0-5. Команда самопроверки
|
||||||
|
|
||||||
|
Расширить `print_diagnostics_cli` до проверки, отвечающей на вопрос «работает ли Hub» **без запуска десктопа Hermes**:
|
||||||
|
|
||||||
|
- зависимости в venv с указанием, чего не хватает;
|
||||||
|
- свежесть развёрнутого плагина против версии приложения (для этого при установке писать манифест: версия, дата, коммит);
|
||||||
|
- валидность `router_profiles.yaml`, число профилей и ролей;
|
||||||
|
- по каждому профилю: провайдер, идентичность, авторизация, квота, источник данных;
|
||||||
|
- реальный тестовый вызов по одному профилю на провайдера;
|
||||||
|
- итог одной строкой: готов / частично / не готов, с причинами.
|
||||||
|
|
||||||
|
Секреты в выводе маскируются.
|
||||||
|
|
||||||
|
## P1-6. Остаток по YAML
|
||||||
|
|
||||||
|
Внутренние комментарии `router_profiles.yaml` теряются (7 → 2). Либо полный round-trip, либо статус «частично» с перечнем теряемого — в контракте и отчёте.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Ограничения
|
||||||
|
|
||||||
|
- Граница прежняя: зона Codex (`router/ui/**`, `hermes_hub_app.py`, `tests/test_ui_*.py`) — не трогать. Исключение по P0-1: проверка зависимостей до создания окна лежит в точке входа; согласовать минимальную правку, остальное — данными.
|
||||||
|
- Тег `v0.1.1` не создавать.
|
||||||
|
|
||||||
|
## Критерии приёмки
|
||||||
|
|
||||||
|
1. Hub запускается на машине без `customtkinter`: либо доустанавливает, либо показывает окно с понятной ошибкой. Проверено на изолированном venv.
|
||||||
|
2. Любой сбой до создания окна попадает в `startup.log` с трейсбеком.
|
||||||
|
3. Для всех пяти провайдеров мастера `find_free_slot` возвращает существующий профиль или `None`.
|
||||||
|
4. Тест профиля с просроченной авторизацией не открывает браузер.
|
||||||
|
5. Повторное развёртывание удаляет исчезнувшие файлы.
|
||||||
|
6. Самопроверка работает без запущенного Hermes и печатает связный вердикт без секретов.
|
||||||
|
7. Прогон **в обоих окружениях**; обе команды и оба результата в отчёте.
|
||||||
|
8. `ruff check .` чисто; release gate PASSED на финальном коммите.
|
||||||
|
9. Отчёт: `START_HEAD`, `FINAL_HEAD`, `origin/main`, `git status`, точный `X passed / Y skipped / Z failed`.
|
||||||
|
|
||||||
|
## Порядок сдачи
|
||||||
|
Передать точный `FINAL_COMMIT_SHA`.
|
||||||
105
agents/inbox/2026-08-22-B7-codex-usability-defects.md
Normal file
105
agents/inbox/2026-08-22-B7-codex-usability-defects.md
Normal file
|
|
@ -0,0 +1,105 @@
|
||||||
|
# Задание B7 (Codex): дефекты, найденные при живой эксплуатации
|
||||||
|
|
||||||
|
## Дата поступления
|
||||||
|
2026-08-22
|
||||||
|
|
||||||
|
## База
|
||||||
|
Проверочный HEAD: **`8cddc9f`**, `origin/main` = `8cddc9f`. `git fetch`, зафиксировать `BASE_SHA`.
|
||||||
|
|
||||||
|
## Ветка
|
||||||
|
`codex/usability-fixes`
|
||||||
|
|
||||||
|
## Отношение к B6
|
||||||
|
Задание **B6 (граф маршрутизации) остаётся в силе**, но это — приоритетнее. Владелец впервые прошёл сценарий вживую, и половина действий не сработала. Сначала чинится то, что он не смог сделать, потом граф.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Что сообщил владелец, дословно
|
||||||
|
|
||||||
|
1. «завершить не нажимается. пишет что все исчерпано, но нет»
|
||||||
|
2. «при тесте открывается опять окно авторизации и ничего»
|
||||||
|
3. «появляется код, куда его вставлять, не понятно»
|
||||||
|
4. «назначить роль не получается, ничего не видно»
|
||||||
|
5. «в маршрутизации при нажатии на кнопку настроить ничего не происходит»
|
||||||
|
|
||||||
|
Каждое проверено по коду. Ниже — что относится к вам; пункты 1 (частично) и 2 уходят в backend отдельным заданием A8.
|
||||||
|
|
||||||
|
## P0-1. «Настроить» в маршрутизации не делает ничего
|
||||||
|
|
||||||
|
`hermes_hub_app.py:632`:
|
||||||
|
|
||||||
|
```python
|
||||||
|
elif action == "edit_route":
|
||||||
|
self._show_toast("Редактор цепочки использует кнопки и селекторы; drag-and-drop отключён.")
|
||||||
|
```
|
||||||
|
|
||||||
|
Кнопка показывает сообщение про отключённый drag-and-drop — и всё. С точки зрения пользователя нажатие не делает ничего, а текст объясняет то, чего он не спрашивал.
|
||||||
|
|
||||||
|
Требуется настоящий редактор цепочки для роли: список профилей в порядке приоритета, изменение порядка, добавление и удаление профиля из цепочки, сохранение через `AutoAssigner`. Кнопочный и селекторный, без drag-and-drop — это оговорено и допустимо. Но он должен существовать.
|
||||||
|
|
||||||
|
## P0-2. Результат действия не виден
|
||||||
|
|
||||||
|
«назначить роль не получается, ничего не видно».
|
||||||
|
|
||||||
|
Проверил: модальное окно назначения роли **открывается** и содержит семь вариантов — здесь дефекта нет. Проблема в обратной связи: результат уходит в `_show_toast`, то есть в строку состояния внизу окна, где его легко не заметить. Если профиль не найден (а при выборе Claude или Grok он сейчас действительно не найден — см. A8), пользователь видит ровно ничего.
|
||||||
|
|
||||||
|
Требуется:
|
||||||
|
- результат действия показывать заметно: в самой модалке до закрытия либо всплывающим уведомлением рядом с местом действия;
|
||||||
|
- **при ошибке модалку не закрывать** — сейчас `modal.destroy()` вызывается до показа результата, и человек остаётся без контекста;
|
||||||
|
- то же для остальных действий карточки: «Тест», «Основной», «Оркестратор».
|
||||||
|
|
||||||
|
## P0-3. Код авторизации: непонятно, что с ним делать
|
||||||
|
|
||||||
|
«появляется код, куда его вставлять, не понятно».
|
||||||
|
|
||||||
|
Сейчас в мастере для Codex и Grok показывается поле со ссылкой, отдельная метка с кодом и статус «Ожидание подтверждения кода XXX в браузере…». Ни одной фразы о том, что нужно сделать.
|
||||||
|
|
||||||
|
Требуется явная пронумерованная последовательность прямо в шаге:
|
||||||
|
|
||||||
|
```
|
||||||
|
1. Откройте ссылку — [кнопка «Открыть в браузере»] [копировать]
|
||||||
|
2. Введите на странице код: ABCD-1234 [копировать]
|
||||||
|
3. Подтвердите доступ — окно закроется само
|
||||||
|
```
|
||||||
|
|
||||||
|
Код — крупно, моноширинным, с кнопкой копирования. Статус ожидания — ниже, отдельной строкой. Пользователь не должен догадываться о порядке действий.
|
||||||
|
|
||||||
|
## P0-4. Мастер: честное поведение при отсутствии свободного слота
|
||||||
|
|
||||||
|
Backend вернёт `None`, когда свободных слотов действительно нет (A8 это чинит). Сейчас мастер подставляет `f"{provider[:3]}-spare-1"` — придуманный идентификатор, который может не существовать:
|
||||||
|
|
||||||
|
```python
|
||||||
|
AutoAssigner.find_free_slot(self.selected_provider) or f"{self.selected_provider[:3]}-spare-1"
|
||||||
|
```
|
||||||
|
|
||||||
|
Требуется: если слот не найден — не выдумывать, а показать понятное объяснение («все слоты этого провайдера заняты, освободите один или удалите неиспользуемый аккаунт») и не давать пройти дальше. Кнопка «Завершить» должна быть либо активной и работающей, либо отключённой с подсказкой почему — но не «нажимается и ничего не происходит».
|
||||||
|
|
||||||
|
## P1-5. Первый запуск должен вести пользователя
|
||||||
|
|
||||||
|
Остаётся из B6: на пустой конфигурации «Обзор» показывает «Критическое состояние» и пять `Н/Д` без единой подсказки. Первый экран обязан объяснять следующий шаг и вести к нему.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Ограничения
|
||||||
|
|
||||||
|
- Граница: ваша зона — `src/antigravity_provider/router/ui/**`, `hermes_hub_app.py`, `tests/test_ui_*.py`.
|
||||||
|
- Не выдумывать идентификаторы, значения и метрики. Нет данных — «Н/Д» либо блок отсутствует.
|
||||||
|
- Три темы сохранить.
|
||||||
|
- Мастер не ломать: шесть рабочих потоков подключения и трёхэлементная распаковка `start_profile_oauth`.
|
||||||
|
- Тег `v0.1.1` не создавать.
|
||||||
|
|
||||||
|
## Критерии приёмки
|
||||||
|
|
||||||
|
1. Ни один файл чужой зоны не изменён.
|
||||||
|
2. «Настроить» открывает работающий редактор цепочки; изменение сохраняется и видно после перезапуска.
|
||||||
|
3. Ошибка любого действия видна пользователю в месте действия; модалка при ошибке остаётся открытой.
|
||||||
|
4. Шаг с кодом устройства содержит пронумерованную инструкцию и кнопки копирования для ссылки и кода.
|
||||||
|
5. При отсутствии свободного слота мастер объясняет причину и не подставляет выдуманный идентификатор.
|
||||||
|
6. Пустое состояние «Обзора» ведёт к подключению аккаунта.
|
||||||
|
7. Тесты на каждый пункт: редактор цепочки сохраняет порядок; ошибка действия отображается; мастер без свободных слотов не завершается молча.
|
||||||
|
8. Прогон **в обоих окружениях** — без UI-зависимостей и с `customtkinter`/`pillow`/`psutil`; обе команды и оба результата в отчёте.
|
||||||
|
9. `ruff check .` чисто; release gate не ухудшен.
|
||||||
|
10. **Скриншоты живого сценария**: подключение аккаунта, назначение роли, редактор цепочки — с реальными данными.
|
||||||
|
|
||||||
|
## Порядок сдачи
|
||||||
|
Передать точный `FINAL_COMMIT_SHA`.
|
||||||
Loading…
Reference in a new issue