Skip to content

fix(desktop): mint oauth ticket before cold-start unsigned hard-fail - #101547

Closed
FalconOrtiz wants to merge 1 commit into
NousResearch:mainfrom
FalconOrtiz:fix/fe-101339-remote-roster-reauth
Closed

FalconOrtiz wants to merge 1 commit into
NousResearch:mainfrom
FalconOrtiz:fix/fe-101339-remote-roster-reauth

Conversation

@FalconOrtiz

Copy link
Copy Markdown

Why

Registered remote OAuth gateways vanished from the Desktop fleet rail after restart until Settings → Connections → Test. Cookie-jar preflight on buildRemoteConnection hard-failed as unsigned while the persist: jar was still hydrating, so roster dial never minted a ws-ticket. Test mints first and succeeds. The 10s roster deadline also raced oauth mint + readiness.

Scope

  • apps/desktop/electron/main.ts: mint-first oauth dial; unsigned only via shouldTreatOauthMintFailureAsUnsigned; oauth roster sources use rosterSourceEnumerationTimeoutMs (30s).
  • apps/desktop/electron/native-auth-decisions.ts (+ tests): pure helpers for mint-failure classification and roster budgets.
  • apps/desktop/src/store/fleet-roster.ts (+ tests): incomplete snapshots (unreachable remotes) do not fill the 60s stale window.
  • apps/desktop/src/app/settings/connections-registry.tsx: successful Test forces refreshFleetRoster({ force: true }).
  • Source contract asserts in backend-dial-claim.test.ts.

Out of scope: gateway/backend auth, interactive re-login UX, SSH inventory.

Tradeoffs

Mint-first can issue one extra network round-trip for a truly signed-out user before the unsigned overlay. That matches Test and avoids dropping a live session on cold start.

Blast Radius

Desktop oauth remote/cloud connect and fleet roster refresh. Local/token/SSH paths keep the 10s roster budget. Safe when cookies are live: mint already ran on the previous path.

Verification

Worktree C:\Users\falco\projects\hermes-agent-wt-u22:

cd apps/desktop
npm run test:desktop:platforms -- electron/native-auth-decisions.test.ts electron/backend-dial-claim.test.ts
# 37 passed, exit 0

npm run test:ui -- src/store/fleet-roster.test.ts
# 5 passed, exit 0

No live HERMES_HOME / packaged Electron run in this unit.

Fixes #101339

Remote roster dial skipped ws-ticket mint when the persist cookie jar still looked empty, then the 10s enumeration deadline raced a successful Test path. Mint first, budget oauth sources longer, and refresh an incomplete fleet roster.

Co-authored-by: Cursor <cursoragent@cursor.com>
@alt-glitch alt-glitch added type/bug Something isn't working P2 Medium — degraded but workaround exists comp/desktop Electron desktop app (apps/desktop/*) area/auth Authentication, OAuth, credential pools sweeper:risk-session-state Sweeper risk: may lose/corrupt/mis-associate session or context state labels Sep 2, 2026
@Enough1122

Copy link
Copy Markdown

AI code review — automated review for reference; please use your judgment.

Overall: Cold-start OAuth roster misses fixed at the root: the ws-ticket mint (the same authoritative check Settings → Test uses) now runs before unsigned classification, and OAuth remotes get a 30 s enumeration budget (#101339).

Correctness:

  • apps/desktop/electron/main.ts:buildRemoteConnection — cookie-jar preflight demoted from gate to post-failure signal; shouldTreatOauthMintFailureAsUnsigned returns unsigned only on confirmed auth rejection + no live session + guard-eligible providers. Transport blips and live-but-expired sessions surface as ticket failures, never the Sign-in overlay.
  • native-auth-decisions.ts:rosterSourceEnumerationTimeoutMs — remote/cloud + oauth → 30 s; ssh/token/local unchanged at 10 s.
  • fleet-roster.ts:fleetRosterIsComplete — incomplete snapshots bypass the 60 s stale window so a post-Test retry re-enumerates immediately; connect-on-demand still counts as complete; Settings → Test forces refreshFleetRoster({force: true}).
  • Tests pin the unsigned matrix (all four quadrants), per-kind timeouts, and incomplete-cache bypass vs complete-cache skip.

Non-blocking nit:

  • Worst-case cold roster enumeration now takes up to 30 s per OAuth remote before reporting unreachable; the per-source deadline still bounds the total, and correctness (no dropped remote groups) wins — just noting the slower failure mode.

Verdict: LGTM.

@FalconOrtiz

Copy link
Copy Markdown
Author

Requesting squash-merge per engineer agreement (2026-09-04): AI-review merge-ready pack; nits non-blocking; no rewrites.

This PR is in the agreed pack with #101523 #101528 #101529 #101530 #101531 #101537 #101544 #101547 #101548 #101549 #101551.

Out of pack (do not block this merge): #101564, #101796/#101091, #101318.

@OutThisLife

Copy link
Copy Markdown

Superseded by #108183. The consolidated fix preserves contributor credit and covers the remaining remote-gateway recovery paths on current main.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/auth Authentication, OAuth, credential pools comp/desktop Electron desktop app (apps/desktop/*) P2 Medium — degraded but workaround exists sweeper:risk-session-state Sweeper risk: may lose/corrupt/mis-associate session or context state type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Remote connections fail to enumerate agent roster on Desktop startup — requires manual re-auth

4 participants