Skip to main content

crackle_runtime/
profile.rs

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