lean_ctx_patterns/
safety_needles.rs1const SAFETY_NEEDLES: &[&str] = &[
4 "CRITICAL",
5 "FATAL",
6 "panic",
7 "FAILED",
8 "unhealthy",
9 "Exited",
10 "OOMKilled",
11 "DETACHED HEAD",
12 "detached",
13 "vulnerability",
14 "CVE-",
15 "denied",
16 "unauthorized",
17 "forbidden",
18 "error",
19 "ERROR",
20 "WARNING",
21 "WARN",
22 "fail",
23 "segfault",
24 "Segmentation fault",
25 "SIGSEGV",
26 "SIGKILL",
27 "killed",
28 "out of memory",
29 "stack overflow",
30 "permission denied",
31 "certificate",
32 "expired",
33 "corrupt",
34 "test result:", "passed", "passing", "panicked", "assertion", "traceback", "tests run", "ran all test", ];
46
47pub fn is_safety_relevant(line: &str) -> bool {
48 let lower = line.to_ascii_lowercase();
49 SAFETY_NEEDLES
50 .iter()
51 .any(|needle| lower.contains(&needle.to_ascii_lowercase()))
52}
53
54pub fn extract_safety_lines(lines: &[&str], max: usize) -> Vec<String> {
55 lines
56 .iter()
57 .filter(|l| is_safety_relevant(l))
58 .take(max)
59 .map(std::string::ToString::to_string)
60 .collect()
61}
62
63#[cfg(test)]
64mod tests {
65 use super::*;
66
67 #[test]
68 fn detects_critical() {
69 assert!(is_safety_relevant("CRITICAL: disk full"));
70 assert!(is_safety_relevant("container unhealthy"));
71 assert!(is_safety_relevant("CVE-2024-12345 found"));
72 assert!(is_safety_relevant("error: something broke"));
73 assert!(is_safety_relevant("permission denied"));
74 }
75
76 #[test]
77 fn ignores_normal_lines() {
78 assert!(!is_safety_relevant("compiled successfully"));
79 assert!(!is_safety_relevant("200 OK"));
80 assert!(!is_safety_relevant("Downloaded 3 crates"));
81 }
82
83 #[test]
84 fn preserves_test_runner_summaries() {
85 assert!(is_safety_relevant(
88 "test result: ok. 23 passed; 0 failed; 0 ignored"
89 ));
90 assert!(is_safety_relevant(
91 "test result: FAILED. 1 passed; 2 failed"
92 ));
93 assert!(is_safety_relevant("=== 5 passed, 1 warning in 0.42s ==="));
94 assert!(is_safety_relevant(
95 "Tests: 1 failed, 5 passed, 6 total"
96 ));
97 assert!(is_safety_relevant("5 passing (1s)"));
98 assert!(is_safety_relevant(
99 "thread 'main' panicked at src/lib.rs:10:5"
100 ));
101 assert!(is_safety_relevant("Traceback (most recent call last):"));
102 }
103
104 #[test]
105 fn extracts_limited_safety_lines() {
106 let lines = vec![
107 "line 1",
108 "ERROR: something",
109 "line 3",
110 "CRITICAL: disk",
111 "line 5",
112 "WARNING: old version",
113 ];
114 let result = extract_safety_lines(&lines, 2);
115 assert_eq!(result.len(), 2);
116 assert!(result[0].contains("ERROR"));
117 assert!(result[1].contains("CRITICAL"));
118 }
119}