hermes-hub/src/antigravity_provider/router
ochenstarik-ui eac8352dc2 fix(release,web): ворота публикации перестали пропускать всё подряд, /api/action — межсайтовые запросы
P0 аудита, каждый сначала подтверждён исполнением, а не принят со слов.

1. Release Gate объявлял проверку хеша, которой не было. Печаталась строка
   PACKAGE_HASH_VERIFIED=True при том, что hashlib в scripts/release_gate.py
   не вызывался ни разу: скачивались байты 0-10 через заголовок Range, и
   этого хватало, чтобы счесть хеш проверенным. «Проверенным ассетом» при
   этом оказывался первый в списке — checksums.txt, а не пакет.

2. Ворота публикации были fail-open. Измерено в трёх условиях: полный обрыв
   сети -> PASS, манифест 404 -> PASS, пакет 404 -> PASS. Ворота пропускали
   релиз при любом исходе, включая полное отсутствие релиза.

   Разделено на офлайновую часть (проверки 1-7: версии, тесты, updater,
   статика, секреты, список разрешённых адресов) и Publication Gate: релиз
   есть, ассеты есть, пакет скачан ЦЕЛИКОМ, SHA-256 сошёлся с опубликованным
   checksums.txt. Публикационные ворота блокируют в режиме публикации
   (--publication или HERMES_RELEASE_PUBLICATION_GATE=1); в обычном прогоне
   CI, где релиза для ветки нет и быть не должно, результат сообщается как
   есть и не блокирует. Неизмеренное называется причиной, а не выдаётся за
   проверенное. Проверено на живом релизе v0.1.3-b1: два пакета скачаны
   целиком, хеши сошлись.

3. POST /api/action на loopback принимал межсайтовые запросы. Токен там не
   требуется, а действие меняет состояние: удаляет учётные данные, чистит
   аккаунты, переключает маршрутизацию, запускает входы OAuth. CORS от этого
   не защищает — он мешает прочитать ответ, а не отправить запрос. Измерено
   на конфигурации по умолчанию: POST с Content-Type text/plain уходит
   кросс-сайтом без предварительного запроса, request.json() разбирает тело
   независимо от Content-Type, и запрос с Origin чужого сайта без токена
   доходил до исполнителя действий.

   Проверяется Sec-Fetch-Site, при его отсутствии — Origin против адреса
   запроса. Собственный интерфейс, адресная строка и не-браузерные клиенты
   работают как раньше. Защита распространена на все пять небезопасных
   методов, не только на /api/action.

4. pricing fallback: safe_load вместо safe_dump. dump сериализовал текст
   обратно в строку, проверка isinstance(data, dict) не выполнялась никогда,
   таблица цен не загружалась ни разу, а except это глушил.

5. Симуляция Linux в тесте stop_running_hub падала на Windows: os.getuid там
   не существует.

