mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-07-30 19:09:28 +00:00
shouldLatchBackendStartFailure deliberately never latches a remote failure: remote faults are usually transient and must stay retryable without an app restart. A confirmed reauth rejection is the exception — it cannot self-heal, because nothing changes until the user signs in again. Worse, not latching actively prevents the recovery it was protecting. A non-latching remote boot failure re-runs startHermes on every getConnection/api call, re-emits running: true, and the boot-failure overlay (visible = Boolean(boot.error) && !boot.running) hides itself — so the "Sign in" button flickers out from under the user before it can be clicked. Add shouldLatchRemoteReauthFailure as a separate predicate rather than changing the existing one, so transient remote failures keep self-healing. The two latches are complementary and never fire for the same failure.
52 lines
2.5 KiB
TypeScript
52 lines
2.5 KiB
TypeScript
import assert from 'node:assert/strict'
|
|
|
|
import { test } from 'vitest'
|
|
|
|
import { shouldLatchBackendStartFailure, shouldLatchRemoteReauthFailure } from './backend-start-failure'
|
|
|
|
test('latches a LOCAL backend failure so the install-retry loop is broken', () => {
|
|
assert.equal(shouldLatchBackendStartFailure({ attemptedRemote: false }), true)
|
|
})
|
|
|
|
test('never latches a REMOTE failure so recovery stays retryable without a restart', () => {
|
|
// A lapsed OAuth session / mint timeout / host briefly unreachable across a
|
|
// laptop sleep must not wedge the app: the next connect has to re-attempt and
|
|
// re-mint against the refreshed session.
|
|
assert.equal(shouldLatchBackendStartFailure({ attemptedRemote: true }), false)
|
|
})
|
|
|
|
test('the two branches are mutually exclusive (a failure either latches or stays retryable)', () => {
|
|
for (const attemptedRemote of [true, false]) {
|
|
const latched = shouldLatchBackendStartFailure({ attemptedRemote })
|
|
assert.equal(latched, !attemptedRemote)
|
|
}
|
|
})
|
|
|
|
test('latches a CONFIRMED remote reauth failure so the overlay stays clickable', () => {
|
|
// Without this the non-latching remote path re-runs startHermes on every
|
|
// getConnection/api call, re-emits running:true, and the overlay hides
|
|
// itself — the "Sign in" button flickers away before it can be clicked.
|
|
assert.equal(shouldLatchRemoteReauthFailure({ attemptedRemote: true, isReauth: true }), true)
|
|
})
|
|
|
|
test('does not latch a transient remote failure as reauth', () => {
|
|
// A mint timeout or a host unreachable across sleep must still self-heal.
|
|
assert.equal(shouldLatchRemoteReauthFailure({ attemptedRemote: true, isReauth: false }), false)
|
|
})
|
|
|
|
test('never latches a LOCAL failure as reauth (that is backendStartFailure job)', () => {
|
|
assert.equal(shouldLatchRemoteReauthFailure({ attemptedRemote: false, isReauth: true }), false)
|
|
assert.equal(shouldLatchRemoteReauthFailure({ attemptedRemote: false, isReauth: false }), false)
|
|
})
|
|
|
|
test('the two latches never fire for the same failure', () => {
|
|
// They are complementary, not overlapping: local failures latch via
|
|
// backendStartFailure, confirmed remote reauth latches via its own flag.
|
|
for (const attemptedRemote of [true, false]) {
|
|
for (const isReauth of [true, false]) {
|
|
const start = shouldLatchBackendStartFailure({ attemptedRemote })
|
|
const reauth = shouldLatchRemoteReauthFailure({ attemptedRemote, isReauth })
|
|
assert.ok(!(start && reauth), `both latched for remote=${attemptedRemote} reauth=${isReauth}`)
|
|
}
|
|
}
|
|
})
|