Skip to main content

split_brain_harness/
soul.rs

1use crate::types::Soul;
2use anyhow::{anyhow, Result};
3
4const DEFAULT_SOUL: &str = include_str!("../soul.md");
5
6const OPEN_LOGIC: &str = "[LOGIC_SYSTEM_PROMPT]";
7const CLOSE_LOGIC: &str = "[/LOGIC_SYSTEM_PROMPT]";
8const OPEN_CREATIVE: &str = "[CREATIVE_SYSTEM_PROMPT]";
9const CLOSE_CREATIVE: &str = "[/CREATIVE_SYSTEM_PROMPT]";
10const OPEN_VERIFIER: &str = "[VERIFIER_SYSTEM_PROMPT]";
11const CLOSE_VERIFIER: &str = "[/VERIFIER_SYSTEM_PROMPT]";
12const OPEN_CODE_GEN: &str = "[CODE_GEN_SYSTEM_PROMPT]";
13const CLOSE_CODE_GEN: &str = "[/CODE_GEN_SYSTEM_PROMPT]";
14
15/// Load a Soul from disk (if path given) or fall back to the embedded default.
16pub fn load(path: Option<&str>) -> Result<Soul> {
17    let raw = match path {
18        Some(p) if !p.is_empty() => std::fs::read_to_string(p)
19            .map_err(|e| anyhow!("failed to read soul file '{}': {}", p, e))?,
20        _ => DEFAULT_SOUL.to_string(),
21    };
22    parse(&raw)
23}
24
25/// Wrap a raw user input string in payload tags for injection into the prompt.
26pub fn wrap_payload(input: &str) -> String {
27    format!("<payload>\n{}\n</payload>", input)
28}
29
30/// Wrap an original input + proposed analysis for the verifier prompt.
31pub fn wrap_verifier_payload(original_input: &str, proposed_analysis: &str) -> String {
32    format!(
33        "<original_input>\n{}\n</original_input>\n<proposed_analysis>\n{}\n</proposed_analysis>",
34        original_input, proposed_analysis
35    )
36}
37
38// ---------------------------------------------------------------------------
39// Internal
40// ---------------------------------------------------------------------------
41
42fn parse(raw: &str) -> Result<Soul> {
43    Ok(Soul {
44        logic_system_prompt: extract(raw, OPEN_LOGIC, CLOSE_LOGIC)?,
45        creative_system_prompt: extract(raw, OPEN_CREATIVE, CLOSE_CREATIVE).unwrap_or_default(),
46        verifier_system_prompt: extract(raw, OPEN_VERIFIER, CLOSE_VERIFIER).unwrap_or_default(),
47        code_gen_system_prompt: extract(raw, OPEN_CODE_GEN, CLOSE_CODE_GEN).unwrap_or_default(),
48    })
49}
50
51fn extract(raw: &str, open: &str, close: &str) -> Result<String> {
52    let start = raw
53        .find(open)
54        .ok_or_else(|| anyhow!("soul.md missing opening tag: {}", open))?
55        + open.len();
56
57    let end = raw[start..]
58        .find(close)
59        .ok_or_else(|| anyhow!("soul.md missing closing tag: {}", close))?
60        + start;
61
62    Ok(raw[start..end].trim().to_string())
63}
64
65// ---------------------------------------------------------------------------
66// Tests
67// ---------------------------------------------------------------------------
68
69#[cfg(test)]
70mod tests {
71    use super::*;
72
73    #[test]
74    fn default_soul_parses() {
75        let soul = load(None).expect("default soul should parse");
76        assert!(
77            !soul.logic_system_prompt.is_empty(),
78            "logic prompt must not be empty"
79        );
80        assert!(
81            soul.logic_system_prompt.contains("telemetry engine"),
82            "logic prompt should contain identity marker"
83        );
84        assert!(
85            !soul.verifier_system_prompt.is_empty(),
86            "verifier prompt must not be empty"
87        );
88        assert!(
89            soul.verifier_system_prompt.contains("claim verifier"),
90            "verifier prompt should contain identity marker"
91        );
92    }
93
94    #[test]
95    fn wrap_payload_contains_tags() {
96        let wrapped = wrap_payload("hello world");
97        assert!(wrapped.contains("<payload>"));
98        assert!(wrapped.contains("</payload>"));
99        assert!(wrapped.contains("hello world"));
100    }
101
102    #[test]
103    fn wrap_verifier_payload_contains_both_sections() {
104        let wrapped = wrap_verifier_payload("raw input", r#"{"foo":"bar"}"#);
105        assert!(wrapped.contains("<original_input>"));
106        assert!(wrapped.contains("raw input"));
107        assert!(wrapped.contains("<proposed_analysis>"));
108        assert!(wrapped.contains(r#"{"foo":"bar"}"#));
109    }
110
111    #[test]
112    fn extract_section_trims_whitespace() {
113        let raw = "[LOGIC_SYSTEM_PROMPT]\n  content  \n[/LOGIC_SYSTEM_PROMPT]";
114        let result = extract(raw, "[LOGIC_SYSTEM_PROMPT]", "[/LOGIC_SYSTEM_PROMPT]").unwrap();
115        assert_eq!(result, "content");
116    }
117
118    #[test]
119    fn missing_close_tag_errors() {
120        let raw = "[LOGIC_SYSTEM_PROMPT]\ncontent";
121        assert!(extract(raw, "[LOGIC_SYSTEM_PROMPT]", "[/LOGIC_SYSTEM_PROMPT]").is_err());
122    }
123}