fix: AI Patrol only runs when AI is enabled. Related to #885

Users who haven't enabled AI were seeing AI patrol findings from
heuristic analysis that they couldn't dismiss (license-gated).

- IsPatrolEnabled() now checks if Enabled is true
- IsAlertTriggeredAnalysisEnabled() also checks Enabled
- Updated tests to reflect new behavior

AI patrol and alert-triggered analysis require AI to be enabled
as a master switch. This prevents confusing UX where users see
AI features without having configured them.
This commit is contained in:
rcourtman
2025-12-24 15:11:46 +00:00
parent e5c7cf7d1e
commit e86998ec58
2 changed files with 31 additions and 10 deletions

View File

@@ -445,8 +445,13 @@ func PresetToMinutes(preset string) int {
}
// IsPatrolEnabled returns true if patrol should run
// Note: Patrol uses local heuristics and doesn't require an AI API key
// Note: Patrol uses local heuristics and doesn't require an AI API key,
// but still requires AI to be enabled as a master switch
func (c *AIConfig) IsPatrolEnabled() bool {
// If AI is disabled globally, patrol is disabled
if !c.Enabled {
return false
}
// If preset is "disabled", patrol is disabled
if c.PatrolSchedulePreset == "disabled" {
return false
@@ -456,6 +461,10 @@ func (c *AIConfig) IsPatrolEnabled() bool {
// IsAlertTriggeredAnalysisEnabled returns true if AI should analyze resources when alerts fire
func (c *AIConfig) IsAlertTriggeredAnalysisEnabled() bool {
// Requires AI to be enabled as a master switch
if !c.Enabled {
return false
}
return c.AlertTriggeredAnalysis
}

View File

@@ -606,18 +606,23 @@ func TestAIConfig_IsPatrolEnabled(t *testing.T) {
expected bool
}{
{
name: "patrol disabled by preset",
config: AIConfig{PatrolEnabled: true, PatrolSchedulePreset: "disabled"},
name: "patrol disabled when AI disabled",
config: AIConfig{Enabled: false, PatrolEnabled: true},
expected: false,
},
{
name: "patrol enabled",
config: AIConfig{PatrolEnabled: true},
name: "patrol disabled by preset",
config: AIConfig{Enabled: true, PatrolEnabled: true, PatrolSchedulePreset: "disabled"},
expected: false,
},
{
name: "patrol enabled when AI enabled",
config: AIConfig{Enabled: true, PatrolEnabled: true},
expected: true,
},
{
name: "patrol disabled by flag",
config: AIConfig{PatrolEnabled: false},
config: AIConfig{Enabled: true, PatrolEnabled: false},
expected: false,
},
}
@@ -633,15 +638,22 @@ func TestAIConfig_IsPatrolEnabled(t *testing.T) {
}
func TestAIConfig_IsAlertTriggeredAnalysisEnabled(t *testing.T) {
t.Run("enabled", func(t *testing.T) {
config := AIConfig{AlertTriggeredAnalysis: true}
t.Run("enabled when AI enabled", func(t *testing.T) {
config := AIConfig{Enabled: true, AlertTriggeredAnalysis: true}
if !config.IsAlertTriggeredAnalysisEnabled() {
t.Error("expected true")
}
})
t.Run("disabled", func(t *testing.T) {
config := AIConfig{AlertTriggeredAnalysis: false}
t.Run("disabled when AI disabled", func(t *testing.T) {
config := AIConfig{Enabled: false, AlertTriggeredAnalysis: true}
if config.IsAlertTriggeredAnalysisEnabled() {
t.Error("expected false when AI is disabled")
}
})
t.Run("disabled by flag", func(t *testing.T) {
config := AIConfig{Enabled: true, AlertTriggeredAnalysis: false}
if config.IsAlertTriggeredAnalysisEnabled() {
t.Error("expected false")
}