Skip to content

fix(desktop): stop local profile picks routing to the remote primary - #106207

Open
ctaylor86 wants to merge 1 commit into
NousResearch:mainfrom
ctaylor86:fix/desktop-exact-local-profile-salvage
Open

ctaylor86 wants to merge 1 commit into
NousResearch:mainfrom
ctaylor86:fix/desktop-exact-local-profile-salvage

Conversation

@ctaylor86

@ctaylor86 ctaylor86 commented Sep 9, 2026 •

Copy link
Copy Markdown

What does this PR do?

With a remote/cloud gateway saved as primary, choosing a named profile under “This device” can silently activate the remote primary instead of the local profile. The profile pick drops its explicit local connection ID and falls through to legacy routing. New-chat creation inherits that incorrect source.

Preserve the local source through profile selection, new-chat creation and subsequent requests. A failed local descriptor lookup must not be reported as a successful shared-remote activation. Explicit per-profile remote overrides remain supported by the existing Electron resolver.

Why it matters / suggested P2: this corrects wrong-backend routing and disagreement between the selected profile and its socket, not visual profile labelling. The workaround is to avoid this mixed-primary named-profile path or change the saved primary; the intended workflow should not require either. The PR does not claim observed data loss or a security incident.

Related Issue

Related to #90149 and the per-profile override intent in #94166. #105139/#102673 address broader readiness/cache behavior but do not remove this local-source downgrade. Existing override and routing logic is reused rather than reimplemented.

Type of Change

  • 🐛 Bug fix (non-breaking change that fixes an issue)
  • ✨ New feature (non-breaking change that adds functionality)
  • 🔒 Security fix
  • 📝 Documentation update
  • ✅ Tests (adding or improving test coverage)
  • ♻️ Refactor (no behavior change)
  • 🎯 New skill (bundled or hub)

Changes Made

  • apps/desktop/src/store/profile.ts: remove the explicit-local-to-legacy downgrade; retain the selected source for both profile entry points and draft ownership.
  • apps/desktop/src/store/gateway.ts: exclude local routes from the failed-probe shared-remote fallback.
  • apps/desktop/src/store/profile-select-source.test.ts and apps/desktop/src/app/session/hooks/profile-rail-fresh-chat-owner.test.tsx: exercise selection, failed lookup, session creation and two submissions, including saved per-profile overrides.

How to Test

  1. Save a remote/cloud primary and select the “This device” gateway.
  2. Select a named local profile or start a new chat in that profile.
  3. Before: the request loses connectionId: 'local' and takes the remote-primary route. After: activation, one session.create and both prompt.submit calls retain the exact local/profile owner. A rejected local descriptor cannot falsely publish the requested profile over the old socket.

Run against head 3a07612321fce3b042ee82a5606b1859bf148d68:

cd apps/desktop
npx --no-install vitest run src/store/profile-select-source.test.ts src/app/session/hooks/profile-rail-fresh-chat-owner.test.tsx src/store/profile.test.ts src/store/profile-agent-activation.test.ts src/store/profile-switch-failure.test.ts src/store/gateway-connection-scope.test.ts src/store/gateway-profile-request.test.ts electron/connection-config.test.ts electron/connection-registry.test.ts
npm run typecheck

Final-head verification: 304 tests / 9 files passed, including existing Electron route/registry suites; all three Desktop TypeScript projects passed. Changed-file lint and git diff --check also passed. The baseline routing regressions were reproduced before the fix.

These tests use real stores, hooks and production routing policies with synthetic process/network boundaries. They do not claim a real hosted Cloud/SSH deployment test. No Electron routing-precedence rewrite or backend persistence change is included. This preserves the configured per-profile remote-override behavior; explicit local selection only prevents accidental inheritance of the global remote primary.

Checklist

Code

  • I've read the Contributing Guide
  • My commit messages follow Conventional Commits (fix(scope):, feat(scope):, etc.)
  • I searched for existing PRs to make sure this isn't a duplicate
  • My PR contains only changes related to this fix/feature (no unrelated commits)
  • I've run pytest tests/ -q and all tests pass
  • I've added tests for my changes (required for bug fixes, strongly encouraged for features)
  • I've tested on my platform: macOS; platform-independent renderer logic, no new native APIs

Documentation & Housekeeping

  • I've updated relevant documentation (README, docs/, docstrings) — or N/A (inline behavior comments updated; no new setup required)
  • I've updated cli-config.yaml.example if I added/changed config keys — or N/A
  • I've updated CONTRIBUTING.md or AGENTS.md if I changed architecture or workflows — or N/A
  • I've considered cross-platform impact (Windows, macOS) per the compatibility guide — or N/A
  • I've updated tool descriptions/schemas if I changed tool behavior — or N/A

Screenshots / Logs

The regressions above were run against the baseline and the reviewed fix. git diff --check and the public-data/secret scan passed. Independent code review and isolated UI review were completed before publication. Private workspace screenshots are intentionally omitted; no user data or configuration is included.

No new dependencies, configuration keys or model-tool schemas. No Python source changes; the full Python suite was not run and its checklist item remains unchecked. macOS was executed; Windows/Linux were considered but not run locally. Live CI results are available in the PR checks rather than frozen here.

@alt-glitch alt-glitch added type/bug Something isn't working P3 Low — cosmetic, nice to have comp/desktop Electron desktop app (apps/desktop/*) area/profiles Multi-profile isolation, HERMES_HOME scoping labels Sep 9, 2026
@ctaylor86 ctaylor86 changed the title fix(desktop): preserve explicit local profile ownership fix(desktop): stop local profile picks routing to the remote primary Sep 9, 2026
@ctaylor86

Copy link
Copy Markdown
Author

Priority clarification after updating the description: could this be considered P2 (reliability with a workaround) rather than the current P3?

The reproduced failure sends a named This device profile selection/new chat through the saved remote primary after dropping the local source ID. The regression checks activation, session.create and two submissions, as well as failed descriptor lookup; configured per-profile remote overrides remain supported. A local-primary setup avoids the path, but this is incorrect backend ownership rather than cosmetic labelling. No observed data disclosure or data loss is claimed.

The PR body now includes concise reproduction, the protected invariant, exact-head verification commands and explicit test limits. I am not requesting P1/P0; the severity decision remains with maintainers.

@ctaylor86
ctaylor86 force-pushed the fix/desktop-exact-local-profile-salvage branch from 5dbf191 to 3a07612 Compare September 11, 2026 16:14

This branch has not been deployed

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

Labels

area/profiles Multi-profile isolation, HERMES_HOME scoping comp/desktop Electron desktop app (apps/desktop/*) P3 Low — cosmetic, nice to have type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants