pub struct ThermalProfile {
pub rate: CoolingRate,
pub max_cooling_duration: Duration,
pub detect_clustering: bool,
pub detect_phase_transitions: bool,
pub detect_conservation: bool,
pub detect_correlations: bool,
}Expand description
The thermal profile controls how the kiln cools.
Just as a potter controls the cooling rate to influence crackle patterns, the thermal profile controls the sensitivity and character of pattern detection.
Fields§
§rate: CoolingRateThe cooling rate.
max_cooling_duration: DurationMaximum time to spend in cooling phase per task.
detect_clustering: boolWhether to enable clustering pattern detection.
detect_phase_transitions: boolWhether to enable phase transition detection.
detect_conservation: boolWhether to enable conservation law detection.
detect_correlations: boolWhether to enable correlation detection.
Implementations§
Source§impl ThermalProfile
impl ThermalProfile
Sourcepub fn fast_cooling() -> Self
pub fn fast_cooling() -> Self
Create a profile optimized for fast cooling — many fine patterns.
Examples found in repository?
29fn main() {
30 let mut kiln = Kiln::new(ThermalProfile::fast_cooling());
31
32 kiln.fire_and_record(NumberTask { value: 2.0, name: "a".into() }).unwrap();
33 kiln.fire_and_record(NumberTask { value: 2.1, name: "b".into() }).unwrap();
34 kiln.fire_and_record(NumberTask { value: 9.8, name: "c".into() }).unwrap();
35 kiln.fire_and_record(NumberTask { value: 10.0, name: "d".into() }).unwrap();
36 kiln.fire_and_record(NumberTask { value: 2.2, name: "e".into() }).unwrap();
37
38 println!("Tasks in kiln: {}", kiln.task_count());
39
40 let patterns = kiln.cool();
41 println!("\nDetected {} pattern(s):\n", patterns.len());
42
43 for p in &patterns {
44 println!("[{}] {}", p.kind(), p.description());
45 println!(" confidence: {:.2}", p.confidence());
46 println!(" tasks: {:?}\n", p.involved_tasks());
47 }
48}More examples
98fn main() {
99 let total_events = 1000;
100 let batch_size = 100;
101 let num_batches = total_events / batch_size;
102
103 println!("═══════════════════════════════════════════════════════════════");
104 println!(" CRACKLE-RUNTIME: EVENT STREAM PROCESSOR TEST");
105 println!("═══════════════════════════════════════════════════════════════\n");
106 println!("Processing {} events across {} batches of {}...\n",
107 total_events, num_batches, batch_size);
108
109 let start = Instant::now();
110
111 // Phase 1: Healthy system (batches 1-4)
112 println!("─── Phase 1: Healthy System ───");
113 let mut healthy_kiln = Kiln::new(
114 ThermalProfile::fast_cooling()
115 );
116
117 // Batch 1-4: all healthy, 10ms baseline latency
118 for batch_id in 1..=4 {
119 let events = simulate_batch(batch_id, batch_size as u32, 10.0, 0.05);
120 for event in events {
121 healthy_kiln.fire_and_record(event).unwrap();
122 }
123
124 let elapsed = start.elapsed();
125 println!(" Batch {}/{} fired ({} events, {:.0}ms)",
126 batch_id, num_batches, batch_size, elapsed.as_millis());
127 }
128
129 // Cool healthy phase
130 let healthy_patterns = healthy_kiln.cool();
131 println!("\n Healthy system patterns ({} detected):", healthy_patterns.len());
132 for p in &healthy_patterns {
133 println!(" [{:?}] {} (conf: {:.2})", p.kind(), p.description(), p.confidence());
134 }
135 // Also check conservation on records_in/records_out
136 let conservation = healthy_kiln.distribution_shift(10);
137 println!(" Distribution shifts:");
138 for (name, shift) in &conservation[..conservation.len().min(3)] {
139 println!(" {} → KL = {:.4}", name, shift);
140 }
141
142 println!();
143
144 // Phase 2: Degrading system (batches 5-8)
145 println!("─── Phase 2: Degrading System ───");
146
147 let mut degrading_kiln = Kiln::new(
148 ThermalProfile::fast_cooling()
149 );
150
151 // Batches where degradation ramps up
152 let degradation_levels = [0.2, 0.5, 0.9, 1.5];
153 for (i, °radation) in degradation_levels.iter().enumerate() {
154 let batch_id = (5 + i) as u32;
155 // latency increases with degradation
156 let base_latency = 10.0 + degradation * 50.0;
157
158 let events = simulate_batch(batch_id, batch_size as u32, base_latency, degradation);
159 for event in events {
160 degrading_kiln.fire_and_record(event).unwrap();
161 }
162
163 let elapsed = start.elapsed();
164 println!(" Batch {}/{} [degradation={:.1}x] fired (latency baseline: {:.0}ms, {:.0}ms total)",
165 batch_id, num_batches, degradation, base_latency, elapsed.as_millis());
166 }
167
168 let degrading_patterns = degrading_kiln.cool();
169 println!("\n Degrading system patterns ({} detected):", degrading_patterns.len());
170 for p in °rading_patterns {
171 println!(" [{:?}] {} (conf: {:.2})", p.kind(), p.description(), p.confidence());
172 }
173
174 // JSD shift (distribution shape changes)
175 let jsd_shifts = degrading_kiln.jsd_shift(10);
176 println!(" JSD shifts (distribution shape changes):");
177 for (name, shift) in &jsd_shifts[..jsd_shifts.len().min(5)] {
178 println!(" {} → JSD = {:.4}", name, shift);
179 }
180
181 // Permutation entropy (temporal structure)
182 let pes = degrading_kiln.permutation_entropies(4);
183 println!(" Permutation entropies (temporal structure):");
184 for (name, pe) in &pes {
185 println!(" {} → PE = {:.4}", name, pe);
186 }
187
188 println!();
189
190 // Phase 3: Conservation law test — records in = records out should be violated
191 // as errors increase
192 println!("─── Phase 3: Conservation Law Verification ───");
193 let mut conservation_kiln = Kiln::new(
194 ThermalProfile::fast_cooling()
195 );
196
197 // Force records_in = records_out for first 3 batches (healthy conservation)
198 for batch_id in 1..=3 {
199 let event = ProcessedEvent {
200 event_id: batch_id as u64,
201 batch_id: batch_id as u32,
202 processing_time_ms: 10.0,
203 throughput: 100.0,
204 memory_mb: 128.0,
205 error_rate: 0.01,
206 records_in: 1000.0,
207 records_out: 995.0, // nearly conserved
208 cpu_temp_c: 65.0,
209 latency_p99_ms: 25.0,
210 consumer_lag: 10.0,
211 gc_pause_ms: 5.0,
212 };
213 conservation_kiln.fire_and_record(event).unwrap();
214 }
215
216 // Force violation of records conservation (errors spike)
217 for batch_id in 4..=6 {
218 let event = ProcessedEvent {
219 event_id: batch_id as u64,
220 batch_id: batch_id as u32,
221 processing_time_ms: 10.0 + batch_id as f64 * 10.0,
222 throughput: 50.0,
223 memory_mb: 256.0,
224 error_rate: 0.3,
225 records_in: 1000.0,
226 records_out: 700.0, // 30% loss — conservation violated
227 cpu_temp_c: 80.0,
228 latency_p99_ms: 100.0,
229 consumer_lag: 500.0,
230 gc_pause_ms: 20.0,
231 };
232 conservation_kiln.fire_and_record(event).unwrap();
233 }
234
235 let conservation_patterns = conservation_kiln.cool();
236 println!(" Conservation-specific patterns ({} detected):", conservation_patterns.len());
237 for p in &conservation_patterns {
238 println!(" [{:?}] {} (conf: {:.2})", p.kind(), p.description(), p.confidence());
239 }
240
241 // MI matrix to show nonlinear dependencies
242 let mi = conservation_kiln.mi_matrix(8);
243 println!(" Mutual Information matrix (8 bins):");
244 let metric_names = ["processing_time_ms", "error_rate", "records_in", "records_out", "memory_mb"];
245 for (i, name_i) in metric_names.iter().enumerate() {
246 for (j, name_j) in metric_names.iter().enumerate() {
247 if i == j {
248 println!(" I({:25}; {:25}) = H({})", name_i, name_j, name_i);
249 } else {
250 println!(" I({:25}; {:25}) = {:.4} bits", name_i, name_j, mi[i][j]);
251 }
252 }
253 }
254
255 println!();
256 println!("───────────────────────────────────────────────────────────────");
257 println!(" SUMMARY");
258 println!("───────────────────────────────────────────────────────────────\n");
259
260 // Degradation detection analysis
261 println!(" Degradation Metrics:");
262 let pt = degrading_patterns.iter().filter(|p| matches!(p.kind(), crackle_runtime::PatternKind::PhaseTransition));
263 let pt_count = pt.count();
264 println!(" Phase transitions detected in degraded system: {} alerts",
265 pt_count);
266
267 let corr = degrading_patterns.iter().filter(|p| matches!(p.kind(), crackle_runtime::PatternKind::Correlation));
268 let corr_count = corr.count();
269 println!(" Correlations in degraded system: {} pairs", corr_count);
270
271 let cons = degrading_patterns.iter().filter(|p| matches!(p.kind(), crackle_runtime::PatternKind::Conservation));
272 let cons_count = cons.count();
273 println!(" Conservation laws in degraded system: {} found", cons_count);
274
275 let clust = degrading_patterns.iter().filter(|p| matches!(p.kind(), crackle_runtime::PatternKind::Clustering));
276 let clust_count = clust.count();
277 println!(" Clusters in degraded system: {} groups", clust_count);
278
279 println!();
280 let total_duration = start.elapsed();
281 println!(" Total test duration: {:.2}s", total_duration.as_secs_f64());
282 println!(" Events processed: {}", total_events);
283 println!(" Avg throughput: {:.0} events/s",
284 total_events as f64 / total_duration.as_secs_f64());
285}Sourcepub fn slow_cooling() -> Self
pub fn slow_cooling() -> Self
Create a profile optimized for slow cooling — fewer, larger patterns.
Sourcepub fn no_detection() -> Self
pub fn no_detection() -> Self
Create a profile with all detection disabled (useful for benchmarking).
Sourcepub fn with_rate(self, rate: CoolingRate) -> Self
pub fn with_rate(self, rate: CoolingRate) -> Self
Set the cooling rate.
Sourcepub fn without_clustering(self) -> Self
pub fn without_clustering(self) -> Self
Disable clustering detection.
Sourcepub fn without_phase_transitions(self) -> Self
pub fn without_phase_transitions(self) -> Self
Disable phase transition detection.
Sourcepub fn without_conservation(self) -> Self
pub fn without_conservation(self) -> Self
Disable conservation law detection.
Sourcepub fn without_correlations(self) -> Self
pub fn without_correlations(self) -> Self
Disable correlation detection.
Trait Implementations§
Source§impl Clone for ThermalProfile
impl Clone for ThermalProfile
Source§fn clone(&self) -> ThermalProfile
fn clone(&self) -> ThermalProfile
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read more