From 430f0d3fa230598a45faf61c884d5ced5d8f22ba Mon Sep 17 00:00:00 2001 From: rcourtman Date: Sun, 26 Apr 2026 21:08:15 +0100 Subject: [PATCH] Clarify Pro Plus continuity feature contract --- pkg/licensing/features.go | 2 +- pkg/licensing/features_test.go | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/pkg/licensing/features.go b/pkg/licensing/features.go index ad998f737..d9a2023f4 100644 --- a/pkg/licensing/features.go +++ b/pkg/licensing/features.go @@ -301,7 +301,7 @@ var TierFeatures = map[Tier][]string{ TierFree: freeFeatures, TierRelay: relayFeatures, TierPro: proFeatures, - TierProPlus: proFeatures, // Same features as Pro, just higher host limit + TierProPlus: proFeatures, // Legacy compatibility tier; same runtime features as Pro TierProAnnual: proFeatures, // Legacy: same features as Pro TierLifetime: proFeatures, // Legacy: same features as Pro TierCloud: proFeatures, // Cloud includes all Pro features + managed hosting diff --git a/pkg/licensing/features_test.go b/pkg/licensing/features_test.go index 9aa2f4285..ff0b5b67a 100644 --- a/pkg/licensing/features_test.go +++ b/pkg/licensing/features_test.go @@ -384,6 +384,17 @@ func TestTierFeatureInheritance(t *testing.T) { } } + // Pro+ is a legacy continuity tier, not a bigger self-hosted monitoring tier. + proPlusSet := asSet(TierFeatures[TierProPlus]) + if len(proPlusSet) != len(proSet) { + t.Fatalf("Pro+ feature count = %d, want Pro feature count %d", len(proPlusSet), len(proSet)) + } + for f := range proSet { + if !proPlusSet[f] { + t.Errorf("Pro+ tier missing Pro feature %q", f) + } + } + // MSP must include all Pro features. mspSet := asSet(TierFeatures[TierMSP]) for f := range proSet {