hermes-hub/agents/inbox/2026-08-24-A23-recovery-and-model-validation.md
Hermes Team 9c6a4e8f6d docs(task): A23 — самовосстановление профилей и честная проверка моделей
Написано под схему владельца: Flash реализует, Pro проводит аудит.
Пункт P0-4 — чек-лист для второго прохода, составлен из дефектов,
которые уже проходили мимо первого.

P0-1: mark_auth_required ставит состояние без срока истечения, а
маршрутизация пропускает нездоровый профиль — успеха не случится,
отметка не снимется никогда. Подтверждено: после починки авторизации в
A22 все шесть профилей Antigravity остались помечены, ревьюер снимал
отметки вручную.

P0-2: do_set_model пропускает проверку целиком при пустом кэше моделей.
Проверено — выдуманная модель записалась в конфигурацию владельца.
Отсутствие данных трактуется как разрешение.

P0-3: ручного обновления списка моделей нет с A18.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-24 01:35:52 +07:00

13 KiB
Raw Permalink Blame History

Задание A23: самовосстановление профилей и честная проверка моделей

Дата поступления

2026-08-24

База

Проверочный HEAD на момент выдачи: 45fd01a.

Ветка

antigravity/recovery-and-validation

Порядок исполнения

Задание выполняется в два прохода, как прошлый раз:

  1. Flash реализует.
  2. Pro проводит аудит и правит найденное.

Схема себя оправдала: в A22 второй проход поймал ложную инструкцию в веб-клиенте. Пункт P0-4 написан специально для аудитора — он же приёмка.


Порядок работы с git

cd <каталог репозитория>; git fetch origin --prune; git status
git checkout main; git pull --ff-only origin main
git checkout -b antigravity/recovery-and-validation
git commit -m "..."          <- сначала коммит
git push -u origin antigravity/recovery-and-validation

В main напрямую не пушить: работа A20 ушла туда минуя ревью. В конце — push и проверка git log --oneline -1 origin/antigravity/recovery-and-validation, git status чистый.


Что принято по A22

Задача решена, все три доказательства получены проверкой ревьюера:

1. agy models через профиль  -> 14 моделей, включая gemini-3.1-pro-high
2. adapter.invoke(ag-w1)     -> модель ответила «ОК»
3. route_request             -> переключение codex-worker-1 -> ag-w1, ответ получен

Реализация аккуратная: видимая консоль на Windows через CREATE_NEW_CONSOLE, терминалы на Linux, HOMEDRIVE выставляется корректно. Пересохранение профиля не трогает глобальный ~/.gemini — проверено.

Исправлено ревьюером при слиянии: инструкция в веб-клиенте вела на несуществующий launcher/main.py; тест проверял дословную формулировку и падал при её правке.

Отменённое утверждение — прочитать обязательно

agents/inbox/2026-08-24-CORRECTION-gemini-model-names.md.

Ревьюер четырежды написал, что gemini-3.7-flash «у провайдера не существует». Это неверно. Модель настоящая, уровень усилия у неё — отдельный параметр. Дефект был в коде: _model_supported_efforts вызывала обнаружение без профиля, карта усилий оставалась пустой, подстановка уровня по умолчанию не срабатывала. Исправлено, gemini-3.7-flash работает без указания усилия.

Конфигурацию владельца по этому поводу не править.


P0-1. Отказ авторизации — состояние без выхода

Проверено исполнением, дефект подтверждён.

health_tracker.mark_auth_required (строка 376) ставит overall_state = AUTH_REQUIRED и не задаёт ни срока истечения, ни reset_at:

def mark_auth_required(self, profile_id, reason=None):
    record.overall_state = AUTH_REQUIRED
    record.last_error = reason
    self._save_state()

Сравните с квотой: у неё reset_at есть, и состояние само рассасывается.

Дальше замыкается круг: маршрутизация пропускает нездоровый профиль (skipped_unhealthy), значит успешного вызова по нему не случится, значит mark_success не вызовется, значит состояние не снимется. Никогда.

Это не теория. После того как A22 починил авторизацию, все шесть профилей Antigravity остались помечены и пропускались — ревьюер вручную вызывал clear_cooldown, иначе третье доказательство не прошло бы. Владелец такой команды не знает и знать не должен.

Требуется путь наружу. Варианты на выбор, обосновать в отчёте:

  • срок истечения у AUTH_REQUIRED, как у квоты;
  • периодическая перепроверка помеченных профилей — редкая, чтобы не жечь квоту;
  • снятие отметки при событии, которое достоверно означает починку: успешный вход через мастер, обновление учётных данных профиля.

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

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

Сейчас на машине владельца: 2 «Работает», 6 «Не проверялся», 11 «Аккаунт не добавлен», 3 «Отключён».

