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>
13 KiB
Задание A22: вход в Antigravity силами самого agy
Дата поступления
2026-08-24
База
Проверочный HEAD на момент выдачи: bb4f6df.
Ветка
antigravity/agy-native-login
Приоритет
Выше всего остального. Маршрутизация через Antigravity не работает ни для одного из шести аккаунтов — это десять профилей из двадцати двух и основной провайдер владельца.
Порядок работы с git
cd <каталог репозитория>; git fetch origin --prune; git status
git checkout main; git pull --ff-only origin main
git checkout -b antigravity/agy-native-login
git commit -m "..." <- сначала коммит
git push -u origin antigravity/agy-native-login
В main напрямую не пушить. Работа A20 ушла в основную ветку минуя ревью; в тот раз обошлось, но правка, ломающая сборку, попала бы к владельцу без проверки. Ветка существует именно для этого.
В конце — push и проверка git log --oneline -1 origin/antigravity/agy-native-login, git status чистый.
Задание A20 закрыто как неверное. Ошибка в постановке, не в исполнении
A20 требовал сохранять id_token и scope и писать <профиль>/.gemini/oauth_creds.json в формате agy. Это сделано, и сделано аккуратно — атомарная запись через временный файл, поля не затираются при обновлении, 350 passed, ruff чисто.
Но задача не решилась, и подход в принципе не может её решить. Формулировал задание ревьюер, ошибка в гипотезе его.
Проверено исполнением, каждая гипотеза закрыта:
| Проверено | Результат |
|---|---|
Все шесть полей в oauth_creds.json |
на месте — отказ |
| Токены не просрочены | живы ещё 43 минуты — отказ |
Тот же OAuth-клиент (aud, azp) |
совпадают полностью — отказ |
| Тот же набор разрешений | 6 из 6, различий нет — отказ |
| Активный аккаунт согласован с владельцем токена | согласован — отказ |
И решающий опыт: в подменённый HOME положены рабочие глобальные учётные данные владельца, действительные ещё 40 минут, — agy отказал и им.
Вывод: agy не принимает учётные данные, выпущенные не им самим. Ни в каком расположении, ни с какими полями. Синтезировать их из OAuth-потока Hub нельзя.
Что при этом выяснилось полезного
agy уважает подмену HOME. В каталогах профилей лежат его собственные файлы, созданные им же: .gemini/antigravity-cli/conversation_summaries.db и installation_id с отметкой 23 августа 12:19. Изоляция профилей работает — не работал только синтез учётных данных.
Значит путь один: вход должен выполнять сам agy, в окружении нужного профиля.
P0-1. Разведка перед реализацией
Не повторяйте ошибку A20 — сначала проверьте, потом стройте.
Установлено: agy без аргументов — интерактивный TUI. Запущенный с перехваченными потоками он ничего не выводит в пайп и виснет; ему нужен настоящий терминал.
Прежде чем писать код, выясните и напишите в отчёте:
- Есть ли у
agyнеинтерактивный вход — флаг, подкоманда, переменная окружения. Вagy --helpподкоманд входа нет (agent,agents,changelog,help,install,mcp,models,plugin,plugins,update), но проверьтеagy help <подкоманда>и документацию. - Пишет ли
agyпри входе что-нибудь пригодное для автоматики — URL, код устройства — в файл или в stderr. - Как надёжно определить, что вход завершился: появление
oauth_creds.jsonв каталоге профиля, изменениеgoogle_accounts.json, что-то ещё.
Если неинтерактивного входа нет — так и напишите. Это законный результат, и он определяет всё остальное.
P0-2. Вход по профилям
Опираясь на разведку, сделать в Hub подключение аккаунта Antigravity через родной вход agy:
- окружение подменяется на каталог профиля (
USERPROFILE,HOME,HOMEPATH) — механизм уже есть вantigravity_adapter.get_profile_env_dir, он проверен и работает; - если неинтерактивного входа нет — открывать видимое консольное окно с этим окружением, чтобы владелец прошёл вход сам. Это честный путь: он ровно так и делал вручную;
- Hub дожидается завершения, определяя его признаком из разведки, и сообщает результат в интерфейсе;
- шесть аккаунтов подряд: мастер должен вести по ним, а не заставлять повторять всё руками для каждого.
Ограничение по безопасности, без исключений. Учётные данные вводит владелец в окне agy. Hub их не перехватывает, не читает из потоков, не логирует и не пересылает. Задача Hub — подготовить окружение и дождаться результата.
P0-3. Веб-интерфейс должен сказать правду
На сервере без экрана консольный вход невозможен. Это уже зафиксировано в контракте: Antigravity и Claude требуют redirect на localhost и на headless не работают.
В вебе для Antigravity показывать не кнопку подключения, а объяснение и обходной путь: пройти вход на десктопе, либо пробросить порт по SSH. Неработающая кнопка недопустима — правило то же, что и с зелёным «Работает» на нерабочем аккаунте.
P0-4. Проверить глобальную сессию владельца
Побочная находка, требует проверки: в глобальном ~/.gemini/google_accounts.json активным записан victor.trushenko@gmail.com, а токен в ~/.gemini/oauth_creds.json принадлежит ochenstarik@gmail.com.
Похоже, Hub где-то пишет мимо каталога профиля, в глобальное расположение, и мог сломать владельцу обычный agy.
Найти, откуда это, и убедиться, что Hub не трогает глобальные учётные данные ни при каких обстоятельствах. Тест обязателен: сохранение и обновление профиля не изменяет ни одного файла в ~/.gemini.
P0-5. Доказательство
Задание принимается только с подтверждением исполнением. Приложить:
- вывод
agy models, вернувший непустой список, через профиль Hub; - успешный реальный вызов модели через
adapter.invoke— ответ модели, а неAuthExpiredError; route_requestна роли, ведущей на Antigravity, отработавший без ухода в резерв по причине авторизации.
Без этих трёх пунктов приёмки не будет. A20 был написан правильно по букве задания и всё равно не работал — цена ненадёжной гипотезы уже заплачена один раз.
P1-6. Обнаружение моделей — после починки входа
Когда agy models заработает, доделать пропущенное в A18: кэш моделей на диске, переживающий перезапуск; фоновое обновление с таймаутом, не затирающим кэш; ручная кнопка обновления; при пустом кэше — «список ещё не получен» без литеральных подстановок.
Сейчас set_model отклоняет любую модель, включая настоящую, потому что сравнивать не с чем. Владелец хочет поставить двум кодерам gemini-3.1-pro-high и не может.
Ограничения
- Параллельно идёт A21 (четыре экрана веб-интерфейса). Его зона:
router/web/**целиком. Не заходить туда, кроме честного объяснения для Antigravity по P0-3 — согласовать эту правку в отчёте. - Ваши файлы:
oauth.py,router/profile_oauth.py,router/profile_manager.py,agy_subprocess.py,router/adapters/antigravity_adapter.py,model_discovery*,credentials.py,router/ui/add_account_wizard.py. - Учётные данные не логировать и не отдавать наружу; существующий тест на секреты должен продолжать проходить.
- Десктоп и веб не ломать. На
mainсейчас 350 passed, 2 skipped. - Тег
v0.1.1не создавать.
Критерии приёмки
- Ветка в
origin, вmainнапрямую не пушилось,git statusчист. - В отчёте есть результат разведки по трём вопросам P0-1.
- Подключение аккаунта Antigravity проходит через родной вход
agyв окружении профиля. - Мастер ведёт по нескольким аккаунтам подряд.
- Hub не перехватывает и не логирует учётные данные.
- Приложен непустой вывод
agy modelsчерез профиль Hub. - Приложен успешный реальный вызов модели.
- Приложен
route_request, не ушедший в резерв по авторизации. - Тест: сохранение и обновление профиля не изменяет ни одного файла в
~/.gemini. - В вебе Antigravity показан с объяснением и обходным путём, а не нерабочей кнопкой.
ruff check .чисто; релизный гейт не ухудшен.- Отчёт:
START_HEAD,FINAL_HEAD,origin/main,git status,X passed / Y skipped / Z failed.
Главное
Продукт создан ради маршрутизации между аккаунтами Antigravity. Она не работает при полностью валидных токенах, и обойти это синтезом учётных данных уже пробовали — не выходит. Остаётся дать agy войти самому, а Hub должен это организовать и не мешать.
Порядок сдачи
Передать точный FINAL_COMMIT_SHA. Сдано только после появления коммита в origin.