mirror of
https://github.com/rcourtman/Pulse.git
synced 2026-05-19 07:54:10 +00:00
Prove v6 paid feature claims
This commit is contained in:
parent
9695ae5fc7
commit
df3ab06174
11 changed files with 76 additions and 24 deletions
|
|
@ -161,7 +161,7 @@ Patrol and the Assistant support tiered autonomy:
|
|||
- Everything in Community, plus:
|
||||
- 14-day history.
|
||||
- Remote access via Relay.
|
||||
- Mobile app access and push notifications.
|
||||
- Pulse Mobile pairing for handoff and push notifications.
|
||||
|
||||
### Pro
|
||||
- Everything in Relay, plus:
|
||||
|
|
|
|||
|
|
@ -10,7 +10,8 @@
|
|||
|
||||
This document is the single source of truth for Pulse v6 pricing, tiering, feature
|
||||
allocation, and conversion mechanics. All code, UI, marketing, and documentation must
|
||||
align with this document. If there is a conflict, this document wins.
|
||||
align with this document. If there is a conflict with release-control state, the
|
||||
release-control source wins and this file must be corrected.
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -110,7 +111,7 @@ than sold by monitored-system volume.
|
|||
| Alert-triggered root-cause analysis | No |
|
||||
| Relay | No |
|
||||
| Push notifications | No |
|
||||
| Custom URL | No |
|
||||
| Customer-specific Relay URL | No |
|
||||
| RBAC | No |
|
||||
| Audit logging | No |
|
||||
| SAML SSO | No |
|
||||
|
|
@ -133,9 +134,9 @@ remediation actions through Pulse.
|
|||
| Monitoring scope | **Core self-hosted monitoring included** |
|
||||
| Everything in Free | Yes |
|
||||
| Relay remote access | **Yes** |
|
||||
| Mobile app access | **Yes** |
|
||||
| Pulse Mobile pairing | **Yes** (handoff and push notifications) |
|
||||
| Push notifications | **Yes** |
|
||||
| Custom URL | **yourlab.pulserelay.pro** |
|
||||
| Customer-specific Relay URL | No; Relay uses the standard outbound relay service for v6 GA |
|
||||
| Metrics history | **14 days** |
|
||||
| Safe remediation workflows | No |
|
||||
| Alert-triggered root-cause analysis | No |
|
||||
|
|
@ -143,7 +144,7 @@ remediation actions through Pulse.
|
|||
| Reporting | No |
|
||||
|
||||
**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
|
||||
someone wants secure remote access, mobile pairing, push notifications, and longer history
|
||||
without changing their self-hosted monitoring scope.
|
||||
|
||||
### Pro — $8.99/month or $79/year
|
||||
|
|
@ -160,7 +161,7 @@ without changing their self-hosted monitoring scope.
|
|||
| SAML SSO | **Yes** |
|
||||
| Agent profiles | **Yes** |
|
||||
| PDF/CSV reporting | **Yes** |
|
||||
| Trial | **14-day, no credit card** |
|
||||
| Self-hosted trial acquisition | No; local trial CTAs are retired for v6 GA |
|
||||
|
||||
**Positioning:** For serious self-hosted operators who want Pulse to move from monitoring
|
||||
into operations. The marketing pitch focuses on three things:
|
||||
|
|
@ -345,7 +346,7 @@ want to self-host.
|
|||
|
||||
## Self-Hosted Cap Migration
|
||||
|
||||
- There is no v6 self-hosted monitored-system cap migration for Community, Relay, Pro, or Pro+
|
||||
- There is no v6 self-hosted monitored-system capacity migration for Community, Relay, Pro, or Pro+
|
||||
- Existing self-hosted users keep their monitored coverage through the v6 rollout
|
||||
- Hosted Cloud and MSP capacity limits remain plan-specific license claims, not self-hosted static tier defaults
|
||||
- The UI may still explain monitored-system identity, but it must not frame self-hosted growth as a capacity upsell
|
||||
|
|
@ -479,7 +480,7 @@ explain monitored-system identity:
|
|||
|
||||
### Frontend
|
||||
|
||||
- [x] Remove self-hosted monitored-system cap pressure from billing and pricing surfaces
|
||||
- [x] Remove self-hosted monitored-system capacity pressure from billing and pricing surfaces
|
||||
- [x] Present the public self-hosted ladder as Community / Relay / Pro
|
||||
- [ ] Keep ledger and inventory language focused on what Pulse monitors, not paid capacity pressure
|
||||
- [ ] Keep paid prompts out of ordinary self-hosted runtime surfaces; commercial copy belongs in explicit pricing, activation, recovery, hosted, or entitlement-aware paths
|
||||
|
|
@ -521,7 +522,7 @@ explain monitored-system identity:
|
|||
| Date | Change | Author |
|
||||
|---|---|---|
|
||||
| 2026-04-29 | Replaced stale capacity-style monitoring phrasing with core-monitoring-included language across active v6 docs and upgrade-return copy so Community does not read like a former capacity upsell. | Codex |
|
||||
| 2026-04-23 | Removed stale self-hosted monitored-system cap and Pro+ public-checkout language. Reaffirmed Community / Relay / Pro as current public self-hosted tiers, with Pro+ as continuity only and Pro value centered on operations, history, and admin controls. | Codex |
|
||||
| 2026-04-23 | Removed stale self-hosted monitored-system capacity and Pro+ public-checkout language. Reaffirmed Community / Relay / Pro as current public self-hosted tiers, with Pro+ as continuity only and Pro value centered on operations, history, and admin controls. | Codex |
|
||||
| 2026-03-17 | Re-locked the self-hosted commercial model around monitored systems rather than installed agents. New self-hosted public pricing: Relay $4.99/$39, Pro $8.99/$79, Pro+ $14.99/$129. Added free-tier grace policy and marked the monitored-system counting migration as still required in code. | Codex + Richard |
|
||||
| 2026-02-25 | Initial v6 pricing structure finalized | Richard + Claude + Codex |
|
||||
| 2026-02-25 | Changed counting to agents-only model. Only installed Pulse Unified Agents count toward limits. PVE/PBS/PMG/Docker/K8s connections and discovered resources don't count. This makes limits much more generous in practice (5 agents can monitor an entire multi-node cluster). | Richard + Claude |
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ python3 scripts/release_control/paid_feature_claims_proof.py --json
|
|||
- Relay claims only remote web access, mobile pairing, push notifications, and 14-day metric history.
|
||||
- Pro preserves Relay capabilities and adds operator extras: root-cause analysis, safe remediation workflows, 90-day metric history, RBAC, audit logging, reporting, SAML SSO, and agent profiles.
|
||||
- Public app, docs, and site copy must not reintroduce old self-hosted monitoring-limit, higher-limit, default-trial, hosted-model-credit, or bundled-Patrol-credit claims.
|
||||
- Relay must not be marketed as including a customer-specific `*.pulserelay.pro` URL until that product surface exists; v6 GA Relay is the standard outbound relay service.
|
||||
- History claims are enforced by the runtime metrics-history API, not only shown in copy.
|
||||
- Pro admin extras are backed by concrete core and enterprise runtime tests for RBAC, audit logging, reporting, SAML SSO, and agent profile behavior.
|
||||
- Public pricing, checkout, download, and relay-server entitlement behavior remain consistent with those claims.
|
||||
|
|
|
|||
|
|
@ -1542,7 +1542,13 @@ it as a current public Pulse Pro+ package. When direct plan-selection intent
|
|||
opens the explicit self-hosted comparison surface, the shared presentation
|
||||
helpers must show Pro's operations, admin, and reporting extras together while
|
||||
still framing Community, Relay, and Pro as core monitoring included in every
|
||||
self-hosted tier rather than monitored-system capacity tiers. The same factual
|
||||
self-hosted tier rather than monitored-system capacity tiers. Relay copy in
|
||||
that shared owner must describe the current v6 GA product as standard Relay
|
||||
remote access, supported Pulse Mobile pairing, push notifications, and 14-day
|
||||
history, and it must not market a customer-specific Relay URL until that
|
||||
routing surface exists as a backed product capability. Cloud common-inclusion
|
||||
copy follows the same mobile-language rule: describe supported Pulse Mobile
|
||||
pairing and push notifications rather than generic mobile app access. The same factual
|
||||
plan surface must keep inactive-state copy neutral: default Community installs
|
||||
must describe the instance as ready to use rather than as missing an activation
|
||||
key, and they must not foreground paid self-hosted activation, v5-era "No Pro
|
||||
|
|
|
|||
|
|
@ -546,7 +546,7 @@ describe('ProLicensePanel', () => {
|
|||
|
||||
expect(
|
||||
screen.getByText(
|
||||
'Relay is active on this instance. Remote web access, mobile pairing, push notifications, and longer history are available right now.',
|
||||
'Relay is active on this instance. Remote web access, Pulse Mobile pairing, push notifications, and longer history are available right now.',
|
||||
),
|
||||
).toBeInTheDocument();
|
||||
expect(screen.queryByText('Optional extras')).not.toBeInTheDocument();
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ describe('cloudPlans', () => {
|
|||
'Managed hosting',
|
||||
'Daily backups',
|
||||
'Secure agent connectivity via Relay',
|
||||
'Mobile app access and push notifications',
|
||||
'Pulse Mobile pairing and push notifications',
|
||||
'Dedicated workspace URL',
|
||||
],
|
||||
setupHeading: 'How it works',
|
||||
|
|
|
|||
|
|
@ -426,7 +426,7 @@ describe('licensePresentation', () => {
|
|||
cards: [
|
||||
{
|
||||
title: 'What Relay adds',
|
||||
body: 'Reach your Pulse web UI securely from anywhere, pair the mobile app for handoff and push notifications, and keep 14 days of history.',
|
||||
body: 'Reach your Pulse web UI securely from anywhere, pair supported Pulse Mobile clients for handoff and push notifications, and keep 14 days of history.',
|
||||
highlights: [
|
||||
'Pulse Relay (Remote Access)',
|
||||
'Mobile App Pairing',
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@ describe('selfHostedPlans', () => {
|
|||
expect(SELF_HOSTED_COMMERCIAL_PRESENTATION).toEqual({
|
||||
pageTitle: 'Pricing',
|
||||
pageDescription:
|
||||
'Self-hosted Pulse includes core monitoring for free. Relay adds secure remote access to the Pulse web UI, mobile pairing, and push notifications, while Pro adds root-cause analysis, safe remediation workflows, 90-day history, and admin/reporting extras.',
|
||||
'Self-hosted Pulse includes core monitoring for free. Relay adds secure remote access to the Pulse web UI, Pulse Mobile pairing, and push notifications, while Pro adds root-cause analysis, safe remediation workflows, 90-day history, and admin/reporting extras.',
|
||||
mostPopularBadge: 'Most Popular',
|
||||
currentPlanLabel: 'Current Plan',
|
||||
includedLabel: 'Included',
|
||||
|
|
@ -109,7 +109,7 @@ describe('selfHostedPlans', () => {
|
|||
'Remote web access, mobile pairing, and push',
|
||||
);
|
||||
expect(SELF_HOSTED_PLAN_BY_TIER.relay.entitlementSummary).toContain(
|
||||
'Remote web access, mobile pairing, push notifications, and longer history are available right now.',
|
||||
'Remote web access, Pulse Mobile pairing, push notifications, and longer history are available right now.',
|
||||
);
|
||||
expect(SELF_HOSTED_PLAN_BY_TIER.relay.comparisonSummary).toContain(
|
||||
'Reach your Pulse web UI securely from anywhere',
|
||||
|
|
@ -121,6 +121,11 @@ describe('selfHostedPlans', () => {
|
|||
'14-day metric history',
|
||||
]);
|
||||
expect(SELF_HOSTED_PLAN_BY_TIER.relay.includedExtras).toEqual([]);
|
||||
expect(SELF_HOSTED_PLAN_BY_TIER.relay.highlights).toContain('Pulse Mobile pairing');
|
||||
expect(SELF_HOSTED_PLAN_BY_TIER.relay.highlights).toContain('No inbound ports required');
|
||||
expect(SELF_HOSTED_PLAN_BY_TIER.relay.highlights.join('\n')).not.toMatch(
|
||||
/yourlab\.pulserelay\.pro|custom\s+(?:url|subdomain|domain)/i,
|
||||
);
|
||||
expect(SELF_HOSTED_PLAN_BY_TIER.pro.billingExtrasSummary).toBe(
|
||||
'Analysis, remediation, and admin controls',
|
||||
);
|
||||
|
|
@ -245,6 +250,9 @@ describe('selfHostedPlans', () => {
|
|||
expect(paidClaimText).not.toMatch(
|
||||
/unlimited|monitoring capacity|guest capacity|hosted quickstart|trial/i,
|
||||
);
|
||||
expect(paidClaimText).not.toMatch(
|
||||
/yourlab\.pulserelay\.pro|custom\s+(?:url|subdomain|domain)/i,
|
||||
);
|
||||
});
|
||||
|
||||
it('maps current billing tiers back to the shared self-hosted plan definitions', () => {
|
||||
|
|
|
|||
|
|
@ -112,7 +112,7 @@ export const CLOUD_COMMERCIAL_PRESENTATION: CloudCommercialPresentation = {
|
|||
'Managed hosting',
|
||||
'Daily backups',
|
||||
'Secure agent connectivity via Relay',
|
||||
'Mobile app access and push notifications',
|
||||
'Pulse Mobile pairing and push notifications',
|
||||
'Dedicated workspace URL',
|
||||
],
|
||||
setupHeading: 'How it works',
|
||||
|
|
|
|||
|
|
@ -82,7 +82,7 @@ export function getSelfHostedPlanEntitlementSummary(
|
|||
case 'community':
|
||||
return `${planLabel} is active on this instance. It includes self-hosted monitoring, 7-day metric history, Pulse Patrol (BYOK), and update alerts.`;
|
||||
case 'relay':
|
||||
return `${planLabel} is active on this instance. Remote web access, mobile pairing, push notifications, and longer history are available right now.`;
|
||||
return `${planLabel} is active on this instance. Remote web access, Pulse Mobile pairing, push notifications, and longer history are available right now.`;
|
||||
case 'pro':
|
||||
return `${planLabel} is active on this instance. Root-cause analysis, safe remediation workflows, 90-day history, and admin/reporting extras are available right now.`;
|
||||
}
|
||||
|
|
@ -135,13 +135,13 @@ export const SELF_HOSTED_PLAN_DEFINITIONS: readonly SelfHostedPlanDefinition[] =
|
|||
entitlementHighlights: getTierEntitlementHighlights('relay', 14),
|
||||
includedExtras: [],
|
||||
comparisonSummary:
|
||||
'Reach your Pulse web UI securely from anywhere, pair the mobile app for handoff and push notifications, and keep 14 days of history.',
|
||||
'Reach your Pulse web UI securely from anywhere, pair supported Pulse Mobile clients for handoff and push notifications, and keep 14 days of history.',
|
||||
highlights: [
|
||||
'Everything in Community',
|
||||
'Remote web access via Relay',
|
||||
'Mobile app pairing',
|
||||
'Pulse Mobile pairing',
|
||||
'Push notifications',
|
||||
'Custom URL (yourlab.pulserelay.pro)',
|
||||
'No inbound ports required',
|
||||
'14-day metric history',
|
||||
],
|
||||
},
|
||||
|
|
@ -196,7 +196,7 @@ export function getSelfHostedPlanDefinitionForBillingTier(
|
|||
export const SELF_HOSTED_COMMERCIAL_PRESENTATION: SelfHostedCommercialPresentation = {
|
||||
pageTitle: 'Pricing',
|
||||
pageDescription:
|
||||
'Self-hosted Pulse includes core monitoring for free. Relay adds secure remote access to the Pulse web UI, mobile pairing, and push notifications, while Pro adds root-cause analysis, safe remediation workflows, 90-day history, and admin/reporting extras.',
|
||||
'Self-hosted Pulse includes core monitoring for free. Relay adds secure remote access to the Pulse web UI, Pulse Mobile pairing, and push notifications, while Pro adds root-cause analysis, safe remediation workflows, 90-day history, and admin/reporting extras.',
|
||||
mostPopularBadge: 'Most Popular',
|
||||
currentPlanLabel: 'Current Plan',
|
||||
includedLabel: 'Included',
|
||||
|
|
|
|||
|
|
@ -48,6 +48,10 @@ FORBIDDEN_PUBLIC_COPY_PATTERNS: tuple[tuple[str, str], ...] = (
|
|||
("hosted model credits", r"\b(?:ai|model)\s+credits?\b"),
|
||||
("hosted Patrol quickstart", r"\bhosted\s+(?:patrol\s+)?quickstart\b"),
|
||||
("bundled Patrol run allowance", r"\b25\s+runs,\s+no\s+api\s+key\b"),
|
||||
(
|
||||
"customer-specific Relay URL promise",
|
||||
r"\byourlab\.pulserelay\.pro\b|\ba\s+custom\s+url\b|custom\s+url\s*\([^)]*pulserelay",
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
|
|
@ -82,6 +86,17 @@ PUBLIC_COPY_AUDIT_FILES: tuple[CopyAuditFileSpec, ...] = (
|
|||
r"does not expose a general in-app trial",
|
||||
),
|
||||
),
|
||||
CopyAuditFileSpec(
|
||||
repo="pulse",
|
||||
relative_path="docs/architecture/v6-pricing-and-tiering.md",
|
||||
required_patterns=(
|
||||
r"monitored systems are not the paid\s+gate",
|
||||
r"Customer-specific Relay URL.*standard outbound relay service",
|
||||
r"Self-hosted trial acquisition.*No",
|
||||
r"Metrics history.*14 days",
|
||||
r"Metrics history.*90 days",
|
||||
),
|
||||
),
|
||||
CopyAuditFileSpec(
|
||||
repo="pulse",
|
||||
relative_path="frontend-modern/src/utils/selfHostedPlans.ts",
|
||||
|
|
@ -93,12 +108,22 @@ PUBLIC_COPY_AUDIT_FILES: tuple[CopyAuditFileSpec, ...] = (
|
|||
r"admin/reporting extras",
|
||||
),
|
||||
),
|
||||
CopyAuditFileSpec(
|
||||
repo="pulse-pro",
|
||||
relative_path="MONETIZATION.md",
|
||||
required_patterns=(
|
||||
r"Relay Tier.*14-day history",
|
||||
r"Pulse Relay.*secure remote access",
|
||||
r"No inbound firewall ports",
|
||||
r"Self-hosted Pro should be sold on root-cause analysis",
|
||||
),
|
||||
),
|
||||
CopyAuditFileSpec(
|
||||
repo="pulse-pro",
|
||||
relative_path="landing-page/index.html",
|
||||
required_patterns=(
|
||||
r"Community keeps core monitoring free",
|
||||
r"mobile app pairing, push notifications, and 14-day history",
|
||||
r"(?:Pulse Mobile|mobile app) pairing, push notifications, and 14-day history",
|
||||
r"root-cause analysis, safe remediation workflows, and 90-day history",
|
||||
r"Do Relay or Pro charge by server\?",
|
||||
r"Existing Pulse Pro and legacy Pro\+ holders keep their paid runtime access",
|
||||
|
|
@ -109,11 +134,21 @@ PUBLIC_COPY_AUDIT_FILES: tuple[CopyAuditFileSpec, ...] = (
|
|||
relative_path="license-server/public_pricing.go",
|
||||
required_patterns=(
|
||||
r"Community keeps core monitoring free",
|
||||
r"mobile app pairing, push notifications, and 14-day history",
|
||||
r"(?:Pulse Mobile|mobile app) pairing, push notifications, and 14-day history",
|
||||
r"root-cause analysis, safe remediation workflows, team controls, and 90-day history",
|
||||
r"not as the self-hosted paid gate",
|
||||
),
|
||||
),
|
||||
CopyAuditFileSpec(
|
||||
repo="pulse-pro",
|
||||
relative_path="license-server/scripts/create-v6-stripe-prices.sh",
|
||||
required_patterns=(
|
||||
r"Pulse Relay",
|
||||
r"Pulse Mobile pairing",
|
||||
r"no inbound firewall ports",
|
||||
r"14-day history",
|
||||
),
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
|
|
@ -234,6 +269,7 @@ def build_command_specs(args: argparse.Namespace) -> list[CommandSpec]:
|
|||
"test",
|
||||
"--",
|
||||
"src/utils/__tests__/selfHostedPlans.test.ts",
|
||||
"src/utils/__tests__/cloudPlans.test.ts",
|
||||
"src/utils/__tests__/commercialBillingModel.test.ts",
|
||||
"src/utils/__tests__/licensePresentation.test.ts",
|
||||
"src/stores/__tests__/license.test.ts",
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue