Skip to content

fix(desktop): respect profile scope for cron jobs and messaging sessions - #52910

Closed
lerryzou wants to merge 1 commit into
NousResearch:mainfrom
lerryzou:fix/desktop-profile-isolation
Closed

fix(desktop): respect profile scope for cron jobs and messaging sessions#52910
lerryzou wants to merge 1 commit into
NousResearch:mainfrom
lerryzou:fix/desktop-profile-isolation

Conversation

@lerryzou

Copy link
Copy Markdown

Problem

When a non-default profile is selected in the Desktop App sidebar, cron jobs from ALL profiles are displayed instead of just the active profile's jobs. This violates profile isolation and confuses users who expect to see only their current profile's data.

Root Cause

Four functions in the Desktop App frontend were hardcoded to fetch data from 'all' profiles, ignoring the active profile context:

  1. refreshCronSessions() - always passed profile='all'
  2. refreshMessagingSessions() - always passed profile='all'
  3. loadMoreMessagingForPlatform() - always passed profile='all'
  4. getCronJobs() - didn't pass any profile parameter (backend defaulted to 'all')

Solution

Updated these functions to respect the profileScope computed store, which reflects the currently selected profile in the sidebar. Each function now:

  • Uses profileScope instead of hardcoded 'all'
  • Includes profileScope in the useCallback dependency array to ensure refetch on profile change

Testing

  • Verified lint passes: npm run lint
  • Verified relevant tests pass: npm test for cron and messaging components
  • Manual testing confirmed: switching profiles now shows only that profile's cron jobs and messaging sessions

Impact

The Desktop App was displaying cron jobs, messaging sessions, and
messaging channels from all profiles regardless of which profile was
selected. This broke the profile isolation boundary.

Root cause: Three data-fetching calls hardcoded 'all' as the profile
parameter instead of respecting the active profile scope:
- getCronJobs() in hermes.ts didn't pass profile query param
- refreshCronSessions() hardcoded profile='all'
- refreshMessagingSessions() hardcoded profile='all'
- loadMoreMessagingForPlatform() hardcoded profile='all'

Fix: Pass the current profileScope (from  store) to all
these calls, matching the pattern already used by refreshSessions().
The backend already supports profile filtering, so this is purely a
frontend fix.

Fixes NousResearch#52401
@alt-glitch alt-glitch added type/bug Something isn't working comp/desktop Electron desktop app (apps/desktop/*) comp/cron Cron scheduler and job management P3 Low — cosmetic, nice to have labels Jun 26, 2026
@alt-glitch

Copy link
Copy Markdown
Collaborator

This was generated by AI during triage.

Related: competing-cluster member for desktop profile-scoping. Fixes #52401 (superset issue) and overlaps the cron-sidebar cluster (#51520 spec; competing fix PRs #42654 call-site arg, #47429 helper-internal profileScoped() spread, #51531 ?profile= via _apiProfile). This PR is broader — it also scopes messaging sessions, not just cron jobs. Same goal, different mechanism across the cluster; a maintainer should pick one approach. Not a duplicate of any sibling.

@teknium1 teknium1 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for tracing the cross-profile sidebar leak. The underlying bug remains on current main, but this patch needs a targeted salvage.

Problems

  • The three session callbacks moved from apps/desktop/src/app/desktop-controller.tsx to apps/desktop/src/app/session/hooks/use-session-list-actions.ts:84-139 in 25c7900fb58239552c530fd6cf8be28e5efbcec4, so the frontend hunk no longer applies.
  • apps/desktop/src/hermes.ts in this PR builds the cron query from _apiProfile, whereas the sidebar is governed by profileScope. apps/desktop/src/store/profile.ts:294-295 supports explicit ALL_PROFILES; in that mode _apiProfile still follows the active gateway profile, so this would filter the All profiles view to one profile.
  • Please add profile-scoping regression coverage. Current apps/desktop/src/hermes.test.ts:96-112 covers only the unscoped cron path.

Suggested changes

  • Port the three session calls to use-session-list-actions.ts and pass profileScope === ALL_PROFILES ? 'all' : profileScope.
  • Give getCronJobs an explicit scope argument and pass the sidebar scope through all callers, including the Cron view.

Automated hermes-sweeper review.

}

export function getCronJobs(): Promise<CronJob[]> {
const qs = _apiProfile ? `?profile=${encodeURIComponent(_apiProfile)}` : ''

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

_apiProfile follows the active gateway profile, but the sidebar may be in explicit All profiles mode ($profileScope === ALL_PROFILES). In that mode this sends one active profile rather than profile=all. Accept the sidebar scope as a getCronJobs argument and pass profileScope === ALL_PROFILES ? 'all' : profileScope from the callers.

@teknium1 teknium1 added sweeper:risk-session-state Sweeper risk: may lose/corrupt/mis-associate session or context state sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades sweeper:blast-moderate Sweeper blast radius: moderate — a subsystem or single platform area/sessions Session lifecycle, resume, persistence, history area/profiles Multi-profile isolation, HERMES_HOME scoping labels Jul 15, 2026
@teknium1

Copy link
Copy Markdown
Contributor

Status update: the cron-jobs half of this PR is now superseded — profileScoped() routing landed via #67493, the contract test via #67602, and the endpoint-level ?profile= list scoping (sidebar + overlay) via #67615, merged today. The messaging/cron session fetch scoping half overlaps #60688's territory and is not yet covered on main — that half still stands. If you rebase onto current main and narrow to the listAllProfileSessions scoping (coordinating with #60688, which targets the same call sites), it can be reviewed on its own merits. Leaving open for that half.

@teknium1

Copy link
Copy Markdown
Contributor

Resolved on main by #87566 — cron and messaging sidebar slices now follow the selected profile end to end. You submitted this early in the cluster (June 26); thanks for the contribution!

@teknium1 teknium1 closed this Aug 16, 2026
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 area/sessions Session lifecycle, resume, persistence, history comp/cron Cron scheduler and job management comp/desktop Electron desktop app (apps/desktop/*) P3 Low — cosmetic, nice to have sweeper:blast-moderate Sweeper blast radius: moderate — a subsystem or single platform sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades 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.

Desktop App (macOS): Non-default profile shows sessions and cron jobs from default profile — cross-profile data leak in UI

3 participants