Commit graph

176 commits

Author SHA1 Message Date
a9c04b75a2 fix(ui): repair startup crash in TeamView and tighten the headless guard
Launching the app died with "'dict' object has no attribute 'readiness'".
TeamView.__init__ forwarded its legacy app_state dict into update_data(snapshot),
whose guard only handled None, so {} reached snapshot.readiness. TeamView is the
default view, so the window never appeared.

Fixes the call site and hardens every snapshot guard to fall back on anything
that is not a HubSnapshot. Adds tests/test_view_startup_contract.py, which
checks both conditions statically and therefore runs headless; verified to fail
on the pre-fix sources.

The GUI-import invariant previously matched the literal string "customtkinter",
which missed modules pulling it transitively. Rewritten over the AST, it
immediately found test_codex_opencode_wizard.py importing router.ui.components
without pytest.importorskip — the same defect that took the release gate down
once before, hidden until now behind conftest's name-based skip.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-20 23:22:19 +07:00
93883f9ce4 docs(task): split Plan A and UI redesign into two non-overlapping assignments
The UI redesign draft duplicated eight Plan A phases on the same files
(accounts_view, routing_view, hermes_hub_app, unified_health), which would have
put two agents into the same merge conflicts. Ownership is now split by file
path, with docs/UI_STATE_CONTRACT.md as the interface between them.

Four draft items were already implemented at 50fde5f and are marked as such
rather than reassigned: OAuth URL copy-before-open, keyed account card reuse,
the no-fake-metrics rule, and the importorskip guard.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-20 23:13:59 +07:00
Hermes Team
50fde5f16e refactor(plan-a): close residual blockers, concurrency race, and feed verification
- 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
2026-08-20 22:55:43 +07:00
559a56d80b docs(task): Plan A refactoring task with verified baseline statuses
Every Round 4 finding re-checked against HEAD 63c0385 instead of being carried
forward as still-open. Four are already fixed (customtkinter collection guard,
_CM_LOCK scope, gemini:antigravity restore, session affinity TTL), two are
partial, one is obsolete (web stack moved to legacy/), and five remain open.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-20 22:31:07 +07:00
63c0385f5c fix: repair seven undefined names and make CI ruff step meaningful
`ruff check .` failed on every push since CI was added (1221 findings), so the
job aborted before pytest and the release gate ever ran. Adds [tool.ruff]
selecting bug-catching rules only (E9, F63, F7, F82, F811); style and
modernization rules stay off until their ~1200 findings are burned down.

That selection immediately surfaced seven live defects:
- hermes_hub_app: HubModal used but never imported, so the "Назначить" role
  modal raised NameError — the handler added to close an earlier review
  finding could never open.
- hermes_hub_app: three `after(0, lambda: ...(e))` callbacks referencing the
  except-bound name, which Python unbinds at block exit, so every UI error
  path raised NameError instead of reporting the error.
- auto_assigner: build_team_hierarchy referenced an undefined `is_main` and
  crashed on every call.
- ui/assets and live_provision_and_validate: annotations naming Any/Tuple
  without importing them.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-20 22:28:08 +07:00
46a185395c docs(review): add independent audit, five review rounds, and remediation task
Full audit of the project (93 findings) plus the review record for rounds 1-5:
P0 release blockers, 65482e8, 42dfe2c, the v0.1.1 candidate verdict, and the
review of the previously unreviewed OAuth/wizard/quota work. Includes the
remediation task with acceptance criteria that 42eddb3 was verified against.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-20 22:22:57 +07:00
Hermes Team
51e5b67921 Merge branch 'chore/import-invariants-and-ci' 2026-08-20 22:22:44 +07:00
8db5c46515 test(ci): add import invariants, repair DeepSeek adapter, guard headless runs
deepseek_adapter.py had never been importable: it referenced ProviderAdapter
and ProfileConfig, neither of which exists in src/, and profile.extra, which
RouterProfileConfig does not define. Rewritten against BaseProviderAdapter with
the three missing abstract methods and registered as "deepseek".

