Skip to main content

ThermalProfile

Struct ThermalProfile 

Source
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: CoolingRate

The cooling rate.

§max_cooling_duration: Duration

Maximum time to spend in cooling phase per task.

§detect_clustering: bool

Whether to enable clustering pattern detection.

§detect_phase_transitions: bool

Whether to enable phase transition detection.

§detect_conservation: bool

Whether to enable conservation law detection.

§detect_correlations: bool

Whether to enable correlation detection.

Implementations§

Source§

impl ThermalProfile

Source

pub fn fast_cooling() -> Self

Create a profile optimized for fast cooling — many fine patterns.

Examples found in repository?
examples/basic.rs (line 30)
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
Hide additional examples
examples/event_stream_processor.rs (line 114)
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, &degradation) 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 &degrading_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}
Source

pub fn slow_cooling() -> Self

Create a profile optimized for slow cooling — fewer, larger patterns.

Source

pub fn no_detection() -> Self

Create a profile with all detection disabled (useful for benchmarking).

Source

pub fn with_rate(self, rate: CoolingRate) -> Self

Set the cooling rate.

Source

pub fn without_clustering(self) -> Self

Disable clustering detection.

Source

pub fn without_phase_transitions(self) -> Self

Disable phase transition detection.

Source

pub fn without_conservation(self) -> Self

Disable conservation law detection.

Source

pub fn without_correlations(self) -> Self

Disable correlation detection.

Trait Implementations§

Source§

impl Clone for ThermalProfile

Source§

fn clone(&self) -> ThermalProfile

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for ThermalProfile

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for ThermalProfile

Source§

fn default() -> Self

Returns the “default value” for a type. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.