diff --git a/agents/inbox/2026-09-02-A58-agy-eligibility-state.md b/agents/inbox/2026-09-02-A58-agy-eligibility-state.md new file mode 100644 index 0000000..4dac1f3 --- /dev/null +++ b/agents/inbox/2026-09-02-A58-agy-eligibility-state.md @@ -0,0 +1,151 @@ +# Задание A58: хаб видит состояние проверки доступности agy + +## Дата поступления +2026-09-02 + +## База + +`origin/main` (`e431e39`). + +``` +git fetch origin --prune +git checkout -b antigravity/a58-agy-eligibility-state origin/main +``` + +В `main` напрямую не пушить. + +## Порядок исполнения + +Два прохода: **Flash** реализует, **Pro** проводит аудит. Пункт **P0-7** написан для аудитора. + +Зона: обнаружение состояния `agy`. С кодом входа (A57) пересекается только чтением пути к исполняемому файлу. + +--- + +## Задача + +Владелец не может пользоваться Antigravity: `agy` отвечает + +``` +Eligibility check failed: Your current account is not eligible for Antigravity, +because it is not currently available in your location. +``` + +Вход при этом проходит полностью: терминал открывается, каталог профиля верный, аккаунт опознан. Отказывает Google. + +Владелец обходит это сторонним патчером, который держит у себя. После каждого обновления `agy` патч слетает, и владелец узнаёт об этом, только наткнувшись на отказ посреди работы. Задание закрывает именно это: **хаб должен замечать смену состояния и говорить о ней**, а не оставлять владельца выяснять причину заново. + +--- + +## Что проверено ревьюером — заново не выяснять + +### Проверка не в клиенте, но отказ выносит клиент + +В бинарнике `agy` **нет** строки «not currently available in your location» — её присылает сервер. При этом есть перечисление `EPD_ELIGIBILITY_NOT_ELIGIBLE_REGION_OUT_OF_SCOPE`, `ENDPOINT_AIM_ELIGIBILITY` и `AIM_ELIGIBILITY_FETCH_STATUS_*`: клиент запрашивает право доступа у Google и отказывается работать сам. + +### Прокси не помогает — ограничение привязано к аккаунту + +Измерено на сервере владельца: выход через Финляндию и через Данию даёт один и тот же отказ. Описание патчера это подтверждает — он снимает ограничение «без VPN и смены региона аккаунта Google», то есть обычные пути именно эти два. + +**Поддержку прокси, добавленную в `fa7bbef`, не удалять**: она нужна и работает, просто эту задачу не решает. + +### Что делает патчер + +Для CLI это правка машинного кода, а не настройка. Ищется последовательность байтов и переписывается так, чтобы ветвление всегда уходило по разрешённому пути: + +``` +было: test rax,rax ; je eligible ; cmp byte[rax+8],0 ; jne eligible ; call failure +стало: test rax,rax ; je eligible ; test rax,rax ; nop ; jne eligible +``` + +Четыре байта. В исходнике патчера это названо «единственный гейт начальной проверки». Есть подписи для x86-64 и для arm64. + +Подменять в настройках нечего: проверка не в настройках. + +### Версии + +У владельца `Antigravity CLI 1.1.23`. Патчер объявляет минимальные версии `2.5.5` и `2.9.1` — соответствие надо проверить, иначе подпись не найдётся. Обновление CLI выполняется командой `agy update` и перезаписывает файл, снимая патч. + +--- + +## P0-1. Хаб не патчит ничего сам + +1. **Хаб не изменяет исполняемые файлы.** Ни при каких условиях, ни по кнопке, ни автоматически. +2. **Хаб ничего не скачивает и не запускает из сети.** Стороннего кода в хабе нет. +3. **Только чтение**: состояние определяется чтением файла, который уже лежит на машине. + +## P0-2. Состояние определяется и показывается + +1. **Признак патча** — по наличию в файле изменённой последовательности байтов. Подписи для x86-64 и arm64. Чтение файла, ничего больше. +2. **Три состояния, а не два**: «проверка снята», «проверка на месте», «определить не удалось» — с причиной. Не найдена подпись ни в исходном, ни в изменённом виде означает именно третье: другая версия CLI, а не «не пропатчен». +3. **Версия и отпечаток файла** запоминаются. Смена любого из них после обновления — повод пересчитать состояние и сказать владельцу. +4. **Показывать в карточке аккаунта Antigravity** и в «Состоянии системы». + +## P0-3. Владелец узнаёт о смене состояния + +1. **Событие в журнале**, когда состояние сменилось: было «снята» — стало «на месте». +2. **Заметное указание в интерфейсе**, а не строчка в глубине: этот отказ останавливает работу целиком. +3. **Не опрашивать в цикле.** Достаточно проверки при запуске, после обновления `agy` и по кнопке. Опрос в цикле уже приводил к тому, что интерфейс сам себя кормил запросами. + +## P0-4. Кнопка запускает то, что владелец сам поставил + +1. **Путь к сценарию владельца задаётся в настройках.** Умолчания не выдумывать: не задан — кнопки нет, показывается `Н/Д: сценарий не указан`. +2. **Запуск только по нажатию.** Никакого автоматического запуска при обновлении: владелец должен видеть, что и когда выполняется. +3. **Запуск в терминале**, как вход в A57 — владелец видит ход и результат. Использовать существующий `find_terminal_emulator`, заново не писать. +4. **После выполнения состояние пересчитывается** и показывается новое. +5. **Отказ запуска доходит текстом**, с указанием пути и причины. + +## P0-5. Обновление CLI + +1. **Показывать установленную версию** `agy`. Не удалось определить — `Н/Д` с причиной. +2. **Кнопка обновления** выполняет `agy update` в терминале. +3. **Предупредить о порядке**: обновление перезаписывает файл и снимает патч, поэтому сначала обновление, потом патч. Это подсказка в интерфейсе, а не комментарий в коде. + +## P0-6. Проверка исполнением + +1. **Определить состояние на настоящем `agy` владельца** и приложить вывод. +2. **Проверить все три состояния**, третье — на файле другой версии. +3. **Проверить, что хаб файл не изменил**: контрольная сумма до и после определения состояния совпадает. +4. **Проверить кнопку** на незаданном пути и на неверном. + +## P0-7. Аудит вторым проходом + +1. **Убедиться, что хаб не пишет в исполняемый файл** ни на одном пути. +2. **Проверить, что «определить не удалось» не выдаётся за «не пропатчен»** — это разные вещи, и путать их нельзя. +3. **Проверить, что нет опроса в цикле.** +4. **Побочные изменения** объяснить. +5. **Пропущенный пункт назвать пропущенным.** + +--- + +## Ограничения + +- Хаб не изменяет чужие исполняемые файлы и не выполняет загруженный из сети код. +- Поддержку прокси из `fa7bbef` не удалять. +- Правки ревьюера из `main` не откатывать. +- Фронтенд без npm, без сборки, без фреймворков — по `docs/web-api/CONTRACT.md` §1. +- Пути и версии в код не зашивать: определять и сообщать, что проверяли. +- Версию `0.1.3` не понижать. +- Правило честности без исключений: неопределённое — `Н/Д` с причиной. + +## Критерии приёмки + +1. Ветка в `origin`, `git status` чист. +2. Состояние проверки определяется на настоящем `agy`; вывод приложен. +3. Три состояния различаются; «определить не удалось» называет причину. +4. Контрольная сумма исполняемого файла до и после определения совпадает. +5. Смена состояния после обновления `agy` попадает в журнал и видна в интерфейсе. +6. Кнопка запускает указанный владельцем сценарий в терминале; путь не задан — кнопки нет. +7. Показывается версия `agy`; есть кнопка `agy update` с предупреждением о порядке. +8. Опроса в цикле нет. +9. `ruff check .` чисто; релизный гейт 10/10; тестов не меньше **704**. +10. Отчёт: `START_HEAD`, `FINAL_HEAD`, `origin/main`, `git status`, `X passed / Y skipped / Z failed`. + +## Главное + +Владелец теряет время не на сам обход, а на то, что узнаёт о слетевшем патче случайно — посреди работы, по невнятному отказу. Хаб для того и нужен, чтобы состояние было видно заранее. + +Поэтому хаб **смотрит и говорит**, а действие остаётся за владельцем и выполняется его собственным средством. Патчить чужой бинарник самому хабу нельзя: подпись привязана к версии, любое обновление её ломает, и отлаживать пришлось бы чужой код внутри своего. + +## Порядок сдачи +Передать точный `FINAL_COMMIT_SHA`.