# Задание A3 (Antigravity): релиз, честность контракта, оставшиеся долги ## Дата поступления 2026-08-21 ## База Проверочный HEAD: **`2035c14`**, `origin/main` = `2035c14`. Перед началом `git fetch`, зафиксировать фактический `BASE_SHA`. ## Ветка `antigravity/release-readiness`. Ветки `state-layer` и `contract-gaps` влиты в `main`, их и связанные worktree можно удалить. --- ## Что принято по A2 Проверено исполнением: - **граница соблюдена** — в зоне Codex ни одного изменения; - **точечные события действительно появились**: все 11 объявленных констант имеют публикаторов (`ACCOUNT_ADDED/UPDATED/REMOVED/AUTH_CHANGED`, `QUOTA_UPDATED`, `ROUTING_UPDATED`, `AGENT_UPDATED`, `SYSTEM_READINESS_CHANGED`, три `REFRESH_*`), три невостребованные константы удалены. Это закрывает главный блокер интерфейса; - **происхождение тарифа доведено** до `ProfileViewModel` (`plan_code`, `plan_source`) — `PlanBadge` теперь можно показывать осмысленно; - **`AgentViewModel`** получил `session_id`, `active_quota_status`, `active_quota_label`; **`PipelineNode`** — `account_identity`, `quota_status`, `failover_reason`. Экраны «Команда» и «Маршрутизация» разблокированы; - **`seq` выставлен наружу**, поздний ответ отбрасывается, есть два теста с проверкой; - **решение по квотам сильнее, чем требовалось**: вместо имитации сбора baseline теперь `None` (данных нет), а реальные значения берутся из фактических 429 через `record_runtime_quota_error`, вызываемый из `router_engine.py:283`, с источником `runtime_event` и `is_estimated=False`. Честно и работоспособно без провайдерских API. Прогон: headless 167 passed, с UI-зависимостями 204 passed, ruff чисто, release gate PASSED. --- ## P0-1. Вернуть в контракт то, что было из него убрано Раздел «Backend gaps» заменён на «Closed Gaps & Audit Status (v1.1)», где перечислены закрытые пробелы 1, 2, 3, 6, 7, 8, 9, 10, 11. **Пробелы 4, 5 и 12 исчезли из документа, не будучи закрытыми.** - **Gap 12** — «латентность, RPS, проценты ошибок, стоимость и SLA отсутствуют; UI обязан показывать `Н/Д` или скрывать блок». Это была прямая инструкция интерфейсу, и она пропала ровно в тот момент, когда Codex начинает строить Dashboard. Без неё он вправе решить, что метрики существуют. - **Gap 4** — поверхностная неизменяемость снапшота. - **Gap 5** — политика `is_stale`. Похоже, фактически закрыт: в разделе 1 появилось «`True` … when background refresh is overdue (> 300s)». Если так — так и записать со ссылкой на коммит. Документ, из которого молча исчезают незакрытые ограничения, перестаёт быть контрактом. Нужен раздел, где **и** закрытые, **и** оставшиеся пробелы видны одновременно. Правило прежнее: пробел уходит из списка только вместе с коммитом, который его закрыл. ## P0-2. Релизный артефакт `package_url` из живого манифеста по-прежнему отдаёт **HTTP 404** — проверено на `2035c14`. Это единственный пункт A2, который не сдвинулся вообще. Порядок: build → checksum → upload artifact → verify → publish manifest → verify feed. Манифест не должен рекламировать несуществующий артефакт. `dist/checksums.txt` — только из `scripts/build_dist.py`. В GitHub Release должны лежать `hermes-hub-0.1.1.zip` и `HermesHubSetup.exe`. **Тег `v0.1.1` не создавать** — ставится отдельным решением после ручной проверки продукта. ## P1-3. Оставшиеся долги - **Комментарии `router_profiles.yaml`** — 5 строк → 2 при сохранении. Либо round-trip YAML, либо явная фиксация, что файл перезаписывается приложением. - **`HKCU` в тестах установщика** — `Registry.CurrentUser` используется дважды, переменными окружения реестр не перенаправляется. Вынести реальный запуск в integration-режим либо параметризовать ключ. - **Сериализация Antigravity** — `_AGY_INVOCATION_LOCK` держит вызовы профилей со своим auth по одному. Либо изоляция только через `USERPROFILE` без глобальной записи `gemini:antigravity`, либо осознанный долг с обоснованием. - **`fastapi` / `uvicorn`** остаются обязательными зависимостями, хотя `gui_server` живёт в `legacy/` и не поставляется. ## P2-4. Подготовка к ручной проверке Продукт ни разу не прогонялся человеком целиком. Подготовить то, что для этого нужно со стороны backend: - диагностическая команда, печатающая по каждому профилю: провайдер, идентичность, состояние авторизации, состояние квоты и источник данных; - в журнал событий писать факт переключения маршрута с причиной, чтобы failover было видно без отладчика. Не изобретать полноценный CLI — достаточно одной команды и корректных записей в журнале. --- ## Критерии приёмки 1. Ни один файл зоны Codex не изменён. 2. В контракте одновременно видны закрытые и оставшиеся пробелы; 4, 5 и 12 присутствуют с актуальным статусом. 3. `curl -I ` → HTTP 200, sha256 совпадает с загруженным артефактом; в Release лежат оба файла. 4. `dist/checksums.txt` генерируется скриптом, ручных правок нет. 5. Прогон **в обоих окружениях** — без UI-зависимостей и с `customtkinter`/`pillow`/`psutil`; обе команды и оба результата в отчёте. 6. `ruff check .` чисто; release gate PASSED **на финальном коммите**, без функциональных коммитов после него. 7. Отчёт: `START_HEAD`, `FINAL_HEAD`, `origin/main`, `git status`, точный `X passed / Y skipped / Z failed`, список оставшегося. ## Порядок сдачи Ревьюеру передать точный `FINAL_COMMIT_SHA` и не вести разработку поверх него до вердикта.