hermes-hub/agents/inbox/2026-09-02-A58-agy-eligibility-state.md
Hermes Team 7b36538ded docs(agents): задание A58 — хаб видит состояние проверки доступности agy
Владелец теряет время не на сам обход, а на то, что узнаёт о слетевшем патче
случайно, по невнятному отказу посреди работы.

Установлено ревьюером: строки отказа в бинарнике нет — её присылает сервер, но
отказывается работать клиент. Прокси не помогает, измерено на двух странах:
ограничение привязано к аккаунту. Патчер владельца правит четыре байта машинного
кода, подменять в настройках нечего.

Хаб только читает и сообщает; действие остаётся за владельцем и выполняется его
собственным средством. Патчить чужой бинарник хабу запрещено отдельным пунктом.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-02 00:58:26 +07:00

151 lines
12 KiB
Markdown
Raw Permalink 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.

# Задание 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`.