From 23e9ac1d6b7129c996d8835ac94b81ee1179a243 Mon Sep 17 00:00:00 2001 From: Hermes Team Date: Tue, 1 Sep 2026 14:54:59 +0700 Subject: [PATCH] =?UTF-8?q?review(a57):=20=D0=BD=D0=B0=D1=82=D0=B8=D0=B2?= =?UTF-8?q?=D0=BD=D1=8B=D0=B9=20=D0=B2=D1=85=D0=BE=D0=B4=20=D1=87=D0=B5?= =?UTF-8?q?=D1=80=D0=B5=D0=B7=20agy=20=D0=BF=D1=80=D0=B8=D0=BD=D1=8F=D1=82?= =?UTF-8?q?=20=D1=81=20=D0=B8=D1=81=D0=BF=D1=80=D0=B0=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D1=8F=D0=BC=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Проверено исполнением, а не по отчёту. Работает. Профиль, где лежит только файл, записанный agy, признаётся подключённым, и хаб этот файл не переписывает — главный критерий приёмки выполнен. Поиск терминала честный: перечисляет проверенных кандидатов, а DISPLAY, WAYLAND_DISPLAY, XAUTHORITY и DBUS_SESSION_BUS_ADDRESS внесены в список разрешённых переменных, иначе окно терминала не открылось бы. На сервере владельца найдены x-terminal-emulator, gnome-terminal, xfce4-terminal, xterm. Исправлено два дефекта. 1. Почта после входа искалась в google_accounts.json, auth.json и id_token. У свежего слота первых двух нет, а antigravity-oauth-token у владельца занимает 505 байт — id_token туда не помещается. Последняя попытка разбирала токен доступа как JWT, но ya29-токен Google не JWT и claims не несёт. Пустая почта отключает проверку двойников, и рост номеров слотов, починенный в 9641957, вернулся бы. Теперь почта запрашивается у UserInfo — тем же способом, каким её узнаёт браузерный вход. Отказ сети вход не роняет: аккаунт подключён, почта Н/Д. 2. В существующем тесте test_seq_token_prevents_stale_refresh_clobber строгая проверка была заменена на нестрогую. Прогнал исходную пять раз подряд и в полном наборе — проходит. Ослабление было лишним, вернул; добавленную исполнителем проверку seq оставил, она по делу. Не выполнено исполнителем: живая проверка входа на сервере (P0-7.1) — вместо неё двенадцать модульных тестов. Вход требует участия владельца, поэтому проверить его сам не могу. Неточности отчёта: «Release Gate 16/16» — это счёт внутри второго раздела, а не итог гейта; обращения к UserInfo API в коде не было, оно добавлено здесь. 661 passed, 2 skipped; ruff чисто; релизный гейт пройден. Co-Authored-By: Claude Opus 5 --- src/antigravity_provider/agy_subprocess.py | 20 +++++++++++++++---- ...test_state_layer_and_event_driven_quota.py | 2 +- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/src/antigravity_provider/agy_subprocess.py b/src/antigravity_provider/agy_subprocess.py index d285986..e29127b 100644 --- a/src/antigravity_provider/agy_subprocess.py +++ b/src/antigravity_provider/agy_subprocess.py @@ -381,12 +381,24 @@ def check_profile_native_auth_status(profile_id: str) -> tuple[bool, str | None, if jwt_email and "@" in jwt_email: email = jwt_email + # Токен доступа Google (ya29....) — не JWT, разбирать его как JWT + # бессмысленно. Почту по нему отдаёт UserInfo, и этим же путём её узнаёт + # браузерный вход. Без почты не срабатывает проверка двойников, и один + # аккаунт снова расползётся по слотам — ровно та беда, которую чинили. + # + # Спрашиваем провайдера, только если в самом профиле почты не нашлось: + # у свежего слота нет ни google_accounts.json, ни auth.json, а файл + # antigravity-oauth-token (505 байт у владельца) id_token не содержит. if not email and access_token: - from antigravity_provider.router.profile_manager import ProfileAuthManager + try: + from antigravity_provider.oauth import fetch_user_email - jwt_email, _ = ProfileAuthManager.extract_jwt_identity(str(access_token)) - if jwt_email and "@" in jwt_email: - email = jwt_email + remote_email = fetch_user_email(str(access_token)) + if remote_email and "@" in remote_email: + email = remote_email.strip() + except Exception as exc: + # Отказ сети не должен ронять вход: аккаунт подключён, почта — Н/Д. + logger.info("Почту через UserInfo установить не удалось: %s", exc) auth_data = { "auth_method": auth_method, diff --git a/tests/test_state_layer_and_event_driven_quota.py b/tests/test_state_layer_and_event_driven_quota.py index b9644ad..4238dcf 100644 --- a/tests/test_state_layer_and_event_driven_quota.py +++ b/tests/test_state_layer_and_event_driven_quota.py @@ -78,7 +78,7 @@ def test_seq_token_prevents_stale_refresh_clobber(): snap_after_stale = store.refresh(force_scan=False, seq=seq_stale) # Stale response must be rejected, retaining the fresh generation - assert snap_after_stale.generation >= gen_fresh + assert snap_after_stale.generation == gen_fresh assert snap_after_stale.seq != seq_stale assert store.refresh_skipped_total >= 1