Проверено исполнением, оба главных пункта закрыты.
P0-1, восстановление после отказа авторизации: выбран самый честный из
предложенных вариантов — снятие отметки по событию починки, а не по
таймеру. HealthTracker подписывается на EVENT_ACCOUNT_ADDED и
EVENT_ACCOUNT_AUTH_CHANGED. Проверено: профиль с AUTH_REQUIRED после
события возвращается в строй без ручного вмешательства.
P0-2, проверка моделей. Выдуманная модель отклоняется; базовое имя
gemini-3.7-flash принимается (поправка учтена); склеенное
gemini-3.1-pro-high тоже. Главное — при ПУСТОМ кэше выдумка больше не
проходит: молчаливое согласие устранено.
P0-3, ручное обновление списка моделей: действие refresh_models плюс
кнопка в клиенте.
Исправлено при слиянии:
1. Блокировка файла состояния была переведена с неблокирующей на
БЕСКОНЕЧНО блокирующую. Исходный вариант был неверен — при неудаче
исключение проглатывалось и запись шла без блокировки, — но
бесконечное ожидание хуже: на Unix flock(LOCK_EX) висит вечно, и один
застрявший держатель подвесил бы приложение целиком. Впереди
Linux-сервер. Ожидание ограничено 5 секундами, дальше честный отказ.
Проверено: 6 потоков по 5 записей — 0.11 с, ошибок нет.
2. Действие refresh_models не было занесено в контракт. Ровно тот дрейф,
ради предотвращения которого контракт и существует. Контракт поднят
до 1.3, действий стало девятнадцать.
Тесты: 370 passed, ruff чисто.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
- Implemented 3-tier release feed status (MANIFEST_LIVE, PACKAGE_LIVE, PACKAGE_HASH_VERIFIED)
- Added reproducible package and checksum builder in scripts/build_dist.py
- Preserved user header comments across YAML saves in router_config.py
- Connected model_timeout_seconds, monitoring_interval_seconds, and auto_monitoring to runtime
- Guarded global gemini:antigravity credential swap with _AGY_INVOCATION_LOCK to eliminate concurrent subprocess race
- Added concurrency regression test in tests/test_antigravity_concurrency.py
- Added interprocess file locking (_FileLock) for router_state.json in health_tracker.py
- Sandboxed APPDATA and USERPROFILE in tests/test_installer.py
- Exported roadmap modules in router/__init__.py
- Verified 151 passing tests (100%) and 7/7 release gate checks
- Implemented HubSnapshot and central HubStateStore for normalized in-memory state caching (<0.05ms)
- Refactored AccountsView and RoutingView with reusable AccountCardWidget and RoutingRoleWidget to eliminate widget recreation
- Implemented central HermesRefreshScheduler with 5s tick, concurrency throttling, dedup, and spread initial delays
- Added typed EventBus with thread-safe UI main loop dispatching via root.after
- Implemented dynamic ModelRegistry with capability-based role requirements and multi-dimensional scoring
- Integrated Antigravity separate quota buckets (Claude vs Gemini) and same-account model fallback
- Enhanced SessionAffinityTracker with TTL expiration and LRU capacity bounds
- Eliminated long subprocess holding of _CM_LOCK and ensured Windows credential restoration in finally block
- Added FastAPI REST contracts in gui_server.py as foundation for future Tauri frontend
- Verified 100% pass across all 91 pytest tests and 7/7 release gate criteria