inspector_analysis/
task_growth.rs1use inspector_core::{Diagnosis, FindingStatus, Snapshot};
3
4pub const GROWTH_THRESHOLD: i64 = 50;
5
6pub fn detect_task_growth(
7 base: &Snapshot,
8 current: &Snapshot,
9 base_id: &str,
10 current_id: &str,
11) -> Diagnosis {
12 let evidence = vec![base_id.to_string(), current_id.to_string()];
13 match (base.overview.active_tasks, current.overview.active_tasks) {
14 (Some(b), Some(c)) => {
15 let growth = c as i64 - b as i64;
16 if growth >= GROWTH_THRESHOLD {
17 Diagnosis {
18 status: FindingStatus::Hypothesis,
19 finding: format!("active tasks grew {b} -> {c} (+{growth})"),
20 hypothesis: Some(
21 "growth may indicate spawn leak or contention pile-up; correlate with scheduled-time".into(),
22 ),
23 confidence: 0.65,
24 evidence,
25 verification: Some(
26 "capture task list sorted by polls; check for unbounded spawners".into(),
27 ),
28 }
29 } else {
30 Diagnosis {
31 status: FindingStatus::NoIssue,
32 finding: format!("task count stable ({b} -> {c})"),
33 hypothesis: None,
34 confidence: 0.85,
35 evidence,
36 verification: None,
37 }
38 }
39 }
40 _ => Diagnosis {
41 status: FindingStatus::Observed,
42 finding: "task counts unavailable; no growth verdict".into(),
43 hypothesis: None,
44 confidence: 0.3,
45 evidence,
46 verification: Some("check completeness.missing_fields".into()),
47 },
48 }
49}