hermes-hub/agents/inbox/2026-08-24-A24-routing-as-control-center.md
Hermes Team f757639b7e docs(task): A24 — маршрутизация как главный экран управления
Решение владельца по итогам живой эксплуатации: разделов семь вместо
девяти. Убираются «Команда агентов» и «Модели и провайдеры», их
содержимое перераспределяется между маршрутизацией и обзором. Аналитика
остаётся, но должна объяснять свои метрики.

Маршрутизация становится местом управления: перестановка блоков
перетаскиванием, смена модели на месте, кнопка «Изменить цепочку»
убирается.

В задание вынесен вывод из только что найденного дефекта: в веб-мастере
стояли выдуманные коды устройства GRK-7842 и CDX-9104, а тест ТРЕБОВАЛ
наличия неверного адреса, то есть защищал выдумку от исправления.
Пункт P0-6 для второго прохода дополнен проверкой на выдуманные
значения и на тесты, закрепляющие дефект.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-24 10:31:10 +07:00

163 lines
16 KiB
Markdown
Raw Permalink 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.

# Задание A24: маршрутизация как главный экран управления
## Дата поступления
2026-08-24
## База
Проверочный HEAD на момент выдачи: **`6b8a4aa`**.
## Ветка
`antigravity/routing-control-center`
## Порядок исполнения
Два прохода, как прежде: **Flash** реализует, **Pro** проводит аудит. Пункт **P0-6** написан для аудитора.
---
## Порядок работы с git
```
cd <каталог репозитория>; git fetch origin --prune; git status
git checkout main; git pull --ff-only origin main
git checkout -b antigravity/routing-control-center
git commit -m "..." <- сначала коммит
git push -u origin antigravity/routing-control-center
```
В `main` напрямую не пушить. В конце — push и проверка `git log --oneline -1 origin/antigravity/routing-control-center`, `git status` чистый.
---
## Что случилось перед этим заданием
Владелец установил Hub на две машины и прошёл сценарий вживую. Разобрано и **уже исправлено ревьюером**, переделывать не нужно:
- веб-сервер не запускался на Windows — установщик не ставил `fastapi` и `uvicorn`;
- окно приложения показывало «отказано в подключении» — лаунчер убивал сервер, потому что `WaitForExit` у Edge возвращался мгновенно при уже запущенном браузере;
- установщик по галочке «Запустить» открывал десктоп вместо веба;
- «Ролей в строю: 0/6» при пяти работающих — готовность не засчитывала роли на резерве;
- диаграмма перерисовывалась на каждое событие `<Configure>`, окно ползло после отпускания мыши.
**И главное, из чего надо сделать вывод.** В веб-мастере подключения стояли **выдуманные коды устройства** `GRK-7842` и `CDX-9104` и жёстко вписанный адрес `x.ai/device`, отдающий 404. Мастер не был подключён к серверу вовсе — владелец вводил бы несуществующий код бесконечно.
Хуже: тест `test_headless_server_auth_matrix` **требовал** наличия этого адреса в коде, то есть закреплял выдумку как требование и защищал её от исправления.
Это тот класс дефекта, ради борьбы с которым проект и затевался: первый аудит нашёл выдуманные проценты квот, и вот выдумка вернулась в новом коде. **Ни одного значения, которого не дал провайдер или измерение.** Не готово — так и напишите в интерфейсе.
---
## Решение владельца: перестройка навигации
Дословно: «в маршрутизации надо сделать возможность просто переставлять блоки, ну и менять модель, кнопка настроить не нужна»; «команда агентов лишняя вкладка, выбор моделей должен быть в обзоре и в маршрутизации»; «модели и провайдеры вообще не надо оставлять, перераспредели между маршрутизацией и обзором»; «аналитику оставь».
Итог — **семь разделов вместо девяти**:
```
Обзор Аккаунты Маршрутизация Аналитика Состояние Журнал событий Настройки
```
Убираются: **«Команда агентов»** и **«Модели и провайдеры»**.
## P0-1. Маршрутизация — главный экран управления
Сейчас цепочка меняется через кнопку «Изменить цепочку», открывающую отдельное окно. Кнопка не нужна.
**Что требуется:**
1. **Перестановка блоков перетаскиванием.** Основной и резервы меняются местами мышью, прямо в цепочке. Порядок сохраняется через существующий `AutoAssigner` и переживает перезапуск.
2. **Смена модели на месте.** У каждого блока — выбор модели, без перехода в другое окно. Действие `set_model` уже существует, второй реализации не заводить.
3. **Кнопку «Изменить цепочку» убрать.**
4. Добавление и удаление профиля из цепочки остаётся доступным — решите, как, но не отдельным окном настроек.
Осторожно с двумя вещами:
- **порядок в цепочке — это приоритет отказоустойчивости**, а не косметика. Перестановка меняет, кто отвечает на запросы. Показывайте это явно;
- **перетаскивание не должно ронять состояние при отпускании вне зоны.** Отменённое перетаскивание возвращает блок на место, а не теряет его.
**Тест:** перестановка сохраняется в конфигурацию и видна после перезапуска; смена модели с экрана маршрутизации доходит до `router_profiles.yaml`.
## P0-2. Убрать «Команду агентов», перенести содержимое
Раздел показывает роли с назначенными профилями и квотами — то же, что маршрутизация, но без управления.
Перенести в маршрутизацию то, чего там нет: описание роли («Основная разработка кода», «Read-only поиск в кодовой базе») и оперативную квоту активного профиля.
Пункт навигации и `renderTeam` удалить.
Отдельно про подачу, владелец на это обращал внимание: на карточке роли «Кодер 1» было написано «Назначенный аккаунт: **Кодер 2**». Формально верно — это имя профиля `ag-w2`, — но читается как путаница ролей. **Показывайте почту аккаунта**, а имя профиля оставьте второстепенным.
## P0-3. Убрать «Модели и провайдеры», перераспределить
Сейчас там: имя провайдера, «Всего слотов / Подключено / Онлайн», кнопка «Запросить модели» и список обнаруженных моделей.
Куда переезжает:
- **счётчики слотов и подключений** — в «Обзор», к блокам провайдеров на схеме маршрутизации. Числа там уже есть частично, сведите в одно место;
- **список обнаруженных моделей** — в выбор модели: он и нужен именно там, а отдельным списком бесполезен;
- **кнопка «Запросить модели»** — рядом с выбором модели. Это ручное обновление из A23, действие `refresh_models` существует;
- **доступность runtime и версия CLI**, если показываются, — в «Состояние», к остальной диагностике.
Пункт навигации и `renderProviders` удалить.
## P0-4. Выбор модели на «Обзоре»
Владелец просит выбор моделей и там. На «Обзоре» роли уже показаны на схеме — добавить выбор модели прямо в узле роли.
То же действие `set_model`, тот же список из кэша обнаружения. При пустом кэше — «список моделей ещё не получен» и кнопка обновления, **никаких литеральных списков**.
## P0-5. Аналитика остаётся, но должна объяснять себя
Владелец: «аналитика тоже непонятно что показывает пока». Раздел остаётся, данные в нём настоящие — их нужно объяснить.
Сейчас видно: всего вызовов 33, доля отказов 63.6%, латентность P50/P95/MAX, разрезы по провайдерам и ролям, токены `Н/Д (не отдаются)`.
Требуется:
- **подпись у каждой метрики**, что она означает и за какое окно. «Всего вызовов (24ч)» есть, у остальных нет;
- **P50 = 0.0 ms при MAX = 7.8 s** выглядит как поломка. Разберитесь и объясните на экране: если медиана близка к нулю потому, что большинство вызовов падают мгновенно, так и напишите. Если это дефект подсчёта — почините;
- **пустые строки таблицы** (`claude`, `grok` с нулями и `Н/Д`) — либо скрывать неподключённых провайдеров, либо помечать, что аккаунт не добавлен, а не показывать как «ноль вызовов»;
- зачем экран нужен, одной строкой сверху.
## P0-6. Аудит вторым проходом
Для проверяющего. Список составлен из дефектов, которые уже проходили мимо первого прохода.
1. **Выдуманные значения.** Только что найдены захардкоженные коды устройства в мастере. Пройдите весь новый код и убедитесь: ни одного значения, которого не дал провайдер или измерение. Особое внимание — заглушкам, которые «пока поставим, потом заменим».
2. **Тесты, закрепляющие дефект.** Тест требовал наличия неверного адреса. Проверьте, что новые тесты проверяют желаемое поведение, а не текущее.
3. **Запустить изменённое.** В A15 вынесли действия и уничтожили класс приложения — модуль импортировался, тесты проходили, приложение не запускалось.
4. **Пути и команды в текстах интерфейса.** Инструкция вела на несуществующий `launcher/main.py`. Каждый путь должен существовать.
5. **Побочные изменения.** Дважды ревьюер находил в диффах правки, к заданию не относящиеся: блокировку файла перевели на бесконечное ожидание, действие не занесли в контракт. Просмотрите диффы файлов, которых задание не касалось, и объясните каждое изменение.
6. **Пропущенный пункт назвать пропущенным.**
---
## Ограничения
- Десктоп (`router/ui/**`) в этом задании **не трогать**: перестройка только в вебе. Паритет нарушится осознанно, десктоп остаётся как есть.
- Правило честности без исключений. Нет данных — «Н/Д» и причина; не реализовано — так и написать.
- Действия только через существующий `action_handler`; второй реализации `set_model` и `refresh_models` быть не должно.
- Меняете контракт — правьте `docs/web-api/CONTRACT.md` и скажите в отчёте.
- Тег `v0.1.1` не создавать.
## Критерии приёмки
1. Ветка в `origin`, `git status` чист.
2. Разделов семь; `renderTeam` и `renderProviders` удалены вместе с пунктами навигации.
3. В маршрутизации блоки переставляются мышью; порядок сохраняется и переживает перезапуск; проверено тестом.
4. Модель меняется с экрана маршрутизации и с «Обзора»; изменение доходит до конфигурации; проверено тестом.
5. Кнопки «Изменить цепочку» нет; отменённое перетаскивание не теряет блок.
6. Содержимое удалённых разделов перенесено полностью; в отчёте таблица «что куда переехало».
7. На карточке роли виден аккаунт, а не имя профиля, похожее на другую роль.
8. У каждой метрики аналитики есть подпись; расхождение P50 и MAX объяснено или исправлено; неподключённые провайдеры не показаны как «ноль вызовов».
9. Ни одного выдуманного значения; проверено отдельно и описано в отчёте.
10. `ruff check .` чисто; релизный гейт не ухудшен.
11. **Скриншоты: маршрутизация с перетаскиванием, выбор модели, «Обзор», аналитика.** Открыть и посмотреть перед отправкой.
12. Отчёт: `START_HEAD`, `FINAL_HEAD`, `origin/main`, `git status`, `X passed / Y skipped / Z failed`. На `main` сейчас 375 passed, 2 skipped.
## Главное
Владелец хочет управлять маршрутизацией напрямую: перетащил блок — поменялся приоритет, выбрал модель — она применилась. Без промежуточных окон и разделов, дублирующих друг друга. Всё остальное в задании обслуживает это.
## Порядок сдачи
Передать точный `FINAL_COMMIT_SHA`. Сдано только после появления коммита в `origin`.