Тесты: 756 -> 776 passed, 2 skipped, 4 deselected. ruff check . чисто.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-03 19:01:30 +07:00
..
adapters feat(antigravity): выход через прокси вместо патча бинарника 2026-09-01 16:49:04 +07:00
scheduler feat(hub): product stabilization, native windows ux v3, provider icons, and architecture roadmap 2026-08-20 11:01:52 +07:00
supervisor feat(state): harden snapshots quotas and routing 2026-08-21 00:03:50 +07:00
web fix(release,web): ворота публикации перестали пропускать всё подряд, /api/action — межсайтовые запросы 2026-09-03 19:01:30 +07:00
__init__.py feat(dashboard): expose telemetry breakdown, provider call_share, host metrics, and active leases 2026-08-21 17:44:56 +07:00
account_identity.py feat(router): integrate local LLM provider (llama.cpp/vLLM/Ollama) with zero quotas (A25) 2026-08-24 14:00:25 +07:00
account_probe_service.py fix(a54): validate accounts synchronously and manage Windows runtime lifecycle 2026-08-31 20:54:19 +07:00
action_handler.py merge main 2026-09-02 19:23:31 +07:00
agy_eligibility_service.py feat(agy): A58 read-only eligibility state detection and owner patcher controls 2026-09-02 01:26:46 +07:00
auto_assigner.py merge: A51 — подключённый аккаунт реально попадает в цепочку роли 2026-08-31 19:13:02 +07:00
claude_oauth.py merge: complete antigravity state layer 2026-08-21 00:10:56 +07:00
cli_commands.py fix(security): граница workspace держится одинаково на Windows и Linux 2026-09-03 19:01:30 +07:00
codex_oauth.py fix(windows): чёрные окна консоли выскакивали каждую минуту 2026-08-31 19:39:12 +07:00
connection_preflight.py fix(antigravity): рабочий аккаунт падал из-за незаданного уровня усилия 2026-09-01 03:05:44 +07:00
context_compressor.py review(a56): сжатие контекста принято с исправлениями 2026-09-01 14:32:35 +07:00
dual_coder_pipeline.py feat(a52): local models replacement, local-supervisor, and dual coder with cloud judge 2026-08-31 19:12:07 +07:00
event_bus.py feat(agy): A58 read-only eligibility state detection and owner patcher controls 2026-09-02 01:26:46 +07:00
exceptions.py fix: close P0 release blockers 2026-08-20 16:25:11 +07:00
grok_oauth.py fix(grok): опрос device-flow не различал отказ, просрочку и ожидание 2026-08-24 15:11:54 +07:00
health_tracker.py feat(providers): A42 подключение OpenRouter, NVIDIA, Ollama, исправление discovery и ложной квоты Codex 2026-08-31 11:36:55 +07:00
host_metrics.py fix(dashboard): unify LeaseManager, warm up initial CPU measurement, add live network speed, and clarify YAML comment support 2026-08-21 22:18:59 +07:00
launcher_bootstrap.py fix(windows): чёрные окна консоли выскакивали каждую минуту 2026-08-31 19:39:12 +07:00
local_discovery.py fix(roles): 19 агентов вместо 13, шесть пар неотличимы по названию; поиск локальных серверов 2026-08-30 20:46:25 +07:00
local_supervisor.py review(a56): сжатие контекста принято с исправлениями 2026-09-01 14:32:35 +07:00
model_discovery.py Merge antigravity/quotas-models-migration (A9) 2026-08-23 12:57:49 +07:00
model_discovery_service.py fix(a55): account connection fixes - antigravity windows/linux, ollama server discovery, version display, full settings 2026-08-31 23:39:53 +07:00
model_entitlements.py feat(nvidia): определение моделей, доступных конкретному аккаунту 2026-09-01 02:45:01 +07:00
model_registry.py feat(pipeline): A35 and A36 canonical Antigravity workflow pipeline with role resolution and loops 2026-08-30 15:34:07 +00:00
preflight_service.py feat(a31): preflight dependency agent, workflow run state recovery, local concurrency and context guard, PII email masking, and cost-controller token honesty 2026-08-26 09:27:36 +07:00
profile_manager.py feat(antigravity): нативный вход через agy в терминале (A57) 2026-09-01 14:25:13 +07:00
profile_oauth.py fix(antigravity): вход завершался успешно, а agy требовал войти снова 2026-09-01 10:37:27 +07:00
quota_collector.py fix(ollama): облачный аккаунт объявлялся неработающим и безлимитным 2026-09-01 02:55:39 +07:00
role_registry.py feat(a52): local models replacement, local-supervisor, and dual coder with cloud judge 2026-08-31 19:12:07 +07:00
router_config.py feat(config): A41 чистая конфигурация при первой установке, безопасность учетных данных и сброс 2026-08-31 02:27:42 +07:00
router_engine.py feat(pipeline): A35 and A36 canonical Antigravity workflow pipeline with role resolution and loops 2026-08-30 15:34:07 +00:00
scheduler.py feat(state): close contract gaps v1.1, canonical event publishers, and view model enrichment 2026-08-21 08:20:56 +07:00
security_guard.py fix(security): граница workspace держится одинаково на Windows и Linux 2026-09-03 19:01:30 +07:00
session_affinity.py feat(dashboard): expose telemetry breakdown, provider call_share, host metrics, and active leases 2026-08-21 17:44:56 +07:00
settings_service.py feat(agy): A58 read-only eligibility state detection and owner patcher controls 2026-09-02 01:26:46 +07:00
skills_service.py feat(skills): A49 subagents layout, skills tab, SkillDoctor, and Obsidian memory integration 2026-08-31 18:19:01 +07:00
state_store.py fix(a55): account connection fixes - antigravity windows/linux, ollama server discovery, version display, full settings 2026-08-31 23:39:53 +07:00
telemetry_service.py fix(release,web): ворота публикации перестали пропускать всё подряд, /api/action — межсайтовые запросы 2026-09-03 19:01:30 +07:00
unified_health.py fix(accounts): отказ проверки переживал более свежий каталог моделей 2026-09-01 14:03:56 +07:00
workflow_service.py feat(skills): A49 subagents layout, skills tab, SkillDoctor, and Obsidian memory integration 2026-08-31 18:19:01 +07:00