hermes-hub/agents/inbox/2026-08-25-A31-preflight-state-batching-pii.md
Hermes Team d6ec34d482 docs(agents): задание A31 — проверка готовности, состояние прогона, батчинг, персональные данные
Владелец передал набор описаний субагентов. Ревьюер сверил каждое с кодом:
большая часть уже реализована в Hermes Hub и сильнее шаблонов. Model Router —
это сам Hub; Retry & Fallback — router_engine с цепочками и порогами квот из
A26; Coordinator в части конфликтов доступа — LeaseManager с max_concurrency,
настраиваемым на профиль. Всё это внесено в задание таблицей «не
реализовывать заново», чтобы к вопросу не возвращались.

В работу вошло только отсутствующее:

- роль «Проверяющий готовность»: проект терял раунды на коде 12 установщика,
  неустановленных fastapi/uvicorn, обязательном --effort и отсутствующем
  ag_slot_oauth.py — всё это выяснялось посреди прогона;
- состояние прогона для workflow из A30, как механика, а не роль;
- ограничение одновременных вызовов и контекст для локальных моделей: на
  сервере владельца два llama.cpp с --parallel 1 и почти исчерпанной памятью;
- маскирование почт: sanitize_snapshot вычищает секреты, но слово email в
  server.py не встречается ни разу, а хаб теперь открыт в домашнюю сеть
  поверх HTTP.

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

Выполнять после A28, A29 и A30.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-25 19:26:12 +07:00

15 KiB
Raw Permalink Blame History

Задание A31: проверка готовности, состояние прогона, батчинг и персональные данные

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

2026-08-25

База

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

Ветка

antigravity/preflight-state-batching

Когда выполнять

После A28, A29 и A30. Задание дорабатывает то, что они закладывают, и раньше их начинать нельзя: пункты P0-1 и P0-2 опираются на реестр ролей из A28 и на механику workflow из A30.

Два прохода: Flash реализует, Pro проводит аудит. Пункт P0-6 написан для аудитора.


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

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

В main напрямую не пушить.


Откуда взялось

Владелец передал набор описаний субагентов (Скиллы/, 13 файлов). Ревьюер сверил каждое с текущим кодом. Большая часть уже реализована в Hermes Hub и сильнее шаблонов — их брать не нужно, и это зафиксировано ниже, чтобы к вопросу не возвращались. В задание вошло только то, чего действительно нет.

Что уже есть — не реализовывать заново

Шаблон Что в проекте вместо него
Model Router Сам Hub: route_request, цепочки по ролям, обнаружение моделей, set_model
Retry & Fallback Agent router_engine: цепочки, max_failover_attempts, cooldown, здоровье по семействам, пороги квот из A26
Coordinator (конфликты доступа) LeaseManager, max_concurrency на профиль — router_config.py:21, применяется в router_engine.py:217
Tool Router Маршрутизация инструментов — дело Hermes Agent, а не Hub
Test Agent Дублирует роль tester из A28
Retriever / Chunker / QA RAG по базе знаний; Hermes Hub не про это
Lyrics-to-Structure, Timing & Pacing, Multimodal Validator Музыка и озвучка, к продукту отношения не имеют

P0-1. Роль «Проверяющий готовность» (Dependency Agent)

Тринадцатая роль в реестре A28.

Обязанности: до начала задачи убедиться, что на месте всё необходимое — исполняемые файлы и CLI, библиотеки, учётные данные, права доступа, доступность локальных серверов. Сообщить о нехватке до запуска, а не посреди прогона.

Обоснование не теоретическое. Проект терял раунды ровно на этом:

  • установщик падал с кодом 12, потому что проверочный скрипт был заморожен на 16 профилях;
  • веб-сервер не стартовал на Windows: установщик не ставил fastapi и uvicorn;
  • gemini отказывался работать без --effort, когда карта моделей была пуста;
  • гайд владельца вёл копировать scripts/ag_slot_oauth.py, которого нет ни в репозитории, ни в истории git.

Требуется:

  1. Роль заведена в реестре с описанием обязанностей, видимым в интерфейсе.
  2. Набор проверок реальный и исполняемый: наличие agy, fastapi, uvicorn, доступность настроенных локальных серверов, наличие учётных данных у профилей в цепочках ролей.
  3. Результат — список с причинами, а не «всё плохо». Каждая непройденная проверка называет, чего именно не хватает и что с этим делать.
  4. Проверка не должна ходить в сеть к платным провайдерам и жечь квоту.

P0-2. Состояние прогона (State Manager)

Не отдельная роль, а механика внутри workflow из A30. Заводить агента с таким именем не нужно.

Workflow из A30 идёт итерациями с возвратами на доработку. Прогон может прерваться: сервер перезапустили, обновление установилось, машина ушла в перезагрузку. Сейчас всё это теряется.

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

Осторожно: состояние прогона не должно содержать секретов. Смотри P0-4.

P0-3. Батчинг и контекст для локальных моделей

Дополняет A25, который уже влит: adapters/local_adapter.py на месте.

