Commit Graph

1984 Commits

Author SHA1 Message Date
Lucas Coutinho 7acbb3d99d Cache PBKDF2 password hash to eliminate ~1s overhead on every HTTP request
get_password_hash() computes PBKDF2-SHA256 with 600k iterations to
hash the HERMES_WEBUI_PASSWORD env var.  This is called on nearly every
HTTP request via check_auth -> is_auth_enabled -> get_password_hash.

Before: ~1s of PBKDF2 per request, regardless of how many times the
same env-var value has already been hashed.  A page load hitting 5+
API endpoints would burn 5+ seconds purely on password hashing.

After: compute once on first call, cache the hex result in a module-
level variable.  Subsequent calls are a single global-variable read
(~50ns).  The env var is immutable for the process lifetime, so there
is nothing to invalidate.

Thread-safe: double-checked locking ensures that under a burst of
concurrent requests only one thread computes PBKDF2, while the fast
path (after initialisation) requires zero locks.

10 unit tests covering all branches, cache-lifetime semantics, and
concurrent burst safety (8 threads, exactly 1 PBKDF2 call).
Test isolation: reloads only api.auth via importlib.reload, leaving
api.config untouched so test_pytest_state_isolation.py is unaffected.

Security analysis: zero regression.  The hash is derived from a static
env var and a static signing key — both already readable from process
memory.  Caching does not introduce any new disclosure or replay
vector.  PBKDF2 is still used for the initial computation and for
verify_password() on login.

AI: deepseek/deepseek-v4-flash
2026-05-13 00:54:50 -03:00
Lucas Coutinho bc3f4e54a6 Cache PBKDF2 password hash to eliminate ~1s overhead on every HTTP request
get_password_hash() computes PBKDF2-SHA256 with 600k iterations to
hash the HERMES_WEBUI_PASSWORD env var.  This is called on nearly every
HTTP request via check_auth -> is_auth_enabled -> get_password_hash.

Before: ~1s of PBKDF2 per request, regardless of how many times the
same env-var value has already been hashed.  A page load hitting 5+
API endpoints would burn 5+ seconds purely on password hashing.

After: compute once on first call, cache the hex result in a module-
level variable.  Subsequent calls are a single global-variable read
(~50ns).  The env var is immutable for the process lifetime, so there
is nothing to invalidate.

Thread-safe: double-checked locking ensures that under a burst of
concurrent requests only one thread computes PBKDF2, while the fast
path (after initialisation) requires zero locks.

Security analysis: zero regression.  The hash is derived from a static
env var and a static signing key — both already readable from process
memory.  Caching does not introduce any new disclosure or replay
vector.  PBKDF2 is still used for the initial computation and for
verify_password() on login.

AI: deepseek/deepseek-v4-flash
2026-05-13 00:25:41 -03:00
nesquena-hermes 9268f411d8 Merge pull request #2153 from nesquena/stage-345
stage-345: 2-PR low-risk batch — stream-ownership guard against stale writebacks + Refresh-usage button on provider quota card
v0.51.52
2026-05-12 16:56:15 -07:00
Hermes Agent 9336161fbd docs: CHANGELOG stage-345 — close v0.51.51, open Unreleased for #2136 + #2150 2026-05-12 23:12:22 +00:00
Hermes Agent 5f33901b6a Merge pull request #2150 into stage-345
feat: add manual provider usage refresh (Jordan-SkyLF)

Adds a 'Refresh usage' button on the Provider quota card in Settings → Providers,
with cache: 'no-store' fetch + browser cache-bust query string. Pure browser-side
cache-busting; the server-side /api/provider/quota endpoint has no cache layer
yet (refresh=1 query param is currently a no-op server-side; the win is bypassing
browser/proxy/SW caches).
2026-05-12 23:11:49 +00:00
Hermes Agent 20717a0d0a Merge pull request #2136 into stage-345
fix: guard stale stream writebacks (LumenYoung)

