Установка на Windows упала с кодом 12, и причина была не в новом коде, а в
накопленном состоянии: конфигурация тащила роль под старым именем, роли без
цепочек и 24 пустых заготовки, переживших несколько переименований. Проверка
споткнулась о наследие.
Владелец сформулировал вывод: при первой установке всё должно начинаться с
нуля — сначала аккаунты, потом распределение по агентам.
Задание разводит два случая: конфигурации нет — первая установка, профилей не
создаётся вовсе; конфигурация есть — обновление, ничего не трогается. Плюс
явная кнопка сброса с подтверждением и резервной копией.
Отдельным пунктом, из-за цены ошибки: сброс касается только маршрутизации.
Каталог agy_profiles не затрагивается ни при каких условиях — потеря учётных
данных означает повторный ручной вход в два десятка аккаунтов, включая
Antigravity со входом по ссылке для каждого профиля.
Требуется также прогнать проверочный скрипт установщика на ПУСТОЙ
конфигурации: он этого случая никогда не видел, у него всегда было 24
профиля, и падение на чистой машине дало бы тот же код 12 новому
пользователю.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Отчёт benchmarks/BENCHMARK_REPORT.md открывается словами «Все метрики сняты
реальным исполнением на стенде». Для трёх строк из семи это неправда.
Сверено с диском сервера. Четыре модели существуют, их размеры совпадают с
отчётом до сотых: 17,67 / 8,37 / 4,60 / 2,33 ГБ. Трёх других нет вовсе:
deepseek-coder-v2-lite и phi-4-14b — каталоги пусты, файлов GGUF нет;
nemotron-cascade-30b не существует на сервере нигде. При этом в
benchmark_results.json DeepSeek и Phi-4 помечены COMPLETED, а у Nemotron
статус честнее, но числа при нём всё равно проставлены.
На этом построена рекомендация: DeepSeek-Coder-V2-Lite назван «лучшим
выбором для максимальной скорости» с точностью до десятой доли — по модели,
которая никогда не запускалась. Владелец собирается менять рабочую модель, и
цена такой строки — неверное решение, а не неточность в документе.
Замеры по четырём настоящим моделям признаны и переделке не подлежат;
главный вывод — Qwen2.5-Coder-14B держит качество 27B при втрое большей
скорости — остаётся в силе.
Задание вводит правило: строка появляется только при наличии пути к файлу,
размера в байтах из stat, контрольной суммы и сырых таймингов от сервера.
Модель не скачалась — раздел «не проверено» с причиной, это принимается.
Добавлены новые кандидаты, отобранные по проверенным характеристикам:
qwen2.5-coder-32b, granite4.2:8b (на диске лежит 3.2-preview, а не релиз),
nemotron-3.5-lightning, laguna-xs-2.1, lfm2.5. Отклонены с проверкой:
gpt-oss:120b (80 ГБ), Qwen3.8-Flash-Next (125B/6B, ужатое IQ1_S — 72,5 ГБ).
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Локальная модель не закрывает задачи: Hermes сообщает о таймауте 180 секунд
после четырёх вызовов и переключается на другого провайдера.
Причина измерена, а не предположена. Служба запущена с --reasoning on и
--reasoning-budget 4096, а модель выдаёт 13,4 токена в секунду. На простой
задаче рефакторинга с лимитом 1500 токенов получено:
сгенерировано 1500 токенов за 111,6 с
рассуждений 5483 символа
ответа 0 символов
Весь лимит уходит на размышления, до ответа модель не доходит. За 180 секунд
она успевает около 2400 токенов — и это тоже одни рассуждения.
Отключение рассуждений на уровне запроса проверено и работает:
reasoning_effort: none ответ за 19,5 с
chat_template_kwargs: enable_thinking=false ответ за 11,4 с
Одиннадцать секунд вместо ста одиннадцати. Серверный флаг --reasoning off
решил бы это грубо, лишив рассуждений насовсем, поэтому владелец выбрал
гибкий путь: параметры задаёт хаб, по профилю.
Задание требует не зашивать ни enable_thinking, ни reasoning_effort: набор
ключей зависит от версии llama.cpp, и это данные конфигурации, а не
константы кода. Отдельным критерием — проверка живым запросом к серверу
владельца с замером времени до и после.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Локальный кодер выдаёт 13,6 токена в секунду, и владелец хочет понять, есть
ли модель быстрее при сопоставимом качестве.
Базовая линия снята ревьюером на живом сервере и вписана в задание, чтобы не
мерилась заново: Qwen3.8-27B даёт 13,6 ток/с генерации, Qwen3-4B — 124,1,
разница почти девятикратная. Цена контекста измерена точно: 39 КиБ на токен у
27B и 81,5 у 4B.
Отдельно измерен диск, и он оказался узким местом: Crucial BX500 без DRAM,
187 МБ/с мимо кэша, NVMe на машине нет. Загрузка 19-гигабайтной модели с
холодного диска занимает около 100 секунд. Первый замер дал 4,1 ГБ/с, но это
было чтение из кэша оперативной памяти — случай вписан в задание как
предупреждение.
Из списка владельца проверкой отклонён gpt-oss:120b: в карточке модели прямо
указано 80 ГБ и H100. Остальные отсортированы по пригодности для V100, где
скорость определяется активными параметрами, а не общим размером, поэтому
модели MoE поставлены первыми.
Главное требование задания: мерить качество, а не только скорость. Модель,
выдающая 120 ток/с неработающего кода, хуже той, что даёт 13 ток/с рабочего.
Нужен набор из настоящих правок по репозиторию, а не синтетические задачки.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Повод пришёл из разбора новостей: OpenAI описала инцидент, где
экспериментальные агенты использовали внутренний Artifactory как канал связи
между собой, обменивались найденными обходами и в итоге скомпрометировали
часть инфраструктуры Hugging Face. Вывод: deny internet != secure agent.
Задание опирается не на этот инцидент, а на наши собственные случаи, каждый
из которых проверен или произошёл в проекте:
- CORS стоял как allow_origins=["*"] с allow_credentials=True, а на localhost
токен не требуется вовсе: любая открытая рядом страница получала полный
снапшот со всеми аккаунтами и могла вызывать /api/action. Закрыто в
c35bc48;
- агенты координируются через публичный репозиторий, и однажды работа ушла в
main минуя ревью;
- агент Codex переключил ветку в каталоге, где работал ревьюер;
- учётные данные 24 аккаунтов лежат общей кучей, разделения по агентам нет;
- ревьюер удалил учётные данные grok-worker-1, проверяя кнопку удаления, и
ничто этому не помешало;
- хаб открыт в домашнюю сеть поверх HTTP.
Отдельным критерием вынесено требование, что защита не должна ломать продукт:
хаб с включёнными ограничениями обязан оставаться полностью работоспособным.
Выполнять после A34 и A35: пока нельзя подключить аккаунт и хаб не участвует
в вызовах Hermes, укреплять периметр преждевременно.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Владелец описал рабочую схему: flash 3.7 пишет как Кодер 1, gemini pro
проверяет его как Кодер 2 и возвращает на доработку до одобрения, опус 4.6
включается ревьюером после одобрения Pro и при необходимости возвращает
работу Кодеру 2. Две вложенные петли.
Смысл экономический: опус не тратится на то, что отсеет Pro, а Pro не
тратится на то, что flash исправит сам.
Имена моделей взяты из кэша обнаружения на аккаунтах владельца, а не из
головы. Три места, где легко ошибиться, вынесены в задание отдельно:
«гемини про» — это gemini-3.1-pro-high, версии 3.7 у Pro нет вовсе; «опус
4.6» называется claude-opus-4-6-thinking; у flash идентификаторы приходят с
суффиксом усилия, но базовое имя gemini-3.7-flash валидно — ревьюер однажды
уже утверждал обратное и был неправ.
Отдельным пунктом — обязательные пределы итераций. Две вложенные петли без
ограничителя жгут квоту молча, и это самый дорогой дефект в задании.
Приёмка требует журнала живого прогона, где петля действительно сработала:
конвейер, прошедший с первого раза, ничего не доказывает.
Зависит от A35: без него хаб в вызовах Hermes не участвует и конвейер будет
собран, но не заработает.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Владелец заметил, что настройки Hermes не соответствуют настройкам хаба.
Проверка подтвердила худшее: хаб не участвует в вызовах Hermes вообще.
Доказано исполнением. В исходниках Hermes, agent/conversation_loop.py:3221,
middleware вызывается без параметра role — передаются model, provider,
base_url, session_id, task_id, platform, но не роль. А плагин при
неопределённой роли делает next_call(request), то есть пропускает вызов мимо
маршрутизатора. Подача того же набора аргументов на живой плагин:
как зовёт Hermes (без роли) -> МИМО хаба
если роль передана -> обработал хаб
Механизм исправен целиком, его просто никто не включает: аккаунты, цепочки,
квоты и переключение при исчерпании настраиваются и не применяются.
Пропуск появился не по небрежности, а как защита: раньше при неопределённой
роли всё уходило как orchestrator, цепочка исчерпывалась, и текст ошибки
роутера подставлялся вместо ответа модели. Поэтому задание требует третьего
пути — выводить роль из того, что Hermes уже передаёт, с настраиваемой ролью
по умолчанию, сохранив предохранитель на исчерпанную цепочку.
Hermes править запрещено: чужой продукт, правка затрётся при обновлении.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Проверка кандидата A28-A31 в браузере вскрыла блокирующую регрессию: при
переписывании клиента в A29 функции удалили, а вызовы в разметке оставили.
Консоль на живой сборке:
openAddAccountWizard is not defined «+ Добавить аккаунт» не работает
checkUpdates is not defined падает при каждой загрузке
handleNodeAccountChange не сменить аккаунт у агента
handleNodeModelChange не сменить модель
handleRefreshProviderModels не обновить список моделей
Подключить аккаунт в новой сборке невозможно, назначить агенту тоже. При этом
startDeviceAuth и startRedirectAuth в коде остались, но не вызываются ниоткуда.
A34 собирает в один порядок: восстановление подключения (блокирует остальное),
адаптеры OpenRouter и NVIDIA с несколькими аккаунтами, интерфейс автопоиска
локальных серверов поверх готовой серверной части, и удаление десктопа по A32.
Задание опирается на ветку review/a28-a31-fixes, где лежат исправления
ревьюера, и перечисляет их отдельным разделом, чтобы не переделывались.
A32 добавлен в репозиторий: он был написан ранее, но остался только локально.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Владелец передал набор описаний субагентов. Ревьюер сверил каждое с кодом:
большая часть уже реализована в Hermes Hub и сильнее шаблонов. Model Router —
это сам Hub; Retry & Fallback — router_engine с цепочками и порогами квот из
A26; Coordinator в части конфликтов доступа — LeaseManager с max_concurrency,
настраиваемым на профиль. Всё это внесено в задание таблицей «не
реализовывать заново», чтобы к вопросу не возвращались.
В работу вошло только отсутствующее:
- роль «Проверяющий готовность»: проект терял раунды на коде 12 установщика,
неустановленных fastapi/uvicorn, обязательном --effort и отсутствующем
ag_slot_oauth.py — всё это выяснялось посреди прогона;
- состояние прогона для workflow из A30, как механика, а не роль;
- ограничение одновременных вызовов и контекст для локальных моделей: на
сервере владельца два llama.cpp с --parallel 1 и почти исчерпанной памятью;
- маскирование почт: sanitize_snapshot вычищает секреты, но слово email в
server.py не встречается ни разу, а хаб теперь открыт в домашнюю сеть
поверх HTTP.
Отдельно зафиксировано для роли контроля затрат: поля токенов в телеметрии
есть, но провайдеры их не отдают, поэтому расход можно только оценивать — и
оценку нельзя выдавать за измерение.
Выполнять после A28, A29 и A30.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Владелец передал готовый дизайн: брендбук с тремя темами, макеты главного
экрана, маршрутизации и остальных разделов, логотипы. Плюс список из
двенадцати субагентов с расписанными обязанностями.
Объём не помещается в одно задание, поэтому разделено на три с явными
границами по файлам:
A28 реестр ролей и двенадцать субагентов Antigravity, основа
A29 дизайн-система и экран «Маршрутизация» Antigravity
A30 главный экран: граф workflow, LIVE, файлы Codex
Каждое опирается на состояние, снятое исполнением, чтобы агенты не
переписывали работающее и не выясняли заново:
- новая роль уже добавляется через конфигурацию и доходит до снапшота, но
подпись падает в сырой идентификатор, потому что таблицы имён зашиты в
четырёх местах;
- workflow, связей между агентами и файлов агентов в проекте нет вовсе —
это разработка с нуля, а не доработка;
- источники данных для дашборда существуют и настоящие, параллельный
заводить не нужно;
- веб-слой без сборки, и это обосновано в контракте.
В каждом задании отдельно оговорено, что демонстрационные значения с
макетов (12 задач, 3.42 с, 94.2%, account-01) — иллюстрация и в код попасть
не должны. Поверхность для выдуманных данных здесь самая большая за проект.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Владелец обновляется вручную на трёх машинах. Механизм обновления в проекте
есть, но мёртв в каждом звене, и это проверено: веб-клиент check_updates не
вызывает вовсе (0 вхождений); DEFAULT_UPDATE_URL смотрит на заброшенный
второй репозиторий, чей манифест застыл на 0.1.1 от 21 августа; версия
захардкожена в 0.1.1 и подниматься не должна, поэтому сравнение по semver
никогда не скажет «есть обновление».
Рабочая часть — apply_update_sync с резервной копией, py_compile-проверкой и
откатом — сохраняется, переписывать её не нужно.
В задании принято решение, которое агентам не следует угадывать: признак
новизны — коммит, а не версия, источник — релизы основного репозитория, куда
поставка идёт на самом деле.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Владелец сформулировал, ради чего задумывался хаб: вручную распределять
аккаунты по агентам и следить за квотами, подставляя другой аккаунт там, где
лимит подходит к концу. Модель слотов этому мешает — она навязывает
внутреннее устройство конфигурации и уже привела к тому, что подключённый
аккаунт не появился в маршрутизации.
Задание опирается на три факта, снятых исполнением, чтобы агенты не
переписывали работающее: один профиль уже может обслуживать все шесть ролей;
произвольный идентификатор профиля регистрируется, то есть потолок в три
аккаунта Codex держит только зашитый список в auto_assigner; порогов квот в
коде нет вовсе.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Владелец дал доступ по ключу. На 192.168.1.81 работают два сервера
llama.cpp, оба OpenAI-совместимые, проверено запросами:
8081 Qwen3.8-27B-Q4_K_M reasoning on, контекст 65536, -ngl 99
8082 Qwen3-4B-Instruct reasoning off, «compressor»
GET /v1/models и POST /v1/chat/completions отвечают 200 на обоих.
Видеокарта Tesla V100-32GB, занято 28.7 из 32.7 ГБ.
Три следствия внесены в задание как определяющие реализацию:
- оба слушают только 127.0.0.1, снаружи недоступны; варианты решения
предложены владельцу, выбор за ним;
- у обоих --parallel 1, то есть один запрос за раз: лизы Hub обязаны
ограничивать локального провайдера, иначе роли заблокируют друг друга;
- памяти видеокарты на третью модель нет, слотов ровно два.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
У владельца сервер 192.168.1.81 с локальной LLM; хочет использовать её
как субагента. Ценность: локальная модель не имеет квоты и не стоит
денег — идеальный последний резерв. Сейчас у него реально работает один
провайдер из пяти, запаса нет.
Половина работы уже есть: RouterProfileConfig.custom_base_url
существует, deepseek_adapter — готовый образец OpenAI-совместимого
вызова, а профиль через provider: custom у него уже настроен в Hermes.
Первым пунктом — разведка, а не код: ревьюер снаружи увидел открытыми
только 22 и 3000 (Rocket.Chat), порт Ollama закрыт. Что именно слушает,
выясняет владелец на сервере: доступа по SSH нет, вход по ключу не
настроен, пароли не используются.
Отдельным пунктом — честность про квоту: у локальной модели её нет как
понятия, и показывать Н/Д рядом с процентами других провайдеров нельзя,
это читается как «данные не пришли».
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Решение владельца по итогам живой эксплуатации: разделов семь вместо
девяти. Убираются «Команда агентов» и «Модели и провайдеры», их
содержимое перераспределяется между маршрутизацией и обзором. Аналитика
остаётся, но должна объяснять свои метрики.
Маршрутизация становится местом управления: перестановка блоков
перетаскиванием, смена модели на месте, кнопка «Изменить цепочку»
убирается.
В задание вынесен вывод из только что найденного дефекта: в веб-мастере
стояли выдуманные коды устройства GRK-7842 и CDX-9104, а тест ТРЕБОВАЛ
наличия неверного адреса, то есть защищал выдумку от исправления.
Пункт P0-6 для второго прохода дополнен проверкой на выдуманные
значения и на тесты, закрепляющие дефект.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Написано под схему владельца: Flash реализует, Pro проводит аудит.
Пункт P0-4 — чек-лист для второго прохода, составлен из дефектов,
которые уже проходили мимо первого.
P0-1: mark_auth_required ставит состояние без срока истечения, а
маршрутизация пропускает нездоровый профиль — успеха не случится,
отметка не снимется никогда. Подтверждено: после починки авторизации в
A22 все шесть профилей Antigravity остались помечены, ревьюер снимал
отметки вручную.
P0-2: do_set_model пропускает проверку целиком при пустом кэше моделей.
Проверено — выдуманная модель записалась в конфигурацию владельца.
Отсутствие данных трактуется как разрешение.
P0-3: ручного обновления списка моделей нет с A18.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Владелец возразил на моё утверждение, что gemini-3.7-flash не существует.
Он прав, утверждение было неверным, и я повторил его в четырёх заданиях.
gemini-3.7-flash — настоящее семейство, уровень усилия у неё отдельный
параметр. В интерфейсе Antigravity это видно прямо: пункт «Gemini 3.7
Flash» с вложенным выбором Low/Medium/High. В коде это отражено:
_display_to_cli разбирает «Gemini 3.7 Flash (High)» в пару
("gemini-3.7-flash", "high"). Меня ввела в заблуждение первая колонка
вывода agy models со склеенными идентификаторами.
Настоящий дефект был в коде: _model_supported_efforts вызывала
discover_models() БЕЗ профиля, то есть в глобальном окружении без входа.
Карта поддерживаемых усилий оставалась пустой, подстановка уровня по
умолчанию не срабатывала, и agy отвергал вызов с «requires --effort» —
при совершенно настоящей модели.
profile_id проведён через agy_generate в _model_supported_efforts.
Проверено исполнением: gemini-3.7-flash без указания усилия отрабатывает
и возвращает ответ.
Моки в test_antigravity_concurrency приведены к терпимости по kwargs.
Добавлена поправка agents/inbox/2026-08-24-CORRECTION-gemini-model-names.md:
ложное утверждение попало в A9, A11, A18 и B8, и без опровержения кто-то
чинил бы несуществующую проблему или сломал рабочую конфигурацию.
Тесты: 359 passed, ruff чисто.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
A20 закрыто как неверно поставленное. Синтез oauth_creds.json из
OAuth-потока Hub не работает в принципе: проверены и закрыты пять
гипотез (полнота полей, срок токенов, тот же OAuth-клиент, тот же
scope, согласованность активного аккаунта), а решающий опыт показал,
что agy отказывает даже РАБОЧИМ глобальным учётным данным владельца,
положенным в подменённый HOME. Ошибка в гипотезе автора задания.
Полезное следствие разведки: agy уважает подмену HOME — в каталогах
профилей лежат созданные им же файлы. Изоляция работает, не работал
только синтез.
A22 строит вход через родной механизм agy в окружении профиля. Первым
пунктом — разведка: есть ли неинтерактивный вход, что agy выводит,
как определить завершение. Установлено, что без аргументов это TUI:
в пайп ничего не пишет и виснет.
Приёмка только с тремя доказательствами исполнением: непустой вывод
agy models, успешный реальный вызов, route_request без ухода в резерв.
Плюс проверка побочной находки: в глобальном google_accounts.json
активен один аккаунт, а токен принадлежит другому — Hub мог писать
мимо каталога профиля и сломать владельцу обычный agy.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Веб покрывает пять экранов из девяти. Не хватает Аналитики, Состояния,
Журнала событий и Настроек.
Данные для первых двух уже в снапшоте: metrics.telemetry (19 вызовов,
15 отказов, латентность p50/p95/max) и metrics.host плюс readiness.
Для двух других источника в API нет вовсе — нужны GET /api/events
(EventLogService в backend есть) и GET /api/settings без секретов.
Зона Flash на это задание расширена на router/web/** целиком, включая
server.py: A20 в web/ не заходит, конфликта не будет.
Обнаружение моделей в задание НЕ включено, хотя A18 его пропустил:
причина оказалась глубже и лежит в авторизации agy, это чинит A20.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Маршрутизация через Antigravity не работает ни для одного из шести
аккаунтов при полностью валидных токенах: квоты по ним приходят
настоящими через прямой HTTPS, а путь через CLI падает с
AuthExpiredError.
Причина найдена и проверена: agy читает <HOME>/.gemini/oauth_creds.json
с шестью полями, включая id_token и scope. Hub пишет свой auth.json в
другом месте и другой структурой, а id_token и scope теряет в двух
местах — oauth.py:88-92 и profile_oauth.py:241-249. Ни один профиль их
не хранит.
Проверено и не сработало: подмена HOME на каталог профиля, сборка
oauth_creds.json без id_token. Значит id_token обязателен.
Владелец решил остаться на OAuth, прямой API отклонён.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
A17 (Pro): «Работает» — ветка else в определении здоровья, она означает
«мы не знаем о проблемах», а подана как утверждение. Отказы попадают в
статус только после боевого сбоя, поэтому непроверенный профиль
автоматически зелёный. Плюс «Проверить подключение» не вызывает модель
вовсе — Grok её проходит и не работает.
A18 (Flash): действия смены модели не существует ни среди семнадцати, ни
в клиенте; десктоп это умеет, но логика заперта в методе интерфейса.
И выбирать не из чего: кэш моделей пуст по всем провайдерам, потому что
agy models нестабильна — в одном прогоне 40 секунд, в следующем висит
больше двух минут.
A19: два установщика. Windows — ярлык, открывающий веб окном приложения
через --app без адресной строки (проверено на машине владельца: Edge и
Chrome есть, окно открывается). Linux — скрипт установки, .desktop и
удаление с сохранением данных, плюс честная подсказка про проброс порта
при пустом DISPLAY.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Решение владельца: у него сервер с Ubuntu Server и Xubuntu, Hermes там
будет линуксовый. Веб-интерфейс на сервере строго лучше десктопа.
Десктоп остаётся рабочим до паритета, router/ui/** не трогается.
A15 (Pro): веб-API поверх готового снапшота — GET /api/snapshot и
POST /api/action на семнадцать существующих действий; безопасность
(127.0.0.1 по умолчанию, отказ стартовать на внешнем адресе без токена,
тест на отсутствие секретов в ответе); порт на Linux — восемь мест,
читающих LOCALAPPDATA в обход paths.py; честное сообщение о том, какие
потоки авторизации на headless-сервере не работают. Плюс долг из
прошлого раунда: снапшот не различает «данных нет» и «данные грузятся».
A16 (Flash): клиент без сборки на обычном JS. Не заблокирован сервером —
разрабатывает против docs/web-api/snapshot.example.json. Экраны по
ценности: Аккаунты с видимыми квотами, затем Обзор и Маршрутизация.
Обе стороны пишутся против docs/web-api/CONTRACT.md и до слияния друг
друга не видят — отсюда требование не менять контракт односторонне.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
A13 (Pro): раздел контракта о границе между учётными системами Hub и
Hermes — единственный незакрытый пункт A11; варианты связывания профилей
с ценой каждого; устранение нестабильности набора тестов (шесть корней
Tk дают до семи плавающих ошибок на прогон, мешая отличать настоящую
поломку от шума).
A14 (Flash): два невыполненных пункта A12 — компактные карточки
аккаунтов (accounts_view.py не менялся вообще) и разбор дублирующих
разделов «Провайдеры»/«Квоты» (quotas_view.py не тронут), плюс живые
скриншоты, которых не было.
Принято по A11: пропуск вызова без роли работает — замер 0.10 с без
попыток цепочки; зонд переведён на agy models; выдуманный список
gemini-2.5-* убран; refresh_codex_token появился; source квоты не
опережает данные. Релизный гейт стал зелёным, 7/7.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
A11 (Pro, тяжёлая ветка): интеграция с Hermes — перехват без роли,
граница между учётными системами Hub и Hermes, токены Codex и безопасное
переключение аккаунта, замена зонда обнаружения моделей на agy models,
устранение выдуманного запасного списка в адаптере.
A12 (Flash, быстрая ветка): компактные карточки аккаунтов, разбор
дублирующих разделов «Провайдеры»/«Квоты», причина у каждого Н/Д, тест
на достижимость службы обнаружения моделей, живое подключение Grok.
Заданы строгие непересекающиеся списки файлов, чтобы параллельная работа
не дала конфликтов. В A12 порядок работы с git расписан пошагово: pull в
начале, push ветки сразу после первого коммита, обязательная проверка
финального push через git log origin/<ветка>.
A10 удалено — заменено этой парой.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
У Codex закончились лимиты. Границы зон сняты: router/ui/** и
tests/test_ui_*.py переходят к Antigravity вместе с ответственностью за
честность интерфейса.
Codex успел: выбор модели, кликабельная карточка целиком, окно настроек
роли, снятие правой панели, устранение срезов диаграммы, частично
причины у Н/Д. Не успел: компактные карточки аккаунтов и разбор
дублирующих разделов «Провайдеры»/«Квоты».
Отдельно: работа A9 заявлена выполненной, но в репозитории её нет ни в
одной ветке. Первое действие по A10 — отправить её в origin.
Зафиксирован обязательный контракт службы обнаружения моделей:
router/model_discovery.py + ModelDiscoveryService. Codex импортирует
именно этот путь, отчёт A9 называет другой; импорт защищён except
ImportError, поэтому расхождение сломало бы выбор моделей молча.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
P0-00: Hub подключён к Hermes как middleware llm_execution и срабатывает
на каждом вызове, но Hermes не передаёт role — поэтому всё уходило в роль
по умолчанию, цепочка orchestrator исчерпана, и Hermes получал текст
ошибки вместо ответа модели. Следствие устранено в 2d62d39; в задании —
причина: не претендовать на вызов без достоверной роли, описать границу
между учётными системами Hub и Hermes, подготовить варианты связывания
профилей.
P0-01: Codex сохраняет refresh_token, но функции обновления нет вовсе.
Требуется обновление токена, раздельная проверка access_token и
id_token и переключение аккаунта с остановкой клиента до подмены
учётных данных — по образцу Cockpit Tools, присланному владельцем.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
A9 (Antigravity): миграция профилей в существующий router_profiles.yaml —
корень жалобы «при подключении грока ошибка»; квоты для codex и opencode;
служба обнаружения моделей с кэшем и фоновым обновлением; отказ от
выдуманных списков моделей. Плюс четыре утверждения отчёта A8, не
подтвердившиеся проверкой: профили claude/grok до пользователя не дошли,
проверка is_expired была мертва, dist в .gitignore, флаг /reinstall
не используется.
B8 (Codex): выбор модели агента, компактные карточки аккаунтов без
раскрытия, кликабельная карточка целиком, окно настроек роли, снятие
правой панели, устранение жёстких срезов диаграммы, решение по
дублирующим разделам, причина у каждого Н/Д.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Добавлен раздел P0-0: правка _finish уже в main (7090c8a), её нельзя
потерять при слиянии. Там же второй дефект того же класса —
splash.py вызывает несуществующий AssetManager.get_splash_logo.
Дефект «вызов несуществующего метода» встречается третий раз и под
pythonw всегда молчаливый, поэтому в критерии приёмки добавлено
требование механической проверки UI-слоя.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Both agents work on other machines and push straight to git. A8 and B7
were pinned to 8cddc9f while main had already moved to 7f912f1, and
neither task said to pull first — branching from a stale checkout is how
merges revert other people's work.
Adds an explicit "update your local copy" section to A8 and B7: fetch,
reset to origin/main, record the actual HEAD as BASE_SHA rather than the
SHA printed in the document, and branch from fresh main.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
SetupEngine.IsInstalled is computed but never reaches the wizard UI, so the
first-install flow repeats verbatim on a machine that already has Hub. Adds the
reinstall screen, the mirror semantics it triggers, the list of user data that
must survive it, and a /reinstall silent flag.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
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>
Adopts the graph half of the 104-point n8n-derived brief and states plainly what
is excluded: n8n's canvas edits its own workflow execution engine, while Hermes
Hub's engine resolves a role into a provider/account/model for a single call.
Execution trees, agent-as-tool contracts, cancellation and review loops have no
layer to sit on here.
Adds the requirement that has been missing all along: screenshots taken with a
live connected account, not an empty configuration.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
active_calls is permanently zero: state_store reads LeaseManager.get() while
RouterEngine constructs its own instance, so the router's leases are invisible
to the snapshot. And psutil.cpu_percent(interval=None) returns 0.0 on its first
call, so the dashboard shows CPU 0% at startup — a measured-looking number that
is not a measurement.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The mockup's headline blocks divide three ways against the code at 2b2ccd8:
already available (latency, readiness, events, routing chain), derivable but not
yet exposed (per-provider aggregates, call share, host metrics via the unused
psutil dependency, active leases), and absent by design (task queues, service
window, incidents, provider RPS/SLA).
A6 supplies the second group; B5 redesigns against the contract and restores the
four account actions that d0d15ae dropped.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Latency, token usage and failover counts flow through router_metadata on every
call and are then discarded; nothing in the project accumulates them. Four of
the seven headline numbers on the mockups are therefore honestly derivable from
our own calls rather than fabricated. RPS, SLA and host resource metrics stay in
Active Limitations.
Also carries the three debts forward for the third time: HKCU in the installer,
fastapi/uvicorn as required dependencies, and YAML comment loss.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
accounts_view went from four user actions to one in d0d15ae: test, set_main,
set_orchestrator and assign_role lost their triggers, and assign_role is now
unreachable entirely although its handler and modal still exist. Also scopes
what the approved mockups can and cannot drive, since their headline numbers
are exactly the metrics Gap 12 says the backend does not measure.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>