diff --git a/docs/release-control/v6/internal/subsystems/cloud-paid.md b/docs/release-control/v6/internal/subsystems/cloud-paid.md index da1f339ff..b511cee88 100644 --- a/docs/release-control/v6/internal/subsystems/cloud-paid.md +++ b/docs/release-control/v6/internal/subsystems/cloud-paid.md @@ -1450,12 +1450,12 @@ That Pro-license presentation rule is explicit UX, not only hidden metadata: when a migrated recurring v5 plan is active or in grace, the settings surface must render plan terms and a continuity notice that makes it clear the existing recurring price remains in force until cancellation, while -self-hosted monitoring and child-resource volume are not metered under the -current v6 policy. The same plan summary must not render a separate +self-hosted monitoring and child-resource volume are not metered in current v6 +self-hosted packaging. The same plan summary must not render a separate `Guest Capacity`, child-resource allowance, or equivalent volume-cap row for uncapped/grandfathered self-hosted plans; the customer-facing continuity story is existing-price protection plus unmetered self-hosted monitoring and -child-resource volume under the current v6 policy, not a new paid +child-resource volume in current v6 self-hosted packaging, not a new paid guest-capacity benefit. The self-hosted commercial presentation on that same surface is now locked to the no-cap monitored-system model as well. `ProLicensePanel.tsx`, @@ -1467,7 +1467,8 @@ remote access/mobile/push convenience and 14-day history, Pro adds Relay plus AI operations, automation, root-cause analysis, safe remediation, advanced administration, and 90-day history, while Pro+ remains legacy continuity only. Cloud/MSP pricing semantics stay separate, and grandfathered v5 continuity copy -remains an explicit boundary policy. +must describe legacy continuity and recorded baselines rather than current +self-hosted monitored-system caps, capacity, or policy boundaries. That same settings-owned presentation must distinguish between active grandfathered recurring v5 continuity and stale bounded legacy fallback metadata. Active grandfathered recurring v5 plans must render the existing @@ -1582,38 +1583,36 @@ default billing and pricing surfaces should use concise monitored-system copy, while the full counted-unit definition appears only behind explicit disclosure such as `View counting rules` on the usage-owned monitored-system surfaces instead of sitting as persistent plan-tab chrome. -The same boundary also owns where monitored-system capacity truth lives. A -dedicated self-hosted Pro plan-surface capacity section is only canonical -when Pulse is reconciling or enforcing a finite monitored-system limit, such -as bounded migration continuity, grandfathered floors, or other explicit -carry-forward limits. Unmetered self-hosted plans should not keep a -`Monitoring capacity` section alive just to restate that monitoring is -included without a monitored-system volume gate; those plan surfaces should -reserve counted-unit explanation plus current usage inspection for the bounded -legacy usage ledger/disclosure path. When a finite -plan is full, the section must explain that existing monitoring continues -while new monitored systems are blocked; when an installation is already above -the current plan, it must explain that Pulse is in an over-plan frozen state -rather than implying a hard runtime blackout. +The same boundary also owns where monitored-system continuity truth lives. A +dedicated self-hosted Pro plan-surface continuity section is only canonical when +Pulse is reconciling bounded legacy migration continuity or other explicit +carry-forward support context. Normal self-hosted plans should not keep a +`Monitoring capacity` section alive just to restate that monitoring is included +without a monitored-system volume gate; those plan surfaces should reserve +counted-unit explanation plus current usage inspection for the legacy +ledger/disclosure path. When a carried-forward baseline needs review, the +section must explain that existing monitoring remains visible while new +top-level additions wait for continuity review or verification, not that the +customer has hit a current self-hosted plan quota. The app-shell monitored-system warning entry point must also use that same -shape: urgent finite-policy states review the usage-owned policy ledger, not -the plan-selection surface, and the CTA must not revive "View capacity" copy as -an upsell-shaped monitored-system prompt. -Community overflow/setup-slot messaging must still explain the included -monitored systems plus the temporary setup slot in customer terms rather than -compressing the contract into slash-style quota strings that imply Pulse is -counting every child device. -That same billing-facing boundary also owns why an installation can be above -plan at all. When the monitored-system posture is `over_limit_frozen`, customer -copy must explain whether the installation was already above the current plan -before new admissions were blocked or whether migrated v5 continuity capture is -still pending. Billing surfaces must not render an unexplained `15 monitored, -plan includes 5` state that looks like Pulse is ignoring its own cap model. +shape: urgent legacy-continuity states review the usage-owned ledger, not the +plan-selection surface, and the CTA must not revive "View capacity" copy as an +upsell-shaped monitored-system prompt. +Community overflow/setup-slot messaging must still explain the current +top-level monitored systems plus any temporary setup slot in customer terms +rather than compressing the contract into slash-style quota strings that imply +Pulse is counting every child device. +That same billing-facing boundary also owns why an installation can require +legacy review at all. When the monitored-system posture is `over_limit_frozen`, +customer copy must explain whether a carried-forward baseline needs review or +whether migrated v5 continuity capture is still pending. Billing surfaces must +not render an unexplained `15 monitored, plan includes 5` state that looks like +Pulse is enforcing a current self-hosted cap model. Those same billing-facing surfaces must also describe the commercial contract in -customer terms: monitored systems, plan limits, subscription status, and -license status. They must not revive legacy `installed-agent` wording or vague -internal nouns like `allocation` once the monitored-system billing model is the -canonical product truth. +customer terms: monitored systems, legacy continuity baselines, subscription +status, and license status. They must not revive legacy `installed-agent` +wording or vague internal nouns like `allocation` once the monitored-system +billing model is the canonical product truth. Loading, empty, and temporary-unavailable states on monitored-system usage surfaces follow that same rule: they should use calm customer-facing status language such as usage loading or usage unavailable with a clear retry action, diff --git a/frontend-modern/src/components/Settings/__tests__/MonitoredSystemAdmissionPreview.test.tsx b/frontend-modern/src/components/Settings/__tests__/MonitoredSystemAdmissionPreview.test.tsx index 3c04dfdbd..dd1f602f7 100644 --- a/frontend-modern/src/components/Settings/__tests__/MonitoredSystemAdmissionPreview.test.tsx +++ b/frontend-modern/src/components/Settings/__tests__/MonitoredSystemAdmissionPreview.test.tsx @@ -57,7 +57,7 @@ describe('MonitoredSystemAdmissionPreview', () => { ).toBeInTheDocument(); }); - it('describes active-policy failures without slash quota copy', () => { + it('describes continuity review failures without slash quota copy', () => { render(() => ( { )); expect( - screen.getByText('This change exceeds the active monitored-system policy'), + screen.getByText('This change needs continuity review before saving'), ).toBeInTheDocument(); expect( screen.getByText( - 'Pulse currently counts 9 monitored systems. Saving this change would bring the count to 11 monitored systems (+2), above the active policy of 10 monitored systems.', + 'Pulse currently counts 9 monitored systems. Saving this change would bring the count to 11 monitored systems (+2), above the current verified baseline of 10 monitored systems.', ), ).toBeInTheDocument(); }); diff --git a/frontend-modern/src/components/Settings/__tests__/MonitoredSystemLedgerPanel.test.tsx b/frontend-modern/src/components/Settings/__tests__/MonitoredSystemLedgerPanel.test.tsx index 6b7e4355b..62d061497 100644 --- a/frontend-modern/src/components/Settings/__tests__/MonitoredSystemLedgerPanel.test.tsx +++ b/frontend-modern/src/components/Settings/__tests__/MonitoredSystemLedgerPanel.test.tsx @@ -269,11 +269,11 @@ describe('MonitoredSystemLedgerPanel', () => { expect(screen.getByText('7 monitored systems')).toBeInTheDocument(); }); - expect(screen.getByText('Plan continuity')).toBeInTheDocument(); - expect(screen.getByText('Plan limit')).toBeInTheDocument(); - expect(screen.getByText('Effective limit')).toBeInTheDocument(); - expect(screen.getByText('Grandfathered floor')).toBeInTheDocument(); - expect(screen.getByText('Continuity capture')).toBeInTheDocument(); + expect(screen.getByText('Legacy continuity')).toBeInTheDocument(); + expect(screen.getByText('Plan baseline')).toBeInTheDocument(); + expect(screen.getByText('Current baseline')).toBeInTheDocument(); + expect(screen.getByText('Observed legacy estate')).toBeInTheDocument(); + expect(screen.getByText('Verification')).toBeInTheDocument(); expect(screen.getByText('5')).toBeInTheDocument(); expect(screen.getAllByText('12')).toHaveLength(2); expect(screen.getByText('Pending')).toBeInTheDocument(); @@ -372,7 +372,7 @@ describe('MonitoredSystemLedgerPanel', () => { expect(screen.getAllByText('server-b (PBS Server via PBS)').length).toBeGreaterThan(0); expect( screen.getByText( - 'Review the top-level monitored systems Pulse has identified for reporting and any applicable policy.', + 'Review the top-level monitored systems Pulse has identified for reporting, migration continuity, and support context.', ), ).toBeInTheDocument(); expect(screen.getByRole('button', { name: 'View counting rules' })).toBeInTheDocument(); @@ -391,9 +391,7 @@ describe('MonitoredSystemLedgerPanel', () => { ).toBeInTheDocument(); expect(screen.getByText('server-b')).toBeInTheDocument(); expect(screen.getByText('2 monitored systems')).toBeInTheDocument(); - expect( - screen.getByText('8 remaining before additional monitored-system admissions pause.'), - ).toBeInTheDocument(); + expect(screen.queryByText('Continuity review')).not.toBeInTheDocument(); expect(screen.getAllByRole('button', { name: 'View counting details' })).toHaveLength(2); fireEvent.click(screen.getAllByRole('button', { name: 'View counting details' })[1]!); expect( diff --git a/frontend-modern/src/components/Settings/__tests__/ProLicensePanel.test.tsx b/frontend-modern/src/components/Settings/__tests__/ProLicensePanel.test.tsx index 4418ec3f0..9d51b1ac5 100644 --- a/frontend-modern/src/components/Settings/__tests__/ProLicensePanel.test.tsx +++ b/frontend-modern/src/components/Settings/__tests__/ProLicensePanel.test.tsx @@ -377,7 +377,7 @@ describe('ProLicensePanel', () => { ), ).toBeInTheDocument(); expect(screen.queryByText('Included Monitored Systems')).not.toBeInTheDocument(); - expect(screen.queryByText('Grandfathered monitored-system floor')).not.toBeInTheDocument(); + expect(screen.queryByText('Legacy monitoring continuity')).not.toBeInTheDocument(); expect(screen.queryByText('Plan Monitored System Limit')).not.toBeInTheDocument(); expect(screen.getByRole('tab', { name: 'Plan' })).toHaveAttribute('aria-selected', 'true'); expect(screen.queryByRole('tab', { name: 'Usage' })).not.toBeInTheDocument(); @@ -465,7 +465,7 @@ describe('ProLicensePanel', () => { ).not.toBeInTheDocument(); expect( screen.getAllByText( - /self-hosted monitoring and child-resource volume are not metered under the current v6 policy/i, + /self-hosted monitoring and child-resource volume are not metered in current v6 self-hosted packaging/i, ).length, ).toBeGreaterThan(0); expect( @@ -610,7 +610,7 @@ describe('ProLicensePanel', () => { 'Included', ), ).toBeInTheDocument(); - expect(screen.queryByText('Migration continuity verification pending')).not.toBeInTheDocument(); + expect(screen.queryByText('Legacy continuity verification pending')).not.toBeInTheDocument(); expect(screen.queryByText('Continuity pending')).not.toBeInTheDocument(); expect(screen.queryByText('Plan Monitored System Limit')).not.toBeInTheDocument(); expect(screen.queryByText('Effective Monitored System Limit')).not.toBeInTheDocument(); @@ -669,13 +669,13 @@ describe('ProLicensePanel', () => { 'Included', ), ).toBeInTheDocument(); - expect(screen.queryByText(/already monitoring 23/i)).not.toBeInTheDocument(); - expect(screen.queryByText('Migration continuity verification pending')).not.toBeInTheDocument(); + expect(screen.queryByText(/identified 23 monitored systems/i)).not.toBeInTheDocument(); + expect(screen.queryByText('Legacy continuity verification pending')).not.toBeInTheDocument(); expect(screen.queryByText('Monitored-system policy')).not.toBeInTheDocument(); expect(screen.queryByText('Why is continuity still pending?')).not.toBeInTheDocument(); expect(screen.queryByRole('tab', { name: 'Usage' })).not.toBeInTheDocument(); expect( - screen.queryByText('Monitoring continues above the current policy boundary'), + screen.queryByText('New top-level additions are paused until this legacy continuity state is reviewed.'), ).not.toBeInTheDocument(); }); @@ -730,11 +730,11 @@ describe('ProLicensePanel', () => { 'Included', ), ).toBeInTheDocument(); - expect(screen.queryByText('Grandfathered monitored-system floor')).not.toBeInTheDocument(); + expect(screen.queryByText('Legacy monitoring continuity')).not.toBeInTheDocument(); expect( - screen.queryByText(/keeps an effective monitored-system limit of 23/i), + screen.queryByText(/observed legacy estate available/i), ).not.toBeInTheDocument(); - expect(screen.queryByText('Grandfathered floor')).not.toBeInTheDocument(); + expect(screen.queryByText('Legacy continuity')).not.toBeInTheDocument(); expect(screen.queryByText('23 monitored systems')).not.toBeInTheDocument(); expect(screen.queryByText('Monitored-system policy')).not.toBeInTheDocument(); expect( diff --git a/frontend-modern/src/components/Settings/__tests__/useTrueNASSettingsPanelState.test.tsx b/frontend-modern/src/components/Settings/__tests__/useTrueNASSettingsPanelState.test.tsx index 33ae789e6..457ba3f07 100644 --- a/frontend-modern/src/components/Settings/__tests__/useTrueNASSettingsPanelState.test.tsx +++ b/frontend-modern/src/components/Settings/__tests__/useTrueNASSettingsPanelState.test.tsx @@ -244,7 +244,7 @@ describe('useTrueNASSettingsPanelState', () => { expect(TrueNASAPI.createConnection).not.toHaveBeenCalled(); expect(notificationStore.error).toHaveBeenCalledWith( - 'Pulse must verify the monitored-system policy for this platform connection before it can be saved.', + 'Pulse must preview the monitored-system impact for this platform connection before it can be saved.', ); }); diff --git a/frontend-modern/src/components/Settings/__tests__/useVMwareSettingsPanelState.test.tsx b/frontend-modern/src/components/Settings/__tests__/useVMwareSettingsPanelState.test.tsx index 60fd8b5ef..f8d3f9da3 100644 --- a/frontend-modern/src/components/Settings/__tests__/useVMwareSettingsPanelState.test.tsx +++ b/frontend-modern/src/components/Settings/__tests__/useVMwareSettingsPanelState.test.tsx @@ -242,7 +242,7 @@ describe('useVMwareSettingsPanelState', () => { expect(VMwareAPI.createConnection).not.toHaveBeenCalled(); expect(notificationStore.error).toHaveBeenCalledWith( - 'Pulse must verify the monitored-system policy for this platform connection before it can be saved.', + 'Pulse must preview the monitored-system impact for this platform connection before it can be saved.', ); }); diff --git a/frontend-modern/src/components/shared/__tests__/MonitoredSystemLimitWarningBanner.test.tsx b/frontend-modern/src/components/shared/__tests__/MonitoredSystemLimitWarningBanner.test.tsx index 3584dcbfa..8742c5cac 100644 --- a/frontend-modern/src/components/shared/__tests__/MonitoredSystemLimitWarningBanner.test.tsx +++ b/frontend-modern/src/components/shared/__tests__/MonitoredSystemLimitWarningBanner.test.tsx @@ -216,8 +216,8 @@ describe('MonitoredSystemLimitWarningBanner', () => { )); - expect(screen.getByText('1 remaining. 5 monitored, 6 included.')).toBeInTheDocument(); - expect(screen.getByText('Review policy')).toHaveAttribute( + expect(screen.getByText('5 monitored systems.')).toBeInTheDocument(); + expect(screen.getByText('Review continuity')).toHaveAttribute( 'href', '/settings/system/billing/usage', ); @@ -270,9 +270,9 @@ describe('MonitoredSystemLimitWarningBanner', () => { )); - expect(screen.getByText('1 remaining. 5 monitored, 6 included.')).toBeInTheDocument(); + expect(screen.getByText('5 monitored systems.')).toBeInTheDocument(); expect(screen.getByText('Install v6 collectors')).toHaveAttribute('href', '/settings'); - expect(screen.getByText('Review policy')).toHaveAttribute( + expect(screen.getByText('Review continuity')).toHaveAttribute( 'href', '/settings/system/billing/usage', ); @@ -297,7 +297,7 @@ describe('MonitoredSystemLimitWarningBanner', () => { )); expect( - screen.queryByText('1 remaining. 5 monitored, 6 included.'), + screen.queryByText('5 monitored systems.'), ).not.toBeInTheDocument(); expect(mockTrackUpgradeMetricEvent).not.toHaveBeenCalled(); }); @@ -320,12 +320,12 @@ describe('MonitoredSystemLimitWarningBanner', () => { )); expect( - screen.queryByText('1 remaining. 5 monitored, 6 included.'), + screen.queryByText('5 monitored systems.'), ).not.toBeInTheDocument(); expect(mockTrackUpgradeMetricEvent).not.toHaveBeenCalled(); }); - it('stays hidden for self-hosted installs even when a stale finite policy is urgent', async () => { + it('stays hidden for self-hosted installs even when stale continuity metadata is urgent', async () => { mockGetLimit.mockReturnValue({ key: 'max_monitored_systems', limit: 6, @@ -341,7 +341,7 @@ describe('MonitoredSystemLimitWarningBanner', () => { )); expect( - screen.queryByText('1 remaining. 5 monitored, 6 included.'), + screen.queryByText('5 monitored systems.'), ).not.toBeInTheDocument(); expect(mockTrackUpgradeMetricEvent).not.toHaveBeenCalled(); }); diff --git a/frontend-modern/src/utils/__tests__/commercialBillingModel.test.ts b/frontend-modern/src/utils/__tests__/commercialBillingModel.test.ts index ed3dcbe90..bdaa91936 100644 --- a/frontend-modern/src/utils/__tests__/commercialBillingModel.test.ts +++ b/frontend-modern/src/utils/__tests__/commercialBillingModel.test.ts @@ -55,21 +55,55 @@ describe('commercialBillingModel', () => { expect(JSON.stringify(model)).not.toContain('Unlimited'); }); - it('keeps bounded monitored-system details on legacy fallback paths', () => { + it('keeps bounded monitored-system details as legacy support context', () => { const model = buildSelfHostedCommercialPlanModel({ ...createBaseInput(), monitoredSystemsSummary: '7 monitored systems', - capacityStatusSummary: '3 remaining', + capacityStatusSummary: 'Continuity review', maxMonitoredSystems: 10, retailPlanDefinition: null, }); expect(model.summary).toEqual([ { label: 'Monitored Systems', value: '7 monitored systems' }, - { label: 'Capacity Status', value: '3 remaining' }, + { label: 'Continuity Status', value: 'Continuity review' }, { label: 'Plan Status', value: 'Active' }, ]); - expect(model.details.map((item) => item.label)).toContain('Included Monitored Systems'); + expect(model.details.map((item) => item.label)).toContain('Recorded Monitoring Baseline'); expect(model.details.map((item) => item.label)).not.toContain('Guest Capacity'); }); + + it('labels captured legacy continuity as baselines instead of current limits', () => { + const model = buildSelfHostedCommercialPlanModel({ + ...createBaseInput(), + monitoredSystemsSummary: '23 monitored systems', + capacityStatusSummary: 'Continuity review', + maxMonitoredSystems: SELF_HOSTED_NOT_METERED_LABEL, + retailPlanDefinition: null, + monitoredSystemContinuity: { + plan_limit: 10, + grandfathered_floor: 23, + effective_limit: 23, + capture_pending: false, + }, + }); + + expect(model.summary).toEqual([ + { label: 'Monitored Systems', value: '23 monitored systems' }, + { label: 'Continuity Status', value: 'Continuity review' }, + { label: 'Plan Status', value: 'Active' }, + ]); + expect(model.details.map((item) => item.label)).toEqual([ + 'Tier', + 'Licensed Email', + 'Plan Terms', + 'Expires', + 'Days Remaining', + 'Plan Baseline', + 'Current Baseline', + 'Observed Legacy Estate', + 'Continuity Verification', + ]); + expect(JSON.stringify(model)).not.toContain('Monitored System Limit'); + }); }); diff --git a/frontend-modern/src/utils/__tests__/licensePresentation.test.ts b/frontend-modern/src/utils/__tests__/licensePresentation.test.ts index 760eb64f7..82484b8ac 100644 --- a/frontend-modern/src/utils/__tests__/licensePresentation.test.ts +++ b/frontend-modern/src/utils/__tests__/licensePresentation.test.ts @@ -374,7 +374,7 @@ describe('licensePresentation', () => { ], supplementalBadges: ['Grandfathered price'], supplementalSummary: - 'This migrated v5 subscription keeps its existing recurring price until cancellation. Self-hosted monitoring and child-resource volume are not metered under the current v6 policy.', + 'This migrated v5 subscription keeps its existing recurring price until cancellation. Self-hosted monitoring and child-resource volume are not metered in current v6 self-hosted packaging.', }); }); @@ -579,8 +579,8 @@ describe('licensePresentation', () => { }, ), ).toMatchObject({ - title: 'Migration continuity verification pending', - body: expect.stringContaining('grandfathered monitored-system floor'), + title: 'Legacy continuity verification pending', + body: expect.stringContaining('legacy v5 monitoring continuity'), tone: expect.stringContaining('amber'), }); expect( @@ -610,8 +610,8 @@ describe('licensePresentation', () => { }, ), ).toMatchObject({ - title: 'Migration continuity verification pending', - body: expect.stringContaining('already monitoring 23'), + title: 'Legacy continuity verification pending', + body: expect.stringContaining('identified 23 monitored systems'), tone: expect.stringContaining('amber'), }); expect( @@ -671,7 +671,7 @@ describe('licensePresentation', () => { }, ), ).toMatchObject({ - title: 'Grandfathered monitored-system floor', + title: 'Legacy monitoring continuity', tone: expect.stringContaining('green'), }); }); diff --git a/frontend-modern/src/utils/__tests__/monitoredSystemPresentation.test.ts b/frontend-modern/src/utils/__tests__/monitoredSystemPresentation.test.ts index 2a5cc94bf..b049336e8 100644 --- a/frontend-modern/src/utils/__tests__/monitoredSystemPresentation.test.ts +++ b/frontend-modern/src/utils/__tests__/monitoredSystemPresentation.test.ts @@ -3,6 +3,7 @@ import { describe, expect, it } from 'vitest'; import proLicensePanelStateSource from '@/components/Settings/useProLicensePanelState.ts?raw'; import monitoredSystemLedgerPanelSource from '@/components/Settings/MonitoredSystemLedgerPanel.tsx?raw'; import monitoredSystemLimitWarningBannerModelSource from '@/components/shared/monitoredSystemLimitWarningBannerModel.ts?raw'; +import commercialBillingModelSource from '@/utils/commercialBillingModel.ts?raw'; import licensePresentationSource from '@/utils/licensePresentation.ts?raw'; import monitoredSystemPresentationSource from '@/utils/monitoredSystemPresentation.ts?raw'; import { @@ -62,18 +63,18 @@ describe('monitoredSystemPresentation', () => { disclosureDefinition: 'A monitored system is a top-level monitored root such as a Docker host, Kubernetes cluster, Proxmox node, standalone host, or TrueNAS system. Each root counts once no matter how Pulse collects it. Child resources like VMs, containers, pods, disks, backups, and services underneath that root are included.', ledgerDescription: - 'Review the top-level monitored systems Pulse has identified for reporting and any applicable policy.', + 'Review the top-level monitored systems Pulse has identified for reporting, migration continuity, and support context.', tableNameLabel: 'Name', tableStatusLabel: 'Status', tableLatestIncludedSignalLabel: 'Latest Included Signal', countedSystemBadgeLabel: 'Counts as 1 monitored system', groupedSourcesHeading: 'Grouped sources', countingExplanationHeading: 'Why this counts', - continuityHeading: 'Plan continuity', - continuityPlanLimitLabel: 'Plan limit', - continuityEffectiveLimitLabel: 'Effective limit', - continuityGrandfatheredFloorLabel: 'Grandfathered floor', - continuityCaptureLabel: 'Continuity capture', + continuityHeading: 'Legacy continuity', + continuityPlanLimitLabel: 'Plan baseline', + continuityEffectiveLimitLabel: 'Current baseline', + continuityGrandfatheredFloorLabel: 'Observed legacy estate', + continuityCaptureLabel: 'Verification', continuityCapturePendingLabel: 'Pending', continuityCaptureCapturedLabel: 'Captured', usageVerifyingLabel: 'Verifying…', @@ -99,7 +100,7 @@ describe('monitoredSystemPresentation', () => { policyLoadingState: { title: 'Checking monitored-system visibility', message: - 'Pulse waits for the session presentation policy before loading monitored-system usage details.', + 'Pulse waits for the session visibility state before loading monitored-system usage details.', }, hiddenState: { title: 'Monitored-system usage is hidden in demo mode', @@ -124,7 +125,7 @@ describe('monitoredSystemPresentation', () => { unknown: 'Pulse cannot determine a canonical runtime status for this monitored system yet.', }, limitBanner: { - reviewPolicyLabel: 'Review policy', + reviewPolicyLabel: 'Review continuity', installCollectorsLabel: 'Install v6 collectors', overflowSummaryPrefix: 'A temporary setup slot is active', legacyConnectionSuffix: @@ -133,20 +134,20 @@ describe('monitoredSystemPresentation', () => { admissionPreview: { requiredTitle: 'Preview monitored-system impact before saving', requiredMessage: - 'Pulse must verify the monitored-system policy for this platform connection before it can be saved.', + 'Pulse must preview the monitored-system impact for this platform connection before it can be saved.', fallbackTitle: 'Monitored-system impact', - exceedsPolicyTitle: 'This change exceeds the active monitored-system policy', + exceedsPolicyTitle: 'This change needs continuity review before saving', addsSystemsTitle: 'This change adds monitored systems', removesSystemsTitle: 'This change removes monitored systems', unchangedTitle: 'This change keeps monitored-system count unchanged', unavailableTitle: 'Monitored-system verification is temporarily unavailable', unavailableFallbackMessage: - 'Pulse cannot verify monitored-system policy right now, so this connection cannot be saved yet. Retry preview in a moment.', + 'Pulse cannot verify monitored-system impact right now, so this connection cannot be saved yet. Retry preview in a moment.', unavailableUnsettledMessage: 'Pulse is still settling provider-owned inventory for this platform connection, so the monitored-system check is not safe yet. Retry preview after the first baseline finishes.', unavailableRebuildPendingMessage: 'Pulse has settled provider-owned inventory and is rebuilding the canonical monitored-system view, so this connection cannot be saved yet. Retry preview in a moment.', - saveBlockedLimitMessage: 'This change would exceed the active monitored-system policy', + saveBlockedLimitMessage: 'This change needs monitored-system review before saving', saveBlockedLoadingMessage: 'Wait for the monitored-system impact preview to finish', }, }); @@ -158,7 +159,7 @@ describe('monitoredSystemPresentation', () => { expect(getMonitoredSystemDisclosureDefinition()).toContain('Docker host'); expect(getMonitoredSystemDisclosureDefinition()).toContain('Proxmox node'); expect(getMonitoredSystemLedgerDescription()).toBe( - 'Review the top-level monitored systems Pulse has identified for reporting and any applicable policy.', + 'Review the top-level monitored systems Pulse has identified for reporting, migration continuity, and support context.', ); expect(getMonitoredSystemLedgerLoadingState()).toEqual({ text: 'Loading monitored system usage…', @@ -180,7 +181,7 @@ describe('monitoredSystemPresentation', () => { expect(getMonitoredSystemLedgerPolicyLoadingState()).toEqual({ title: 'Checking monitored-system visibility', message: - 'Pulse waits for the session presentation policy before loading monitored-system usage details.', + 'Pulse waits for the session visibility state before loading monitored-system usage details.', }); expect(getMonitoredSystemLedgerHiddenState()).toEqual({ title: 'Monitored-system usage is hidden in demo mode', @@ -230,16 +231,43 @@ describe('monitoredSystemPresentation', () => { } expect(proLicensePanelStateSource).not.toContain("'Verifying…'"); expect(proLicensePanelStateSource).not.toContain("'Unavailable'"); + + const paidLimitPhrases = [ + 'active monitored-system policy', + 'additional monitored-system admissions', + 'finite policy', + 'policy boundary', + 'capacity is available', + 'Grandfathered monitored-system floor', + 'effective monitored-system limit', + 'Plan Monitored System Limit', + 'Effective Monitored System Limit', + 'Included Monitored Systems', + 'remaining before', + 'Over policy', + ]; + for (const source of [ + commercialBillingModelSource, + licensePresentationSource, + monitoredSystemLedgerPanelSource, + monitoredSystemLimitWarningBannerModelSource, + monitoredSystemPresentationSource, + proLicensePanelStateSource, + ]) { + for (const phrase of paidLimitPhrases) { + expect(source).not.toContain(phrase); + } + } }); it('returns canonical monitored-system limit warning copy', () => { - expect(getMonitoredSystemLimitReviewPolicyLabel()).toBe('Review policy'); + expect(getMonitoredSystemLimitReviewPolicyLabel()).toBe('Review continuity'); expect(getMonitoredSystemLimitInstallCollectorsLabel()).toBe('Install v6 collectors'); expect(formatMonitoredSystemLimitSummary({ current: 5, limit: 6 })).toBe( - '1 remaining. 5 monitored, 6 included.', + '5 monitored systems.', ); expect(formatMonitoredSystemLimitSummary({ current: 16, limit: 5, state: 'enforced' })).toBe( - 'Over policy by 11. 16 monitored, 5 included.', + 'Continuity review needed. 16 monitored systems.', ); expect( formatMonitoredSystemLimitSummary( @@ -257,7 +285,7 @@ describe('monitoredSystemPresentation', () => { existing_monitoring_continues: true, }, ), - ).toBe('Continuity verification pending. 16 monitored, 5 included.'); + ).toBe('Continuity verification pending. 16 monitored systems.'); expect( formatMonitoredSystemLegacyConnectionBreakdown({ proxmox_nodes: 2, @@ -291,20 +319,20 @@ describe('monitoredSystemPresentation', () => { ).toEqual({ stats: [ { label: 'Monitored', value: '16 monitored systems' }, - { label: 'Included', value: '5' }, - { label: 'Status', value: 'Over policy by 11' }, + { label: 'Baseline', value: '5' }, + { label: 'Status', value: 'Continuity review' }, ], - statusMessage: 'Existing monitoring continues. Additional monitored systems are paused.', + statusMessage: 'Existing monitoring remains visible. New top-level additions need review.', detailMessage: - 'Reduce usage or resolve the applicable policy before adding another monitored system.', + 'Review the legacy continuity state before adding another top-level monitored system.', explanation: { - label: 'Why is this over policy?', - body: 'This installation was already monitoring 16 monitored systems before Pulse paused net-new monitored-system admissions at the active finite policy boundary. Pulse keeps those existing systems visible, but additional monitored systems stay paused until usage is reduced or the policy changes.', + label: 'Why does this need review?', + body: 'Pulse has already identified 16 monitored systems for this installation. Existing monitoring remains visible, but new top-level additions are paused until this legacy continuity state is reviewed.', }, }); }); - it('does not build a monitored-system capacity section for uncapped plans', () => { + it('does not build a monitored-system capacity section for unmetered or healthy self-hosted states', () => { expect( buildMonitoredSystemCapacitySectionModel(undefined, { mode: 'unlimited', @@ -318,6 +346,14 @@ describe('monitoredSystemPresentation', () => { existing_monitoring_continues: true, }), ).toBeNull(); + expect( + buildMonitoredSystemCapacitySectionModel({ + current: 7, + limit: 10, + current_available: true, + state: 'ok', + }), + ).toBeNull(); }); it('centralizes monitored-system limit availability and capacity presentation', () => { @@ -358,7 +394,7 @@ describe('monitoredSystemPresentation', () => { limit: 10, current_available: true, }), - ).toBe('3 remaining'); + ).toBe('Healthy'); expect( getMonitoredSystemLimitCapacityStatusSummary({ current: 7, @@ -374,7 +410,7 @@ describe('monitoredSystemPresentation', () => { state: 'enforced', }), ).toBe( - 'This finite policy includes 10. Existing monitoring continues; additional monitored systems stay paused until capacity is available or the policy changes.', + 'Existing monitoring remains visible. New top-level additions are paused until this legacy continuity state is reviewed.', ); expect( getMonitoredSystemLimitContextSummary({ @@ -384,7 +420,7 @@ describe('monitoredSystemPresentation', () => { state: 'enforced', }), ).toBe( - 'This finite policy includes 5. This installation is already over policy by 11 because it was monitoring above that boundary before additional admissions paused. Existing monitoring continues; additional monitored systems stay paused until usage is reduced or the policy changes.', + 'Existing monitoring remains visible. New top-level additions are paused until this legacy continuity state is reviewed.', ); expect( getMonitoredSystemLimitContextSummary( @@ -408,7 +444,7 @@ describe('monitoredSystemPresentation', () => { }, ), ).toBe( - 'This finite policy includes 5. Pulse is still verifying the migrated v5 continuity floor for this installation. Existing monitoring continues while additional monitored-system admissions pause until continuity capture finishes.', + 'Pulse is verifying legacy v5 continuity for this installation. Existing monitoring remains visible while new top-level additions wait for verification to finish.', ); expect( isMonitoredSystemLimitUrgent({ @@ -438,7 +474,7 @@ describe('monitoredSystemPresentation', () => { expect(getMonitoredSystemAdmissionPreviewRequiredState()).toEqual({ title: 'Preview monitored-system impact before saving', message: - 'Pulse must verify the monitored-system policy for this platform connection before it can be saved.', + 'Pulse must preview the monitored-system impact for this platform connection before it can be saved.', }); expect(getMonitoredSystemAdmissionPreviewUnavailableTitle()).toBe( 'Monitored-system verification is temporarily unavailable', @@ -458,7 +494,7 @@ describe('monitoredSystemPresentation', () => { expect( formatMonitoredSystemAdmissionPreviewUnavailableMessage('monitor_state_unavailable'), ).toBe( - 'Pulse cannot verify monitored-system policy right now, so this connection cannot be saved yet. Retry preview in a moment.', + 'Pulse cannot verify monitored-system impact right now, so this connection cannot be saved yet. Retry preview in a moment.', ); expect( buildMonitoredSystemAdmissionPreviewUnavailableState({ @@ -488,13 +524,13 @@ describe('monitoredSystemPresentation', () => { }), ).toBe(false); expect(getMonitoredSystemAdmissionPreviewSaveBlockedMessage({ preview: null })).toBe( - 'Pulse must verify the monitored-system policy for this platform connection before it can be saved.', + 'Pulse must preview the monitored-system impact for this platform connection before it can be saved.', ); expect( getMonitoredSystemAdmissionPreviewSaveBlockedMessage({ preview: { would_exceed_limit: true }, }), - ).toBe('This change would exceed the active monitored-system policy'); + ).toBe('This change needs monitored-system review before saving'); expect( getMonitoredSystemAdmissionPreviewSaveBlockedMessage({ preview: { would_exceed_limit: false }, @@ -531,7 +567,7 @@ describe('monitoredSystemPresentation', () => { projected_count: 11, would_exceed_limit: true, }), - ).toBe('This change exceeds the active monitored-system policy'); + ).toBe('This change needs continuity review before saving'); }); it('formats monitored-system admission preview summaries without quota math', () => { @@ -552,7 +588,7 @@ describe('monitoredSystemPresentation', () => { would_exceed_limit: true, }), ).toBe( - 'Pulse currently counts 9 monitored systems. Saving this change would bring the count to 11 monitored systems (+2), above the active policy of 10 monitored systems.', + 'Pulse currently counts 9 monitored systems. Saving this change would bring the count to 11 monitored systems (+2), above the current verified baseline of 10 monitored systems.', ); }); diff --git a/frontend-modern/src/utils/commercialBillingModel.ts b/frontend-modern/src/utils/commercialBillingModel.ts index f6c732522..ccfa5e154 100644 --- a/frontend-modern/src/utils/commercialBillingModel.ts +++ b/frontend-modern/src/utils/commercialBillingModel.ts @@ -139,7 +139,7 @@ export const buildSelfHostedCommercialPlanModel = ( value: input.monitoredSystemsSummary, }, { - label: 'Capacity Status', + label: 'Continuity Status', value: input.capacityStatusSummary, }, { @@ -152,14 +152,14 @@ export const buildSelfHostedCommercialPlanModel = ( ...(input.monitoredSystemContinuity ? [ { - label: 'Plan Monitored System Limit', + label: 'Plan Baseline', value: input.monitoredSystemContinuity.plan_limit > 0 ? input.monitoredSystemContinuity.plan_limit : SELF_HOSTED_NOT_METERED_LABEL, }, { - label: 'Effective Monitored System Limit', + label: 'Current Baseline', value: input.monitoredSystemContinuity.effective_limit > 0 ? input.monitoredSystemContinuity.effective_limit @@ -169,13 +169,13 @@ export const buildSelfHostedCommercialPlanModel = ( input.monitoredSystemContinuity.grandfathered_floor > 0 ? [ { - label: 'Grandfathered Floor', + label: 'Observed Legacy Estate', value: input.monitoredSystemContinuity.grandfathered_floor, }, ] : []), { - label: 'Continuity Capture', + label: 'Continuity Verification', value: input.monitoredSystemContinuity.capture_pending ? 'Pending' : input.continuityCapturedAt || 'Captured', @@ -184,7 +184,7 @@ export const buildSelfHostedCommercialPlanModel = ( : hasFiniteSelfHostedLimit(input.maxMonitoredSystems) ? [ { - label: 'Included Monitored Systems', + label: 'Recorded Monitoring Baseline', value: input.maxMonitoredSystems, }, ] diff --git a/frontend-modern/src/utils/licensePresentation.ts b/frontend-modern/src/utils/licensePresentation.ts index 2cf451a3f..1a1e6e95d 100644 --- a/frontend-modern/src/utils/licensePresentation.ts +++ b/frontend-modern/src/utils/licensePresentation.ts @@ -251,7 +251,7 @@ export const getGrandfatheredPriceContinuityNotice = ( return { tone: 'border-green-200 dark:border-green-900 bg-green-50 dark:bg-green-900 text-green-900 dark:text-green-100', title: 'Grandfathered v5 pricing', - body: 'This migrated v5 Pro subscription keeps its existing recurring price until you cancel. Self-hosted monitoring and child-resource volume are not metered under the current v6 policy. If you cancel and return later, current v6 pricing applies for paid features.', + body: 'This migrated v5 Pro subscription keeps its existing recurring price until you cancel. Self-hosted monitoring and child-resource volume are not metered in current v6 self-hosted packaging. If you cancel and return later, current v6 pricing applies for paid features.', }; }; @@ -280,8 +280,8 @@ export const getMonitoredSystemContinuityNotice = ( if (!resolvedCapacity?.current_available) { return { tone: 'border-amber-200 dark:border-amber-900 bg-amber-50 dark:bg-amber-900 text-amber-900 dark:text-amber-100', - title: 'Migration continuity verification pending', - body: `Pulse is still verifying the grandfathered monitored-system floor for this migrated v5 installation. ${formatMonitoredSystemUsageUnavailableMessage( + title: 'Legacy continuity verification pending', + body: `Pulse is still verifying legacy v5 monitoring continuity for this installation. ${formatMonitoredSystemUsageUnavailableMessage( getMonitoredSystemLimitUnavailableReason(limit, capacity), )}`, }; @@ -290,15 +290,15 @@ export const getMonitoredSystemContinuityNotice = ( if (resolvedCapacity.mode === 'over_limit_frozen') { return { tone: 'border-amber-200 dark:border-amber-900 bg-amber-50 dark:bg-amber-900 text-amber-900 dark:text-amber-100', - title: 'Migration continuity verification pending', - body: `Pulse is still verifying the grandfathered monitored-system floor for this migrated v5 installation. The finite policy includes ${displayContinuity.plan_limit}, while this installation is already monitoring ${resolvedCapacity.current}. Existing monitoring continues while additional monitored-system admissions pause until continuity capture finishes.`, + title: 'Legacy continuity verification pending', + body: `Pulse is still verifying legacy v5 monitoring continuity for this installation. Pulse has already identified ${resolvedCapacity.current} monitored systems for continuity reporting, and existing monitoring remains visible while new top-level additions wait for verification to finish.`, }; } return { tone: 'border-amber-200 dark:border-amber-900 bg-amber-50 dark:bg-amber-900 text-amber-900 dark:text-amber-100', - title: 'Migration continuity verification pending', - body: 'Pulse is still verifying the grandfathered monitored-system floor for this migrated v5 installation. Existing monitoring continues while Pulse finalizes the effective monitored-system limit.', + title: 'Legacy continuity verification pending', + body: 'Pulse is still verifying legacy v5 monitoring continuity for this installation. Existing monitoring remains visible while Pulse finalizes the continuity baseline.', }; } @@ -319,8 +319,8 @@ export const getMonitoredSystemContinuityNotice = ( ) { return { tone: 'border-green-200 dark:border-green-900 bg-green-50 dark:bg-green-900 text-green-900 dark:text-green-100', - title: 'Grandfathered monitored-system floor', - body: `This migrated v5 installation keeps an effective monitored-system limit of ${displayContinuity.effective_limit}. The current plan includes ${displayContinuity.plan_limit}, and the observed legacy estate was grandfathered at ${displayContinuity.grandfathered_floor}.`, + title: 'Legacy monitoring continuity', + body: `This migrated v5 installation keeps its observed legacy estate available for continuity reporting on this instance. Pulse recorded ${displayContinuity.grandfathered_floor} monitored systems during migration.`, }; } @@ -506,12 +506,12 @@ export const getSelfHostedCurrentPlanPresentation = ({ ) { supplementalBadges.push('Grandfathered price'); supplementalDetails.push( - 'This migrated v5 subscription keeps its existing recurring price until cancellation. Self-hosted monitoring and child-resource volume are not metered under the current v6 policy.', + 'This migrated v5 subscription keeps its existing recurring price until cancellation. Self-hosted monitoring and child-resource volume are not metered in current v6 self-hosted packaging.', ); } else if (hasUncappedContinuity && current.is_lifetime) { supplementalBadges.push('Grandfathered lifetime'); supplementalDetails.push( - 'This migrated lifetime install remains valid permanently, and self-hosted monitoring plus child-resource volume are not metered under the current v6 policy.', + 'This migrated lifetime install remains valid permanently, and self-hosted monitoring plus child-resource volume are not metered in current v6 self-hosted packaging.', ); } @@ -526,7 +526,7 @@ export const getSelfHostedCurrentPlanPresentation = ({ if (continuity?.capture_pending) { supplementalBadges.push('Continuity pending'); supplementalDetails.push( - 'Pulse is still verifying the grandfathered monitored-system floor for this migrated v5 installation.', + 'Pulse is still verifying legacy v5 monitoring continuity for this migrated installation.', ); } else if ( continuity && @@ -534,9 +534,9 @@ export const getSelfHostedCurrentPlanPresentation = ({ continuity.grandfathered_floor > 0 && continuity.effective_limit > continuity.plan_limit ) { - supplementalBadges.push('Grandfathered floor'); + supplementalBadges.push('Legacy continuity'); supplementalDetails.push( - `This installation keeps an effective monitored-system limit of ${continuity.effective_limit} from the observed legacy estate.`, + 'This migrated installation keeps the observed legacy estate available for continuity reporting on this instance.', ); } diff --git a/frontend-modern/src/utils/monitoredSystemPresentation.ts b/frontend-modern/src/utils/monitoredSystemPresentation.ts index 3cc8b9b11..aae9a171d 100644 --- a/frontend-modern/src/utils/monitoredSystemPresentation.ts +++ b/frontend-modern/src/utils/monitoredSystemPresentation.ts @@ -18,18 +18,18 @@ const MONITORED_SYSTEM_LEDGER_PRESENTATION = { disclosureDefinition: 'A monitored system is a top-level monitored root such as a Docker host, Kubernetes cluster, Proxmox node, standalone host, or TrueNAS system. Each root counts once no matter how Pulse collects it. Child resources like VMs, containers, pods, disks, backups, and services underneath that root are included.', ledgerDescription: - 'Review the top-level monitored systems Pulse has identified for reporting and any applicable policy.', + 'Review the top-level monitored systems Pulse has identified for reporting, migration continuity, and support context.', tableNameLabel: 'Name', tableStatusLabel: 'Status', tableLatestIncludedSignalLabel: 'Latest Included Signal', countedSystemBadgeLabel: 'Counts as 1 monitored system', groupedSourcesHeading: 'Grouped sources', countingExplanationHeading: 'Why this counts', - continuityHeading: 'Plan continuity', - continuityPlanLimitLabel: 'Plan limit', - continuityEffectiveLimitLabel: 'Effective limit', - continuityGrandfatheredFloorLabel: 'Grandfathered floor', - continuityCaptureLabel: 'Continuity capture', + continuityHeading: 'Legacy continuity', + continuityPlanLimitLabel: 'Plan baseline', + continuityEffectiveLimitLabel: 'Current baseline', + continuityGrandfatheredFloorLabel: 'Observed legacy estate', + continuityCaptureLabel: 'Verification', continuityCapturePendingLabel: 'Pending', continuityCaptureCapturedLabel: 'Captured', usageVerifyingLabel: 'Verifying…', @@ -55,7 +55,7 @@ const MONITORED_SYSTEM_LEDGER_PRESENTATION = { policyLoadingState: { title: 'Checking monitored-system visibility', message: - 'Pulse waits for the session presentation policy before loading monitored-system usage details.', + 'Pulse waits for the session visibility state before loading monitored-system usage details.', }, hiddenState: { title: 'Monitored-system usage is hidden in demo mode', @@ -80,7 +80,7 @@ const MONITORED_SYSTEM_LEDGER_PRESENTATION = { unknown: 'Pulse cannot determine a canonical runtime status for this monitored system yet.', }, limitBanner: { - reviewPolicyLabel: 'Review policy', + reviewPolicyLabel: 'Review continuity', installCollectorsLabel: 'Install v6 collectors', overflowSummaryPrefix: 'A temporary setup slot is active', legacyConnectionSuffix: @@ -89,20 +89,20 @@ const MONITORED_SYSTEM_LEDGER_PRESENTATION = { admissionPreview: { requiredTitle: 'Preview monitored-system impact before saving', requiredMessage: - 'Pulse must verify the monitored-system policy for this platform connection before it can be saved.', + 'Pulse must preview the monitored-system impact for this platform connection before it can be saved.', fallbackTitle: 'Monitored-system impact', - exceedsPolicyTitle: 'This change exceeds the active monitored-system policy', + exceedsPolicyTitle: 'This change needs continuity review before saving', addsSystemsTitle: 'This change adds monitored systems', removesSystemsTitle: 'This change removes monitored systems', unchangedTitle: 'This change keeps monitored-system count unchanged', unavailableTitle: 'Monitored-system verification is temporarily unavailable', unavailableFallbackMessage: - 'Pulse cannot verify monitored-system policy right now, so this connection cannot be saved yet. Retry preview in a moment.', + 'Pulse cannot verify monitored-system impact right now, so this connection cannot be saved yet. Retry preview in a moment.', unavailableUnsettledMessage: 'Pulse is still settling provider-owned inventory for this platform connection, so the monitored-system check is not safe yet. Retry preview after the first baseline finishes.', unavailableRebuildPendingMessage: 'Pulse has settled provider-owned inventory and is rebuilding the canonical monitored-system view, so this connection cannot be saved yet. Retry preview in a moment.', - saveBlockedLimitMessage: 'This change would exceed the active monitored-system policy', + saveBlockedLimitMessage: 'This change needs monitored-system review before saving', saveBlockedLoadingMessage: 'Wait for the monitored-system impact preview to finish', }, } as const; @@ -447,11 +447,11 @@ export function getMonitoredSystemLimitCapacityStatusSummary( case 'unlimited': return MONITORED_SYSTEM_LEDGER_PRESENTATION.unlimitedLimitLabel; case 'over_limit_frozen': - return `Over policy by ${resolved.overage}`; + return 'Continuity review'; case 'at_limit_blocking_new': - return 'At policy boundary'; + return 'Continuity review'; default: - return `${resolved.available_slots} remaining`; + return 'Healthy'; } } @@ -469,16 +469,16 @@ export function getMonitoredSystemLimitContextSummary( switch (resolved.mode) { case 'unlimited': - return 'This policy does not cap monitored systems.'; + return 'Self-hosted monitoring is included for this instance.'; case 'over_limit_frozen': if (resolved.reason === 'legacy_migration_capture_pending') { - return `This finite policy includes ${resolved.limit}. Pulse is still verifying the migrated v5 continuity floor for this installation. Existing monitoring continues while additional monitored-system admissions pause until continuity capture finishes.`; + return 'Pulse is verifying legacy v5 continuity for this installation. Existing monitoring remains visible while new top-level additions wait for verification to finish.'; } - return `This finite policy includes ${resolved.limit}. This installation is already over policy by ${resolved.overage} because it was monitoring above that boundary before additional admissions paused. Existing monitoring continues; additional monitored systems stay paused until usage is reduced or the policy changes.`; + return 'Existing monitoring remains visible. New top-level additions are paused until this legacy continuity state is reviewed.'; case 'at_limit_blocking_new': - return `This finite policy includes ${resolved.limit}. Existing monitoring continues; additional monitored systems stay paused until capacity is available or the policy changes.`; + return 'Existing monitoring remains visible. New top-level additions are paused until this legacy continuity state is reviewed.'; default: - return `${resolved.available_slots} remaining before additional monitored-system admissions pause.`; + return ''; } } @@ -493,6 +493,13 @@ export function buildMonitoredSystemCapacitySectionModel( if (resolved.limit <= 0) { return null; } + if ( + resolved.current_available && + resolved.mode !== 'over_limit_frozen' && + resolved.mode !== 'at_limit_blocking_new' + ) { + return null; + } const includedValue = resolved.limit > 0 @@ -505,7 +512,7 @@ export function buildMonitoredSystemCapacitySectionModel( value: getMonitoredSystemLimitUsageSummary(limit, capacity), }, { - label: 'Included', + label: 'Baseline', value: includedValue, }, { @@ -528,43 +535,42 @@ export function buildMonitoredSystemCapacitySectionModel( case 'unlimited': return { stats, - statusMessage: 'This policy does not cap monitored systems.', + statusMessage: 'Self-hosted monitoring is included for this instance.', }; case 'at_limit_blocking_new': return { stats, - statusMessage: 'Existing monitoring continues. Additional monitored systems are paused.', + statusMessage: 'Existing monitoring remains visible. New top-level additions need review.', detailMessage: - 'Reduce usage or resolve the applicable policy before adding another monitored system.', + 'Review the legacy continuity state before adding another top-level monitored system.', }; case 'over_limit_frozen': if (resolved.reason === 'legacy_migration_capture_pending') { return { stats, statusMessage: - 'Existing monitoring continues. Additional monitored systems are temporarily paused.', - detailMessage: 'Pulse is still verifying migrated v5 continuity for this installation.', + 'Existing monitoring remains visible. New top-level additions wait for verification.', + detailMessage: 'Pulse is still verifying legacy v5 continuity for this installation.', explanation: { label: 'Why is continuity still pending?', - body: `Pulse is still verifying the grandfathered monitored-system floor for this migrated v5 installation. The finite policy includes ${resolved.limit}, while this installation is already monitoring ${resolved.current}. Existing monitoring continues while additional monitored-system admissions pause until continuity capture finishes.`, + body: `Pulse is still verifying legacy v5 continuity for this installation. It has already identified ${resolved.current} monitored systems for continuity reporting, and existing monitoring remains visible while new top-level additions wait for verification to finish.`, }, }; } return { stats, - statusMessage: 'Existing monitoring continues. Additional monitored systems are paused.', + statusMessage: 'Existing monitoring remains visible. New top-level additions need review.', detailMessage: - 'Reduce usage or resolve the applicable policy before adding another monitored system.', + 'Review the legacy continuity state before adding another top-level monitored system.', explanation: { - label: 'Why is this over policy?', - body: `This installation was already monitoring ${resolved.current} monitored systems before Pulse paused net-new monitored-system admissions at the active finite policy boundary. Pulse keeps those existing systems visible, but additional monitored systems stay paused until usage is reduced or the policy changes.`, + label: 'Why does this need review?', + body: `Pulse has already identified ${resolved.current} monitored systems for this installation. Existing monitoring remains visible, but new top-level additions are paused until this legacy continuity state is reviewed.`, }, }; default: return { stats, - statusMessage: 'New monitored systems can still be added.', - detailMessage: `${resolved.available_slots} remaining before additional monitored-system admissions pause.`, + statusMessage: 'Current monitored-system accounting is healthy.', }; } } @@ -648,7 +654,7 @@ export function formatMonitoredSystemAdmissionPreviewSummary( const delta = projected - current; const policySuffix = preview.would_exceed_limit && limit > 0 - ? `, above the active policy of ${formatAdmissionPreviewCount(limit)}` + ? `, above the current verified baseline of ${formatAdmissionPreviewCount(limit)}` : ''; const currentSummary = `Pulse currently counts ${formatAdmissionPreviewCount(current)}.`; @@ -745,15 +751,17 @@ export function formatMonitoredSystemLimitSummary( switch (resolved.mode) { case 'over_limit_frozen': if (resolved.reason === 'legacy_migration_capture_pending') { - return `Continuity verification pending. ${resolved.current} monitored, ${resolved.limit} included.`; + return `Continuity verification pending. ${formatMonitoredSystemCount( + resolved.current, + )}.`; } - return `Over policy by ${resolved.overage}. ${resolved.current} monitored, ${resolved.limit} included.`; + return `Continuity review needed. ${formatMonitoredSystemCount(resolved.current)}.`; case 'at_limit_blocking_new': - return `At policy boundary. ${resolved.current} monitored, ${resolved.limit} included.`; + return `Continuity review needed. ${formatMonitoredSystemCount(resolved.current)}.`; case 'unlimited': - return `${resolved.current} monitored.`; + return `${formatMonitoredSystemCount(resolved.current)}.`; default: - return `${resolved.available_slots} remaining. ${resolved.current} monitored, ${resolved.limit} included.`; + return `${formatMonitoredSystemCount(resolved.current)}.`; } }