hermes-hub/agents/inbox/2026-08-22-B7-codex-usability-defects.md
Hermes Team 559289d839 docs(task): B7 — зафиксировать исправленный дефект мастера и потребовать проверку на несуществующие методы
Добавлен раздел P0-0: правка _finish уже в main (7090c8a), её нельзя
потерять при слиянии. Там же второй дефект того же класса —
splash.py вызывает несуществующий AssetManager.get_splash_logo.

Дефект «вызов несуществующего метода» встречается третий раз и под
pythonw всегда молчаливый, поэтому в критерии приёмки добавлено
требование механической проверки UI-слоя.

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

14 KiB
Raw Blame History

Задание B7 (Codex): дефекты, найденные при живой эксплуатации

Дата поступления

2026-08-22

База

Проверочный HEAD на момент выдачи: 7f912f1. Обязательно обновить локальную копию — см. следующий раздел.

Ветка

codex/usability-fixes

Отношение к B6

Задание B6 (граф маршрутизации) остаётся в силе, но это — приоритетнее. Владелец впервые прошёл сценарий вживую, и половина действий не сработала. Сначала чинится то, что он не смог сделать, потом граф.


Перед началом: обновить локальную копию

Задание выдано, когда origin/main был 7f912f1. Ваша рабочая копия на другой машине почти наверняка отстала — за последние сутки в main вошло 9 коммитов, включая работу Codex по интерфейсу и принятые задания Antigravity A6A8.

Порядок:

cd <каталог репозитория>; git fetch origin --prune; git status

Если рабочее дерево чистое:

git checkout main; git reset --hard origin/main

Если есть незакоммиченные правки — сначала сохранить их отдельной веткой, вслепую сбрасывать нельзя.

После обновления зафиксировать фактический BASE_SHA командой git rev-parse --short HEAD и указать его в отчёте. Не считать 7f912f1 актуальным автоматически: пока вы работаете, main может уйти вперёд.

Ветку создавать от свежего origin/main, не от старого состояния. Иначе слияние принесёт откат чужой работы — так уже случалось: одна из веток содержала устаревшую распаковку start_profile_oauth, и при неаккуратном слиянии подключение Antigravity-аккаунта снова бы сломалось.


Что сообщил владелец, дословно

  1. «завершить не нажимается. пишет что все исчерпано, но нет»
  2. «при тесте открывается опять окно авторизации и ничего»
  3. «появляется код, куда его вставлять, не понятно»
  4. «назначить роль не получается, ничего не видно»
  5. «в маршрутизации при нажатии на кнопку настроить ничего не происходит»

Каждое проверено по коду. Ниже — что относится к вам; пункты 1 (частично) и 2 уходят в backend отдельным заданием A8.

P0-0. Уже исправлено на main — не откатите при слиянии

Владелец сообщил: «завершить кнопка нажимается, но окно не закрывается». Найдено и исправлено ревьюером в 7090c8a, файл вашей зоны — add_account_wizard.py.

Причина: _finish первой строкой вызывал EventLogService.get().log_event(...). Метода log_event у сервиса нет — настоящая сигнатура log(category, message, details=None, level="info"). AttributeError уходил в обработчик Tk, консоли под pythonw нет, и для пользователя кнопка просто не работала: окно оставалось открытым, on_complete не вызывался, подключённый аккаунт не попадал в маршрутизацию.

Правка: вызов приведён к настоящему API; журналирование и on_complete обёрнуты так, чтобы сбой в них не запирал пользователя в мастере. Регрессия закрыта тестом tests/test_ui_wizard_finish.py.

От вас требуется:

  1. При слиянии сохранить эту правку. Ветку создавать от свежего origin/main — тогда конфликта не будет.
  2. Найденный тем же способом второй дефект: ui/splash.py:40 вызывает AssetManager.get().get_splash_logo(...) — такого метода нет, есть get_logo_image. Модуль сейчас нигде не импортируется, то есть это мёртвый код. Либо подключить и починить, либо удалить. Решение обосновать в отчёте.
  3. Механическая проверка на весь UI-слой. Это третий дефект класса «вызов несуществующего метода», и все они молчаливые: под pythonw трейсбек Tk уходит в никуда, кнопка выглядит нерабочей. Нужен тест, который статически обходит UI-слой и проверяет, что вызываемые методы существуют у своих классов. Ревьюер проверял разбором AST по образцу Klass.get().method(...) — этого хватило, чтобы найти оба дефекта; ваш вариант может быть шире.

P0-1. «Настроить» в маршрутизации не делает ничего

hermes_hub_app.py:632:

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" — придуманный идентификатор, который может не существовать:

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. Правка _finish из 7090c8a сохранена; tests/test_ui_wizard_finish.py проходит.
  3. Есть тест, механически ловящий вызовы несуществующих методов в UI-слое; на нём проверено, что таких вызовов не осталось.
  4. «Настроить» открывает работающий редактор цепочки; изменение сохраняется и видно после перезапуска.
  5. Ошибка любого действия видна пользователю в месте действия; модалка при ошибке остаётся открытой.
  6. Шаг с кодом устройства содержит пронумерованную инструкцию и кнопки копирования для ссылки и кода.
  7. При отсутствии свободного слота мастер объясняет причину и не подставляет выдуманный идентификатор.
  8. Пустое состояние «Обзора» ведёт к подключению аккаунта.
  9. Тесты на каждый пункт: редактор цепочки сохраняет порядок; ошибка действия отображается; мастер без свободных слотов не завершается молча.
  10. Прогон в обоих окружениях — без UI-зависимостей и с customtkinter/pillow/psutil; обе команды и оба результата в отчёте.
  11. ruff check . чисто; release gate не ухудшен.
  12. Скриншоты живого сценария: подключение аккаунта, назначение роли, редактор цепочки — с реальными данными.

Порядок сдачи

Передать точный FINAL_COMMIT_SHA.