From be98fd67516587262ef05f858f19f07116c56bcb Mon Sep 17 00:00:00 2001 From: Hermes Team Date: Tue, 1 Sep 2026 14:10:49 +0700 Subject: [PATCH] =?UTF-8?q?docs(agents):=20=D0=B7=D0=B0=D0=B4=D0=B0=D0=BD?= =?UTF-8?q?=D0=B8=D0=B5=20A57=20=E2=80=94=20=D0=B2=D1=85=D0=BE=D0=B4=20?= =?UTF-8?q?=D0=B2=20Antigravity=20=D1=87=D0=B5=D1=80=D0=B5=D0=B7=20=D1=81?= =?UTF-8?q?=D0=B0=D0=BC=20agy?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Хаб сейчас записывает чужой файл учётных данных своим кодом: формат восстановлен по рабочему профилю владельца и по строкам в бинарнике. Работает, но до следующего обновления agy — и отказ будет молчаливым. Проверено запуском: подкоманд login или auth у agy нет, вход только запуском CLI без аргументов. Значит вход переносится в терминал с HOME на каталог профиля, а браузерный путь остаётся запасным для удалённого случая. Co-Authored-By: Claude Opus 5 --- .../inbox/2026-09-01-A57-agy-native-login.md | 169 ++++++++++++++++++ 1 file changed, 169 insertions(+) create mode 100644 agents/inbox/2026-09-01-A57-agy-native-login.md diff --git a/agents/inbox/2026-09-01-A57-agy-native-login.md b/agents/inbox/2026-09-01-A57-agy-native-login.md new file mode 100644 index 0000000..0e54e0f --- /dev/null +++ b/agents/inbox/2026-09-01-A57-agy-native-login.md @@ -0,0 +1,169 @@ +# Задание 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`.