From 15856ce760590590ebc3fb61e14be8ffca0e4333 Mon Sep 17 00:00:00 2001 From: rcourtman Date: Sun, 28 Jun 2026 13:30:53 +0100 Subject: [PATCH] fix(frontend): hide stale agent prompts in demo mode --- .../subsystems/frontend-primitives.md | 5 ++++ .../SharedPrimitives.guardrails.test.ts | 6 +++++ .../PlatformOutdatedAgentNotice.test.tsx | 27 +++++++++++++++++++ .../PlatformOutdatedAgentNotice.tsx | 4 ++- 4 files changed, 41 insertions(+), 1 deletion(-) diff --git a/docs/release-control/v6/internal/subsystems/frontend-primitives.md b/docs/release-control/v6/internal/subsystems/frontend-primitives.md index 143f320d5..a716b1b86 100644 --- a/docs/release-control/v6/internal/subsystems/frontend-primitives.md +++ b/docs/release-control/v6/internal/subsystems/frontend-primitives.md @@ -2462,6 +2462,11 @@ payload, but the browser-owned shared primitive is now the resolved monitored-system warning banners, dashboard upsells, Patrol upgrade CTAs, history-lock paywalls, and other public-demo commercial affordances when the browser is rendering a public demo runtime. +Platform stale-agent notices are also command-style upgrade affordances: +`frontend-modern/src/features/platformPage/PlatformOutdatedAgentNotice.tsx` +must stay hidden while the resolved presentation policy marks the session +read-only, including public demo mode, even though the same notice remains +available for ordinary customer installs that report outdated agents. That same shared settings-shell boundary also owns demo-mode organization suppression. `frontend-modern/src/components/Settings/settingsNavigationModel.ts`, `frontend-modern/src/components/Settings/settingsNavCatalog.ts`, diff --git a/frontend-modern/src/components/shared/SharedPrimitives.guardrails.test.ts b/frontend-modern/src/components/shared/SharedPrimitives.guardrails.test.ts index 3d6605024..b8953263b 100644 --- a/frontend-modern/src/components/shared/SharedPrimitives.guardrails.test.ts +++ b/frontend-modern/src/components/shared/SharedPrimitives.guardrails.test.ts @@ -4833,6 +4833,12 @@ describe('shared primitive guardrails', () => { expect(source).not.toContain('rounded-lg border border-amber-300 bg-amber-50'); expect(source).not.toContain('text-amber-900 underline-offset-2'); } + expect(platformOutdatedAgentNoticeSource).toContain( + "import { presentationPolicyIsReadOnly } from '@/stores/sessionPresentationPolicy';", + ); + expect(platformOutdatedAgentNoticeSource).toContain( + 'const visible = createMemo(() => count() > 0 && !presentationPolicyIsReadOnly());', + ); }); it('routes dismissible demo notices through InlineNotice banner primitives', () => { diff --git a/frontend-modern/src/features/platformPage/PlatformOutdatedAgentNotice.test.tsx b/frontend-modern/src/features/platformPage/PlatformOutdatedAgentNotice.test.tsx index a92bb64db..447ad0546 100644 --- a/frontend-modern/src/features/platformPage/PlatformOutdatedAgentNotice.test.tsx +++ b/frontend-modern/src/features/platformPage/PlatformOutdatedAgentNotice.test.tsx @@ -1,9 +1,11 @@ import { cleanup, render, screen } from '@solidjs/testing-library'; import { afterEach, describe, expect, it } from 'vitest'; +import { syncSessionPresentationPolicy } from '@/stores/sessionPresentationPolicy'; import { PlatformOutdatedAgentNotice } from './PlatformOutdatedAgentNotice'; afterEach(() => { cleanup(); + syncSessionPresentationPolicy(null); }); describe('PlatformOutdatedAgentNotice', () => { @@ -65,6 +67,31 @@ describe('PlatformOutdatedAgentNotice', () => { ); }); + it('hides agent upgrade commands when the session presentation policy hides upgrade prompts', () => { + syncSessionPresentationPolicy({ + presentationPolicy: { + demoMode: true, + readOnly: true, + hideCommercial: true, + hideUpgrade: true, + }, + }); + + render(() => ( + + )); + + expect(screen.queryByTestId('platform-outdated-agent-notice')).not.toBeInTheDocument(); + expect(screen.queryByRole('link', { name: 'Open agent upgrade commands' })).toBeNull(); + }); + it('can describe stale in-guest agents on VMs without host copy', () => { render(() => ( props.actionLabel || 'Open Infrastructure settings'); const subjectSingular = createMemo(() => props.subjectSingular || 'host'); const subjectPlural = createMemo(() => props.subjectPlural || 'hosts'); + const visible = createMemo(() => count() > 0 && !presentationPolicyIsReadOnly()); const message = createMemo(() => { const target = props.targetVersion ? ` to ${props.targetVersion}` : ''; @@ -49,7 +51,7 @@ export function PlatformOutdatedAgentNotice(props: PlatformOutdatedAgentNoticePr }); return ( - 0}> +