Skip to main content

crackle_runtime/
profile.rs

1use std::time::Duration;
2
3/// How fast the kiln cools — controls pattern sensitivity.
4///
5/// Fast cooling produces many fine cracks (more patterns detected, lower threshold).
6/// Slow cooling produces fewer, larger patterns (higher confidence).
7///
8/// Like pottery: the rate of cooling determines the character of the crackle.
9#[derive(Debug, Clone, Copy, PartialEq, Default)]
10pub enum CoolingRate {
11    /// Fast cooling: many fine cracks, lower thresholds, more patterns.
12    /// Like quenching hot pottery — dramatic, lots of crackle lines.
13    Fast,
14    /// Normal cooling: balanced pattern detection.
15    #[default]
16    Normal,
17    /// Slow cooling: fewer but more significant patterns.
18    /// Like letting the kiln cool naturally — fewer cracks, but the ones that form
19    /// are large and meaningful.
20    Slow,
21}
22
23impl CoolingRate {
24    /// The clustering distance threshold for this cooling rate.
25    pub fn cluster_threshold(&self) -> f64 {
26        match self {
27            CoolingRate::Fast => 1.5,
28            CoolingRate::Normal => 2.5,
29            CoolingRate::Slow => 4.0,
30        }
31    }
32
33    /// The correlation threshold for this cooling rate.
34    pub fn correlation_threshold(&self) -> f64 {
35        match self {
36            CoolingRate::Fast => 0.5,
37            CoolingRate::Normal => 0.7,
38            CoolingRate::Slow => 0.9,
39        }
40    }
41
42    /// The minimum number of tasks needed before pattern detection activates.
43    pub fn min_tasks_for_detection(&self) -> usize {
44        match self {
45            CoolingRate::Fast => 2,
46            CoolingRate::Normal => 3,
47            CoolingRate::Slow => 5,
48        }
49    }
50
51    /// Phase transition sensitivity — how much shift triggers detection.
52    pub fn phase_transition_sensitivity(&self) -> f64 {
53        match self {
54            CoolingRate::Fast => 0.3,
55            CoolingRate::Normal => 0.5,
56            CoolingRate::Slow => 0.8,
57        }
58    }
59
60    /// The conservation law tolerance — how close to zero a sum must be.
61    pub fn conservation_tolerance(&self) -> f64 {
62        match self {
63            CoolingRate::Fast => 0.5,
64            CoolingRate::Normal => 0.3,
65            CoolingRate::Slow => 0.1,
66        }
67    }
68}
69
70/// The thermal profile controls how the kiln cools.
71///
72/// Just as a potter controls the cooling rate to influence crackle patterns,
73/// the thermal profile controls the sensitivity and character of pattern detection.
74#[derive(Debug, Clone)]
75pub struct ThermalProfile {
76    /// The cooling rate.
77    pub rate: CoolingRate,
78    /// Maximum time to spend in cooling phase per task.
79    pub max_cooling_duration: Duration,
80    /// Whether to enable clustering pattern detection.
81    pub detect_clustering: bool,
82    /// Whether to enable phase transition detection.
83    pub detect_phase_transitions: bool,
84    /// Whether to enable conservation law detection.
85    pub detect_conservation: bool,
86    /// Whether to enable correlation detection.
87    pub detect_correlations: bool,
88}
89
90impl Default for ThermalProfile {
91    fn default() -> Self {
92        ThermalProfile {
93            rate: CoolingRate::Normal,
94            max_cooling_duration: Duration::from_secs(60),
95            detect_clustering: true,
96            detect_phase_transitions: true,
97            detect_conservation: true,
98            detect_correlations: true,
99        }
100    }
101}
102
103impl ThermalProfile {
104    /// Create a profile optimized for fast cooling — many fine patterns.
105    pub fn fast_cooling() -> Self {
106        ThermalProfile {
107            rate: CoolingRate::Fast,
108            max_cooling_duration: Duration::from_secs(10),
109            ..ThermalProfile::default()
110        }
111    }
112
113    /// Create a profile optimized for slow cooling — fewer, larger patterns.
114    pub fn slow_cooling() -> Self {
115        ThermalProfile {
116            rate: CoolingRate::Slow,
117            max_cooling_duration: Duration::from_secs(300),
118            ..ThermalProfile::default()
119        }
120    }
121
122    /// Create a profile with all detection disabled (useful for benchmarking).
123    pub fn no_detection() -> Self {
124        ThermalProfile {
125            detect_clustering: false,
126            detect_phase_transitions: false,
127            detect_conservation: false,
128            detect_correlations: false,
129            ..ThermalProfile::default()
130        }
131    }
132
133    /// Set the cooling rate.
134    pub fn with_rate(mut self, rate: CoolingRate) -> Self {
135        self.rate = rate;
136        self
137    }
138
139    /// Disable clustering detection.
140    pub fn without_clustering(mut self) -> Self {
141        self.detect_clustering = false;
142        self
143    }
144
145    /// Disable phase transition detection.
146    pub fn without_phase_transitions(mut self) -> Self {
147        self.detect_phase_transitions = false;
148        self
149    }
150
151    /// Disable conservation law detection.
152    pub fn without_conservation(mut self) -> Self {
153        self.detect_conservation = false;
154        self
155    }
156
157    /// Disable correlation detection.
158    pub fn without_correlations(mut self) -> Self {
159        self.detect_correlations = false;
160        self
161    }
162}