Prevents stale WebUI stream workers from writing old results into a session
after that session has already moved on to another stream. Adds new helper
_stream_writeback_is_current() (a token equality check against the session's
active_stream_id) and short-circuits the two finalize/cancel paths when the
worker no longer owns the session writeback.
2026-05-12 23:11:48 +00:00
Jordan SkyLF 062ef74ec0 fix: guard provider quota refresh fallback button state 2026-05-12 15:41:19 -07:00
Lumen Yang 4b57b202a0 fix: guard stale stream writebacks 2026-05-13 00:05:09 +02:00
Jordan SkyLF b1f752ad3f feat: add provider quota refresh control 2026-05-12 13:17:27 -07:00
nesquena-hermes 62974438f7 Merge pull request #2148 from nesquena/stage-344
stage-344: 16-PR contributor batch — i18n + insights + manual-compress async + workspace recovery + iOS PWA + Cloudflare login health + bash 3.2 (fr locale)
v0.51.51
2026-05-12 09:41:30 -07:00
Hermes Agent 2def05f385 stage-344: apply Opus SHOULD-FIX #1+#2 — #2128 multi-tab race + stale-done re-emit
(1) compress/status no longer pops the job entry on first read of `done` payload.
    Second open tab no longer sees `idle` and a stale-job toast.
(2) compress/start no longer short-circuits to a stale `done` payload when
    re-invoked within the 10-minute TTL. Re-running /compress always starts
    fresh, so closing-and-reopening a tab mid-compress works correctly.

Third SHOULD-FIX (#2135 cfg["model"] fallback tightening when no custom_providers
entry matches) deferred to follow-up — strictly no-worse-than-master behavior.

