From fcd7adca430bd8428006dc5c5fd32c8f3c94c2a4 Mon Sep 17 00:00:00 2001 From: rcourtman Date: Thu, 23 Apr 2026 14:21:02 +0100 Subject: [PATCH] Align v6 Pro copy with operator value --- README.md | 17 ++--- docs/API.md | 6 +- docs/PULSE_PRO.md | 9 +-- docs/architecture/v6-pricing-and-tiering.md | 74 +++++++++---------- .../v6/internal/subsystems/cloud-paid.md | 5 ++ .../__tests__/ProLicensePanel.test.tsx | 2 +- .../__tests__/licensePresentation.test.ts | 1 + .../src/utils/licensePresentation.ts | 7 +- 8 files changed, 64 insertions(+), 57 deletions(-) diff --git a/README.md b/README.md index a6c52edf6..a63461ab4 100644 --- a/README.md +++ b/README.md @@ -161,7 +161,7 @@ Self-hosted tiers: |---|---:|---|---:|---| | Community | Free | Unlimited | 7 days | Full self-hosted monitoring | | Relay | $4.99/mo or $39/yr | Unlimited | 14 days | Remote access, mobile, and push notifications | -| Pro | $8.99/mo or $79/yr | Unlimited | 90 days | AI investigation, auto-fix, and operations tooling | +| Pro | $8.99/mo or $79/yr | Unlimited | 90 days | Root-cause analysis, safe auto-fix, and operations tooling | Pulse still counts top-level monitored systems once no matter how they are collected. VMs, containers, pods, disks, backups, and other child resources @@ -180,17 +180,16 @@ Runtime-aligned capability summary: |---|:---:|:---:|:---:|:---:| | Pulse Patrol (Background Health Checks) | ✅ | ✅ | ✅ | ✅ | | Remote Access / Mobile / Push | — | ✅ | ✅ | ✅ | -| Alert Analysis | — | — | ✅ | ✅ | +| Alert-Triggered Root-Cause Analysis | — | — | ✅ | ✅ | | Pulse Patrol Auto-Fix | — | — | ✅ | ✅ | -| Kubernetes Analysis | — | — | ✅ | ✅ | | Centralized Agent Profiles | — | — | ✅ | ✅ | | Update Alerts (Container/Package Updates) | ✅ | ✅ | ✅ | ✅ | | Basic SSO (OIDC) | ✅ | ✅ | ✅ | ✅ | -| Advanced SSO (SAML/Multi-Provider) | — | — | ✅ | ✅ | ✅ | -| Role-Based Access Control (RBAC) | — | — | ✅ | ✅ | ✅ | -| Enterprise Audit Logging | — | — | ✅ | ✅ | ✅ | -| Advanced Infrastructure Reporting (PDF/CSV) | — | — | ✅ | ✅ | ✅ | -| Extended Metric History | 7 days | 14 days | 90 days | 90 days | Hosted entitlements | +| Advanced SSO (SAML/Multi-Provider) | — | — | ✅ | ✅ | +| Role-Based Access Control (RBAC) | — | — | ✅ | ✅ | +| Enterprise Audit Logging | — | — | ✅ | ✅ | +| Advanced Infrastructure Reporting (PDF/CSV) | — | — | ✅ | ✅ | +| Extended Metric History | 7 days | 14 days | 90 days | 90 days | Pulse Patrol runs on your schedule (every 10 minutes to every 7 days, default 6 hours) and finds: - ZFS pools approaching capacity @@ -207,7 +206,7 @@ a trial, or use BYOK. Chat Assistant remains BYOK. Technical highlights: - Cross-system context (nodes, VMs, backups, containers, and metrics history) -- LLM analysis with your provider + alert-triggered deep dives (Pro/Pro+/Cloud) +- LLM analysis with your provider + alert-triggered root-cause investigations (Pro/Pro+/Cloud) - Optional auto-fix with command safety policies and audit trail - Centralized agent profiles for consistent fleet settings diff --git a/docs/API.md b/docs/API.md index 3a9464a20..5f4edabca 100644 --- a/docs/API.md +++ b/docs/API.md @@ -882,12 +882,14 @@ Streaming variant of execute (used by the UI for incremental responses). ### Question Answers - `POST /api/ai/question/{id}/answer` -### Kubernetes AI Analysis (Pro) +### Kubernetes AI Analysis (Compatibility) `POST /api/ai/kubernetes/analyze` ```json { "cluster_id": "cluster-id" } ``` -Requires Pro, Pro+, or Cloud with the `kubernetes_ai` feature enabled. +Requires Pro, Pro+, or Cloud with the `kubernetes_ai` feature enabled. This route remains +available for compatibility, but current v6 Pulse Pro marketing does not treat +Kubernetes-specific analysis as a standalone plan pillar. ### Alert Investigation (Pro) `POST /api/ai/investigate-alert` diff --git a/docs/PULSE_PRO.md b/docs/PULSE_PRO.md index 0ef021aa9..81f79070c 100644 --- a/docs/PULSE_PRO.md +++ b/docs/PULSE_PRO.md @@ -87,9 +87,9 @@ This matrix is derived from the canonical table in `docs/architecture/ENTITLEMEN |---|---|---|:---:|:---:|:---:|:---:|:---:|---| | `FeatureAIPatrol` | `ai_patrol` | Pulse Patrol (Background Health Checks) | Y | Y | Y | Y | Y | Patrol itself is available on Community with BYOK. Activated or trial-backed installs can use 25 Patrol quickstart runs with no API key for first-run activation. Higher-autonomy outcomes and fix execution are separately gated. | | `FeatureRelay` | `relay` | Remote Access (Mobile Relay) | N | Y | Y | Y | Y | API route gating via `RequireLicenseFeature(..., relay, ...)` for relay settings and onboarding endpoints. | -| `FeatureAIAlerts` | `ai_alerts` | Alert Analysis | N | N | Y | Y | Y | API route gating via `RequireLicenseFeature(..., ai_alerts, ...)`. | +| `FeatureAIAlerts` | `ai_alerts` | Alert-Triggered Root-Cause Analysis | N | N | Y | Y | Y | API route gating via `RequireLicenseFeature(..., ai_alerts, ...)`. | | `FeatureAIAutoFix` | `ai_autofix` | Pulse Patrol Auto-Fix | N | N | Y | Y | Y | Required for fix execution and higher-autonomy actions. | -| `FeatureKubernetesAI` | `kubernetes_ai` | Kubernetes Analysis | N | N | Y | Y | Y | API route gating via `RequireLicenseFeature(..., kubernetes_ai, ...)`. | +| `FeatureKubernetesAI` | `kubernetes_ai` | Kubernetes AI Analysis (Compatibility) | N | N | Y | Y | Y | Legacy compatibility gate for `/api/ai/kubernetes/analyze`; not a primary marketed v6 Pro plan pillar. | | `FeatureAgentProfiles` | `agent_profiles` | Centralized Agent Profiles | N | N | Y | Y | Y | API route gating via `RequireLicenseFeature(..., agent_profiles, ...)`. | | `FeatureUpdateAlerts` | `update_alerts` | Update Alerts (Container/Package Updates) | Y | Y | Y | Y | Y | Included in Community tier per `TierFeatures[TierFree]`. | | `FeatureSSO` | `sso` | Basic SSO (OIDC) | Y | Y | Y | Y | Y | Basic SSO is included in Community tier. | @@ -131,9 +131,8 @@ Patrol and the Assistant support tiered autonomy: ### Pro - Everything in Relay, plus: -- AI alert analysis. +- Alert-triggered root-cause analysis. - Auto-fix and higher autonomy. -- Kubernetes AI analysis. - Centralized agent profiles. - Advanced SSO, RBAC, audit logging, and advanced reporting. - 90-day history. @@ -161,7 +160,7 @@ Pulse plan upgrades are activated locally with a license key. You can inspect active feature gates via: - `GET /api/license/features` (authenticated) -This returns a feature map including keys like `relay`, `ai_alerts`, `ai_autofix`, `kubernetes_ai`, and `multi_tenant` so you can conditionally enable paid workflows safely. +This returns a feature map including keys like `relay`, `ai_alerts`, `ai_autofix`, `agent_profiles`, and `multi_tenant` so you can conditionally enable paid workflows safely. ## Deep Dives diff --git a/docs/architecture/v6-pricing-and-tiering.md b/docs/architecture/v6-pricing-and-tiering.md index 63c088dc1..8fff5a62b 100644 --- a/docs/architecture/v6-pricing-and-tiering.md +++ b/docs/architecture/v6-pricing-and-tiering.md @@ -31,8 +31,10 @@ align with this document. If there is a conflict, this document wins. ## Counted Unit -**Rule:** Pulse sells monitored coverage. The counted unit is a **monitored system**, not -an installed agent. +**Rule:** Pulse tracks a **monitored system** as the canonical counted unit for product +understanding, migrations, and any hosted or legacy continuity policy that still uses +capacity semantics. On current self-hosted v6 plans, monitored systems are not the paid +gate. **Counts as one monitored system:** - Proxmox PVE node @@ -59,13 +61,14 @@ an installed agent. - If the same underlying system is seen by both an agent and an API connection, it counts once - Deduplication must follow canonical unified-resource identity rather than transport-specific state -**Why this model:** charging by monitored systems matches the product Pulse is actually -becoming. It closes the API loophole, keeps the commercial model honest, and still lets -Pulse include all child resources under the counted system for free. +**Why this model:** counting by monitored systems matches the product Pulse is actually +becoming, keeps inventory honest across collection paths, and avoids turning child-resource +sprawl into self-hosted upsell pressure. Any remaining hosted or continuity capacity logic +should still use this canonical unit rather than transport-specific counts. **Definition (shown on pricing page, add-system UI, and docs):** > "A counted system is a top-level machine or cluster Pulse actively monitors. Each monitored -> system counts once toward your plan limit, no matter how Pulse collects it. Everything under +> system counts once in Pulse's inventory, no matter how Pulse collects it. Everything under > that system — VMs, containers, pods, disks, backups, and services — is included." **Counting stability:** a monitored system should only begin consuming the cap after it is @@ -77,7 +80,8 @@ path, and their first-seen / last-seen state so users can understand why they ar **Implementation transition note:** the current runtime still enforces `max_agents` and agent-backed counting in some paths. That is a transitional compatibility boundary, not the -long-term commercial model. The canonical v6 destination is monitored-system counting. +long-term commercial model. The canonical v6 destination is monitored-system identity and +ledger truth, with self-hosted commercial surfaces treating core monitoring as unlimited. **Examples:** - A 3-node Proxmox cluster monitored node-by-node counts as **3 monitored systems** @@ -94,8 +98,7 @@ long-term commercial model. The canonical v6 destination is monitored-system cou | Element | Value | |---|---| -| Monitored systems | **5** | -| Onboarding overflow | +1 monitored system for 14 days (one-time per workspace) | +| Monitoring scope | **Unlimited self-hosted monitoring** | | Monitoring | Full (Proxmox, Docker, K8s, agents) | | Alerts | Threshold-based | | SSO | Basic OIDC | @@ -103,8 +106,8 @@ long-term commercial model. The canonical v6 destination is monitored-system cou | Metrics history | **7 days** | | AI Patrol | Monitor + root-cause summaries + fix suggestions (BYOK by default, with Patrol quickstart on activated or trial-backed installs) | | AI Quickstart Credits | **25 hosted Patrol runs** (activated or trial-backed installs only; no API key needed, Patrol only, powered by MiniMax 2.5M) | -| AI Auto-Fix | **No** (must apply fixes manually) | -| AI Alert Analysis | No | +| Patrol Auto-Fix | **No** (must apply fixes manually) | +| Alert-triggered root-cause analysis | No | | Relay | No | | Push notifications | No | | Custom URL | No | @@ -143,33 +146,30 @@ suggestions but must apply fixes manually. Pro users click "Apply Fix." | Element | Value | |---|---| -| Monitored systems | **8** | +| Monitoring scope | **Unlimited self-hosted monitoring** | | Everything in Free | Yes | | Relay remote access | **Yes** | | Mobile app access | **Yes** | | Push notifications | **Yes** | | Custom URL | **yourlab.pulserelay.pro** | | Metrics history | **14 days** | -| AI Auto-Fix | No | -| AI Alert Analysis | No | +| Patrol Auto-Fix | No | +| Alert-triggered root-cause analysis | No | | RBAC/Audit/SAML | No | | Reporting | No | -**Positioning:** The low-friction headroom tier. It should feel cheap enough to buy on the -spot when someone is just over the Community boundary and wants remote access, mobile, and -push at the same time. +**Positioning:** The convenience tier. It should feel cheap enough to buy on the spot when +someone wants secure remote access, mobile checks, push notifications, and longer history +without changing their self-hosted monitoring scope. ### Pro — $8.99/month or $79/year | Element | Value | |---|---| -| Monitored systems | **15** | +| Monitoring scope | **Unlimited self-hosted monitoring** | | Everything in Relay | Yes | -| AI Auto-Fix | **Yes** (one-click execution, safety preflight, rollback) | -| AI Alert Analysis | **Yes** | -| Kubernetes AI Analysis | **Yes** | -| Scheduled remediations | **Yes** | -| Execution audit trail | **Yes** | +| Patrol Auto-Fix | **Yes** (one-click execution, safety preflight, rollback) | +| Alert-triggered root-cause analysis | **Yes** | | Metrics history | **90 days** | | RBAC | **Yes** | | Audit logging | **Yes** | @@ -178,25 +178,21 @@ push at the same time. | PDF/CSV reporting | **Yes** | | Trial | **14-day, no credit card** | -**Positioning:** For serious homelabbers who want AI to manage their infrastructure and -want full history. The marketing pitch focuses on three things: -1. "AI that fixes your infrastructure" (Patrol auto-fix) -2. "Monitor from anywhere" (Relay, inherited) -3. "See your full history" (90-day metrics) +**Positioning:** For serious self-hosted operators who want Pulse to move from monitoring +into operations. The marketing pitch focuses on three things: +1. "Explain what broke" (alert-triggered root-cause analysis) +2. "Fix it safely" (Patrol auto-fix) +3. "Keep longer operating memory" (90-day history) -Enterprise features (RBAC, audit, SAML) are included but positioned as bonus value, not -the headline. +Relay convenience and the team extras (RBAC, audit logging, SAML, reporting, and agent +profiles) are included, but they are supporting value rather than the headline. -### Pro+ — $14.99/month or $129/year +### Pro+ — Legacy continuity tier only -| Element | Value | -|---|---| -| Monitored systems | **50** | -| Everything in Pro | Yes | -| Trial | **14-day, no credit card** | - -**Positioning:** For power users with large homelabs (15+ agents). Simple $50/yr bump from -Pro. Anyone with 50+ agents should contact us (likely MSP or business). +Existing Pro+ entitlements remain supported for continuity, but Pro+ is no longer part of +the public v6 self-hosted ladder because monitored-system volume is not the paid boundary. +Runtime feature access matches Pro, while grandfathered recurring or lifetime continuity can +still preserve uncapped monitored-system and guest capacity where applicable. --- diff --git a/docs/release-control/v6/internal/subsystems/cloud-paid.md b/docs/release-control/v6/internal/subsystems/cloud-paid.md index 83b239dc2..efaf9450c 100644 --- a/docs/release-control/v6/internal/subsystems/cloud-paid.md +++ b/docs/release-control/v6/internal/subsystems/cloud-paid.md @@ -1379,6 +1379,11 @@ The shared license presentation owner also holds self-hosted Pro settings trial-ended notice copy for `ProLicensePlanSection.tsx`; that surface must consume canonical helper notices instead of carrying inline upgrade copy or local status-tone branches. +That same `frontend-modern/src/utils/licensePresentation.ts` owner must treat +compatibility-only capability keys such as `kubernetes_ai` as non-marketed +technical facts: API/docs surfaces may still name the compatibility route, but +customer-facing self-hosted current-plan summaries and unlocked-capability +lists must not surface those keys as marquee Pro value. That same plan-section boundary must also defer notice resolution to component runtime. `frontend-modern/src/components/Settings/ProLicensePlanSection.tsx` may not compute trial-ended notices at module scope, because hosted settings diff --git a/frontend-modern/src/components/Settings/__tests__/ProLicensePanel.test.tsx b/frontend-modern/src/components/Settings/__tests__/ProLicensePanel.test.tsx index d40bc7ae0..499f669f6 100644 --- a/frontend-modern/src/components/Settings/__tests__/ProLicensePanel.test.tsx +++ b/frontend-modern/src/components/Settings/__tests__/ProLicensePanel.test.tsx @@ -717,7 +717,6 @@ describe('ProLicensePanel', () => { expect(screen.getByText('Pulse Patrol')).toBeInTheDocument(); expect(screen.getByText('Pulse Alert Analysis')).toBeInTheDocument(); expect(screen.getByText('Patrol Auto-Fix')).toBeInTheDocument(); - expect(screen.getByText('Kubernetes Analysis')).toBeInTheDocument(); expect(screen.getByText('Update Alerts')).toBeInTheDocument(); expect(screen.getByText('Advanced SSO (SAML/Multi-Provider)')).toBeInTheDocument(); expect(screen.getByText('Role-Based Access Control (RBAC)')).toBeInTheDocument(); @@ -729,6 +728,7 @@ describe('ProLicensePanel', () => { expect(screen.getByText('Push Notifications')).toBeInTheDocument(); expect(screen.getByText('Extended Metric History')).toBeInTheDocument(); expect(screen.getByText('Multi-Tenant Mode')).toBeInTheDocument(); + expect(screen.queryByText('Kubernetes Analysis')).not.toBeInTheDocument(); expect(screen.queryByText('Multi-User Mode')).not.toBeInTheDocument(); expect(screen.queryByText('White-Label Branding')).not.toBeInTheDocument(); expect(screen.queryByText('Unlimited Instances')).not.toBeInTheDocument(); diff --git a/frontend-modern/src/utils/__tests__/licensePresentation.test.ts b/frontend-modern/src/utils/__tests__/licensePresentation.test.ts index a1912d46b..3250ef9d8 100644 --- a/frontend-modern/src/utils/__tests__/licensePresentation.test.ts +++ b/frontend-modern/src/utils/__tests__/licensePresentation.test.ts @@ -124,6 +124,7 @@ describe('licensePresentation', () => { it('hides non-operable capability labels from customer-facing plan surfaces', () => { expect(isDisplayableLicenseFeature('ai_patrol')).toBe(true); expect(isDisplayableLicenseFeature('multi_tenant')).toBe(true); + expect(isDisplayableLicenseFeature('kubernetes_ai')).toBe(false); expect(isDisplayableLicenseFeature('multi_user')).toBe(false); expect(isDisplayableLicenseFeature('white_label')).toBe(false); expect(isDisplayableLicenseFeature('unlimited')).toBe(false); diff --git a/frontend-modern/src/utils/licensePresentation.ts b/frontend-modern/src/utils/licensePresentation.ts index 0166fcb56..632926e37 100644 --- a/frontend-modern/src/utils/licensePresentation.ts +++ b/frontend-modern/src/utils/licensePresentation.ts @@ -62,7 +62,12 @@ const FEATURE_MIN_TIER_LABELS: Record = { multi_tenant: 'MSP', }; -const NON_DISPLAYABLE_FEATURES = new Set(['multi_user', 'white_label', 'unlimited']); +const NON_DISPLAYABLE_FEATURES = new Set([ + 'kubernetes_ai', + 'multi_user', + 'white_label', + 'unlimited', +]); export interface LicenseSubscriptionStatusPresentation { label: string;