docs(task): B3 — wire the contract v1.1 fields the UI never picked up
Codex built phases 2-6 against contract v1.0 while Antigravity shipped v1.1, so eight fields now exist in the snapshot and render nowhere: plan_code, plan_source, active_quota_status, active_quota_label, quota_status, failover_reason, unavailable_reason and seq. PlanBadge was built in phase 1 and still has nothing to display. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
2c612f22a0
commit
9ffc815ed5
1 changed files with 97 additions and 0 deletions
97
agents/inbox/2026-08-21-B3-codex-contract-v11-fields.md
Normal file
97
agents/inbox/2026-08-21-B3-codex-contract-v11-fields.md
Normal file
|
|
@ -0,0 +1,97 @@
|
||||||
|
# Задание B3 (Codex): подключить поля контракта v1.1
|
||||||
|
|
||||||
|
## Дата поступления
|
||||||
|
2026-08-21
|
||||||
|
|
||||||
|
## База
|
||||||
|
Проверочный HEAD: **`2c612f2`**, `origin/main` = `2c612f2`. Перед началом `git fetch` и обязательно подтянуть `main` — ваши фазы 2–6 уже влиты, поверх них есть правки.
|
||||||
|
|
||||||
|
## Ветка
|
||||||
|
`codex/contract-v11`. Ветка `codex/ui-redesign` влита в `main`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Что принято по фазам 2–6
|
||||||
|
|
||||||
|
Проверено исполнением, работа хорошая:
|
||||||
|
|
||||||
|
- граница соблюдена — вне вашей зоны только файл отчёта;
|
||||||
|
- **пересоздания виджетов не осталось нигде**: ни одного `winfo_children()` в `views/`, всё на стабильных ключах;
|
||||||
|
- **выдуманных метрик нет**, «Н/Д» используется в семи экранах;
|
||||||
|
- **views вообще не обращаются к backend** — ни `HubStateStore`, ни `scan_all`, ни сервисов; данные приходят только снапшотом;
|
||||||
|
- мастер подключения пережил слияние: трёхэлементная распаковка `start_profile_oauth` и `oauth_port` на месте;
|
||||||
|
- защита от краша при старте не только сохранена, но усилена — `update_data` выходит рано вместо отката к хранилищу.
|
||||||
|
|
||||||
|
Одна правка с моей стороны: инвариант `tests/test_view_startup_contract.py` требовал обращения к хранилищу и после вашей переделки начал скипаться для всех девяти views, то есть перестал защищать тот самый краш. Переписан под новый контракт — проверка `isinstance(snapshot, HubSnapshot)` теперь обязательна независимо от того, читает ли view хранилище.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Задача
|
||||||
|
|
||||||
|
Вы работали по контракту **v1.0**, а Antigravity параллельно выпустил **v1.1** и добавил поля, которых на тот момент не было. Данные в снапшоте есть, но интерфейс их не показывает. Проверено на `2c612f2`:
|
||||||
|
|
||||||
|
| Поле | Где появилось | Используется в UI |
|
||||||
|
|---|---|---|
|
||||||
|
| `plan_code` | `ProfileViewModel` | **0 файлов** |
|
||||||
|
| `plan_source` | `ProfileViewModel` | **0 файлов** |
|
||||||
|
| `active_quota_status` | `AgentViewModel` | **0 файлов** |
|
||||||
|
| `active_quota_label` | `AgentViewModel` | **0 файлов** |
|
||||||
|
| `quota_status` | `PipelineNode` | **0 файлов** |
|
||||||
|
| `failover_reason` | `PipelineNode` | **0 файлов** |
|
||||||
|
| `unavailable_reason` | `QuotaBucket` | **0 файлов** |
|
||||||
|
| `seq` | `HubSnapshot` | **0 файлов** |
|
||||||
|
| `session_id` | `AgentViewModel` | 1 файл |
|
||||||
|
| `account_identity` | `PipelineNode` | 4 файла |
|
||||||
|
| `is_estimated` | `QuotaSnapshot` | 2 файла |
|
||||||
|
|
||||||
|
Перечитайте `docs/UI_STATE_CONTRACT.md` целиком — он переписан, появился раздел «Provider Truth Matrix».
|
||||||
|
|
||||||
|
### 1. Тариф — `PlanBadge` наконец можно показать
|
||||||
|
|
||||||
|
Компонент вы сделали в PHASE 1, данные появились в v1.1. Показывать бейдж, когда `plan_source` говорит, что тариф известен от провайдера (`provider_api`, `jwt_claim`, `provider_auth`), и **не показывать** при `inferred`/`unknown` — либо показывать с явной пометкой, что значение выведено, а не получено. Пользователь должен отличать «PRO по данным провайдера» от «похоже на PRO».
|
||||||
|
|
||||||
|
### 2. Квоты — состояние без данных
|
||||||
|
|
||||||
|
`QuotaBucket.unavailable_reason` объясняет, **почему** данных нет. Сейчас пользователь видит пустоту без причины. Показывать причину в подсказке или подписи корзины.
|
||||||
|
|
||||||
|
Важно: по контракту baseline-значения теперь `None`, а не числа. Убедитесь, что `QuotaBar` и `QuotaBucketWidget` корректно отрисовывают именно отсутствие значения, а не «0 %» — ноль означает «квота исчерпана», это принципиально разные состояния.
|
||||||
|
|
||||||
|
### 3. Команда — состояние агента
|
||||||
|
|
||||||
|
`active_quota_status` и `active_quota_label` показывают, в каком состоянии квота у аккаунта, на котором сейчас работает агент. Это прямо отвечает на вопрос «сколько осталось у того, кто выполняет задачу».
|
||||||
|
|
||||||
|
### 4. Маршрутизация — причина переключения
|
||||||
|
|
||||||
|
`PipelineNode.failover_reason` и `quota_status` — то, ради чего экран существует: видно не только «активен резерв 1», но и почему ушли с основного. Показывать причину у узла, с которого произошло переключение.
|
||||||
|
|
||||||
|
### 5. Свежесть данных
|
||||||
|
|
||||||
|
`HubSnapshot.seq` и политика `is_stale` (по контракту — просрочка фонового обновления свыше 300 с). Показать пользователю, что данные устарели, вместо молчаливого показа старых значений.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Ограничения
|
||||||
|
|
||||||
|
- Граница прежняя: ваша зона — `src/antigravity_provider/router/ui/**`, `hermes_hub_app.py`, `tests/test_ui_*.py`. Остальное не трогать.
|
||||||
|
- Не добавлять сбор данных в UI. Не хватает поля — строка в разделе «Backend gaps» отчёта.
|
||||||
|
- Нет данных — «Н/Д» либо скрытый блок. Ноль и отсутствие значения не путать.
|
||||||
|
- Секреты маскировать, в логи не писать.
|
||||||
|
- Тег `v0.1.1` не создавать.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Критерии приёмки
|
||||||
|
|
||||||
|
1. Ни один файл чужой зоны не изменён.
|
||||||
|
2. `PlanBadge` отображается и различает известный тариф от выведенного.
|
||||||
|
3. Отсутствие данных о квоте отрисовано как отсутствие, а не как ноль; причина видна пользователю.
|
||||||
|
4. Экран «Команда» показывает состояние квоты активного аккаунта агента.
|
||||||
|
5. Экран «Маршрутизация» показывает причину переключения там, где она есть в состоянии.
|
||||||
|
6. Устаревание снапшота видно пользователю.
|
||||||
|
7. Тесты на каждый пункт: известный и выведенный тариф, корзина без данных против нулевой, причина переключения, устаревший снапшот.
|
||||||
|
8. Прогон **в обоих окружениях** — без UI-зависимостей и с `customtkinter`/`pillow`/`psutil`; обе команды и оба результата в отчёте. Прогон только headless не считается: ваши UI-тесты там пропускаются.
|
||||||
|
9. `ruff check .` чисто; release gate не ухудшен.
|
||||||
|
10. Отчёт: `BASE_SHA`, `FINAL_SHA`, изменённые файлы, что подключено, что осталось, раздел «Backend gaps».
|
||||||
|
|
||||||
|
## Порядок сдачи
|
||||||
|
Передать точный `FINAL_COMMIT_SHA` и не вести разработку поверх него до вердикта.
|
||||||
Loading…
Reference in a new issue