Completes the test-sharding half of #3197 (Docker-cache half shipped v0.51.177).
Adds pytest-shard 3-way split to tests.yml (3 shards x 3 Python = 9 jobs,
fail-fast: false). pytest-shard is 0-indexed so the matrix uses [0,1,2] — the
original #3197 used [1,2,3] which would have crashed the out-of-range job and
silently skipped shard 0's tests.
Made the suite shard-safe by fixing 4 cross-test state-pollution bugs that
passed sequentially but failed when sharded:
- test_onboarding_mvp: reset onboarding_completed flag (settings.json) in the
autouse fixture; the config-cleanup only cleared config.yaml/.env.
- test_issue693_system_health_panel: invalidate the process-wide password-hash
cache before/after so a prior test's "no password" cache doesn't defeat the
auth-gate assertion.
- test_auth_session_persistence: assert against auth._SESSIONS_FILE (where auth
actually writes) instead of a local _TEST_STATE path that only matched under a
lucky import order.
- test_profile_env_isolation (root cause of the worst leak): stop deleting +
re-importing api.profiles under a temp HERMES_BASE_HOME — that swapped the
module object and poisoned the cached _DEFAULT_HERMES_HOME for every later
test (broke test_title_aux_routing's load_config). Now points the cached path
via monkeypatch.setattr (auto-restored, no module swap).
- conftest: autouse fixture restores HERMES_HOME/HERMES_BASE_HOME after each
test as defense-in-depth against future switch_profile leaks.
Verified: all 3 shards green (6912 passed, 0 failed); full sequential run still
green (6957 passed, 0 failed). Slowest shard ~70s vs ~180s sequential.
Adds a bootstrap launcher and a blocking first-run onboarding wizard that guides
new users through minimum Hermes setup from the browser UI.
Supported provider flows: OpenRouter, Anthropic, OpenAI, custom OpenAI-compatible.
OAuth/terminal-first flows remain via 'hermes model'.
Security hardening applied during review:
- /api/onboarding/setup restricted to loopback when auth disabled
- Newline injection guard in _write_env_file
- esc() on setup.unsupported_note in onboarding.js
- Test isolation fix (send_key instead of bot_name in contamination test)
- Skip markers for PyYAML-dependent tests in agent-less environments
Tests: 693 passed (up from 679)
Co-authored-by: Nathan Esquenazi <nesquena@gmail.com>
Co-authored-by: gabogabucho <gabogabucho@gmail.com>