From f76acd62564a8c50f11dc62cf83a45eb86f36754 Mon Sep 17 00:00:00 2001 From: Nils Pukropp Date: Thu, 26 Feb 2026 16:09:44 +0100 Subject: [PATCH] audit fix and code stability improvement --- src/engine/mod.rs | 32 +++++++++++++++++++++++--------- src/main.rs | 2 +- src/orchestrator/mod.rs | 23 ++++++++++++++++------- src/sal/dell_xps_9380.rs | 2 +- src/ui/dashboard.rs | 15 ++++++++++++--- 5 files changed, 53 insertions(+), 21 deletions(-) diff --git a/src/engine/mod.rs b/src/engine/mod.rs index 7ae4681..99d094f 100644 --- a/src/engine/mod.rs +++ b/src/engine/mod.rs @@ -38,7 +38,7 @@ impl OptimizerEngine { Self { window_size } } - /// Applies a simple moving average (SMA) filter to a stream of values. + /// Applies a simple moving average (SMA) filter with outlier rejection. pub fn smooth(&self, data: &[f32]) -> Vec { if data.is_empty() { return vec![]; } let mut smoothed = Vec::with_capacity(data.len()); @@ -46,8 +46,19 @@ impl OptimizerEngine { for i in 0..data.len() { let start = if i < self.window_size { 0 } else { i - self.window_size + 1 }; let end = i + 1; - let sum: f32 = data[start..end].iter().sum(); - smoothed.push(sum / (end - start) as f32); + + // Outlier rejection: only average values within a reasonable range + let window = &data[start..end]; + let avg: f32 = window.iter().sum::() / window.len() as f32; + let filtered: Vec = window.iter() + .filter(|&&v| (v - avg).abs() < 20.0) // Reject spikes > 20 units + .cloned().collect(); + + if filtered.is_empty() { + smoothed.push(avg); + } else { + smoothed.push(filtered.iter().sum::() / filtered.len() as f32); + } } smoothed } @@ -55,11 +66,9 @@ impl OptimizerEngine { /// Calculates Thermal Resistance: R_theta = (T_core - T_ambient) / P_package pub fn calculate_thermal_resistance(&self, profile: &ThermalProfile) -> f32 { profile.points.iter() + .filter(|p| p.power_w > 1.0 && p.temp_c > 30.0) // Filter invalid data .max_by(|a, b| a.power_w.partial_cmp(&b.power_w).unwrap_or(std::cmp::Ordering::Equal)) - .map(|p| { - if p.power_w < 1.0 { 0.0 } - else { (p.temp_c - profile.ambient_temp) / p.power_w } - }) + .map(|p| (p.temp_c - profile.ambient_temp) / p.power_w) .unwrap_or(0.0) } @@ -73,11 +82,16 @@ impl OptimizerEngine { /// Finds the "Silicon Knee" - the point where performance per watt (efficiency) /// starts to diminish significantly and thermal density spikes. pub fn find_silicon_knee(&self, profile: &ThermalProfile) -> f32 { - if profile.points.len() < 3 { + let valid_points: Vec<_> = profile.points.iter() + .filter(|p| p.power_w > 5.0 && p.temp_c > 40.0) // Filter idle/noise + .cloned() + .collect(); + + if valid_points.len() < 3 { return profile.points.last().map(|p| p.power_w).unwrap_or(15.0); } - let mut points = profile.points.clone(); + let mut points = valid_points; points.sort_by(|a, b| a.power_w.partial_cmp(&b.power_w).unwrap_or(std::cmp::Ordering::Equal)); let mut best_pl = points[0].power_w; diff --git a/src/main.rs b/src/main.rs index 3f14c3a..b22dc3c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -229,7 +229,7 @@ fn main() -> Result<()> { while let Ok(new_state) = telemetry_rx.try_recv() { if let Some(log) = &new_state.log_event { - ui_state.logs.push(log.clone()); + ui_state.add_log(log.clone()); debug!("Backend Log: {}", log); } else { ui_state.update(&new_state); diff --git a/src/orchestrator/mod.rs b/src/orchestrator/mod.rs index 8674175..5d7d914 100644 --- a/src/orchestrator/mod.rs +++ b/src/orchestrator/mod.rs @@ -7,7 +7,6 @@ use sysinfo::System; use std::sync::Arc; use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::Mutex; -use std::path::PathBuf; use crate::sal::traits::{PlatformSal, AuditStep, SafetyStatus}; use crate::sal::heuristic::discovery::SystemFactSheet; @@ -80,6 +79,21 @@ impl BenchmarkOrchestrator { // Start Watchdog Monitor let _watchdog_handle = self.spawn_watchdog_monitor(); + // Use a closure to ensure cleanup always runs + let result = self.execute_benchmark(); + + // --- MANDATORY CLEANUP --- + self.log("Benchmark sequence finished. Restoring hardware defaults...")?; + let _ = self.workload.stop(); + if let Err(e) = self.sal.restore() { + anyhow::bail!("CRITICAL: Failed to restore hardware state: {}", e); + } + self.log("✓ Hardware state restored.")?; + + result + } + + fn execute_benchmark(&mut self) -> Result { // Phase 1: Audit & Baseline self.phase = BenchmarkPhase::Auditing; for step in self.sal.audit() { @@ -208,9 +222,6 @@ impl BenchmarkOrchestrator { res.config_paths.insert("i8kmon".to_string(), i8k_path.clone()); } - self.sal.restore()?; - self.log("✓ Environment restored.")?; - Ok(res) } @@ -228,9 +239,7 @@ impl BenchmarkOrchestrator { abort.store(true, Ordering::SeqCst); break; } - Ok(SafetyStatus::Warning(_msg)) | Ok(SafetyStatus::Critical(_msg)) => { - // Send warning log to UI - } + Ok(SafetyStatus::Warning(_msg)) | Ok(SafetyStatus::Critical(_msg)) => {} Ok(SafetyStatus::Nominal) => {} Err(e) => { *reason_store.lock().unwrap() = Some(format!("Watchdog Sensor Failure: {}", e)); diff --git a/src/sal/dell_xps_9380.rs b/src/sal/dell_xps_9380.rs index 61eaf21..436387e 100644 --- a/src/sal/dell_xps_9380.rs +++ b/src/sal/dell_xps_9380.rs @@ -108,7 +108,6 @@ impl PreflightAuditor for DellXps9380Sal { } }); - // Tool availability check let tool_check = self.fact_sheet.paths.tools.contains_key("dell_fan_ctrl"); steps.push(AuditStep { description: "Dell Fan Control Tool".to_string(), @@ -125,6 +124,7 @@ impl EnvironmentGuard for DellXps9380Sal { let mut suppressed = self.suppressed_services.lock().unwrap(); for s in services { if Command::new("systemctl").args(["is-active", "--quiet", s]).status()?.success() { + debug!("Suppressing service: {}", s); Command::new("systemctl").args(["stop", s]).status()?; suppressed.push(s.to_string()); } diff --git a/src/ui/dashboard.rs b/src/ui/dashboard.rs index 17d309f..332f85e 100644 --- a/src/ui/dashboard.rs +++ b/src/ui/dashboard.rs @@ -7,20 +7,29 @@ use ratatui::{ Frame, prelude::Stylize, }; +use std::collections::VecDeque; use crate::mediator::TelemetryState; use crate::ui::theme::*; /// DashboardState maintains UI-specific state that isn't part of the core telemetry, /// such as the accumulated diagnostic logs. pub struct DashboardState { - pub logs: Vec, + pub logs: VecDeque, } impl DashboardState { pub fn new() -> Self { - Self { - logs: vec!["ember-tune Initialized.".to_string()], + let mut logs = VecDeque::with_capacity(100); + logs.push_back("ember-tune Initialized.".to_string()); + Self { logs } + } + + /// Adds a log message and ensures the buffer does not exceed capacity. + pub fn add_log(&mut self, msg: String) { + if self.logs.len() >= 100 { + self.logs.pop_front(); } + self.logs.push_back(msg); } /// Updates the UI state based on new telemetry.