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 <noreply@anthropic.com>
11 KiB
Задание 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 строки) — это был допустимый вариант; - честность источников квот сохранена:
baseline6,provider_auth1,unconfigured1, ни одного*_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/и не поставляется. Привести в соответствие.
Критерии приёмки
- Ни один файл зоны Codex не изменён.
- Для каждого объявленного события есть публикатор либо константа удалена; тест доказывает точечность.
PlanBadgeможно показать: тариф и его происхождение доходят доProfileViewModel.AgentViewModelиPipelineNodeсодержат поля, которых требуют экраны «Команда» и «Маршрутизация».- Раздел «Backend gaps» контракта сокращён; по каждому закрытому пункту указан коммит. Что осталось — осталось честно.
- Ни одно локально вычисленное значение не помечено источником провайдера.
- Поздний ответ не перезаписывает свежий — доказано тестом с задержкой, а не порядком строк.
curl -I <package_url>→ HTTP 200, sha256 совпадает с артефактом.- Прогон в обоих окружениях: без UI-зависимостей и с установленными
customtkinter,pillow,psutil. Оба зелёных, обе команды и оба результата в отчёте. ruff check .чисто; release gate PASSED на финальном коммите, без функциональных коммитов после него.- Отчёт содержит
START_HEAD,FINAL_HEAD,origin/main,git statusи точныйX passed / Y skipped / Z failed.
Порядок сдачи
Ревьюеру передать точный FINAL_COMMIT_SHA и не вести разработку поверх него до вердикта.