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>
This commit is contained in:
parent
1a21c8b1a8
commit
d6ec34d482
1 changed files with 171 additions and 0 deletions
171
agents/inbox/2026-08-25-A31-preflight-state-batching-pii.md
Normal file
171
agents/inbox/2026-08-25-A31-preflight-state-batching-pii.md
Normal file
|
|
@ -0,0 +1,171 @@
|
|||
# Задание 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`.
|
||||
Loading…
Reference in a new issue