# Задание B5 (Codex): редизайн по утверждённому макету, три цветовые схемы ## Дата поступления 2026-08-21 ## База Проверочный HEAD: **`2b2ccd8`**, `origin/main` = `2b2ccd8`. `git fetch`, зафиксировать `BASE_SHA`, работать от свежего `main`. ## Ветка `codex/mockup-redesign` ## Зависимость Параллельно выполняется **Задание A6 (Antigravity)** — оно поставляет данные для правой панели, схемы маршрутизации и показателей хоста. Разделы, помеченные ниже «после A6», начинать, когда соответствующие поля появятся в `docs/UI_STATE_CONTRACT.md`. Всё остальное можно делать сразу. --- ## P0. Сначала вернуть то, что пропало В редизайне фаз 2–6 (`d0d15ae`) с экрана «Аккаунты» исчезли управляющие элементы. История файла: ``` a7027b4 действий = 4 ← до редизайна d0d15ae действий = 1 ← после 2b2ccd8 действий = 1 ← сейчас ``` Пропали, при живых обработчиках в `hermes_hub_app._handle_action`: | Действие | Обработчик | Триггер в UI | |---|---|---| | `test` — «⚡ Тест» | есть | только меню «Команда» | | `set_main` — «★ Сделать основным» | есть | только меню «Команда» | | `set_orchestrator` — «👑 Назначить оркестратором» | есть | только меню «Команда» | | `assign_role` — «Назначить роль» | есть, вместе с модалкой | **нигде** | Владелец установил сборку и сообщил, что функции перестали работать — это оно. **Вернуть все четыре на экран «Аккаунты»** и добавить тест: для каждого обработчика в `_handle_action` существует хотя бы один вызывающий элемент в UI. Дефект этого класса возникает третий раз, механическая проверка обязательна. --- ## Макет Утверждён главный экран «Обзор» в трёх схемах: **тёмная**, **средняя (гибрид)**, **светлая (бежевая)**. Все три — один и тот же layout, различаются палитрой. Остальные вкладки привести к тому же языку. ### Композиция - **Левая панель**: логотип, вертикальная навигация, пользователь внизу, версия. - **Верхняя строка**: индикатор состояния, поиск с подсказкой `Ctrl + K`, кнопка «+ Добавить аккаунт», уведомления, справка, настройки. - **Строка KPI**: пять карточек в ряд. - **Центр**: схема маршрутизации — провайдеры слева, оркестратор в центре, кластеры агентов справа, связи с подписями. - **Правая панель**: «Статус в реальном времени», «Системные показатели», «Очереди задач». - **Низ**: «Последние события» — таймлайн с тегами. ### Три темы Палитры вынести в `theme.py` как три набора токенов с общими именами. Переключение — в настройках, с сохранением выбора. Ни один экран не должен содержать цвет вне токенов: смена темы обязана менять всё приложение, а не часть. Семантика цвета сохраняется во всех трёх: зелёный — работает, янтарный — предупреждение, красный — ошибка, серый — нет данных. **Золото остаётся брендом, а не статусом.** --- ## Что чем наполнять Это главная часть задания. Источник каждого блока проверен по коду на `2b2ccd8`. ### Есть данные — рисовать по-настоящему | Блок | Источник | |---|---| | Время отклика | `TelemetryService`, латентность P50, источник `own_measurement` | | Агенты онлайн 18/20 | `SystemReadiness.roles_ready_count` / `total_roles` | | Последние события | `EventLogService` | | Цепочка маршрутизации, приоритеты, резервы | `RolePipeline` / `PipelineNode` | | Состояние провайдеров, авторизация, здоровье | `ProviderSummary`, `ProfileViewModel` | | Тариф аккаунта | `plan_code` + `plan_source` | | Причина переключения | `PipelineNode.failover_reason` | ### После A6 — появятся данные | Блок | Что придёт | |---|---| | Латентность по каждому провайдеру в правой панели | агрегаты по провайдеру | | Доли 45 / 35 / 20 % на схеме | `call_share` по провайдеру | | Счётчики 128 / 74 / 56 запросов | вызовы по ролям | | CPU, память, диск, сеть | `psutil`, источник `host_measurement` | | Активные вызовы | число занятых лизов | До появления этих полей — «Н/Д», не заглушки с числами. ### Данных нет и не будет — не рисовать | Блок макета | Причина | |---|---| | Очереди задач по приоритетам | подсистемы очередей в продукте нет | | Окно обслуживания 09:00–21:00 | понятия нет | | «Инциденты» как раздел | подсистемы инцидентов нет; ближайшее реальное — журнал событий с фильтром по ошибкам | | RPS провайдера, SLA, uptime | провайдеры не отдают, Gap 13 | | Квота 78 % при отсутствии данных | baseline у всех провайдеров `None`; реальное значение появляется только после настоящего 429 | Пункт про квоту важен: на макете она нарисована заполненной, но по контракту до первого 429 данных нет. Показывать «Н/Д» с пояснением, а не 78 %. **Правило без исключений:** если поля нет в `docs/UI_STATE_CONTRACT.md` — числа в интерфейсе не будет. Ни примера, ни placeholder'а, ни «пока так». Продукт создан, чтобы показывать правду о квотах и маршрутах; первый аудит этого проекта нашёл именно выдуманные метрики, и повторения не будет. Пустое место в макете лучше заполнять тем, что есть на самом деле: состоянием авторизации, семейством моделей, позицией в цепочке отказоустойчивости, временем последней проверки. --- ## Остальные вкладки Привести к тому же языку: та же сетка, та же плотность, те же компоненты, постоянная правая панель деталей вместо модальных окон. - **Команда** — иерархия «оркестратор → роли → агенты», карточка агента с провайдером, аккаунтом, моделью, состоянием квоты. - **Аккаунты** — сохранить дельта-отрисовку по ключам, вернуть четыре действия (P0), группировка по провайдерам, поиск, фильтры. - **Маршрутизация** — цепочка основной → резервы с активным узлом и причиной переключения. - **Провайдеры** — сводка, обнаруженные модели, состояние. - **Квоты и лимиты** — мульти-корзинные квоты с пометкой оценки и временем сброса. - **Аналитика** — агрегаты телеметрии: латентность, токены, переключения, доля ошибок. Раздел появляется после A6. - **Журнал событий** — таймлайн с фильтрами, поиском и уровнями. - **Настройки** — параметры, выбор темы, пути, обновления. - **Оркестратор** — если отдельным разделом, то на реальных данных о главной роли; иначе не заводить пустой экран. Экран без данных не создавать: либо скрыть пункт навигации, либо честное «Скоро». --- ## Ограничения - Граница: ваша зона — `src/antigravity_provider/router/ui/**`, `hermes_hub_app.py`, `tests/test_ui_*.py`. - Итеративно: после каждой вкладки приложение запускается. - Сеть, подпроцессы, опрос OAuth — только в фоне. - Дельта-отрисовку по стабильным ключам не терять; полных пересборок виджетов не возвращать. - Мастер подключения не ломать: шесть рабочих потоков и трёхэлементная распаковка `start_profile_oauth`. - Секреты маскировать. - Проверить на 1280×720, 1366×768, 1920×1080 при масштабировании 100 %, 125 %, 150 %. - Тег `v0.1.1` не создавать. ## Критерии приёмки 1. Ни один файл чужой зоны не изменён. 2. Четыре действия вернулись на «Аккаунты»; тест проверяет соответствие обработчиков и триггеров. 3. Три темы переключаются, покрывают всё приложение; ни одного цвета вне токенов. 4. Приложение запускается, все разделы открываются без ошибок. 5. Ни одного числа без поля в контракте: очереди, окно обслуживания, RPS, SLA, CPU до A6 — отсутствуют или «Н/Д». 6. Дельта-отрисовка сохранена: изменение одного аккаунта не перерисовывает остальные. 7. Прогон **в обоих окружениях** — без UI-зависимостей и с `customtkinter`/`pillow`/`psutil`; обе команды и оба результата в отчёте. 8. `ruff check .` чисто; release gate не ухудшен. 9. Отчёт: скриншоты каждой вкладки во всех трёх темах и раздел «расхождения с макетом» с причиной по каждому пункту. ## Порядок сдачи Передать точный `FINAL_COMMIT_SHA`.