From e8a404be035fa04b5f76e3e572c6539fba0e83e4 Mon Sep 17 00:00:00 2001 From: Hermes Team Date: Fri, 21 Aug 2026 08:16:44 +0700 Subject: [PATCH] =?UTF-8?q?docs(task):=20next=20Antigravity=20assignment?= =?UTF-8?q?=20=E2=80=94=20close=20the=20gaps=20its=20own=20contract=20decl?= =?UTF-8?q?ares?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Seven of the twelve backend gaps in UI_STATE_CONTRACT.md block the UI outright: no targeted event has a publisher, plan provenance never reaches ProfileViewModel, and AgentViewModel/PipelineNode lack the fields the Team and Routing screens need. Verified on c6876e9, alongside the release asset still returning 404 and YAML comment loss now at 5 to 2 rather than 5 to 0. Co-Authored-By: Claude Opus 5 --- ...8-21-A2-antigravity-close-contract-gaps.md | 126 ++++++++++++++++++ 1 file changed, 126 insertions(+) create mode 100644 agents/inbox/2026-08-21-A2-antigravity-close-contract-gaps.md diff --git a/agents/inbox/2026-08-21-A2-antigravity-close-contract-gaps.md b/agents/inbox/2026-08-21-A2-antigravity-close-contract-gaps.md new file mode 100644 index 0000000..98458c1 --- /dev/null +++ b/agents/inbox/2026-08-21-A2-antigravity-close-contract-gaps.md @@ -0,0 +1,126 @@ +# Задание A2 (Antigravity): закрыть пробелы контракта и релизную инфраструктуру + +## Дата поступления +2026-08-21 + +## База +Проверочный HEAD: **`c6876e9`**, `origin/main` = `c6876e9`. Перед началом `git fetch`, зафиксировать фактический `BASE_SHA`. + +## Ветка +`antigravity/contract-gaps`. Ветка `antigravity/state-layer` влита в `main` и больше не нужна — можно удалить вместе с worktree `../hermes-hub-state-layer`. + +--- + +## Что принято по Заданию A + +Проверено исполнением, претензий нет: + +- контракт `docs/UI_STATE_CONTRACT.md` опубликован первым коммитом, 7 разделов, честный раздел «Backend gaps»; +- граница работ соблюдена — в зоне UI ни одного изменения; +- **namespace-пакет устранён по корню**: добавлен `src/antigravity_provider/__init__.py`, `__path__` теперь содержит ровно один каталог, установленная копия из `%LOCALAPPDATA%` больше не подмешивается. Два теста, падавшие только в полном прогоне, проходят; +- мёртвые модули удалены (`capability_matrix`, `skill_registry`, `lifecycle_supervisor`, −532 строки) — это был допустимый вариант; +- честность источников квот сохранена: `baseline` 6, `provider_auth` 1, `unconfigured` 1, ни одного `*_api`; +- headless-прогон 165 passed, ruff чисто, release gate PASSED. + +**Исправлено ревьюером, не откатывать:** `0d9005f` изменил `start_profile_oauth` на 3-кортеж `(session_id, auth_url, port)` и обновил тесты, но не вызывающий код. Мастер распаковывал два значения, `ValueError` глушился обработчиком, и URL авторизации не появлялся — подключение Antigravity-аккаунта было сломано с того коммита. Исправлено в `39b1f92` вместе с полем `wizard.oauth_port`. Файл в зоне Codex, вам его не трогать, но знать нужно. + +--- + +## ГРАНИЦА РАБОТ + +Прежняя. Ваша зона — всё, кроме: + +``` +src/antigravity_provider/router/ui/** +src/antigravity_provider/router/hermes_hub_app.py +tests/test_ui_*.py +``` + +Codex параллельно выполняет фазы 2–6 по интерфейсу и опирается на контракт. **Любое расширение контракта — сначала документ, потом код**, иначе он будет писать против несуществующих полей. + +--- + +## Приоритет: пробелы, блокирующие интерфейс + +Эти пункты вы сами зафиксировали в разделе 7 контракта. Пока они открыты, Codex обязан рисовать «Н/Д» — то есть продукт остаётся полупустым. + +### P0-1. Точечные события никто не публикует (gap 9) + +Проверено на `c6876e9`: + +``` +publish(EVENT_REFRESH_STARTED 1 +publish(EVENT_REFRESH_FAILED 1 +publish(EVENT_SYSTEM_READINESS_CHANGED 1 + +EVENT_ACCOUNT_UPDATED публикаций: 0 +EVENT_ACCOUNT_ADDED публикаций: 0 +EVENT_QUOTA_UPDATED публикаций: 0 +EVENT_ROUTING_UPDATED публикаций: 0 +EVENT_AGENT_UPDATED публикаций: 0 +``` + +Константы объявлены, публикаторов нет — событийная модель существует только на бумаге, и любое изменение по-прежнему означает полный снапшот. Требование Задания A («изменение квоты одного аккаунта порождает событие с идентификатором аккаунта») не выполнено. + +Нужно: канонический публикатор для каждого объявленного события либо удаление константы, если событие не нужно. Тест: изменение квоты одного аккаунта публикует ровно одно событие с его `profile_id` и не порождает полного пересбора. + +### P0-2. Происхождение тарифа не доходит до `ProfileViewModel` (gap 6) + +Из-за этого Codex не может показать `PlanBadge` — компонент готов и не используется. Нужно довести до модели и тариф, и его происхождение, чтобы UI отличал «известно от провайдера» от «выведено эвристикой». + +### P0-3. `AgentViewModel` и `PipelineNode` неполны (gaps 7, 8) + +- `AgentViewModel` без активной сессии и квоты → экран «Команда» показывает пустые строки; +- `PipelineNode` без идентичности аккаунта, состояния квоты и причины переключения → экран «Маршрутизация» не может ответить на главный вопрос «почему переключились и что с резервом». + +Добавить поля и описать в контракте. Причину переключения брать из реального состояния маршрута, а не выводить задним числом. + +--- + +## P1. Достоверность данных + +### P1-4. Реальный сбор квот (gaps 1, 2) + +Сейчас **ни один провайдер** не отдаёт живых чисел: все корзины `baseline`. Структура мульти-корзин у Antigravity есть, значения и время сброса не измеряются. + +Довести реальный сбор там, где провайдер это отдаёт. Правила прежние: локально вычисленное не помечать источником провайдера, отсутствие данных отдавать как отсутствие, а не как число. Для каждого провайдера в контракте указать, что именно теперь измеряется. + +### P1-5. Свежесть и защита от устаревшего ответа (gaps 3, 10, 11) + +Вы сами отметили: `seq` наружу не выставлен, вложенные квотные воркеры могут перестроить состояние до завершения, а `seq` записывается **до** окончания медленной работы — то есть доказательства, что поздний ответ не перезапишет свежий, нет. + +Нужно: публичный `seq` в снапшоте, запись `seq` по завершении работы, тест с искусственной задержкой, где поздний ответ гарантированно отбрасывается. + +### P1-6. Релизная инфраструктура + +`package_url` из живого манифеста по-прежнему отдаёт **HTTP 404** — проверено сейчас. Порядок публикации: build → checksum → upload artifact → verify → publish manifest → verify feed. Манифест не должен рекламировать несуществующий артефакт. `dist/checksums.txt` — только из `scripts/build_dist.py`. + +**Тег `v0.1.1` не создавать.** + +--- + +## P2. Долги + +- **Комментарии `router_profiles.yaml`** — стало лучше (было 5 → 0, теперь 5 → 2), но потеря остаётся. Либо round-trip YAML, либо явная фиксация долга с указанием, что файл перезаписывается приложением. +- **`HKCU` в тестах установщика** — `Registry.CurrentUser` по-прежнему используется дважды; переменными окружения реестр не перенаправляется. Вынести реальный запуск в явный integration-режим либо параметризовать ключ. +- **Сериализация Antigravity** — `_AGY_INVOCATION_LOCK` держит вызовы профилей со своим auth по одному. Либо отказаться от глобальной записи `gemini:antigravity` в пользу изоляции через `USERPROFILE`, либо записать как осознанный долг с обоснованием. +- **`fastapi`/`uvicorn`** остаются обязательными зависимостями, хотя `gui_server` живёт в `legacy/` и не поставляется. Привести в соответствие. + +--- + +## Критерии приёмки + +1. Ни один файл зоны Codex не изменён. +2. Для каждого объявленного события есть публикатор либо константа удалена; тест доказывает точечность. +3. `PlanBadge` можно показать: тариф и его происхождение доходят до `ProfileViewModel`. +4. `AgentViewModel` и `PipelineNode` содержат поля, которых требуют экраны «Команда» и «Маршрутизация». +5. Раздел «Backend gaps» контракта сокращён; по каждому закрытому пункту указан коммит. Что осталось — осталось честно. +6. Ни одно локально вычисленное значение не помечено источником провайдера. +7. Поздний ответ не перезаписывает свежий — доказано тестом с задержкой, а не порядком строк. +8. `curl -I ` → HTTP 200, sha256 совпадает с артефактом. +9. Прогон **в обоих окружениях**: без UI-зависимостей и с установленными `customtkinter`, `pillow`, `psutil`. Оба зелёных, обе команды и оба результата в отчёте. +10. `ruff check .` чисто; release gate PASSED **на финальном коммите**, без функциональных коммитов после него. +11. Отчёт содержит `START_HEAD`, `FINAL_HEAD`, `origin/main`, `git status` и точный `X passed / Y skipped / Z failed`. + +## Порядок сдачи +Ревьюеру передать точный `FINAL_COMMIT_SHA` и не вести разработку поверх него до вердикта.