docs(task): next Antigravity assignment — close the gaps its own contract declares
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>
This commit is contained in:
parent
c6876e96b2
commit
e8a404be03
1 changed files with 126 additions and 0 deletions
126
agents/inbox/2026-08-21-A2-antigravity-close-contract-gaps.md
Normal file
126
agents/inbox/2026-08-21-A2-antigravity-close-contract-gaps.md
Normal file
|
|
@ -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 <package_url>` → 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` и не вести разработку поверх него до вердикта.
|
||||
Loading…
Reference in a new issue