Admin config, permissions & frontend
Domain-level configurationβ
Helix behaviour is configured per-domain via JSON keys on domains.config, all editable from the Admin app's Settings page (frontend/src/admin/pages/settings/index.js, "Helix setup"/"Helix UI settings" sections):
| Key | Values | Purpose |
|---|---|---|
helixIntegrationMode | 'helix' | 'learning' | 'both' | The master flag. 'helix' = Helix-only hub (Learning features hidden entirely). 'both' = Helix + Learning. 'learning' = a Learning-only hub with Helix off β also the default when the key is unset. |
helixSendAnalysisEmails | boolean (default true) | Whether meeting-analysis and weekly-analysis emails are sent |
helixUserβ¦ / helixAdminβ¦ display settings | see Display settings | Scores, feedback, quotes, overall score and score bands β set separately for the user view and the admin view |
helixScoreBands | array of {min, label, colour} | Named score ranges shared by both views. See Score bands. |
helixAdminSkillsAnalyticsPage | boolean (default true) | Shows/hides the admin Skills Analytics nav item |
helixReportingTeamType | team type | Which team-type is used for team-level reporting/heatmaps |
helixAnonymiseUsers | boolean | Hides individual names in analytics unless filtered down to a specific team |
helixBotImageUrl | URL (theming) | Custom bot avatar image used when the meeting bot joins a call |
helixScoreOutOf | number (default 100) | Rescales every skill score from the engine's native 0β100 to this domain's chosen maximum (e.g. 5, 10, 20). API/MCP responses whose scores are on this scale include a scoreOutOf field; responses holding band positions instead (scoresNormalisedToBands: true) leave it out. See Scoring engine β Score scale. |
helixScoreDecimalPlaces | '0' | '1' | '2' (default '0') | Decimal places shown for averaged scores β weekly per-skill scores, overall scores, admin analytics averages, emails, and the CSV report. Individual meeting skill scores are always whole numbers. |
helixMeetingSummaryFormatPrompt / helixSkillSummaryFormatPrompt | string | Per-domain override of the format instructions used to make the AI return meeting-level / skill-level summaries as structured Markdown (Overall assessment / What was done well / Where to improve). See Scoring engine β Summary format. |
showAgentInHelixPages | boolean (default false) | Surfaces the Mindset Coach agent on Helix pages β as MindsetAgentDock (sidebar/FAB) once the user has skills data, or embedded via OnboardingMindsetCard on the empty-state welcome page. Forced off when hasMindsetSDK2. Does not depend on isTrialHub. See Frontend surface area. |
helixAllowMeetingTranscriptUpload | boolean (default false) | Lets users manually upload a meeting transcript for analysis, instead of relying solely on the meeting bot. Forced off when hasMindsetSDK2. |
isTrialHub | boolean (default false) | Swaps HelixInfoModal's content for trial-specific info (TrialInfo) and adds extra Hubspot contact tracking. Does not gate agent visibility β that's showAgentInHelixPages alone. |
mindsetOnboardingPlanUid | string (agent plan uid) | The onboarding plan the agent is force-set onto (via forceOnboardingPlan) the first time a user opens it β e.g. from OnboardingMindsetCard. The agent must be linked to this plan or the request times out. |
Display settings: user and admin viewsβ
What Helix shows β scores, feedback, quotes, an overall score, score bands β is configured twice: once for the user view and once for the admin view. The settings page shows one block of four settings per view (frontend/src/admin/pages/settings/sections/HelixDisplaySettings/).
| Setting | User view key | Admin view key | Values |
|---|---|---|---|
| UI mode | helixUserUIMode | helixAdminUIMode | 'scoresAndFeedback' (default) | 'onlyScores' | 'onlyFeedback' β numeric scores, qualitative feedback, or both |
| Show quotes | helixUserShowQuotes | helixAdminShowQuotes | boolean (default true) β transcript quote snippets alongside feedback. Ignored in 'onlyScores'. |
| Show overall score | helixUserShowOverallScore | helixAdminShowOverallScore | boolean (default false) β the overall score (average across a meeting/week's skills) next to summaries, as the first bar-chart/graph-card entry, as an aggregate column on the Skills Analytics heatmap, and as the Overall score column in the weekly analysis report. overall_score is always computed and stored regardless β this only gates display, so no backfill is needed if turned on later. |
| Show score bands | helixUserShowScoreBands | helixAdminShowScoreBands | boolean (default false) β has no effect until helixScoreBands holds at least one valid band |
The key maps live in api/utils/helix/getHelixUIMode.js (AUDIENCE_CONFIG_KEYS) and frontend/src/common/types/helixDisplay.ts (HELIX_AUDIENCE_CONFIG_KEYS), which mirror each other. Both apps resolve a view through getHelixUIMode / getHelixDisplaySettings, which return the derived flags (showScores, showFeedback, showQuotes, showOverallScore, showScoreBands, scoresNormalisedToBands, scoreBands, scoreOutOf, scoreDecimalPlaces). Read settings through these rather than off the config directly.
The two views are fully independent. An unset admin setting takes the default, not the user view's value β so changing the user view can never change what admins see.
Which view appliesβ
| Surface | View |
|---|---|
| Your own analysis β Profile β Skills, the weekly and meeting emails (and the template editor preview), the Mindset MCP tools, the meeting report PDF | Always user, admins included, so admins see what their people see |
Someone's analysis opened by user id β /people/:id/skills, My Teams | Admin for admins and super users; user for everyone else, team managers included. The People page sends the user id for your own analysis too, so it looks the same whoever is opened. |
Admin Skills Analytics (skillsAnalysis/heatmap, skillsAnalysis/progression) | Admin for admins. Scores are always shown here; bands follow helixAdminShowScoreBands. |
| Helix weekly analysis report | Whoever runs it β in practice an admin, so admin |
The rule is implemented in api/utils/helix/:
isHelixAdminViewer(role)β the viewer has the admin role (owners carry it too) or is a super user.isHelixAdminView(role, userId)β used by the fouruserAnalysisroutes. Needs both auserIdquery parameter andisHelixAdminViewer, so a member can't get the admin view by addinguserId.getIsHelixAdminUser(userId, domainId)β the same check for callers that only have a user id, i.e. the weekly analysis report.
The frontend applies the same rule with HelixAdminViewProvider (frontend/src/common/utils/helix/HelixAdminView.tsx), which wraps a page given the userId it was opened with; components read their view's settings with useHelixUIMode(). The meeting PDF renders outside that tree, so it is given the view as a prop.
Team managers have no view of their own and get the user view.
Score bandsβ
helixScoreBands is a list of {min, label, colour}, shared by both views and edited in ScoreBandsEditor (one card per band, with a live preview and the score range each covers). A score falls in the band with the highest min it reaches (getScoreBand, api/utils/helix/getScoreBand.js; mirrored by getHelixScoreBand in the frontend).
minis a whole number on the domain'shelixScoreOutOfscale. Averaged scores can be displayed to 0 decimal places, which would round across a fractional boundary like 2.5. The editor also requires a band starting at0, so every score has one.- Scores are banded as displayed (after rounding to
helixScoreDecimalPlaces), so the band always agrees with the number beside it. colourmust be#rrggbb. It goes straight into CSS, where another value could inject rules of its own, sogetScoreBandsdrops any band with a different colour.
Display modesβ
| UI mode | Bands on | Result |
|---|---|---|
| Scores shown | yes | Each score is ringed in its band's colour, with a band pill (ScoreBandPill) beside it. Responses add a scoreBand / overallScoreBand next to each score, plus scoreBands. |
'onlyFeedback' | yes | Each score is replaced by its band's position (1 = lowest band) and responses set scoresNormalisedToBands: true and omit scoreOutOf. No numbers appear anywhere: graphs are labelled with band names, and the score disc becomes a ScoreBandDonut filled to position Γ· band count. |
| any | no | Scores shown or hidden per the UI mode, with no band fields |
Scores are replaced by band positions, rather than dropped, so the pages still have a value to chart. The Mindset MCP tools strip those positions (api/modules/mindsetMcp/tools/utils/stripNormalisedScores.js) because the assistant would read them out as scores; the bands themselves are kept. withScoreBand and getScoreScaleFields (api/utils/helix/getScoreBand.js) apply all of this to a response.
In 'onlyFeedback' with bands on, Show overall score stays available, since it then controls whether the overall score's band is shown.
Backend permissionsβ
- Privileges (
api/utils/privileges.js):HELIX_READ = 'helix_read',HELIX_WRITE = 'helix_write', plus a'helix'role preset. - Middlewares:
checkIsUserOrTeamManagerOrHelixAdmin.jsandmanagerOrAdminUserOrReportOrHelix.js(api/middlewares/) gate routes like/userAnalysis,/skillsAnalysis, and/me/helixAccess-style endpoints to team managers, admins, or users with Helix admin rights. - Per-user access:
getIsHelixUser()/checkIsHelixUser()(api/routes/userAnalysis/utils/index.js) determine whether a user has access to Helix in the current domain β they must belong to it as theirhelix_domain_idand have existing data or be targeted by ahelix_set. Surfaced viaGET /me/helixAccessandGET /users/{userId}/helixAccess. assertUserBelongsToHelixDomain.jsguards admin routes (e.g. additional-email management) to prevent cross-domain Helix data leakage.
Frontend flag helpersβ
frontend/src/common/utils/helix/ wraps helixIntegrationMode and the display settings into simple booleans/helpers used throughout the app:
// isHelixEnabled.ts
export const isHelixEnabled =
config.helixIntegrationMode === 'helix' ||
config.helixIntegrationMode === 'both';
isHelixEnabledβ Helix features should show at allisHelixOnlyHubβmode === 'helix'(Learning features should be hidden)isHelixAndLearningHubβmode === 'both'getHelixUIMode({isAdminView})β one view's display settings (see Display settings). Components useuseHelixUIMode()instead, which picks the view fromHelixAdminViewProvider.getHelixScoreBand()/useViewerScoreBand()β the band for a score, raw or normalised to a band positiongetHelixGraphTooltip()β tooltip copy helper for score graphs
These gate large parts of both apps' navigation β e.g. on a Helix-only hub, Asset Library/Playlists/Nudges/Topics are hidden entirely from both main (Navigation.tsx, HelixOnlyAccessWrapper.tsx) and admin (nav.tsx, ToolsMenu.tsx, LogsMenu.tsx).
Role-editing UI mirrors the backend privileges: frontend/src/common/utils/privileges/constants.ts merges a helixPermission array into the available permission set only when the domain is in helix/both mode (adminRoles/index.js, NewRoleModal.js, PermissionsEditorPanel.js).
Frontend surface areaβ
Main app (frontend/src/common/screens/UserSkills/) β the "My Skills" experience:
WelcomePageβ onboarding, explains inviting the agent account; embeds the onboarding agent card (OnboardingMindsetCard) inline whenshowAgentInHelixPagesis on and the user has no skills data yetSkillAnalysisPage,WeekAnalysisPage,MeetingAnalysisPageβ score/feedback viewsHelixNotAvailablePageβ shown when a user lacks Helix accessHelixInfoButton/HelixInfoModalβ explains what Helix is inlineMindsetAgentDock(frontend/src/common/components/MindsetAgentDock/) β persistent sidebar (desktop) / FAB (mobile) for Mindset Coach, a separate, related AI-coaching feature (see Scoring engine) that Helix pages surface viauseCheckIfWeShowAgentInPage; hides itself automatically whenever a page embeds its own agent card instead (e.g.OnboardingMindsetCard), so only one agent instance ever runs at once
Admin app:
- Settings page β the domain config flags above, including the per-view display settings and the score band editor
- Skills management (
admin/pages/skills/) β the skills themselves, and the sets that group them. A set's detail panel is where its skills are ordered: alphabetically, or in a custom order dragged into place, stored ashelix_set_skill.sort_order(see Data model) - Skills Analytics (
admin/pages/skillsAnalytics/) β heatmap/progression/weeks-and-teams views - Skill Logs (
admin/pages/logs/skills/) - Meeting Reprocessing (
admin/pages/meetingReprocessing/) β see Scoring engine β Manual reprocessing - Helix email-watch toggle and the "Run Helix weekly email for all users on all hubs" button (see Scoring engine β weekly roll-up)
Calendar connection UI: CalendarDeAuthorisedContent.tsx plus the OAuth callback handlers under me/calendar/google/auth/callback and me/calendar/microsoft/auth/callback β see Meeting bots β User-side calendar connection.