Известное про сервер владельца, снято ревьюером при разведке — заново не выяснять:

192.168.1.81   два сервера llama.cpp, оба OpenAI-совместимые
порт 8081      Qwen3.8-27B-Q4_K_M, reasoning on, контекст 65536
порт 8082      Qwen3-4B-Instruct-2507, reasoning off
оба            --parallel 1, то есть один запрос за раз
видеокарта     Tesla V100-PCIE-32GB, занято 28.7 из 32.7 ГБ

--parallel 1 означает: второй запрос встаёт в очередь. Механизм ограничения у нас есть — LeaseManager с max_concurrency. Требуется убедиться, что для локальных профилей он выставлен в 1 из конфигурации, а не по случайному совпадению с умолчанием, и что при занятом сервере маршрутизация уходит к следующему профилю, а не ждёт.

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

Не выдумывать пределы. Длину контекста и предел одновременных запросов берите у сервера через /v1/models и настройки профиля, а не подставляйте «разумные» числа.

P0-4. Персональные данные в снапшоте

Проверено исполнением: sanitize_snapshot в web/server.py вычищает секреты — access_token, refresh_token, api_key, JWT, Bearer. Почты не маскируются вовсе: слово email в файле не встречается ни разу.

Раньше это было приемлемо: хаб слушал 127.0.0.1. Сейчас у владельца он открыт в домашнюю сеть по 0.0.0.0 с токеном, поверх HTTP. Почты всех подключённых аккаунтов уходят по сети открытым текстом.

Контракт (раздел 3, пункт 4) фиксирует: маскирование — решение владельца, по умолчанию отдаём как есть, потому что интерфейс без опознания аккаунта бесполезен.

Требуется предложить владельцу выбор, а не решить за него:

  1. Настройка маскирования почт в снапшоте: полностью, частично (v***@gmail.com) или как есть.
  2. При включённом маскировании интерфейс обязан оставаться пригодным: аккаунты должны различаться между собой.
  3. Умолчание обосновать в отчёте.

Секреты маскируются всегда и настройке не подлежат.

P0-5. Честность агента контроля затрат

Роль cost-controller заводится в A28. Здесь — предупреждение, которое ей необходимо, иначе она будет врать.

Проверено: поля prompt_tokens, completion_tokens, total_tokens в telemetry_service существуют, но провайдеры их не отдают — в аналитике владельца стоит «Н/Д (не отдаются)».

Значит расход токенов агент может только оценивать. Требуется:

  1. Оценка обозначается как оценка. Не выдавать её за измерение.
  2. Где провайдер всё же вернул настоящие числа — показывать их отдельно от оценок и помечать.
  3. Порог бюджета, построенный на оценке, срабатывает — но владелец должен видеть, что решение принято по оценке.

Это то же правило, что уже дважды спасало проект: отсутствие данных не выдаётся за данные.

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

  1. Выдуманные значения. Особый риск в P0-3 (пределы контекста) и P0-5 (расход токенов). Ни одного числа, которого не дал провайдер или измерение.
  2. Проверки готовности должны действительно исполняться, а не возвращать заранее заготовленный успех. Запустить при намеренно сломанном окружении и убедиться, что причина названа верно.
  3. Состояние прогона не содержит секретов — проверить содержимое отдельно.
  4. Маскирование не ломает интерфейс: аккаунты остаются различимыми.
  5. Побочные изменения объяснить.
  6. Пропущенный пункт назвать пропущенным.

Ограничения

  • Десктоп (router/ui/**) не трогать.
  • Не реализовывать заново то, что перечислено в таблице выше как существующее.
  • State Manager — механика внутри workflow, а не роль в реестре.
  • Действия только через существующий action_handler; новые — с правкой docs/web-api/CONTRACT.md.
  • Правило честности без исключений.
  • Тег v0.1.1 не создавать.

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

  1. Ветка в origin, git status чист.
  2. Роль «Проверяющий готовность» заведена; проверки исполняются по-настоящему; при сломанном окружении названа верная причина — приложить вывод.
  3. Прогон workflow переживает перезапуск хаба либо честно сообщает о прерывании с причиной; проверено.
  4. Состояние прогона не содержит секретов; проверено отдельно.
  5. Для локальных профилей ограничение одновременных вызовов равно 1 и задано конфигурацией; при занятом сервере маршрутизация уходит дальше, а не ждёт; проверено.
  6. Пределы контекста берутся у сервера, а не зашиты.
  7. Маскирование почт настраивается, умолчание обосновано, аккаунты остаются различимыми.
  8. Оценка расхода токенов обозначена как оценка и отличима от измеренных значений.
  9. Ни одного выдуманного значения; проверено отдельно.
  10. ruff check . чисто; релизный гейт не ухудшен.
  11. Отчёт: START_HEAD, FINAL_HEAD, origin/main, git status, X passed / Y skipped / Z failed.

Главное

Четыре доработки, каждая закрывает известную боль: прогон падает посреди работы из-за отсутствующей зависимости; длинный workflow теряется при перезапуске; локальные модели встают в очередь; почты уходят по сети открытым текстом.

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

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