Align v6 Pro copy with operator value

This commit is contained in:
rcourtman 2026-04-23 14:21:02 +01:00
parent 349deb0c41
commit fcd7adca43
8 changed files with 64 additions and 57 deletions

View file

@ -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

View file

@ -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`

View file

@ -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

View file

@ -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.
---

View file

@ -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

View file

@ -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();

View file

@ -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);

View file

@ -62,7 +62,12 @@ const FEATURE_MIN_TIER_LABELS: Record<string, string> = {
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;