diff --git a/src/Backend/AutopilotMonitor.Functions/Functions/GetRuleResultsFunction.cs b/src/Backend/AutopilotMonitor.Functions/Functions/GetRuleResultsFunction.cs
index d6dace29..32bae941 100644
--- a/src/Backend/AutopilotMonitor.Functions/Functions/GetRuleResultsFunction.cs
+++ b/src/Backend/AutopilotMonitor.Functions/Functions/GetRuleResultsFunction.cs
@@ -49,17 +49,17 @@ namespace AutopilotMonitor.Functions.Functions
try
{
var ruleEngine = new RuleEngine(_analyzeRuleService, _storageService, _logger);
- var newResults = await ruleEngine.AnalyzeSessionAsync(tenantId, sessionId);
+ var freshResults = await ruleEngine.AnalyzeSessionAsync(tenantId, sessionId, reanalyze: true);
- foreach (var result in newResults)
+ // Delete existing results so stale entries don't persist after re-analysis
+ await _storageService.DeleteSessionRuleResultsAsync(tenantId, sessionId);
+
+ foreach (var result in freshResults)
{
await _storageService.StoreRuleResultAsync(result);
}
- if (newResults.Count > 0)
- {
- _logger.LogInformation($"On-demand analysis for session {sessionId}: {newResults.Count} new issue(s) detected");
- }
+ _logger.LogInformation($"On-demand re-analysis for session {sessionId}: {freshResults.Count} issue(s) detected");
}
catch (Exception ex)
{
diff --git a/src/Backend/AutopilotMonitor.Functions/Services/RuleEngine.cs b/src/Backend/AutopilotMonitor.Functions/Services/RuleEngine.cs
index 64259abb..7a46059c 100644
--- a/src/Backend/AutopilotMonitor.Functions/Services/RuleEngine.cs
+++ b/src/Backend/AutopilotMonitor.Functions/Services/RuleEngine.cs
@@ -25,8 +25,9 @@ namespace AutopilotMonitor.Functions.Services
///
/// Evaluates ALL active analyze rules against the full session event stream.
/// Called once at enrollment end or on-demand. Fetches events internally.
+ /// When reanalyze=true, all rules are re-evaluated regardless of existing results.
///
- public async Task> AnalyzeSessionAsync(string tenantId, string sessionId)
+ public async Task> AnalyzeSessionAsync(string tenantId, string sessionId, bool reanalyze = false)
{
var results = new List();
@@ -41,9 +42,18 @@ namespace AutopilotMonitor.Functions.Services
return results;
}
- // Get existing rule results to avoid duplicates
- var existingResults = await _storageService.GetRuleResultsAsync(tenantId, sessionId);
- var existingRuleIds = new HashSet(existingResults.Select(r => r.RuleId));
+ // On reanalyze: skip deduplication so all rules are re-evaluated from scratch
+ // On normal run: skip rules already evaluated to avoid duplicate storage
+ HashSet existingRuleIds;
+ if (reanalyze)
+ {
+ existingRuleIds = new HashSet();
+ }
+ else
+ {
+ var existingResults = await _storageService.GetRuleResultsAsync(tenantId, sessionId);
+ existingRuleIds = new HashSet(existingResults.Select(r => r.RuleId));
+ }
_logger.LogInformation($"Analyzing session {sessionId}: {allEvents.Count} events, {activeRules.Count} rules ({existingRuleIds.Count} already evaluated)");