hermes-hub/agents/inbox/2026-08-23-A13-antigravity-pro-contract-stability.md
Hermes Team a18de5d468 docs(tasks): A13 и A14 — оставшийся долг
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>
2026-08-23 15:52:07 +07:00

12 KiB
Raw Blame History

Задание A13 (Antigravity Pro, этот ПК): граница продукта и устойчивость тестов

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

2026-08-23

База

Проверочный HEAD на момент выдачи: 9c0da36.

Ветка

antigravity/contract-stability


Порядок работы с git

В начале — обновить локальную копию:

cd <каталог репозитория>; git fetch origin --prune; git status
git checkout main; git pull --ff-only origin main
git checkout -b antigravity/contract-stability

Сразу после первого коммита — отправить ветку:

git push -u origin antigravity/contract-stability

В конце — push и проверка, что он прошёл:

git push origin antigravity/contract-stability
git log --oneline -1 origin/antigravity/contract-stability

Последняя команда обязана показать ваш финальный коммит.

Отдельно и важно. В прошлый раз работа была выполнена, но осталась незакоммиченной в рабочем каталоге, а в origin ушла пустая ветка — она указывала на тот же коммит, что и main. Ревьюер обнаружил правки случайно и восстановил их вручную. Инструкция «push ветку сразу» была выполнена буквально, а коммит забыт. Push без коммита ничего не сохраняет. Перед отчётом убедитесь, что git status показывает чистое дерево, а не список изменённых файлов.


Что принято по A11

Проверено исполнением — работа сделана и работает:

  • Пропуск вызова без роли работает. Замер на слитом коде: вызов в стиле Hermes без роли уходит вниз за 0.10 секунды, цепочка не пробуется вовсе. Раньше каждый вызов Hermes шёл как orchestrator и тратил попытки на исчерпанную цепочку. Это главный пункт A11, и он закрыт.
  • Зонд обнаружения моделей переведён на agy models вместо разбора ошибки заведомо неверной модели.
  • Выдуманный запасной список gemini-2.5-* убран из адаптера — моделей с такими именами у провайдера нет.
  • refresh_codex_token появился — обновления токена Codex не существовало вовсе.
  • source квоты больше не заявляет provider_api, когда ни одна корзина не измерена; применено последовательно к antigravity и opencode-go.

Замечание по обнаружению моделей: сейчас оно возвращает пустой список, но не по вине кода. Проверено прямым вызовом — agy models виснет и сам по себе (rc=124 по таймауту 100 секунд), хотя часом раньше отвечал за 40 секунд. Зонд ведёт себя правильно: отдаёт пусто и сохраняет кэш вместо того, чтобы выдумать список.

Релизный гейт теперь зелёный, 7/7 — проверка 4 проходит. Она была красной несколько раундов подряд.

Исправлено ревьюером при фиксации: тест test_opencode_shows_published_limits закреплял прежнюю семантику source и падал после вашей правки. Приведён к честной. Код был прав, тест — нет.


P0-1. Граница между учётными системами Hub и Hermes — единственный незакрытый пункт A11

docs/UI_STATE_CONTRACT.md не изменялся. Это тот пункт, ради которого владелец и задал вопрос, решив, что «хаб никак не привязан к гермесу».

Что установлено и должно быть записано:

Hermes ведёт собственные профили в каталоге profiles своего домашнего каталога:

agy-01 … agy-06, worker-fast, worker-research, worker-review,
worker-code, worker-code-2, deepseek

и настраивает delegate_task отдельно: max_concurrent_children=3, provider=opencode-go, model=kimi-k2.7-code.

Профили Hub — ag-w1, ag-orch-fallback, codex-orch, opengo-*, теперь ещё claude-* и grok-*другое множество идентификаторов. Один и тот же аккаунт Google живёт в двух учётных системах под разными именами: у Hermes он agy-05, у Hub ag-w2.

Требуется раздел в контракте, отвечающий на четыре вопроса прямо:

  1. Что Hub получает от Hermes на каждом вызове. Перечислить фактически: task_id, turn_id, api_request_id, session_id, platform, model, provider, base_url, api_mode, api_call_count. И явно: роли среди них нет.
  2. Чего Hub не видит: профиль Hermes, которым выполняется вызов; настройки delegate_task; состав субагентов.
  3. Чем Hub управляет: собственными профилями, цепочками отказоустойчивости, квотами своих аккаунтов.
  4. Чем не управляет: ничем из перечисленного в пункте 2.