P0-2. Проверка модели молча отключается

do_set_model валидирует модель по обнаруженному списку — логика написана верно:

if discovered is not None:
    if model not in discovered and model not in canonical and model not in canonical_short:
        return False, f"Модель '{model}' отсутствует в списке..."

Но при пустом кэше discovered равен None, проверка пропускается целиком, и проходит что угодно. Ревьюер убедился: do_set_model('ag-w1','такой-модели-нет') вернул успех и записал это в конфигурацию владельца. Запись убрана вручную.

Это ровно тот класс дефекта, с которым проект борется с первого аудита: отсутствие данных трактуется как разрешение.

Требуется:

  1. При пустом кэше — не молчать. Либо отказать с внятной причиной, либо сохранить с явной пометкой «модель не подтверждена» и показать это в интерфейсе. Молчаливое согласие недопустимо.
  2. Прогревать кэш перед проверкой, если его нет. Кэш на диске уже реализован (models_cache.json), обнаружение работает — не хватает только вызова в нужный момент.
  3. Учесть при сравнении, что в обнаруженном списке идентификаторы склеенные (gemini-3.7-flash-high), а в конфигурации может стоять базовое имя (gemini-3.7-flash). Базовое имя — валидно. Не отвергать его.

Тесты: несуществующая модель отклоняется при наполненном кэше; при пустом кэше поведение осознанное и проверяемое; базовое имя без суффикса усилия принимается.

P0-3. Ручное обновление списка моделей

Действия обновления моделей нет ни среди действий, ни в интерфейсе — пункт остаётся невыполненным с A18.

Добавить действие обновления и кнопку рядом с выбором модели. Обнаружение ходит в сеть и подпроцесс: выполнять в фоне, интерфейс не блокировать, показывать ход.

Замерено: agy models отвечает за десятки секунд, а иногда висит дольше двух минут. Таймаут обязателен, прежний кэш при таймауте не затирать.

P0-4. Аудит вторым проходом

Это пункт для проверяющего. Схема Flash → Pro уже поймала один дефект в A22; ниже то, на что смотреть в первую очередь.

  1. Запустить то, что изменено. В A15 вынесли действия и уничтожили класс приложения: модуль импортировался, тесты проходили, а launch_hub() упал бы с NameError. Импорт ничего не доказывает — Python примет и недостижимый код.
  2. Проверить тексты, которые видит владелец. В A22 инструкция вела на несуществующий файл. Каждый путь и каждая команда в сообщениях интерфейса должны существовать.
  3. Проверить утверждения отчёта, а не поверить им. По A8 отчёт назвал сделанными четыре вещи, из которых ни одна не работала.
  4. Проверить, что тесты проверяют суть, а не формулировку. Два теста уже падали от переписанного текста при верном поведении.
  5. Пропущенный пункт назвать пропущенным. Дважды главные пункты задания оставались нетронутыми, и выяснялось это только при проверке файлов.

Ограничения

  • Ваши файлы: health_tracker.py, router_engine.py, action_handler.py, model_discovery*, unified_health.py, router/ui/**, router/web/**, соответствующие тесты.
  • Не откатывать: правку усилий из 45fd01a, родной вход agy из A22, прогрев квот в веб-сервере.
  • Никаких статусов и значений без основания. Нет данных — сказать об этом, а не пропустить проверку.
  • Конфигурацию владельца литералами не править.
  • Тег v0.1.1 не создавать.

Критерии приёмки

  1. Ветка в origin, в main напрямую не пушилось, git status чист.
  2. Профиль с AUTH_REQUIRED возвращается в маршрутизацию после починки учётных данных без ручного вмешательства; проверено тестом.
  3. Выбранный способ выхода из состояния обоснован в отчёте.
  4. do_set_model не пропускает непроверенную модель молча; поведение при пустом кэше осознанное; базовое имя без суффикса усилия принимается. Три теста.
  5. Есть ручное обновление списка моделей; интерфейс не блокируется; таймаут не затирает кэш.
  6. Второй проход выполнен, в отчёте перечислено, что проверялось по пунктам P0-4 и что найдено.
  7. ruff check . чисто; релизный гейт не ухудшен.
  8. Отчёт: START_HEAD, FINAL_HEAD, origin/main, git status, X passed / Y skipped / Z failed. На main сейчас 359 passed, 2 skipped.

Главное

Antigravity наконец работает. Осталось, чтобы он не выпадал навсегда после единственного сбоя авторизации и чтобы выбор модели не соглашался на всё подряд, когда сравнить не с чем.

Порядок сдачи

Передать точный FINAL_COMMIT_SHA. Сдано только после появления коммита в origin.