Skip to main content

runifold_testkit/evaluation/
regression.rs

1use super::{Deserialize, EvaluationError, Serialize, ensure_ratio};
2
3/// Allowed relative quality drops.
4#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)]
5pub struct RegressionPolicy {
6    /// Maximum allowed mean score decrease.
7    pub max_mean_drop: f64,
8    /// Maximum allowed pass-rate decrease.
9    pub max_pass_rate_drop: f64,
10    /// Maximum allowed target execution-success decrease.
11    pub max_execution_success_drop: f64,
12}
13
14impl RegressionPolicy {
15    /// Creates a validated regression policy.
16    ///
17    /// # Errors
18    ///
19    /// Returns an error when any allowed drop is outside zero through one.
20    pub fn new(
21        max_mean_drop: f64,
22        max_pass_rate_drop: f64,
23        max_execution_success_drop: f64,
24    ) -> Result<Self, EvaluationError> {
25        let policy = Self {
26            max_mean_drop,
27            max_pass_rate_drop,
28            max_execution_success_drop,
29        };
30        policy.validate()?;
31        Ok(policy)
32    }
33
34    pub(super) fn validate(&self) -> Result<(), EvaluationError> {
35        ensure_ratio("maximum mean drop", self.max_mean_drop)?;
36        ensure_ratio("maximum pass-rate drop", self.max_pass_rate_drop)?;
37        ensure_ratio(
38            "maximum execution-success drop",
39            self.max_execution_success_drop,
40        )
41    }
42}
43
44/// One baseline-to-candidate score comparison.
45#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
46pub struct MetricRegression {
47    /// Stable scorer name.
48    pub name: String,
49    /// Baseline mean.
50    pub baseline_mean: f64,
51    /// Candidate mean.
52    pub candidate_mean: f64,
53    /// Candidate minus baseline mean.
54    pub mean_delta: f64,
55    /// Baseline pass rate.
56    pub baseline_pass_rate: f64,
57    /// Candidate pass rate.
58    pub candidate_pass_rate: f64,
59    /// Candidate minus baseline pass rate.
60    pub pass_rate_delta: f64,
61    /// Whether both drops satisfy policy.
62    pub passed: bool,
63}
64
65/// Complete relative regression decision.
66#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
67pub struct RegressionComparison {
68    /// Baseline candidate version.
69    pub baseline_version: String,
70    /// New candidate version.
71    pub candidate_version: String,
72    /// Candidate minus baseline target execution success.
73    pub execution_success_rate_delta: f64,
74    /// Per-score comparisons.
75    pub metrics: Vec<MetricRegression>,
76    /// Whether every relative regression gate passed.
77    pub passed: bool,
78}