# Задание A51: подключённый аккаунт должен реально использоваться Hermes ## Дата поступления 2026-08-31 ## База `origin/main` (`17b368a`). ``` git fetch origin --prune git checkout -b antigravity/a51-hub-controls-hermes origin/main ``` В `main` напрямую не пушить. ## Порядок исполнения Два прохода: **Flash** реализует, **Pro** проводит аудит. Пункт **P0-6** написан для аудитора. Зона: маршрутизация, назначение ролей, плагин Hermes, карточка аккаунта. С A49 (скиллы и память) и A50 (обнаружение и проверка) не пересекается по смыслу, но **трогает те же файлы, что A50** — `auto_assigner.py` и экран «Аккаунты». Выполнять **после A50**. --- ## Задача Владелец: «в хабе я поставил аккаунт аги. Когда я захожу в Гермеса, какой аккаунт будет выбран? И если я поменяю в Гермесе аккаунт, поменяется он в хабе? Иначе толку от хаба, если в самом Гермесе это не работает». Ответ, проверенный ревьюером: **сейчас не будет выбран ни один из его аккаунтов**. --- ## Что проверено исполнением **Определение роли работает.** A35 встал: плагин перехватывает каждый `llm_execution` и определяет роль четырьмя уровнями — явная, по модели и провайдеру, по устойчивости сессии, по умолчанию. Это переделке не подлежит. **Но цепочки указывают в пустоту.** Конфигурация владельца на рабочей машине: ``` default_role: не задан → используется manager manager → ag-orch-fallback, codex-orch, opengo-3 developer-1 → ag-w1, codex-worker-1, opengo-3 researcher → opengo-1, ag-w3, ag-w4 профилей в конфигурации: 24 ролей: 13 ``` Проверка вхождения **подключённых** аккаунтов владельца в цепочки: ``` ollama-1 НИ В ОДНОЙ grok-1 НИ В ОДНОЙ local-2 НИ В ОДНОЙ local-3 НИ В ОДНОЙ antigravity-1 НИ В ОДНОЙ ``` Все тринадцать ролей по-прежнему ссылаются на заготовки из старой конфигурации на 24 слота, а они не настроены. Значит при обращении Hermes цепочка `manager` перебирает три неавторизованных слота, отказывает, и плагин — правильно, по своему устройству — **пропускает вызов мимо хаба дальше в Hermes**: ```python if isinstance(completion, dict) and completion.get("router_error"): logger.warning("Router failover exhausted for role %r; passing the call downstream to Hermes") ``` Хаб при этом ведёт себя корректно: он не подменяет ответ. Но результат для владельца тот самый, которого он опасается — **хаб не участвует в работе вовсе**. **Карточка аккаунта показывает роль, которой нет.** На экране `ollama-1` подписан «manager (primary)», хотя в цепочке `manager` его нет. Источник подписи — `auto_assigner.get_display_name_and_role`, а она читает **статическую таблицу** `DEFAULT_SLOT_ROLES`, а при промахе достраивает подпись из имени провайдера. В снапшот это попадает так: ```python assigned_roles=role_assignments.get(pid, [log_role]) ``` Есть аккаунт в живой цепочке — берётся живое значение; нет — подставляется **догадка**. Владелец видит «manager (primary)» и считает, что аккаунт назначен. Тот же аккаунт на карточке списка подписан «worker», а в окне — «manager (primary)». Два разных источника в двух местах. **Обратной синхронизации нет.** `_select_model` в `hermes_plugin.py` — ручная команда CLI, которая записывает в конфигурацию Hermes провайдера, модель и адрес. Ничего, что читало бы выбор владельца, сделанный **внутри** Hermes, и переносило бы его в хаб, в коде нет. --- ## P0-1. Подключённый аккаунт попадает в цепочку 1. **Подключение аккаунта ставит его в цепочку выбранной роли.** Роль владелец выбирает на третьем шаге мастера — сейчас этот выбор до цепочки не доходит. 2. **Если аккаунт никуда не назначен — так и писать.** «Не назначен» — нормальное состояние, но оно должно быть видно, а не подменяться догадкой. 3. **Кнопка «Авто»**: разложить подключённые аккаунты по ролям по способностям провайдера. Предложить расстановку и **показать до применения**, а не применять молча. ## P0-2. Карточка показывает то, что есть на самом деле 1. **Роль на карточке берётся только из живой цепочки.** Подстановка из `DEFAULT_SLOT_ROLES` в качестве роли — убрать: статическая таблица годится для человекочитаемого имени, но не для утверждения о назначении. 2. **Один источник для карточки и окна.** Сейчас список пишет «worker», окно — «manager (primary)». 3. **Показывать место в цепочке**: основной или запасной номер такой-то. «primary» без указания, в какой роли и на каком месте, ничего не значит. ## P0-3. Владелец видит, кто ответит на вызов Главное, ради чего задание. 1. **На экране маршрутизации у каждой роли — «сейчас ответит: <аккаунт>»**, вычисленное по текущей цепочке и состоянию аккаунтов. 2. **Если не ответит никто** — сказать прямо: «цепочка пуста или все аккаунты недоступны, вызов уйдёт мимо хаба в Hermes». Это состояние сейчас и есть, и владелец о нём не знает. 3. **Роль по умолчанию видна и настраивается.** Сейчас `default_role` не задан, и молча используется `manager`. Показать это в настройках. ## P0-4. Видно, прошёл вызов через хаб или мимо 1. **Записывать по каждому вызову**: определилась ли роль, каким уровнем, какой профиль выбран, ушёл ли вызов мимо хаба и почему. 2. **Показывать в журнале событий** и счётчиком на «Обзоре»: сколько вызовов прошло через хаб, сколько мимо. 3. Это единственный способ ответить на вопрос владельца «работает ли хаб» измерением, а не рассуждением. ## P0-5. Обратная связь с Hermes Владелец: «если я поменяю в Гермесе аккаунт, поменяется он в хабе?» Сейчас — нет. Прежде чем делать, **выяснить и записать в отчёт**, что именно Hermes позволяет наблюдать: что хранится в его конфигурации, меняется ли она при выборе модели в интерфейсе, есть ли событие или файл, по которому это видно. Дальше по результату: 1. **Если выбор Hermes читается** — показывать его в хабе и отмечать расхождение с цепочкой: «в Hermes выбран X, хаб направил бы на Y». 2. **Если не читается** — так и написать, а в интерфейсе объяснить владельцу, что хаб управляет маршрутом только когда Hermes не задаёт провайдера явно. Честное объяснение принимается. 3. **Ничего не записывать в конфигурацию Hermes автоматически.** `_select_model` остаётся ручной командой: молчаливая правка чужой конфигурации — это то, за что уже возвращались работы. 4. **Не выдумывать механизм**, которого в Hermes нет. Отсутствие способа — результат, он принимается. ## P0-6. Аудит вторым проходом 1. **Пройти путь целиком на живой машине**: подключить аккаунт, назначить роль, сделать запрос через Hermes и убедиться по журналу, что вызов пошёл через хаб и через **этот** аккаунт. Это единственная настоящая проверка задания. 2. **Проверить обратное**: убрать аккаунт из цепочки и убедиться, что вызов уходит мимо хаба и это видно в интерфейсе. 3. **Проверить, что роль на карточке исчезает**, когда аккаунт не назначен, — а не подменяется догадкой. 4. **Сверить карточку и окно**: подпись роли одинакова. 5. **Проверить конфигурацию владельца на копии**: старые цепочки на 24 заготовки не должны молча пропасть; предложить перенос, но не выполнять его без подтверждения. 6. **Побочные изменения** объяснить. 7. **Пропущенный пункт назвать пропущенным.** --- ## Ограничения - Конфигурацию владельца молча не переписывать: перенос цепочек — только с подтверждением. - В конфигурацию Hermes автоматически не писать. - Учётные данные и `~/.hermes/agy_profiles/` не трогать. - Определение роли из A35 не переделывать. - Вёрстку A48 не ломать. - Версию `0.1.1` не поднимать. - Правило честности без исключений. ## Критерии приёмки 1. Ветка в `origin`, `git status` чист. 2. Подключение аккаунта с выбором роли кладёт его в цепочку этой роли; проверено. 3. Неназначенный аккаунт показан как неназначенный; догадка из статической таблицы как роль не используется. 4. Карточка и окно аккаунта показывают одну и ту же роль и место в цепочке. 5. На маршрутизации видно, какой аккаунт ответит для каждой роли; пустая цепочка названа прямо. 6. Роль по умолчанию видна и настраивается. 7. По журналу видно, прошёл вызов через хаб или мимо и почему; есть счётчик. 8. Пройден живой путь: подключение, назначение, запрос через Hermes, подтверждение по журналу. 9. Выяснено и записано, что Hermes позволяет наблюдать о своём выборе; сделано либо честно объявлено невозможным. 10. Конфигурация владельца не изменена без подтверждения. 11. `ruff check .` чисто; релизный гейт 10/10; тестов не меньше **517**. 12. Память проекта в AI-Memory обновлена. 13. Отчёт: `START_HEAD`, `FINAL_HEAD`, `origin/main`, `git status`, `X passed / Y skipped / Z failed`. ## Главное Владелец подключил аккаунты, увидел на карточках «manager (primary)» и решил, что настроил маршрутизацию. На деле ни один его аккаунт не входит ни в одну цепочку: все тринадцать ролей ссылаются на заготовки старой конфигурации. При обращении Hermes цепочка отказывает, и вызов уходит мимо хаба. Хаб ведёт себя корректно и не подменяет ответ. Но владелец об этом не знает и считает, что управляет маршрутизацией, а управляет пустотой. Задание должно сделать так, чтобы назначение действительно назначало, а расхождение было видно на экране, а не выяснялось разбором конфигурации. ## Порядок сдачи Передать точный `FINAL_COMMIT_SHA`.