diff --git a/agents/inbox/2026-08-23-A13-antigravity-pro-contract-stability.md b/agents/inbox/2026-08-23-A13-antigravity-pro-contract-stability.md new file mode 100644 index 0000000..765acc2 --- /dev/null +++ b/agents/inbox/2026-08-23-A13-antigravity-pro-contract-stability.md @@ -0,0 +1,138 @@ +# Задание A13 (Antigravity Pro, этот ПК): граница продукта и устойчивость тестов + +## Дата поступления +2026-08-23 + +## База +Проверочный HEAD на момент выдачи: **`9c0da36`**. + +## Ветка +`antigravity/contract-stability` + +--- + +## Порядок работы с git + +**В начале — обновить локальную копию:** + +``` +cd <каталог репозитория>; git fetch origin --prune; git status +git checkout main; git pull --ff-only origin main +git checkout -b antigravity/contract-stability +``` + +**Сразу после первого коммита — отправить ветку:** + +``` +git push -u origin antigravity/contract-stability +``` + +**В конце — push и проверка, что он прошёл:** + +``` +git push origin antigravity/contract-stability +git log --oneline -1 origin/antigravity/contract-stability +``` + +Последняя команда обязана показать ваш финальный коммит. + +**Отдельно и важно.** В прошлый раз работа была выполнена, но осталась незакоммиченной в рабочем каталоге, а в `origin` ушла пустая ветка — она указывала на тот же коммит, что и `main`. Ревьюер обнаружил правки случайно и восстановил их вручную. Инструкция «push ветку сразу» была выполнена буквально, а коммит забыт. **Push без коммита ничего не сохраняет.** Перед отчётом убедитесь, что `git status` показывает чистое дерево, а не список изменённых файлов. + +--- + +## Что принято по A11 + +Проверено исполнением — работа сделана и работает: + +- **Пропуск вызова без роли работает.** Замер на слитом коде: вызов в стиле Hermes без роли уходит вниз за **0.10 секунды**, цепочка не пробуется вовсе. Раньше каждый вызов Hermes шёл как `orchestrator` и тратил попытки на исчерпанную цепочку. Это главный пункт A11, и он закрыт. +- **Зонд обнаружения моделей переведён на `agy models`** вместо разбора ошибки заведомо неверной модели. +- **Выдуманный запасной список `gemini-2.5-*` убран** из адаптера — моделей с такими именами у провайдера нет. +- **`refresh_codex_token` появился** — обновления токена Codex не существовало вовсе. +- **`source` квоты больше не заявляет `provider_api`**, когда ни одна корзина не измерена; применено последовательно к `antigravity` и `opencode-go`. + +Замечание по обнаружению моделей: сейчас оно возвращает пустой список, но **не по вине кода**. Проверено прямым вызовом — `agy models` виснет и сам по себе (`rc=124` по таймауту 100 секунд), хотя часом раньше отвечал за 40 секунд. Зонд ведёт себя правильно: отдаёт пусто и сохраняет кэш вместо того, чтобы выдумать список. + +**Релизный гейт теперь зелёный, 7/7** — проверка 4 проходит. Она была красной несколько раундов подряд. + +Исправлено ревьюером при фиксации: тест `test_opencode_shows_published_limits` закреплял прежнюю семантику `source` и падал после вашей правки. Приведён к честной. Код был прав, тест — нет. + +--- + +## P0-1. Граница между учётными системами Hub и Hermes — единственный незакрытый пункт A11 + +`docs/UI_STATE_CONTRACT.md` не изменялся. Это тот пункт, ради которого владелец и задал вопрос, решив, что «хаб никак не привязан к гермесу». + +Что установлено и должно быть записано: + +Hermes ведёт **собственные** профили в каталоге `profiles` своего домашнего каталога: + +``` +agy-01 … agy-06, worker-fast, worker-research, worker-review, +worker-code, worker-code-2, deepseek +``` + +и настраивает `delegate_task` отдельно: `max_concurrent_children=3`, `provider=opencode-go`, `model=kimi-k2.7-code`. + +Профили Hub — `ag-w1`, `ag-orch-fallback`, `codex-orch`, `opengo-*`, теперь ещё `claude-*` и `grok-*` — **другое множество идентификаторов**. Один и тот же аккаунт Google живёт в двух учётных системах под разными именами: у Hermes он `agy-05`, у Hub `ag-w2`. + +**Требуется раздел в контракте**, отвечающий на четыре вопроса прямо: + +1. Что Hub получает от Hermes на каждом вызове. Перечислить фактически: `task_id`, `turn_id`, `api_request_id`, `session_id`, `platform`, `model`, `provider`, `base_url`, `api_mode`, `api_call_count`. И явно: **роли среди них нет.** +2. Чего Hub не видит: профиль Hermes, которым выполняется вызов; настройки `delegate_task`; состав субагентов. +3. Чем Hub управляет: собственными профилями, цепочками отказоустойчивости, квотами своих аккаунтов. +4. Чем не управляет: ничем из перечисленного в пункте 2. + +Без этого интерфейс, показывающий «команду агентов» и роли, вводит владельца в заблуждение — он видит на экране роли, которых Hermes не спрашивает, и разумно ожидает, что настройка роли на что-то влияет. + +## P0-2. Варианты связывания профилей Hub и Hermes + +**Подготовить варианты с ценой каждого. Решение принимает владелец. Молча не реализовывать.** + +Как минимум разобрать три: + +1. **Сопоставление по идентичности аккаунта** — email из `id_token`. У Hub он уже извлекается (`extract_jwt_identity` в `profile_manager.py`). Насколько надёжно сопоставляются профили Hermes по тому же признаку? Что делать с профилями без email — `worker-fast`, `deepseek`, ключи OpenCode? +2. **Чтение профилей Hermes как источника** — Hub перестаёт вести свой список и отражает список Hermes. Что при этом теряется: цепочки отказоустойчивости привязаны к профилям Hub, роли тоже. +3. **Явная таблица соответствия** — владелец сам связывает `agy-05` с `ag-w2`. Самое предсказуемое и самое ручное. + +По каждому: что становится возможным, что ломается, сколько работы, какие данные владельца затрагиваются. Формат — таблица плюс абзац рекомендации с обоснованием. + +## P0-3. Набор тестов нестабилен: семь ошибок на прогон + +Полный прогон на `main` даёт **309 passed и до семи ошибок**, причём **ошибки кочуют между файлами от запуска к запуску**: то `test_ui_contract_v11.py`, то `test_ui_mockup_redesign.py`, то `test_oauth_lifecycle.py`. Те же тесты **изолированно проходят**: + +``` +pytest tests/test_ui_contract_v11.py -> 9 passed +pytest -q -> 4 ERROR в этом же файле +``` + +Диагноз: исчерпание ресурсов Tk. В наборе **шесть отдельных вызовов `ctk.CTk()`** в пяти файлах, каждый создаёт свой корень интерпретатора Tcl. Сообщение — `TclError: ... This probably means that tk wasn't installed properly`, что к установке отношения не имеет. + +Это мешает работе прямо сейчас: **невозможно отличить настоящую поломку от шума.** За последние раунды каждый прогон приходилось перепроверять изолированно, и один раз настоящая поломка была замечена только со второго захода. + +**Требуется** один общий корень Tk на весь прогон: фикстура в `tests/conftest.py` с областью видимости `session`, к которой приводятся все UI-тесты; отдельные `ctk.CTk()` в тестовых файлах убираются. + +Осторожно: тесты, проверяющие поведение при уничтожении окна (`test_ui_wizard_finish.py` проверяет `winfo_exists() == 0` после `_finish`), должны продолжать работать — уничтожается дочернее окно, а не корень. + +**Критерий проверки:** десять полных прогонов подряд без единой ошибки. Не один — десять: дефект плавающий, и единственный зелёный прогон ничего не доказывает. + +--- + +## Ограничения + +- Параллельно идёт **A14** (интерфейс). Ваши файлы: `docs/**`, `tests/conftest.py`, `tests/test_ui_*.py` **только в части фикстуры корня Tk**, `src/antigravity_provider/router/**` кроме `ui/`. Не ваши: `router/ui/**` по существу, `installer/**`. +- Правку `2d62d39` и пропуск вызова без роли не откатывать. +- Никаких чисел и идентификаторов без измерения. +- Тег `v0.1.1` не создавать. + +## Критерии приёмки + +1. Ветка в `origin`, финальный коммит виден через `git log origin/antigravity/contract-stability`, `git status` чист. +2. В контракте есть раздел о границе Hub и Hermes, отвечающий на все четыре вопроса; явно сказано, что роль Hermes не передаёт. +3. Варианты связывания профилей поданы с ценой каждого и рекомендацией; ни один не реализован без решения владельца. +4. Десять полных прогонов `pytest -q` подряд без ошибок; вывод всех десяти в отчёте. +5. Тесты, проверяющие уничтожение окна, продолжают проходить. +6. `ruff check .` чисто; релизный гейт остаётся зелёным (7/7 на момент выдачи задания). +7. Отчёт: `START_HEAD`, `FINAL_HEAD`, `origin/main`, `git status`, точный `X passed / Y skipped / Z failed`. + +## Порядок сдачи +Передать точный `FINAL_COMMIT_SHA`. **Сдано только после появления коммита в `origin`** — проверьте командой перед отчётом. diff --git a/agents/inbox/2026-08-23-A14-antigravity-flash-accounts.md b/agents/inbox/2026-08-23-A14-antigravity-flash-accounts.md new file mode 100644 index 0000000..ef18993 --- /dev/null +++ b/agents/inbox/2026-08-23-A14-antigravity-flash-accounts.md @@ -0,0 +1,149 @@ +# Задание A14 (Antigravity Flash, другой ПК): компактные аккаунты и чистка разделов + +## Дата поступления +2026-08-23 + +## База +Проверочный HEAD на момент выдачи: **`9c0da36`**. + +## Ветка +`antigravity/accounts-compact` + +--- + +## Порядок работы с git + +**Шаг 1. В начале — обновить локальную копию:** + +``` +cd <каталог репозитория>; git fetch origin --prune; git status +git checkout main; git pull --ff-only origin main +git checkout -b antigravity/accounts-compact +``` + +**Шаг 2. После первого коммита — отправить ветку:** + +``` +git commit -m "..." <- сначала коммит +git push -u origin antigravity/accounts-compact +``` + +Именно в таком порядке. Push без коммита ничего не сохраняет: в прошлом раунде второй исполнитель отправил ветку, но забыл закоммитить, и его работа существовала только на диске. + +**Шаг 3. В конце — push и проверка:** + +``` +git push origin antigravity/accounts-compact +git status <- дерево должно быть чистым +git log --oneline -1 origin/antigravity/accounts-compact <- должен быть ваш финальный коммит +``` + +--- + +## Что принято по A12 + +Проверено исполнением: + +- **тест достижимости службы моделей написан правильно** — импортирует согласованный путь напрямую и падает при `ImportError`, а не глотает его. Именно это и требовалось: защитный `except ImportError` в интерфейсе прячет несобранную интеграцию, и теперь есть тест, который её не пропустит; +- тесты подключения Claude и Grok; +- упорядочивание пяти провайдеров, тест `test_dashboard_renders_all_five_providers_in_order`; +- причины у `Н/Д` в `providers_view`; +- скрипт съёмки скриншотов `scripts/capture_live_a12_screenshots.py`. + +Граница зоны не нарушена, слияние прошло без конфликтов. + +**Два главных пункта задания не выполнены**, и это задание — про них. + +--- + +## P0-1. Компактные карточки аккаунтов + +`accounts_view.py` **не менялся вообще**. В `components.py` — только мелкие правки уже существовавших ячеек квоты (`height=5` → `height=4`). Переделки нет. + +Жалобы владельца дословно: **«аккаунты должны выглядеть как у кокпит тулс, компактно»**, **«вид не тот, не надо делать раскрывающееся окно»**, **«в аккаунтах квота так и не отображается»**. + +Требуется: + +- плотный список **фиксированной высоты**: провайдер, идентичность, роль, состояние авторизации, квота — одной строкой, **без раскрытия**; +- **квота видна сразу**, числом и полосой, **с указанием пула и периода**. У Antigravity четыре пула, и «просто процент» вводит в заблуждение — надо `Claude/GPT — неделя`, а не `62%`; +- **шестнадцать аккаунтов читаются без прокрутки внутрь карточек**; +- **дельта-отрисовку по стабильным ключам не терять**: изменение одного аккаунта не перерисовывает остальные. + +Данные настоящие и уже приходят. Замер на живых аккаунтах владельца: + +``` +ag-w2 Claude/GPT — неделя осталось 37.4% source=provider_api +ag-w3 Claude/GPT — неделя осталось 90.1% source=provider_api +ag-w1 Gemini — неделя осталось 99.7% source=provider_api +``` + +Где данных нет — `Н/Д` с причиной, а не ноль и не голый прочерк. У `opencode-go` и `grok` провайдер лимитов не отдаёт, причина уже лежит в `unavailable_reason`. + +Про дельта-отрисовку: `COCKPIT_TOOLS_ARCHITECTURE_COMPARISON.md` в корне объясняет, почему это принципиально — при пересборке всех карточек на 50 аккаунтах выходит больше тысячи операций с виджетами в UI-потоке, и окно заметно подвисает. Документ — архитектурное сравнение, **не макет**: берите принцип обновления и плотность, не буквальную вёрстку. + +**Тест:** изменение квоты одного аккаунта не пересоздаёт виджеты остальных. + +## P0-2. Разобрать дублирующие разделы + +`quotas_view.py` не тронут, `providers_view.py` — десять строк. Решение не принято. + +Жалоба: **«провайдеры и квоты и лимиты вообще не понятно для чего нужны, там всё то же, что и в аккаунты»**. + +Владелец прав: после появления квот прямо в карточках аккаунтов отдельный раздел квот потерял смысл. Нужно **решение**, а не сохранение обоих на всякий случай. + +- **«Квоты и лимиты»** — убрать из навигации либо оставить только то, чего нет в «Аккаунтах»: сводка по провайдеру целиком, история расхода, ближайшие сбросы. Нет такого содержания — убрать раздел вместе с пунктом навигации. +- **«Провайдеры»** — оставить относящееся к провайдеру, а не к аккаунту: доступность runtime, обнаруженные модели, версия CLI, состояние авторизации в целом. + +В отчёте перечислить, что перенесено, что удалено и почему. **Пустой раздел не оставлять**: либо содержание, либо нет пункта навигации. + +## P0-3. Живая проверка со скриншотами + +Скрипт съёмки написан, но **скриншотов нет**. Задание без них не принимается — это правило действует с раунда B5 и оно не формальное: пустые состояния доказывают вёрстку, но не работоспособность. + +Нужны снимки **с настоящими данными**: + +1. «Аккаунты» — шестнадцать аккаунтов, видимые квоты с указанием пулов; +2. подключение Grok от начала до конца: выбор провайдера, авторизация, назначение роли, завершение; +3. окно роли с цепочкой и квотами; +4. «Обзор» после чистки разделов. + +По Grok: слоты уже есть, проверено — `find_free_slot("grok")` возвращает `grok-worker-1`, `find_free_slot("claude")` возвращает `claude-orch`. Мастер больше не должен упираться в «свободный слот не найден». Пройти **весь путь**, а не только выдачу слота: подключение, роль, появление в маршрутизации, тест профиля. + +Жалоба владельца была **«при подключении грока ошибка»** — закрывается только пройденным вживую сценарием. + +--- + +## Полезное к сведению + +- **Релизный гейт стал зелёным**, 7/7. Не ухудшать. +- **Набор тестов нестабилен**: полный прогон даёт до семи ошибок, которые кочуют между файлами, хотя изолированно те же тесты проходят. Причина — шесть отдельных корней Tk в наборе. Это **чинит A13**, вам с этим ничего делать не нужно, но знайте: если увидите ошибки в `test_ui_*` при полном прогоне, сначала проверьте файл изолированно, прежде чем искать дефект у себя. +- Обнаружение моделей сейчас отдаёт пустой список, потому что `agy models` виснет сам по себе (проверено прямым вызовом, `rc=124` по таймауту 100 секунд). Это не дефект интерфейса. Карточка обязана честно показывать «Список моделей ещё не получен», а не пустой выпадающий список без объяснения. + +## Ограничения + +- Параллельно идёт **A13**. Ваши файлы: `src/antigravity_provider/router/ui/**`, `tests/test_ui_*.py` по существу, `scripts/capture_live_*`. Не ваши: `docs/**`, `tests/conftest.py`, backend вне `ui/`. +- Не выдумывать числа, идентификаторы и названия моделей. +- Три темы сохранить, дельта-отрисовку не терять. +- Мастер не ломать: шесть потоков подключения, трёхэлементная распаковка `start_profile_oauth`, `destroy()` в `_finish` выполняется всегда. +- Сеть и подпроцессы — не в UI-потоке. +- Тег `v0.1.1` не создавать. + +## Критерии приёмки + +1. Ветка в `origin`, финальный коммит виден через `git log origin/antigravity/accounts-compact`, `git status` чист. +2. Карточка аккаунта компактна, фиксированной высоты, без раскрытия; шестнадцать аккаунтов читаются без внутренней прокрутки. +3. Квота видна сразу, с указанием пула и периода; где данных нет — причина. +4. Дельта-отрисовка сохранена; проверено тестом. +5. Принято решение по «Провайдерам» и «Квотам»; перенесённое и удалённое перечислено; пустых разделов и висящих пунктов навигации нет. +6. **Скриншоты всех четырёх сценариев с настоящими данными приложены.** +7. Grok подключается вживую: подключение, роль, маршрутизация, тест профиля. +8. Прогон в обоих окружениях; обе команды и оба результата в отчёте. +9. `ruff check .` чисто; релизный гейт остаётся 7/7. +10. Отчёт: `START_HEAD`, `FINAL_HEAD`, `origin/main`, `git status`, точный `X passed / Y skipped / Z failed`. + +## Главное + +Это последний крупный визуальный долг. Квоты настоящие, роли настраиваются, Grok разблокирован, гейт зелёный. Осталось, чтобы шестнадцать аккаунтов читались с одного взгляда и в интерфейсе не было разделов, про которые владелец спрашивает «а это зачем». + +## Порядок сдачи +Передать точный `FINAL_COMMIT_SHA`. **Сдано только после появления коммита в `origin`.**