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>
8.1 KiB
Задание 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не создавать.
Критерии приёмки
- Ни один файл чужой зоны не изменён.
PlanBadgeотображается и различает известный тариф от выведенного.- Отсутствие данных о квоте отрисовано как отсутствие, а не как ноль; причина видна пользователю.
- Экран «Команда» показывает состояние квоты активного аккаунта агента.
- Экран «Маршрутизация» показывает причину переключения там, где она есть в состоянии.
- Устаревание снапшота видно пользователю.
- Тесты на каждый пункт: известный и выведенный тариф, корзина без данных против нулевой, причина переключения, устаревший снапшот.
- Прогон в обоих окружениях — без UI-зависимостей и с
customtkinter/pillow/psutil; обе команды и оба результата в отчёте. Прогон только headless не считается: ваши UI-тесты там пропускаются. ruff check .чисто; release gate не ухудшен.- Отчёт:
BASE_SHA,FINAL_SHA, изменённые файлы, что подключено, что осталось, раздел «Backend gaps».
Порядок сдачи
Передать точный FINAL_COMMIT_SHA и не вести разработку поверх него до вердикта.