Skip to main content

lean_ctx/core/
safety_needles.rs

1const SAFETY_NEEDLES: &[&str] = &[
2    "CRITICAL",
3    "FATAL",
4    "panic",
5    "FAILED",
6    "unhealthy",
7    "Exited",
8    "OOMKilled",
9    "DETACHED HEAD",
10    "detached",
11    "vulnerability",
12    "CVE-",
13    "denied",
14    "unauthorized",
15    "forbidden",
16    "error",
17    "ERROR",
18    "WARNING",
19    "WARN",
20    "fail",
21    "segfault",
22    "Segmentation fault",
23    "SIGSEGV",
24    "SIGKILL",
25    "killed",
26    "out of memory",
27    "stack overflow",
28    "permission denied",
29    "certificate",
30    "expired",
31    "corrupt",
32];
33
34pub fn is_safety_relevant(line: &str) -> bool {
35    let lower = line.to_ascii_lowercase();
36    SAFETY_NEEDLES
37        .iter()
38        .any(|needle| lower.contains(&needle.to_ascii_lowercase()))
39}
40
41pub fn extract_safety_lines(lines: &[&str], max: usize) -> Vec<String> {
42    lines
43        .iter()
44        .filter(|l| is_safety_relevant(l))
45        .take(max)
46        .map(std::string::ToString::to_string)
47        .collect()
48}
49
50#[cfg(test)]
51mod tests {
52    use super::*;
53
54    #[test]
55    fn detects_critical() {
56        assert!(is_safety_relevant("CRITICAL: disk full"));
57        assert!(is_safety_relevant("container unhealthy"));
58        assert!(is_safety_relevant("CVE-2024-12345 found"));
59        assert!(is_safety_relevant("error: something broke"));
60        assert!(is_safety_relevant("permission denied"));
61    }
62
63    #[test]
64    fn ignores_normal_lines() {
65        assert!(!is_safety_relevant("compiled successfully"));
66        assert!(!is_safety_relevant("200 OK"));
67        assert!(!is_safety_relevant("all tests passed"));
68    }
69
70    #[test]
71    fn extracts_limited_safety_lines() {
72        let lines = vec![
73            "line 1",
74            "ERROR: something",
75            "line 3",
76            "CRITICAL: disk",
77            "line 5",
78            "WARNING: old version",
79        ];
80        let result = extract_safety_lines(&lines, 2);
81        assert_eq!(result.len(), 2);
82        assert!(result[0].contains("ERROR"));
83        assert!(result[1].contains("CRITICAL"));
84    }
85}