Без этого интерфейс, показывающий «команду агентов» и роли, вводит владельца в заблуждение — он видит на экране роли, которых Hermes не спрашивает, и разумно ожидает, что настройка роли на что-то влияет.

P0-2. Варианты связывания профилей Hub и Hermes

Подготовить варианты с ценой каждого. Решение принимает владелец. Молча не реализовывать.

Как минимум разобрать три:

  1. Сопоставление по идентичности аккаунта — email из id_token. У Hub он уже извлекается (extract_jwt_identity в profile_manager.py). Насколько надёжно сопоставляются профили Hermes по тому же признаку? Что делать с профилями без email — worker-fast, deepseek, ключи OpenCode?
  2. Чтение профилей Hermes как источника — Hub перестаёт вести свой список и отражает список Hermes. Что при этом теряется: цепочки отказоустойчивости привязаны к профилям Hub, роли тоже.
  3. Явная таблица соответствия — владелец сам связывает agy-05 с ag-w2. Самое предсказуемое и самое ручное.

По каждому: что становится возможным, что ломается, сколько работы, какие данные владельца затрагиваются. Формат — таблица плюс абзац рекомендации с обоснованием.

P0-3. Набор тестов нестабилен: семь ошибок на прогон

Полный прогон на main даёт 309 passed и до семи ошибок, причём ошибки кочуют между файлами от запуска к запуску: то test_ui_contract_v11.py, то test_ui_mockup_redesign.py, то test_oauth_lifecycle.py. Те же тесты изолированно проходят:

pytest tests/test_ui_contract_v11.py   ->  9 passed
pytest -q                              ->  4 ERROR в этом же файле

Диагноз: исчерпание ресурсов Tk. В наборе шесть отдельных вызовов ctk.CTk() в пяти файлах, каждый создаёт свой корень интерпретатора Tcl. Сообщение — TclError: ... This probably means that tk wasn't installed properly, что к установке отношения не имеет.

Это мешает работе прямо сейчас: невозможно отличить настоящую поломку от шума. За последние раунды каждый прогон приходилось перепроверять изолированно, и один раз настоящая поломка была замечена только со второго захода.

Требуется один общий корень Tk на весь прогон: фикстура в tests/conftest.py с областью видимости session, к которой приводятся все UI-тесты; отдельные ctk.CTk() в тестовых файлах убираются.

Осторожно: тесты, проверяющие поведение при уничтожении окна (test_ui_wizard_finish.py проверяет winfo_exists() == 0 после _finish), должны продолжать работать — уничтожается дочернее окно, а не корень.

Критерий проверки: десять полных прогонов подряд без единой ошибки. Не один — десять: дефект плавающий, и единственный зелёный прогон ничего не доказывает.


Ограничения

  • Параллельно идёт A14 (интерфейс). Ваши файлы: docs/**, tests/conftest.py, tests/test_ui_*.py только в части фикстуры корня Tk, src/antigravity_provider/router/** кроме ui/. Не ваши: router/ui/** по существу, installer/**.
  • Правку 2d62d39 и пропуск вызова без роли не откатывать.
  • Никаких чисел и идентификаторов без измерения.
  • Тег v0.1.1 не создавать.

Критерии приёмки

  1. Ветка в origin, финальный коммит виден через git log origin/antigravity/contract-stability, git status чист.
  2. В контракте есть раздел о границе Hub и Hermes, отвечающий на все четыре вопроса; явно сказано, что роль Hermes не передаёт.
  3. Варианты связывания профилей поданы с ценой каждого и рекомендацией; ни один не реализован без решения владельца.
  4. Десять полных прогонов pytest -q подряд без ошибок; вывод всех десяти в отчёте.
  5. Тесты, проверяющие уничтожение окна, продолжают проходить.
  6. ruff check . чисто; релизный гейт остаётся зелёным (7/7 на момент выдачи задания).
  7. Отчёт: START_HEAD, FINAL_HEAD, origin/main, git status, точный X passed / Y skipped / Z failed.

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

Передать точный FINAL_COMMIT_SHA. Сдано только после появления коммита в origin — проверьте командой перед отчётом.