Skip to main content

assay_core/
redaction.rs

1use std::borrow::Cow;
2
3#[derive(Debug, Clone, Copy, Default)]
4pub struct RedactionPolicy {
5    pub redact_prompts: bool,
6}
7
8impl RedactionPolicy {
9    pub fn new(redact_prompts: bool) -> Self {
10        Self { redact_prompts }
11    }
12
13    pub fn redact_prompt<'a>(&self, s: &'a str) -> Cow<'a, str> {
14        if self.redact_prompts {
15            "[REDACTED]".into()
16        } else {
17            s.into()
18        }
19    }
20
21    pub fn redact_judge_metadata(&self, meta: &mut serde_json::Value) {
22        if !self.redact_prompts {
23            return;
24        }
25
26        if let Some(obj) = meta
27            .pointer_mut("/assay/judge")
28            .and_then(|v| v.as_object_mut())
29        {
30            for (_, v) in obj.iter_mut() {
31                if let Some(inner) = v.as_object_mut() {
32                    if inner.contains_key("rationale") {
33                        inner.insert("rationale".to_string(), serde_json::json!("[REDACTED]"));
34                    }
35                }
36            }
37        }
38
39        // 2. Redact from TestResultRow.details style (metrics output)
40        if let Some(metrics) = meta.pointer_mut("/metrics").and_then(|v| v.as_object_mut()) {
41            for (_, metric_res) in metrics.iter_mut() {
42                if let Some(details) = metric_res
43                    .get_mut("details")
44                    .and_then(|v| v.as_object_mut())
45                {
46                    if details.contains_key("rationale") {
47                        details.insert("rationale".to_string(), serde_json::json!("[REDACTED]"));
48                    }
49                }
50            }
51        }
52    }
53}
54
55#[cfg(test)]
56mod tests {
57    use super::*;
58
59    #[test]
60    fn test_redaction_on() {
61        let policy = RedactionPolicy::new(true);
62        assert_eq!(policy.redact_prompt("my secret prompt"), "[REDACTED]");
63    }
64
65    #[test]
66    fn test_redaction_off() {
67        let policy = RedactionPolicy::new(false);
68        assert_eq!(policy.redact_prompt("safe prompt"), "safe prompt");
69    }
70}