Skip to main content

lean_ctx/core/
compression_safety.rs

1use std::fmt;
2
3#[derive(Debug, Clone, Copy, PartialEq, Eq)]
4pub enum SafetyLevel {
5    Verbatim,
6    Minimal,
7    Standard,
8    Aggressive,
9}
10
11impl fmt::Display for SafetyLevel {
12    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
13        match self {
14            SafetyLevel::Verbatim => write!(f, "verbatim"),
15            SafetyLevel::Minimal => write!(f, "minimal"),
16            SafetyLevel::Standard => write!(f, "standard"),
17            SafetyLevel::Aggressive => write!(f, "aggressive"),
18        }
19    }
20}
21
22pub struct CommandSafety {
23    pub command: &'static str,
24    pub level: SafetyLevel,
25    pub description: &'static str,
26}
27
28pub const COMMAND_SAFETY_TABLE: &[CommandSafety] = &[
29    // --- Verbatim: output passes through unchanged ---
30    CommandSafety {
31        command: "df",
32        level: SafetyLevel::Verbatim,
33        description: "Disk usage — root filesystem must never be hidden",
34    },
35    CommandSafety {
36        command: "git status",
37        level: SafetyLevel::Verbatim,
38        description: "DETACHED HEAD, staged/unstaged lists preserved verbatim",
39    },
40    CommandSafety {
41        command: "git stash",
42        level: SafetyLevel::Verbatim,
43        description: "Stash save/pop/list output preserved verbatim",
44    },
45    CommandSafety {
46        command: "ls",
47        level: SafetyLevel::Verbatim,
48        description: "All files shown including .env, dotfiles",
49    },
50    CommandSafety {
51        command: "find",
52        level: SafetyLevel::Verbatim,
53        description: "Full absolute paths preserved",
54    },
55    CommandSafety {
56        command: "wc",
57        level: SafetyLevel::Verbatim,
58        description: "Pipe/stdin input handled correctly",
59    },
60    CommandSafety {
61        command: "env/printenv",
62        level: SafetyLevel::Verbatim,
63        description: "Environment variables preserved (values filtered)",
64    },
65    // --- Minimal: light formatting, all critical data preserved ---
66    CommandSafety {
67        command: "git diff",
68        level: SafetyLevel::Minimal,
69        description: "All +/- lines preserved, only index headers and excess context trimmed",
70    },
71    CommandSafety {
72        command: "git log",
73        level: SafetyLevel::Minimal,
74        description: "Up to 50 entries, respects --max-count/-n, shows truncation notice",
75    },
76    CommandSafety {
77        command: "git blame",
78        level: SafetyLevel::Minimal,
79        description: "Verbatim up to 100 lines, then author/line-range summary",
80    },
81    CommandSafety {
82        command: "docker ps",
83        level: SafetyLevel::Minimal,
84        description: "Header-parsed columns; (unhealthy), Exited status always preserved",
85    },
86    CommandSafety {
87        command: "grep/rg",
88        level: SafetyLevel::Minimal,
89        description: "Verbatim up to 100 lines, then grouped by file with line numbers",
90    },
91    CommandSafety {
92        command: "ruff check",
93        level: SafetyLevel::Minimal,
94        description: "Verbatim up to 30 issues (file:line:col preserved), then summary",
95    },
96    CommandSafety {
97        command: "npm audit",
98        level: SafetyLevel::Minimal,
99        description: "CVE IDs, severity, package names, fix recommendations preserved",
100    },
101    CommandSafety {
102        command: "pip list",
103        level: SafetyLevel::Minimal,
104        description: "All packages shown (no truncation)",
105    },
106    CommandSafety {
107        command: "pip uninstall",
108        level: SafetyLevel::Minimal,
109        description: "All removed package names listed",
110    },
111    CommandSafety {
112        command: "pytest",
113        level: SafetyLevel::Minimal,
114        description: "passed/failed/skipped/xfailed/xpassed/warnings all counted",
115    },
116    CommandSafety {
117        command: "docker logs",
118        level: SafetyLevel::Minimal,
119        description: "Dedup + safety-needle scan preserves FATAL/ERROR/CRITICAL lines",
120    },
121    CommandSafety {
122        command: "cat (logs)",
123        level: SafetyLevel::Minimal,
124        description: "Log dedup preserves all severity levels including CRITICAL",
125    },
126    // --- Standard: structured compression, key info preserved ---
127    CommandSafety {
128        command: "cargo build/test",
129        level: SafetyLevel::Standard,
130        description: "Errors and warnings preserved, progress lines removed",
131    },
132    CommandSafety {
133        command: "npm install",
134        level: SafetyLevel::Standard,
135        description: "Package count, vulnerability summary preserved",
136    },
137    CommandSafety {
138        command: "docker build",
139        level: SafetyLevel::Standard,
140        description: "Step count, errors preserved, intermediate output removed",
141    },
142    CommandSafety {
143        command: "git commit",
144        level: SafetyLevel::Standard,
145        description: "Branch, hash, change stats preserved; hook output kept",
146    },
147    CommandSafety {
148        command: "git push/pull",
149        level: SafetyLevel::Standard,
150        description: "Remote, branch, conflict info preserved",
151    },
152    CommandSafety {
153        command: "eslint/biome",
154        level: SafetyLevel::Standard,
155        description: "Error/warning counts, file references preserved",
156    },
157    CommandSafety {
158        command: "tsc",
159        level: SafetyLevel::Standard,
160        description: "Type errors with file:line preserved",
161    },
162    CommandSafety {
163        command: "curl (JSON)",
164        level: SafetyLevel::Standard,
165        description: "Schema extraction; sensitive keys (token/password/secret) REDACTED",
166    },
167    // --- Aggressive: heavy compression for verbose output ---
168    CommandSafety {
169        command: "kubectl describe",
170        level: SafetyLevel::Aggressive,
171        description: "Key fields extracted, verbose event history trimmed",
172    },
173    CommandSafety {
174        command: "aws CLI",
175        level: SafetyLevel::Aggressive,
176        description: "JSON schema extraction for large API responses",
177    },
178    CommandSafety {
179        command: "terraform plan",
180        level: SafetyLevel::Aggressive,
181        description: "Resource changes summarized, full plan truncated",
182    },
183    CommandSafety {
184        command: "docker images",
185        level: SafetyLevel::Aggressive,
186        description: "Compressed to name:tag (size) list",
187    },
188];
189
190pub fn format_safety_table() -> String {
191    let mut out = String::new();
192    out.push_str("Command Compression Safety Levels\n");
193    out.push_str(&"=".repeat(72));
194    out.push('\n');
195    out.push('\n');
196
197    for level in &[
198        SafetyLevel::Verbatim,
199        SafetyLevel::Minimal,
200        SafetyLevel::Standard,
201        SafetyLevel::Aggressive,
202    ] {
203        let label = match level {
204            SafetyLevel::Verbatim => "VERBATIM — output passes through unchanged",
205            SafetyLevel::Minimal => {
206                "MINIMAL — light formatting, all safety-critical data preserved"
207            }
208            SafetyLevel::Standard => "STANDARD — structured compression, key info preserved",
209            SafetyLevel::Aggressive => "AGGRESSIVE — heavy compression for verbose output",
210        };
211        out.push_str(&format!("[{label}]\n"));
212
213        for entry in COMMAND_SAFETY_TABLE.iter().filter(|e| e.level == *level) {
214            out.push_str(&format!("  {:<20} {}\n", entry.command, entry.description));
215        }
216        out.push('\n');
217    }
218
219    out.push_str("Safety features active on ALL commands:\n");
220    out.push_str("  • Safety-needle scan: CRITICAL/FATAL/panic/ERROR/CVE lines preserved\n");
221    out.push_str("  • Safeguard ratio: >95% compression on >100 tokens triggers fallback\n");
222    out.push_str("  • Auth flow detection: login/OAuth prompts never compressed\n");
223    out.push_str("  • Minimum token threshold: outputs <50 tokens pass through unchanged\n");
224    out.push('\n');
225    out.push_str("Use `lean-ctx bypass \"command\"` to run any command with zero compression.\n");
226
227    out
228}
229
230#[cfg(test)]
231mod tests {
232    use super::*;
233
234    #[test]
235    fn safety_table_has_entries() {
236        assert!(COMMAND_SAFETY_TABLE.len() > 20);
237    }
238
239    #[test]
240    fn format_table_contains_all_levels() {
241        let table = format_safety_table();
242        assert!(table.contains("VERBATIM"));
243        assert!(table.contains("MINIMAL"));
244        assert!(table.contains("STANDARD"));
245        assert!(table.contains("AGGRESSIVE"));
246    }
247
248    #[test]
249    fn df_is_verbatim() {
250        let df = COMMAND_SAFETY_TABLE
251            .iter()
252            .find(|e| e.command == "df")
253            .unwrap();
254        assert_eq!(df.level, SafetyLevel::Verbatim);
255    }
256
257    #[test]
258    fn git_diff_is_minimal() {
259        let diff = COMMAND_SAFETY_TABLE
260            .iter()
261            .find(|e| e.command == "git diff")
262            .unwrap();
263        assert_eq!(diff.level, SafetyLevel::Minimal);
264    }
265}