fix(desktop): persist account challenge state and clear it on real execution success

Previously a challenge auth state was lost on client restart (rehydrated
as active/unknown from lastVerifiedAt alone) and never cleared once a
subsequent monitor execution actually succeeded. Persist authState and
authReason so a challenge survives a restart, and add
markTrackedAccountExecutionSucceeded to clear a stale challenge when a
real task run succeeds.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-22 23:56:06 +08:00
parent 555b0abc72
commit 184646f9fe
2 changed files with 80 additions and 3 deletions
+36 -2
View File
@@ -46,6 +46,8 @@ type ProbeTrigger = 'scheduled' | 'manual' | 'preflight' | 'confirm'
interface PersistedAccountHealthRecord {
accountId: string
platform: string
authState?: AccountAuthState
authReason?: AccountAuthReason
lastVerifiedAt: number | null
lastAuthFailureAt: number | null
profile: AccountHealthProfile | null
@@ -138,13 +140,26 @@ function nextRegularProbeAt(now = Date.now()): number {
}
function normalizePersisted(record: PersistedAccountHealthRecord): AccountHealthRecord {
const hasNewerAuthFailure = Boolean(
record.lastAuthFailureAt &&
(!record.lastVerifiedAt || record.lastAuthFailureAt >= record.lastVerifiedAt),
)
const authState = record.authState ?? (hasNewerAuthFailure ? 'challenge_required' : null)
const normalizedAuthState = authState ?? (record.lastVerifiedAt ? 'active' : 'unknown')
return {
accountId: record.accountId,
platform: record.platform,
authRevision: 0,
authState: record.lastVerifiedAt ? 'active' : 'unknown',
authState: normalizedAuthState,
probeState: 'idle',
authReason: record.lastVerifiedAt ? 'probe_success' : null,
authReason:
record.authReason ??
(normalizedAuthState === 'active'
? 'probe_success'
: normalizedAuthState === 'challenge_required'
? 'captcha_gate'
: null),
lastVerifiedAt: record.lastVerifiedAt ?? null,
lastProbeAt: null,
nextProbeAt: nextInitialProbeAt(),
@@ -176,6 +191,8 @@ function persistRecords(): void {
const payload: PersistedAccountHealthRecord[] = [...records.values()].map((record) => ({
accountId: record.accountId,
platform: record.platform,
authState: record.authState,
authReason: record.authReason,
lastVerifiedAt: record.lastVerifiedAt,
lastAuthFailureAt: record.lastAuthFailureAt,
profile: record.profile,
@@ -891,6 +908,23 @@ export function markTrackedAccountBound(
return snapshot
}
export function markTrackedAccountExecutionSucceeded(
account: PublishAccountIdentity,
): AccountHealthSnapshot {
const record = ensureRecord(account)
trackedAccounts.set(account.id, account)
return applyActiveResult(
record,
{
verdict: 'active',
reason: 'probe_success',
profile: record.profile,
sessionFingerprint: record.sessionFingerprint,
},
Date.now(),
)
}
export function markTrackedAccountMissingPartition(
account: PublishAccountIdentity,
): AccountHealthSnapshot {