hermes-hub/agents/inbox/2026-09-01-A57-agy-native-login.md
Hermes Team be98fd6751 docs(agents): задание A57 — вход в Antigravity через сам agy
Хаб сейчас записывает чужой файл учётных данных своим кодом: формат восстановлен
по рабочему профилю владельца и по строкам в бинарнике. Работает, но до
следующего обновления agy — и отказ будет молчаливым.

Проверено запуском: подкоманд login или auth у agy нет, вход только запуском CLI
без аргументов. Значит вход переносится в терминал с HOME на каталог профиля,
а браузерный путь остаётся запасным для удалённого случая.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-01 14:10:49 +07:00

169 lines
14 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Задание A57: вход в Antigravity через сам agy, а не через сочинённый файл
## Дата поступления
2026-09-01
## База
`origin/main` (`f188a18`).
```
git fetch origin --prune
git checkout -b antigravity/a57-agy-native-login origin/main
```
В `main` напрямую не пушить.
## Порядок исполнения
Два прохода: **Flash** реализует, **Pro** проводит аудит. Пункт **P0-8** написан для аудитора.
Зона: подключение аккаунтов Antigravity. С A56 (сжатие контекста) не пересекается.
---
## Задача
Сейчас хаб проводит вход сам: получает токены по OAuth и **записывает чужой файл учётных данных своим кодом**. Формат этого файла ревьюер восстановил по рабочему профилю владельца и по строкам в бинарнике `agy`. Сегодня это работает. Но `agy` обновляется, и формат может измениться молча: файл останется на месте, вход перестанет засчитываться, а владелец увидит ровно ту необъяснимую картину, которую ловили полдня — «Авторизация успешно завершена» и тут же «Please sign in to view available models».
Правильный ответ — дать войти самому `agy`, с `HOME`, указывающим на каталог профиля. Тогда он пишет свои файлы своим форматом, сам обновляет токен по истечении часа, и гадать не о чем.
---
## Что проверено ревьюером — заново не выяснять
### Неинтерактивного входа у agy нет
`agy --help` (проверено запуском) даёт подкоманды: `agent`, `agents`, `changelog`, `help`, `install`, `mcp`, `mic-serve`, `models`, `plugin`, `plugins`, `update`. Подкоманд `login` или `auth` **нет**. Вход один: запустить CLI без аргументов и пройти его в терминале. Это же говорит текст ошибки самого agy:
```
Error: Please sign in to view available models.
Launch the CLI without arguments to sign in.
```
Искать скрытый флаг входа не надо — его нет.
### Что agy держит в каталоге профиля
Рабочий профиль владельца `ag-orch-fallback` (11 моделей):
```
.gemini/oauth_creds.json 1949 байт формат Gemini CLI
.gemini/antigravity-cli/antigravity-oauth-token 505 байт {"auth_method":"consumer","token":{...}}
.gemini/antigravity-cli/settings.json 107 байт enableTelemetry, trustedWorkspaces
.gemini/antigravity-cli/installation_id 36 байт
.gemini/antigravity-cli/jetski_state.pbtxt
.gemini/antigravity-cli/history.jsonl
.gemini/antigravity-cli/conversation_summaries.db
auth.json файл хаба, не agy
```
Вход agy читает из `antigravity-oauth-token`, а не из `oauth_creds.json`. Это установлено сравнением рабочего профиля с неработающим и подтверждено исполнением: файл создали руками для `ag-4``agy models` тут же выдал 11 моделей.
### Изоляция по HOME уже работает
`get_profile_env_dir`, `build_safe_subprocess_env` и `hidden_process_kwargs` существуют и применяются: `agy models` вызывается с `HOME`/`USERPROFILE`, указывающими на каталог профиля. Заново это писать не надо.
### Заготовка уже есть
`launch_native_agy_login` в `agy_subprocess.py` запускает agy с `CREATE_NEW_CONSOLE`. Её никто не вызывает — числится мёртвым кодом с A54. Это отправная точка, а не мусор.
### Рост номеров профилей починен
Слот выбирался до входа, когда почта ещё неизвестна, и повторный вход тем же аккаунтом занимал очередной свободный номер: один аккаунт владельца расползся на ag-2, ag-3, ag-4. В `9641957` после опознания почты учётные данные возвращаются в слот, который этот аккаунт уже занимает. **Не переделывать.**
### Среда владельца
Сервер: Ubuntu 24.04, рабочий стол на месте (Chrome запускается), владелец сидит за машиной. Вторая машина — Windows 11. Хаб работает на обеих.
---
## P0-1. Вход выполняет сам agy
1. **Запуск `agy` в настоящем терминале** с `HOME` и `USERPROFILE`, указывающими на каталог выбранного профиля. Владелец проходит вход глазами и руками — это единственный доступный способ.
2. **Терминал не подразумевать, а искать.** На Linux проверить наличие эмулятора (`x-terminal-emulator`, `gnome-terminal`, `konsole`, `xfce4-terminal`, `xterm`) и назвать в отказе, что именно искали. Отсутствие терминала — честный отказ с перечнем проверенного, а не молчание.
3. **Файл учётных данных хаб больше не сочиняет.** `write_agy_oauth_creds` и запись `antigravity-oauth-token` остаются только для запасного браузерного пути (P0-4).
4. **Ждать окончания входа по появлению файла**, а не по коду возврата терминала: эмулятор часто отсоединяется сразу. Ждать `antigravity-oauth-token` в каталоге профиля с разумным пределом и внятным сообщением по его истечении.
## P0-2. Слот выбирается до входа и не меняется
1. **Каталог профиля определяется заранее** и передаётся через `HOME`. Вход физически не может уйти в чужой каталог — в этом весь смысл.
2. **Занятый слот не перезаписывать.** Если в каталоге уже лежит рабочий вход другого аккаунта, предупредить и потребовать подтверждения.
3. **Каталоги существующих аккаунтов не трогать.** Их два десятка, повторный вход руками стоит владельцу часов.
## P0-3. Почта берётся из профиля, а не выдумывается
1. **После входа опознать аккаунт**, прочитав то, что записал agy. Если почту установить не удалось — показать `Н/Д` с причиной, а не подставить правдоподобное.
2. **Проверить двойников** уже существующим `AutoAssigner.check_duplicate_identity` и вернуть учётные данные в занятый этим аккаунтом слот, если он есть.
3. **Число и время получения моделей** показывать рядом со списком.
## P0-4. Браузерный путь остаётся запасным
1. **Не удалять существующий OAuth.** С другой машины через браузер это единственный способ, и он работает.
2. **Владелец выбирает способ** в мастере: вход в терминале на этой машине или по ссылке из браузера. Предлагать первым тот, который на текущей машине выполним.
3. **Текст объясняет разницу**: терминал доступен только там, где стоит хаб.
## P0-5. Отказ доходит до владельца
1. **Причина отказа — текстом.** `agy` пишет её в stderr; она обязана попадать в интерфейс вместе с указанием `HOME`, с которым шёл запуск.
2. **Пустых сообщений быть не должно.** Запасной текст «Отказ выполнения действия» означает потерянную причину.
3. **Проверка после входа не блокирует ответ.** Действие возвращается сразу, опрос провайдера идёт в фоне — это сделано в `0ad946e`, не откатывать.
## P0-6. Безопасность
1. **Токены и коды в интерфейс не выводить и в журнал не писать.** В сообщениях допустимы пути и имена файлов, но не содержимое.
2. **Права на каталог и файлы**`0700` и `0600`.
3. **`~/.hermes/agy_profiles/` не чистить** и не трогать чужие профили.
## P0-7. Проверка исполнением
Тестами это не ловится: все прежние дефекты входа прошли через зелёный прогон.
1. **Подключить аккаунт через терминал на сервере** и приложить вывод `agy models` для этого профиля.
2. **Подключить второй аккаунт** и убедиться, что первый не задет: у обоих свои каталоги и свои почты.
3. **Повторить вход тем же аккаунтом** и убедиться, что новый слот не создаётся.
4. **Проверить отказ** при отсутствии терминала: сообщение перечисляет, что искали.
5. **Проверить, что браузерный путь по-прежнему работает** с другой машины.
## P0-8. Аудит вторым проходом
1. **Пройти вход целиком на обеих машинах**, скриншоты приложить.
2. **Убедиться, что хаб не пишет `antigravity-oauth-token`** на пути через CLI: файл создаёт agy.
3. **Проверить, что при отказе входа профиль не остаётся наполовину заполненным** и не числится подключённым.
4. **Различать «нет доступа» и «не найдено»** — не повторять ошибку ложного диагноза.
5. **Побочные изменения** объяснить.
6. **Пропущенный пункт назвать пропущенным.**
---
## Ограничения
- Учётные данные и каталоги существующих аккаунтов не трогать.
- Правки ревьюера из `main` не откатывать: `9641957` (запись токена и слоты), `0ad946e` (проверка в фоне), `f188a18` (устаревший вердикт).
- Фронтенд без npm, без сборки, без фреймворков — по `docs/web-api/CONTRACT.md` §1.
- Адреса, пути и имена терминалов в код не зашивать вслепую: искать и сообщать, что искали.
- Версию `0.1.3` не понижать.
- Правило честности без исключений: неизмеренное — `Н/Д` с причиной; отсутствие прав — не то же самое, что отсутствие файла.
## Критерии приёмки
1. Ветка в `origin`, `git status` чист.
2. Вход через `agy` в терминале работает на Linux и на Windows; вывод `agy models` приложен.
3. Файл `antigravity-oauth-token` на этом пути создаёт agy, а не хаб.
4. Слот задаётся до входа через `HOME`; чужой каталог затронуть невозможно.
5. Повторный вход тем же аккаунтом не создаёт новый слот.
6. Почта берётся из профиля; неустановленная показывается как `Н/Д` с причиной.
7. Браузерный путь сохранён и проверен с другой машины.
8. Отсутствие терминала даёт отказ с перечнем проверенного.
9. Токены не попадают ни в интерфейс, ни в журнал.
10. `ruff check .` чисто; релизный гейт 10/10; тестов не меньше **626**.
11. Отчёт: `START_HEAD`, `FINAL_HEAD`, `origin/main`, `git status`, `X passed / Y skipped / Z failed`.
## Главное
Хаб сегодня подделывает чужой формат учётных данных. Это работает ровно до следующего обновления `agy`, и отказ будет молчаливым: файл на месте, вход не засчитан, причина неочевидна. Владелец уже потерял на этом день.
`agy` умеет входить сам и делает это правильно по определению. Задание переносит вход туда, где ему место, оставляя браузерный путь для удалённого случая.
## Порядок сдачи
Передать точный `FINAL_COMMIT_SHA`.