# Задание 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 <package_url>` → 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` и не вести разработку поверх него до вердикта.