Adds tests/test_import_invariants.py, which walks every shipped module and
fails on broken internal references while skipping absent optional GUI extras.
It also asserts that test modules importing customtkinter call
pytest.importorskip, since a missing guard aborts collection of the whole
session and takes the release gate with it.

Adds a headless CI job that uninstalls customtkinter and runs the suite, so
that invariant is enforced rather than remembered.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-20 22:13:54 +07:00
Hermes Team
42eddb3627 fix(quota, oauth): enforce data truthfulness, honest quota sources, and fail-closed OAuth
- Removed fabricated used_percent numbers and fake *_api source tags from quota_collector.py
- Marked quota snapshot sources as baseline/estimated and added visual estimation indicators in accounts_view.py
- Eliminated silent fallback on fake user_code/device_code in codex_oauth.py and grok_oauth.py
- Gated mock OAuth sessions strictly behind HERMES_HUB_DEV_MODE=1 with visible UI warnings
- Documented Google, OpenAI, xAI, and Claude OAuth clients in docs/OAUTH_CLIENT.md
- Relocated unused gui_server.py and gui_cockpit.html to legacy/
- Added test_data_truthfulness_and_oauth_security.py covering fail-closed and source truthfulness invariants
- Verified 98 passed tests (100%) and 7/7 release gate checks
2026-08-20 22:11:57 +07:00
Hermes Team
0c511cd3b6 feat(hub): Plan A stabilization, refresh architecture, delta UI, and capability routing
- 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
2026-08-20 21:20:51 +07:00
Hermes Team
2b8b709ac9 feat: multi-provider accounts, tariffs, quota buckets, Claude & Grok integration 2026-08-20 21:02:13 +07:00
Hermes Team
3aae1a8def feat(wizard): support Codex OAuth/API Key & OpenCode Go with clipboard UX 2026-08-20 20:31:59 +07:00
Hermes Team
249a88867c feat(oauth): adopt Cockpit Tools model with immediate URL readiness, manual callback fallback, and race protection 2026-08-20 20:17:37 +07:00
Hermes Team
0d9005f55b fix(oauth): eliminate ERR_CONNECTION_REFUSED, guarantee immediate listener binding, single session reuse, and diagnostic logging 2026-08-20 19:59:49 +07:00
Hermes Team
8314d46c43 fix: update canonical installer with dependency resolution and close release blockers 2026-08-20 18:17:08 +07:00
Hermes Team
42dfe2caa6 feat: production update feed architecture, host allowlist, and truthful release gate 2026-08-20 17:25:30 +07:00
Hermes Team
2f5e6d9f7a fix: strengthen secret scanning and oauth configuration 2026-08-20 17:23:40 +07:00
Hermes Team
70d34c1642 fix(router): connect persisted settings to runtime behavior 2026-08-20 17:22:23 +07:00
Hermes Team
925e6c6687 fix(router): correct spare assignment and error presentation 2026-08-20 17:21:30 +07:00
Hermes Team
65482e8eee fix(router): address review findings B1-B4 and S1-S9 with full regression suite 2026-08-20 17:04:49 +07:00
Hermes Team
7926de9ad2 feat(release): recovery stabilization, built-in updater, release gate, and v0.1.1 release pipeline 2026-08-20 16:29:35 +07:00
Hermes Team
2a97e80a3e fix: close P0 release blockers 2026-08-20 16:25:11 +07:00
Hermes Team
5ccfd48c41 docs: add completed stabilization and roadmap report 2026-08-20 11:02:28 +07:00
Hermes Team
7609ad87c2 feat(hub): product stabilization, native windows ux v3, provider icons, and architecture roadmap 2026-08-20 11:01:52 +07:00
Hermes Team
e66248ab09 feat: initialize standalone Hermes Hub 2026-08-20 10:53:49 +07:00
Hermes Team
fdf9eccbdb feat: initialize standalone Hermes Hub 2026-08-20 00:17:11 +07:00