tests/test_sprint46.py 10/10 still passes.
2026-05-12 16:37:37 +00:00
Hermes Agent 4ab6cd68ad docs: CHANGELOG stage-344 — close v0.51.50, open Unreleased for 16-PR contributor batch 2026-05-12 16:21:50 +00:00
Hermes Agent 7116c680df stage-344: maintainer fix for #2142 fr locale — add LOCALES tuple entries + _LOGIN_LOCALE block
#2142 (legeantbleu) added the fr locale to static/i18n.js but didn't update:
1. tests/test_issue1488_composer_voice_buttons.py: two TestComposerVoiceButtonI18n + TestVoiceModePreferenceGate LOCALES tuples needed 'fr'
2. api/routes.py: _LOGIN_LOCALE needed an 'fr' block so the login page localizes for French users (issue #1442 parity contract)
3. tests/test_login_locale_parity.py: the test asserting 'fr' falls-back-to-'en' is inverted — fr now resolves to fr, with sibling assertions for fr-FR and fr-CA

Mirrors the stage-340 fix for the it locale (PR #2067 → maintainer adds tuple entries). 46/46 i18n tests pass after fix.
2026-05-12 16:14:47 +00:00
Hermes Agent 9c7eb42658 Merge pull request #2142 into stage-344
i18n: add French (fr) locale (938 keys, alphabetical en→fr→it position)
2026-05-12 16:13:48 +00:00
Hermes Agent c677c19a8f Merge pull request #2128 into stage-344
Fix manual compression proxy timeouts (closes #2087)

# Conflicts:
#	CHANGELOG.md
2026-05-12 16:13:01 +00:00
Hermes Agent 1ee8627acb Merge pull request #2135 into stage-344
Fix custom live model scoping (closes #2126, refs #2131)

# Conflicts:
#	CHANGELOG.md
2026-05-12 16:13:00 +00:00
Hermes Agent aa85bd2e7c Merge pull request #2138 into stage-344
fix: recover from stale deleted workspaces
2026-05-12 16:12:58 +00:00
Hermes Agent 23425b23c8 Merge pull request #2129 into stage-344
fix: purge missing inflight sessions (closes #2092)
2026-05-12 16:12:57 +00:00
Hermes Agent 8dd0b4ec31 Merge pull request #2139 into stage-344
fix: audit turn journal terminal collisions
2026-05-12 16:12:56 +00:00
Hermes Agent a06952ab00 Merge pull request #2140 into stage-344
Preserve fallback provider credential hints (closes #2133)

# Conflicts:
#	CHANGELOG.md
2026-05-12 16:12:54 +00:00
Hermes Agent 4c5a246647 Merge pull request #2125 into stage-344
docs: clarify compression anchor helpers (closes #2093)
2026-05-12 16:12:53 +00:00
Hermes Agent 8520755bd2 Merge pull request #2130 into stage-344
feat: load full lineage segments on demand
2026-05-12 16:12:52 +00:00
Hermes Agent 13c3646c55 Merge pull request #2121 into stage-344
fix: stack analytics usage cards on mobile (refs #2104) — TEST CONFLICT EXPECTED

# Conflicts:
#	tests/test_insights.py
2026-05-12 16:12:40 +00:00
Hermes Agent 2cccb8abcc Merge pull request #2120 into stage-344
fix: bucket long-range daily token charts (closes #2103)
2026-05-12 16:12:11 +00:00
Hermes Agent 56032151f7 Merge pull request #2143 into stage-344
Fix iPhone PWA chat bottom scroll stutter
2026-05-12 16:12:09 +00:00
Hermes Agent 45ac810a37 Merge pull request #2141 into stage-344
Fix Settings System mobile version wrapping (closes #2102)

# Conflicts:
#	CHANGELOG.md
2026-05-12 16:11:55 +00:00
Hermes Agent 76cf06a1a1 Merge pull request #2137 into stage-344
Fix login health probe credentials (closes #2122)
2026-05-12 16:11:42 +00:00
Hermes Agent effd3321f9 Merge pull request #2123 into stage-344
fix: add Portuguese session management i18n (closes #2112)
2026-05-12 16:11:41 +00:00
Hermes Agent 890d65f3e5 Merge pull request #2132 into stage-344
docs: document turn journal fsync tradeoff (refs #2096)
2026-05-12 16:11:39 +00:00
dobby-d-elf 099fdaf012 fix(ui): stabilize chat bottom scrolling on iPhone PWA 2026-05-12 07:47:21 -06:00
JB c5bad3e1c5 i18n: add French (fr) locale
Translation of all 938 string keys from English to French.
Generated programmatically with Google Translate.
2026-05-12 14:56:30 +02:00
Frank Song 76e611d49f Preserve fallback provider credential hints 2026-05-12 20:42:55 +08:00
Frank Song b3f8bee96f Fix settings system mobile version wrapping 2026-05-12 20:42:55 +08:00
dobby-d-elf 516d942d6a refactor: reduce stale workspace recovery fix 2026-05-12 06:28:35 -06:00
Michael Lam f5f59a5813 fix: audit turn journal terminal collisions 2026-05-12 05:20:06 -07:00
Frank Song b718220077 Fix login health probe credentials 2026-05-12 20:09:54 +08:00
Frank Song b7c5ba640c Fix custom live model scoping 2026-05-12 20:05:28 +08:00
dobby-d-elf e03c197cdf fix: recover from stale deleted workspaces 2026-05-12 05:52:16 -06:00
Michael Lam 442f01bbca docs: document turn journal fsync tradeoff 2026-05-12 04:11:14 -07:00
Dennis Soong f1b2a21bd4 feat: lazy-load full lineage segments 2026-05-12 18:02:49 +08:00
Michael Lam dd543e4175 fix: purge missing inflight sessions 2026-05-12 02:57:37 -07:00
Frank Song 8fa92c680f Fix manual compression proxy timeouts 2026-05-12 17:33:59 +08:00
Michael Lam 265496782a docs: clarify compression anchor helpers 2026-05-12 01:43:16 -07:00
Michael Lam 7a16d09f10 fix: add Portuguese session management i18n 2026-05-11 23:23:41 -07:00
Michael Lam a41b4d5afc fix: stack analytics usage cards on mobile 2026-05-11 23:07:35 -07:00
Michael Lam 245288c00d fix: bucket long-range daily token charts 2026-05-11 23:01:13 -07:00
nesquena-hermes 15d620392f Merge pull request #2119 from nesquena/stage-343
stage-343: ctl.sh bash 3.2 macOS compat fix (#2117) + regression test suite
v0.51.50
2026-05-11 22:43:45 -07:00
Hermes Agent 8b8fa0b885 stage-343: add bash 3.2 compat regression tests + CHANGELOG
- New tests/test_ctl_bash32_compat.py (5 static-pattern assertions):
  * strict-mode is enabled (set -euo pipefail)
  * preserved[@] iteration is length-guarded (PR #2117)
  * CTL_BOOTSTRAP_ARGS[@] uses +alt expansion (commit 025f137f)
  * defense-in-depth: catch any future raw "${arr[@]}" w/o whitelist
  * denylist of bash 4+ features (declare -A, mapfile, [[ -v ]], etc.)
- Verified test fails when fix reverted, passes when restored.
- CHANGELOG: close v0.51.49, open Unreleased for #2117.
2026-05-12 05:36:31 +00:00
Hermes Agent 418848f8d2 Merge pull request #2117 from ayushere/fix/ctlsh-bash32-empty-array
fix(ctl): guard empty preserved array iteration for bash 3.2 compat (macOS default)
2026-05-12 05:34:48 +00:00
nesquena-hermes f3d4d64fae Merge pull request #2118 from nesquena/stage-342
stage-342: 3-PR contributor batch — worktree status endpoint + worktree-retained response + Codex quota credential-pool fallback
v0.51.49
2026-05-11 22:24:35 -07:00