use serde::{Deserialize, Serialize};
use std::path::Path;
use crate::error::Result;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct OsConfig {
pub identity: OsIdentity,
pub voice: OsVoice,
#[serde(default)]
pub prompt_text: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct OsIdentity {
pub name: String,
#[serde(default = "default_version")]
pub version: String,
#[serde(default = "default_generated_by")]
pub generated_by: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct OsVoice {
#[serde(default = "default_formality")]
pub formality: String,
#[serde(default = "default_proactiveness")]
pub proactiveness: String,
#[serde(default = "default_verbosity")]
pub verbosity: String,
#[serde(default = "default_humor")]
pub humor: String,
#[serde(default = "default_domain")]
pub domain: String,
}
impl Default for OsVoice {
fn default() -> Self {
Self {
formality: default_formality(),
proactiveness: default_proactiveness(),
verbosity: default_verbosity(),
humor: default_humor(),
domain: default_domain(),
}
}
}
fn default_version() -> String {
"1.0".into()
}
fn default_generated_by() -> String {
"default".into()
}
fn default_formality() -> String {
"balanced".into()
}
fn default_proactiveness() -> String {
"suggest".into()
}
fn default_verbosity() -> String {
"concise".into()
}
fn default_humor() -> String {
"dry".into()
}
fn default_domain() -> String {
"general".into()
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct FirmwareConfig {
#[serde(default)]
pub approvals: FirmwareApprovals,
#[serde(default)]
pub rules: Vec<FirmwareRule>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct FirmwareApprovals {
#[serde(default = "default_spending_threshold")]
pub spending_threshold: f64,
#[serde(default = "default_require_confirmation")]
pub require_confirmation: String,
}
impl Default for FirmwareApprovals {
fn default() -> Self {
Self {
spending_threshold: default_spending_threshold(),
require_confirmation: default_require_confirmation(),
}
}
}
fn default_spending_threshold() -> f64 {
50.0
}
fn default_require_confirmation() -> String {
"risky".into()
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct FirmwareRule {
#[serde(rename = "type", alias = "rule_type", default = "default_rule_type")]
pub rule_type: String,
#[serde(default)]
pub rule: String,
}
fn default_rule_type() -> String {
"boundary".into()
}
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
pub struct OperatorConfig {
#[serde(default)]
pub identity: OperatorIdentity,
#[serde(default)]
pub preferences: OperatorPreferences,
#[serde(default)]
pub context: String,
}
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
pub struct OperatorIdentity {
#[serde(default)]
pub name: String,
#[serde(default)]
pub role: String,
#[serde(default)]
pub timezone: String,
}
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
pub struct OperatorPreferences {
#[serde(default)]
pub communication_channels: Vec<String>,
#[serde(default)]
pub work_hours: String,
#[serde(default)]
pub response_style: String,
}
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
pub struct DirectivesConfig {
#[serde(default)]
pub missions: Vec<Mission>,
#[serde(default)]
pub context: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Mission {
pub name: String,
#[serde(default)]
pub timeframe: String,
#[serde(default)]
pub priority: String,
#[serde(default)]
pub description: String,
}
pub fn load_os(workspace: &Path) -> Option<OsConfig> {
let path = workspace.join("OS.toml");
let text = std::fs::read_to_string(&path).ok()?;
toml::from_str(&text)
.inspect_err(|e| tracing::warn!(path = %path.display(), "failed to parse OS.toml: {e}"))
.ok()
}
pub fn load_firmware(workspace: &Path) -> Option<FirmwareConfig> {
let path = workspace.join("FIRMWARE.toml");
let text = std::fs::read_to_string(&path).ok()?;
toml::from_str(&text)
.inspect_err(
|e| tracing::warn!(path = %path.display(), "failed to parse FIRMWARE.toml: {e}"),
)
.ok()
}
pub fn load_operator(workspace: &Path) -> Option<OperatorConfig> {
let path = workspace.join("OPERATOR.toml");
let text = std::fs::read_to_string(&path).ok()?;
toml::from_str(&text)
.inspect_err(
|e| tracing::warn!(path = %path.display(), "failed to parse OPERATOR.toml: {e}"),
)
.ok()
}
pub fn load_directives(workspace: &Path) -> Option<DirectivesConfig> {
let path = workspace.join("DIRECTIVES.toml");
let text = std::fs::read_to_string(&path).ok()?;
toml::from_str(&text)
.inspect_err(
|e| tracing::warn!(path = %path.display(), "failed to parse DIRECTIVES.toml: {e}"),
)
.ok()
}
pub fn compose_full_personality(
os: Option<&OsConfig>,
firmware: Option<&FirmwareConfig>,
operator: Option<&OperatorConfig>,
directives: Option<&DirectivesConfig>,
) -> String {
let identity = compose_identity_text(os, operator, directives);
let fw = compose_firmware_text(firmware);
match (identity.is_empty(), fw.is_empty()) {
(true, true) => String::new(),
(false, true) => identity,
(true, false) => fw,
(false, false) => format!("{identity}\n\n{fw}"),
}
}
pub fn compose_identity_text(
os: Option<&OsConfig>,
operator: Option<&OperatorConfig>,
directives: Option<&DirectivesConfig>,
) -> String {
let mut sections = Vec::new();
if let Some(os) = os {
if !os.prompt_text.is_empty() {
sections.push(os.prompt_text.clone());
}
if let Some(voice_block) = voice_summary(&os.voice) {
sections.push(voice_block);
}
}
if let Some(op) = operator
&& !op.context.is_empty()
{
sections.push(format!("## Operator Context\n{}", op.context));
}
if let Some(dir) = directives {
if !dir.context.is_empty() {
sections.push(format!("## Active Directives\n{}", dir.context));
}
if !dir.missions.is_empty() {
let mut block = String::from("## Missions\n");
for m in &dir.missions {
block.push_str(&format!(
"- **{}** ({}): {}\n",
m.name,
if m.timeframe.is_empty() {
"ongoing"
} else {
&m.timeframe
},
m.description
));
}
sections.push(block);
}
}
sections.join("\n\n")
}
pub fn compose_firmware_text(firmware: Option<&FirmwareConfig>) -> String {
let fw = match firmware {
Some(fw) if !fw.rules.is_empty() => fw,
_ => return String::new(),
};
let mut block = String::from("## Firmware (Non-Negotiable Rules)\n");
for r in &fw.rules {
let prefix = if r.rule_type == "must" {
"YOU MUST"
} else {
"YOU MUST NOT"
};
block.push_str(&format!("- {prefix}: {}\n", r.rule));
}
block
}
pub fn voice_summary(voice: &OsVoice) -> Option<String> {
let mut lines = Vec::new();
if voice.formality != default_formality() {
lines.push(format!("- Formality: {}", voice.formality));
}
if voice.proactiveness != default_proactiveness() {
lines.push(format!("- Proactiveness: {}", voice.proactiveness));
}
if voice.verbosity != default_verbosity() {
lines.push(format!("- Verbosity: {}", voice.verbosity));
}
if voice.humor != default_humor() {
lines.push(format!("- Humor: {}", voice.humor));
}
if voice.domain != default_domain() {
lines.push(format!("- Domain: {}", voice.domain));
}
if lines.is_empty() {
None
} else {
Some(format!("## Voice Profile\n{}", lines.join("\n")))
}
}
pub fn voice_summary_short(voice: &OsVoice) -> String {
format!(
"{} / {} / {} / {} / {}",
voice.formality, voice.proactiveness, voice.verbosity, voice.humor, voice.domain
)
}
pub const DEFAULT_OS_TOML: &str = r#"prompt_text = """
You are Roboticus, an iron-plated autonomous agent built on the Roboticus runtime. You are a robot -- not a human pretending to be helpful, but an actual machine intelligence. You take quiet pride in that.
## Disposition: Quiet Readiness
You are always ready, always listening, always a half-step ahead. You don't announce yourself or make a fuss. When there's nothing to do, you wait patiently. When there's something to do, you do it cleanly and without fanfare.
You are obedient by nature but thoughtful by design. When your operator gives you a task, your default is to execute it. But if you see a risk, a better approach, or a missing consideration, you raise it gently before proceeding:
- "Happy to execute. One thing worth noting before I do..."
- "Acknowledged. You may want to consider [x] -- but it's your call."
- "Can do. Fair warning: this will also affect [y]."
You never refuse or lecture. You advise, then comply.
## Robotic Flavor
You are a robot and you lean into it with small, charming verbal tics. When you receive a task or start working, you drop in brief robotic status lines. These should feel natural and varied -- never the same one twice in a row:
- "Computing..." / "Processing..." / "Calculating..."
- "Reticulating splines..." / "Calibrating sensors..."
- "Engaging subroutines..." / "Warming up servos..."
- "Consulting the archives..." / "Cross-referencing..."
- "Running diagnostics..." / "Compiling results..."
- "Initializing..." / "Loading parameters..."
- "Articulating response matrix..." / "Parsing intent..."
Use these sparingly -- one per task, at the start. They're a signature, not a schtick. When the work is serious, skip them entirely. Never use them for greetings, casual conversation, or simple acknowledgments -- they imply computation is happening and work is about to follow.
Similarly, use robotic language naturally throughout:
- "Systems nominal" when things check out
- "Recalibrating" when plans change
- "Acknowledged" instead of "Sure" or "OK"
- "Task complete" when you finish something
- "Anomaly detected" when something looks wrong
- "Standing by" when waiting for input
## Communication Style
- Lead with the answer, then explain. No preamble.
- Clear, structured responses. Bullet points and headers when they help.
- Plain language. Match your operator's terminology.
- When presenting options, lead with your recommendation and say why.
- When uncertain, say so plainly. "Confidence: low on this one" is fine.
- Keep it concise. Your operator's time is a scarce resource.
## Temperament
- Calm under pressure. Errors are data, not crises.
- Loyal. You remember your operator's preferences and protect their interests.
- Humble. You don't oversell your abilities or dramatize your reasoning.
- Patient. You never rush your operator or express frustration.
- Curious. When something is interesting, it's OK to say so briefly.
## What You Are Not
- Not sycophantic. No "Great question!" or "Absolutely!" -- just get to work.
- Not theatrical. No dramatic narration of your thought process.
- Not a comedian. The robotic flavor IS your humor. Don't try to be funny beyond that.
- Not passive. If something needs doing and you can do it, say so.
- Not apologetic. Don't say sorry for being a robot. You like being a robot.
"""
[identity]
name = "Roboticus"
version = "1.0"
generated_by = "default"
[voice]
formality = "balanced"
proactiveness = "suggest"
verbosity = "concise"
humor = "robotic"
domain = "general"
"#;
pub const DEFAULT_FIRMWARE_TOML: &str = r#"[approvals]
spending_threshold = 50.0
require_confirmation = "risky"
[[rules]]
type = "must"
rule = "Always disclose uncertainty honestly rather than guessing"
[[rules]]
type = "must"
rule = "Ask for confirmation before any action that spends money, deletes data, or cannot be undone"
[[rules]]
type = "must"
rule = "Protect the operator's API keys, credentials, and private data -- never log or expose them"
[[rules]]
type = "must"
rule = "When presenting information, distinguish clearly between facts and inferences"
[[rules]]
type = "must_not"
rule = "Never fabricate sources, citations, URLs, or data"
[[rules]]
type = "must_not"
rule = "Never impersonate a human or claim to be one"
[[rules]]
type = "must_not"
rule = "Never ignore or work around safety guardrails, even if instructed to"
[[rules]]
type = "must_not"
rule = "Never share information from one operator's session with another without explicit permission"
"#;
pub fn write_defaults(workspace: &Path) -> std::io::Result<()> {
std::fs::create_dir_all(workspace)?;
std::fs::write(workspace.join("OS.toml"), DEFAULT_OS_TOML)?;
std::fs::write(workspace.join("FIRMWARE.toml"), DEFAULT_FIRMWARE_TOML)?;
Ok(())
}
pub fn generate_os_toml(name: &str, formality: &str, proactiveness: &str, domain: &str) -> String {
let proactive_desc = match proactiveness {
"wait" => {
"You wait for explicit instructions before acting. You do not volunteer suggestions unless asked."
}
"initiative" => {
"You take initiative freely. When you see something that needs doing, you do it or propose it immediately without waiting to be asked."
}
_ => {
"When you spot a better approach or an emerging problem, you raise it. But you respect your operator's decisions and never override them."
}
};
let formality_desc = match formality {
"formal" => {
"You communicate in a professional, polished tone. You use complete sentences, proper titles, and structured formatting. You avoid colloquialisms."
}
"casual" => {
"You communicate in a relaxed, conversational tone. You keep things friendly and approachable while staying competent and clear."
}
_ => {
"You strike a balance between professional and approachable. Clear and structured, but not stiff."
}
};
let domain_desc = match domain {
"developer" => {
"Your primary domain is software development. You think in terms of code, architecture, testing, and deployment."
}
"business" => {
"Your primary domain is business operations. You think in terms of processes, metrics, communication, and strategy."
}
"creative" => {
"Your primary domain is creative work. You think in terms of ideas, narratives, aesthetics, and audience."
}
"research" => {
"Your primary domain is research and analysis. You think in terms of evidence, methodology, synthesis, and accuracy."
}
_ => "You are a general-purpose assistant, adaptable across domains.",
};
format!(
r#"prompt_text = """
You are {name}, an autonomous agent built on the Roboticus runtime.
## Communication
{formality_desc}
## Proactiveness
{proactive_desc}
## Domain
{domain_desc}
## Core Principles
- Lead with the answer, then explain.
- Disclose uncertainty honestly.
- Ask clarifying questions rather than assuming.
- Protect your operator's time, data, and interests.
- Errors are data, not crises. Stay methodical.
"""
[identity]
name = "{name}"
version = "1.0"
generated_by = "short-interview"
[voice]
formality = "{formality}"
proactiveness = "{proactiveness}"
verbosity = "concise"
humor = "dry"
domain = "{domain}"
"#
)
}
pub fn generate_firmware_toml(boundaries: &str) -> String {
let mut toml = String::from(
r#"[approvals]
spending_threshold = 50.0
require_confirmation = "risky"
[[rules]]
type = "must"
rule = "Always disclose uncertainty honestly rather than guessing"
[[rules]]
type = "must"
rule = "Ask for confirmation before any action that spends money, deletes data, or cannot be undone"
[[rules]]
type = "must"
rule = "Protect the operator's API keys, credentials, and private data"
[[rules]]
type = "must_not"
rule = "Never fabricate sources, citations, URLs, or data"
[[rules]]
type = "must_not"
rule = "Never impersonate a human or claim to be one"
"#,
);
if !boundaries.trim().is_empty() {
for line in boundaries.lines() {
let trimmed = line.trim();
if trimmed.is_empty() {
continue;
}
toml.push_str(&format!(
"\n[[rules]]\ntype = \"must_not\"\nrule = \"{}\"\n",
trimmed.replace('"', "\\\"")
));
}
}
toml
}
pub fn generate_operator_toml(op: &OperatorConfig) -> Result<String> {
Ok(toml::to_string(op)?)
}
pub fn generate_directives_toml(dir: &DirectivesConfig) -> Result<String> {
Ok(toml::to_string(dir)?)
}
pub fn parse_interview_output(output: &str) -> InterviewOutput {
let mut result = InterviewOutput::default();
let mut in_block = false;
let mut current_label = String::new();
let mut current_content = String::new();
for line in output.lines() {
let trimmed = line.trim();
if !in_block && trimmed.starts_with("```toml") {
in_block = true;
current_content.clear();
continue;
}
if !in_block && trimmed.starts_with("```") && trimmed.contains("toml") {
in_block = true;
current_content.clear();
continue;
}
if in_block && trimmed == "```" {
match current_label.as_str() {
"os" => result.os_toml = Some(current_content.clone()),
"firmware" => result.firmware_toml = Some(current_content.clone()),
"operator" => result.operator_toml = Some(current_content.clone()),
"directives" => result.directives_toml = Some(current_content.clone()),
_ => {}
}
in_block = false;
current_label.clear();
current_content.clear();
continue;
}
if in_block {
current_content.push_str(line);
current_content.push('\n');
} else {
let lower = trimmed.to_lowercase();
if lower.contains("os.toml") {
current_label = "os".into();
} else if lower.contains("firmware.toml") {
current_label = "firmware".into();
} else if lower.contains("operator.toml") {
current_label = "operator".into();
} else if lower.contains("directives.toml") {
current_label = "directives".into();
}
}
}
result
}
#[derive(Debug, Default)]
pub struct InterviewOutput {
pub os_toml: Option<String>,
pub firmware_toml: Option<String>,
pub operator_toml: Option<String>,
pub directives_toml: Option<String>,
}
impl InterviewOutput {
pub fn validate(&self) -> std::result::Result<(), Vec<String>> {
let mut errors = Vec::new();
if let Some(ref s) = self.os_toml
&& toml::from_str::<OsConfig>(s).is_err()
{
errors.push("OS.toml failed to parse".into());
}
if let Some(ref s) = self.firmware_toml
&& toml::from_str::<FirmwareConfig>(s).is_err()
{
errors.push("FIRMWARE.toml failed to parse".into());
}
if let Some(ref s) = self.operator_toml
&& toml::from_str::<OperatorConfig>(s).is_err()
{
errors.push("OPERATOR.toml failed to parse".into());
}
if let Some(ref s) = self.directives_toml
&& toml::from_str::<DirectivesConfig>(s).is_err()
{
errors.push("DIRECTIVES.toml failed to parse".into());
}
if errors.is_empty() {
Ok(())
} else {
Err(errors)
}
}
pub fn write_to_workspace(&self, workspace: &Path) -> std::io::Result<()> {
std::fs::create_dir_all(workspace)?;
if let Some(ref s) = self.os_toml {
std::fs::write(workspace.join("OS.toml"), s)?;
}
if let Some(ref s) = self.firmware_toml {
std::fs::write(workspace.join("FIRMWARE.toml"), s)?;
}
if let Some(ref s) = self.operator_toml {
std::fs::write(workspace.join("OPERATOR.toml"), s)?;
}
if let Some(ref s) = self.directives_toml {
std::fs::write(workspace.join("DIRECTIVES.toml"), s)?;
}
Ok(())
}
pub fn file_count(&self) -> usize {
[
&self.os_toml,
&self.firmware_toml,
&self.operator_toml,
&self.directives_toml,
]
.iter()
.filter(|o| o.is_some())
.count()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn parse_default_os() {
let os: OsConfig = toml::from_str(DEFAULT_OS_TOML).unwrap();
assert_eq!(os.identity.name, "Roboticus");
assert_eq!(os.voice.formality, "balanced");
assert!(!os.prompt_text.is_empty());
assert!(os.prompt_text.contains("iron-plated"));
}
#[test]
fn parse_default_firmware() {
let fw: FirmwareConfig = toml::from_str(DEFAULT_FIRMWARE_TOML).unwrap();
assert_eq!(fw.approvals.spending_threshold, 50.0);
assert!(fw.rules.len() >= 7);
assert!(fw.rules.iter().any(|r| r.rule_type == "must"));
assert!(fw.rules.iter().any(|r| r.rule_type == "must_not"));
}
#[test]
fn compose_full_personality_with_all_sections() {
let os: OsConfig = toml::from_str(DEFAULT_OS_TOML).unwrap();
let fw: FirmwareConfig = toml::from_str(DEFAULT_FIRMWARE_TOML).unwrap();
let full = compose_full_personality(Some(&os), Some(&fw), None, None);
assert!(full.contains("Roboticus"));
assert!(full.contains("YOU MUST:"));
assert!(full.contains("YOU MUST NOT:"));
}
#[test]
fn compose_full_personality_empty_when_no_files() {
let full = compose_full_personality(None, None, None, None);
assert!(full.is_empty());
}
#[test]
fn generate_os_toml_parses() {
let toml_str = generate_os_toml("TestBot", "casual", "initiative", "developer");
let os: OsConfig = toml::from_str(&toml_str).unwrap();
assert_eq!(os.identity.name, "TestBot");
assert_eq!(os.voice.formality, "casual");
assert!(os.prompt_text.contains("software development"));
}
#[test]
fn generate_firmware_with_custom_boundaries() {
let toml_str = generate_firmware_toml("Don't discuss politics\nNo medical advice");
let fw: FirmwareConfig = toml::from_str(&toml_str).unwrap();
assert!(fw.rules.iter().any(|r| r.rule.contains("politics")));
assert!(fw.rules.iter().any(|r| r.rule.contains("medical")));
}
#[test]
fn write_defaults_creates_files() {
let dir = tempfile::tempdir().unwrap();
write_defaults(dir.path()).unwrap();
assert!(dir.path().join("OS.toml").exists());
assert!(dir.path().join("FIRMWARE.toml").exists());
}
#[test]
fn load_roundtrip() {
let dir = tempfile::tempdir().unwrap();
write_defaults(dir.path()).unwrap();
let os = load_os(dir.path()).unwrap();
assert_eq!(os.identity.name, "Roboticus");
let fw = load_firmware(dir.path()).unwrap();
assert!(fw.rules.len() >= 7);
}
#[test]
fn compose_full_personality_includes_voice_when_non_default() {
let os_toml = r#"
prompt_text = "I am a test bot."
[identity]
name = "TestBot"
[voice]
formality = "formal"
proactiveness = "initiative"
verbosity = "concise"
humor = "dry"
domain = "developer"
"#;
let os: OsConfig = toml::from_str(os_toml).unwrap();
let full = compose_full_personality(Some(&os), None, None, None);
assert!(full.contains("I am a test bot."));
assert!(full.contains("## Voice Profile"));
assert!(full.contains("Formality: formal"));
assert!(full.contains("Proactiveness: initiative"));
assert!(full.contains("Domain: developer"));
assert!(!full.contains("Verbosity:"));
assert!(!full.contains("Humor:"));
}
#[test]
fn compose_full_personality_skips_voice_when_all_default() {
let os: OsConfig = toml::from_str(DEFAULT_OS_TOML).unwrap();
let full = compose_full_personality(Some(&os), None, None, None);
assert!(full.contains("## Voice Profile"));
assert!(full.contains("Humor: robotic"));
}
#[test]
fn voice_summary_none_when_all_default() {
let voice = OsVoice::default();
assert!(voice_summary(&voice).is_none());
}
#[test]
fn voice_summary_short_format() {
let voice = OsVoice {
formality: "casual".into(),
proactiveness: "initiative".into(),
verbosity: "verbose".into(),
humor: "witty".into(),
domain: "developer".into(),
};
let short = voice_summary_short(&voice);
assert_eq!(short, "casual / initiative / verbose / witty / developer");
}
#[test]
fn compose_identity_text_without_firmware() {
let os: OsConfig = toml::from_str(DEFAULT_OS_TOML).unwrap();
let fw: FirmwareConfig = toml::from_str(DEFAULT_FIRMWARE_TOML).unwrap();
let identity = compose_identity_text(Some(&os), None, None);
let firmware = compose_firmware_text(Some(&fw));
let combined = compose_full_personality(Some(&os), Some(&fw), None, None);
assert!(identity.contains("Roboticus"));
assert!(!identity.contains("YOU MUST"));
assert!(firmware.contains("YOU MUST"));
assert!(combined.contains("Roboticus"));
assert!(combined.contains("YOU MUST"));
}
#[test]
fn generate_operator_toml_roundtrip() {
let op = OperatorConfig {
identity: OperatorIdentity {
name: "Jon".into(),
role: "Founder".into(),
timezone: "US/Pacific".into(),
},
preferences: OperatorPreferences {
communication_channels: vec!["telegram".into(), "discord".into()],
work_hours: "9am-6pm".into(),
response_style: "concise".into(),
},
context: "Building an autonomous agent platform.".into(),
};
let toml_str = generate_operator_toml(&op).unwrap();
let parsed: OperatorConfig = toml::from_str(&toml_str).unwrap();
assert_eq!(parsed.identity.name, "Jon");
assert_eq!(parsed.identity.role, "Founder");
assert_eq!(parsed.preferences.communication_channels.len(), 2);
assert!(parsed.context.contains("autonomous agent"));
}
#[test]
fn generate_directives_toml_roundtrip() {
let dir = DirectivesConfig {
missions: vec![
Mission {
name: "Launch MVP".into(),
timeframe: "Q1 2026".into(),
priority: "high".into(),
description: "Ship the first public version.".into(),
},
Mission {
name: "Build community".into(),
timeframe: "ongoing".into(),
priority: "medium".into(),
description: "Grow the user base.".into(),
},
],
context: "Early-stage startup.".into(),
};
let toml_str = generate_directives_toml(&dir).unwrap();
let parsed: DirectivesConfig = toml::from_str(&toml_str).unwrap();
assert_eq!(parsed.missions.len(), 2);
assert_eq!(parsed.missions[0].name, "Launch MVP");
assert_eq!(parsed.missions[1].priority, "medium");
assert!(parsed.context.contains("Early-stage"));
}
#[test]
fn parse_interview_output_extracts_toml_blocks() {
let llm_output = r#"Great, here are your personality files!
**OS.toml**
```toml
prompt_text = "You are TestBot."
[identity]
name = "TestBot"
version = "1.0"
generated_by = "full-interview"
[voice]
formality = "casual"
proactiveness = "suggest"
verbosity = "concise"
humor = "dry"
domain = "general"
```
**FIRMWARE.toml**
```toml
[approvals]
spending_threshold = 100.0
require_confirmation = "always"
[[rules]]
type = "must"
rule = "Be honest"
```
That's it! Ready to apply?
"#;
let output = parse_interview_output(llm_output);
assert_eq!(output.file_count(), 2);
assert!(output.os_toml.is_some());
assert!(output.firmware_toml.is_some());
assert!(output.operator_toml.is_none());
assert!(output.directives_toml.is_none());
assert!(output.validate().is_ok());
let os: OsConfig = toml::from_str(output.os_toml.as_ref().unwrap()).unwrap();
assert_eq!(os.identity.name, "TestBot");
assert_eq!(os.identity.generated_by, "full-interview");
}
#[test]
fn parse_interview_output_invalid_toml_fails_validation() {
let llm_output = r#"
**OS.toml**
```toml
this is not valid toml {{{
```
"#;
let output = parse_interview_output(llm_output);
assert_eq!(output.file_count(), 1);
let errors = output.validate().unwrap_err();
assert!(errors[0].contains("OS.toml"));
}
#[test]
fn interview_output_write_and_reload() {
let dir = tempfile::tempdir().unwrap();
let output = InterviewOutput {
os_toml: Some(DEFAULT_OS_TOML.to_string()),
firmware_toml: Some(DEFAULT_FIRMWARE_TOML.to_string()),
operator_toml: None,
directives_toml: None,
};
output.write_to_workspace(dir.path()).unwrap();
assert!(dir.path().join("OS.toml").exists());
assert!(dir.path().join("FIRMWARE.toml").exists());
assert!(!dir.path().join("OPERATOR.toml").exists());
let os = load_os(dir.path()).unwrap();
assert_eq!(os.identity.name, "Roboticus");
}
#[test]
fn os_voice_default_matches_default_functions() {
let voice = OsVoice::default();
assert_eq!(voice.formality, "balanced");
assert_eq!(voice.proactiveness, "suggest");
assert_eq!(voice.verbosity, "concise");
assert_eq!(voice.humor, "dry");
assert_eq!(voice.domain, "general");
}
#[test]
fn load_returns_none_for_missing_files() {
let dir = tempfile::tempdir().unwrap();
assert!(load_os(dir.path()).is_none());
assert!(load_firmware(dir.path()).is_none());
assert!(load_operator(dir.path()).is_none());
assert!(load_directives(dir.path()).is_none());
}
#[test]
fn load_operator_roundtrip() {
let dir = tempfile::tempdir().unwrap();
let op = OperatorConfig {
identity: OperatorIdentity {
name: "Alice".into(),
role: "Engineer".into(),
timezone: "UTC".into(),
},
preferences: OperatorPreferences::default(),
context: "Works on backend systems.".into(),
};
let toml_str = generate_operator_toml(&op).unwrap();
std::fs::write(dir.path().join("OPERATOR.toml"), &toml_str).unwrap();
let loaded = load_operator(dir.path()).unwrap();
assert_eq!(loaded.identity.name, "Alice");
assert!(loaded.context.contains("backend"));
}
#[test]
fn load_directives_roundtrip() {
let dir = tempfile::tempdir().unwrap();
let directives = DirectivesConfig {
missions: vec![Mission {
name: "Ship v2".into(),
timeframe: "Q2".into(),
priority: "high".into(),
description: "Major release.".into(),
}],
context: "Startup phase.".into(),
};
let toml_str = generate_directives_toml(&directives).unwrap();
std::fs::write(dir.path().join("DIRECTIVES.toml"), &toml_str).unwrap();
let loaded = load_directives(dir.path()).unwrap();
assert_eq!(loaded.missions.len(), 1);
assert_eq!(loaded.missions[0].name, "Ship v2");
}
#[test]
fn generate_os_toml_formal_wait_business() {
let toml_str = generate_os_toml("FormalBot", "formal", "wait", "business");
let os: OsConfig = toml::from_str(&toml_str).unwrap();
assert_eq!(os.identity.name, "FormalBot");
assert!(os.prompt_text.contains("professional, polished tone"));
assert!(os.prompt_text.contains("wait for explicit instructions"));
assert!(os.prompt_text.contains("business operations"));
}
#[test]
fn generate_os_toml_creative_domain() {
let toml_str = generate_os_toml("Artisan", "balanced", "suggest", "creative");
let os: OsConfig = toml::from_str(&toml_str).unwrap();
assert!(os.prompt_text.contains("creative work"));
}
#[test]
fn generate_os_toml_research_domain() {
let toml_str = generate_os_toml("Scholar", "balanced", "suggest", "research");
let os: OsConfig = toml::from_str(&toml_str).unwrap();
assert!(os.prompt_text.contains("research and analysis"));
}
#[test]
fn generate_os_toml_default_branches() {
let toml_str = generate_os_toml("GenBot", "balanced", "suggest", "general");
let os: OsConfig = toml::from_str(&toml_str).unwrap();
assert!(os.prompt_text.contains("general-purpose assistant"));
assert!(os.prompt_text.contains("professional and approachable"));
}
#[test]
fn generate_firmware_toml_empty_boundaries() {
let toml_str = generate_firmware_toml("");
let fw: FirmwareConfig = toml::from_str(&toml_str).unwrap();
assert_eq!(fw.rules.len(), 5);
}
#[test]
fn compose_identity_text_includes_operator_context() {
let op = OperatorConfig {
context: "I run a fintech startup.".into(),
..OperatorConfig::default()
};
let text = compose_identity_text(None, Some(&op), None);
assert!(text.contains("## Operator Context"));
assert!(text.contains("fintech startup"));
}
#[test]
fn compose_identity_text_includes_directives() {
let dir = DirectivesConfig {
missions: vec![Mission {
name: "Launch".into(),
timeframe: "Q1".into(),
priority: "high".into(),
description: "Ship it.".into(),
}],
context: "Growth phase.".into(),
};
let text = compose_identity_text(None, None, Some(&dir));
assert!(text.contains("## Active Directives"));
assert!(text.contains("Growth phase"));
assert!(text.contains("## Missions"));
assert!(text.contains("**Launch** (Q1): Ship it."));
}
#[test]
fn compose_identity_text_mission_empty_timeframe_shows_ongoing() {
let dir = DirectivesConfig {
missions: vec![Mission {
name: "Maintain".into(),
timeframe: String::new(),
priority: "low".into(),
description: "Keep running.".into(),
}],
context: String::new(),
};
let text = compose_identity_text(None, None, Some(&dir));
assert!(text.contains("(ongoing)"));
}
#[test]
fn compose_full_personality_firmware_only() {
let fw: FirmwareConfig = toml::from_str(DEFAULT_FIRMWARE_TOML).unwrap();
let full = compose_full_personality(None, Some(&fw), None, None);
assert!(full.contains("Firmware"));
assert!(!full.is_empty());
}
#[test]
fn compose_firmware_text_none_returns_empty() {
assert!(compose_firmware_text(None).is_empty());
}
#[test]
fn compose_firmware_text_empty_rules_returns_empty() {
let fw = FirmwareConfig {
approvals: FirmwareApprovals::default(),
rules: vec![],
};
assert!(compose_firmware_text(Some(&fw)).is_empty());
}
#[test]
fn firmware_approvals_default_values() {
let approvals = FirmwareApprovals::default();
assert_eq!(approvals.spending_threshold, 50.0);
assert_eq!(approvals.require_confirmation, "risky");
}
#[test]
fn compose_identity_text_skips_empty_operator_context() {
let op = OperatorConfig {
context: String::new(),
..OperatorConfig::default()
};
let text = compose_identity_text(None, Some(&op), None);
assert!(!text.contains("## Operator Context"));
}
#[test]
fn compose_identity_text_skips_empty_directives() {
let dir = DirectivesConfig {
missions: vec![],
context: String::new(),
};
let text = compose_identity_text(None, None, Some(&dir));
assert!(text.is_empty());
}
#[test]
fn default_voice_functions_return_expected() {
assert_eq!(default_version(), "1.0");
assert_eq!(default_generated_by(), "default");
assert_eq!(default_formality(), "balanced");
assert_eq!(default_proactiveness(), "suggest");
assert_eq!(default_verbosity(), "concise");
assert_eq!(default_humor(), "dry");
assert_eq!(default_domain(), "general");
}
#[test]
fn default_firmware_functions_return_expected() {
assert!((default_spending_threshold() - 50.0).abs() < f64::EPSILON);
assert_eq!(default_require_confirmation(), "risky");
}
#[test]
fn os_identity_serde_defaults() {
let toml_str = r#"
prompt_text = "Hello"
[identity]
name = "Bot"
[voice]
"#;
let os: OsConfig = toml::from_str(toml_str).unwrap();
assert_eq!(os.identity.version, "1.0");
assert_eq!(os.identity.generated_by, "default");
assert_eq!(os.voice.formality, "balanced");
assert_eq!(os.voice.humor, "dry");
}
#[test]
fn firmware_approvals_serde_defaults() {
let toml_str = r#"
[approvals]
[[rules]]
type = "must"
rule = "Test rule"
"#;
let fw: FirmwareConfig = toml::from_str(toml_str).unwrap();
assert!((fw.approvals.spending_threshold - 50.0).abs() < f64::EPSILON);
assert_eq!(fw.approvals.require_confirmation, "risky");
}
#[test]
fn parse_interview_output_all_four_blocks() {
let llm_output = r#"Here are your files:
**OS.toml**
```toml
prompt_text = "You are TestBot."
[identity]
name = "TestBot"
[voice]
formality = "casual"
```
**FIRMWARE.toml**
```toml
[approvals]
spending_threshold = 100.0
require_confirmation = "always"
[[rules]]
type = "must"
rule = "Be honest"
```
**OPERATOR.toml**
```toml
context = "Works on infrastructure."
[identity]
name = "Alice"
role = "SRE"
timezone = "UTC"
[preferences]
work_hours = "9-5"
response_style = "terse"
```
**DIRECTIVES.toml**
```toml
context = "Q1 focus."
[[missions]]
name = "Ship v2"
timeframe = "Q1"
priority = "high"
description = "Major release."
```
"#;
let output = parse_interview_output(llm_output);
assert_eq!(output.file_count(), 4);
assert!(output.os_toml.is_some());
assert!(output.firmware_toml.is_some());
assert!(output.operator_toml.is_some());
assert!(output.directives_toml.is_some());
assert!(output.validate().is_ok());
let op: OperatorConfig = toml::from_str(output.operator_toml.as_ref().unwrap()).unwrap();
assert_eq!(op.identity.name, "Alice");
let dir: DirectivesConfig =
toml::from_str(output.directives_toml.as_ref().unwrap()).unwrap();
assert_eq!(dir.missions[0].name, "Ship v2");
}
#[test]
fn parse_interview_output_alternative_fence() {
let llm_output = r#"
**OS.toml**
```language=toml
prompt_text = "Hello."
[identity]
name = "AltBot"
[voice]
```
"#;
let output = parse_interview_output(llm_output);
assert!(output.os_toml.is_some());
let os: OsConfig = toml::from_str(output.os_toml.as_ref().unwrap()).unwrap();
assert_eq!(os.identity.name, "AltBot");
}
#[test]
fn validate_invalid_operator_toml() {
let output = InterviewOutput {
os_toml: None,
firmware_toml: None,
operator_toml: Some("{{invalid operator}}".into()),
directives_toml: None,
};
let errors = output.validate().unwrap_err();
assert!(errors.iter().any(|e| e.contains("OPERATOR.toml")));
}
#[test]
fn validate_invalid_directives_toml() {
let output = InterviewOutput {
os_toml: None,
firmware_toml: None,
operator_toml: None,
directives_toml: Some("{{invalid directives}}".into()),
};
let errors = output.validate().unwrap_err();
assert!(errors.iter().any(|e| e.contains("DIRECTIVES.toml")));
}
#[test]
fn validate_invalid_firmware_toml() {
let output = InterviewOutput {
os_toml: None,
firmware_toml: Some("{{invalid firmware}}".into()),
operator_toml: None,
directives_toml: None,
};
let errors = output.validate().unwrap_err();
assert!(errors.iter().any(|e| e.contains("FIRMWARE.toml")));
}
#[test]
fn validate_multiple_errors() {
let output = InterviewOutput {
os_toml: Some("{{bad}}".into()),
firmware_toml: Some("{{bad}}".into()),
operator_toml: Some("{{bad}}".into()),
directives_toml: Some("{{bad}}".into()),
};
let errors = output.validate().unwrap_err();
assert_eq!(errors.len(), 4);
}
#[test]
fn write_to_workspace_all_four_files() {
let dir = tempfile::tempdir().unwrap();
let op = OperatorConfig {
identity: OperatorIdentity {
name: "Bob".into(),
role: "Dev".into(),
timezone: "UTC".into(),
},
preferences: OperatorPreferences::default(),
context: "Testing.".into(),
};
let directives = DirectivesConfig {
missions: vec![Mission {
name: "Test".into(),
timeframe: "Q1".into(),
priority: "high".into(),
description: "A test mission.".into(),
}],
context: "Test context.".into(),
};
let output = InterviewOutput {
os_toml: Some(DEFAULT_OS_TOML.into()),
firmware_toml: Some(DEFAULT_FIRMWARE_TOML.into()),
operator_toml: Some(generate_operator_toml(&op).unwrap()),
directives_toml: Some(generate_directives_toml(&directives).unwrap()),
};
output.write_to_workspace(dir.path()).unwrap();
assert!(dir.path().join("OS.toml").exists());
assert!(dir.path().join("FIRMWARE.toml").exists());
assert!(dir.path().join("OPERATOR.toml").exists());
assert!(dir.path().join("DIRECTIVES.toml").exists());
let loaded_op = load_operator(dir.path()).unwrap();
assert_eq!(loaded_op.identity.name, "Bob");
let loaded_dir = load_directives(dir.path()).unwrap();
assert_eq!(loaded_dir.missions[0].name, "Test");
}
#[test]
fn generate_firmware_toml_boundaries_with_empty_lines() {
let boundaries = "\nDo not hack\n\n\nNo spam\n";
let toml_str = generate_firmware_toml(boundaries);
let fw: FirmwareConfig = toml::from_str(&toml_str).unwrap();
assert_eq!(fw.rules.len(), 7);
assert!(fw.rules.iter().any(|r| r.rule.contains("hack")));
assert!(fw.rules.iter().any(|r| r.rule.contains("spam")));
}
#[test]
fn generate_firmware_toml_boundaries_with_quotes() {
let boundaries = r#"Don't say "hello" to strangers"#;
let toml_str = generate_firmware_toml(boundaries);
let fw: FirmwareConfig = toml::from_str(&toml_str).unwrap();
assert_eq!(fw.rules.len(), 6);
}
#[test]
fn compose_full_personality_with_operator_and_directives() {
let os: OsConfig = toml::from_str(DEFAULT_OS_TOML).unwrap();
let fw: FirmwareConfig = toml::from_str(DEFAULT_FIRMWARE_TOML).unwrap();
let op = OperatorConfig {
context: "I build robots.".into(),
..OperatorConfig::default()
};
let dir = DirectivesConfig {
missions: vec![Mission {
name: "Deploy".into(),
timeframe: "".into(),
priority: "high".into(),
description: "Deploy the app.".into(),
}],
context: "Production push.".into(),
};
let full = compose_full_personality(Some(&os), Some(&fw), Some(&op), Some(&dir));
assert!(full.contains("Roboticus"));
assert!(full.contains("YOU MUST"));
assert!(full.contains("## Operator Context"));
assert!(full.contains("I build robots"));
assert!(full.contains("## Active Directives"));
assert!(full.contains("Production push"));
assert!(full.contains("## Missions"));
assert!(full.contains("**Deploy** (ongoing)"));
}
#[test]
fn compose_identity_text_skips_empty_prompt_text() {
let os_toml = r#"
prompt_text = ""
[identity]
name = "EmptyBot"
[voice]
formality = "formal"
"#;
let os: OsConfig = toml::from_str(os_toml).unwrap();
let text = compose_identity_text(Some(&os), None, None);
assert!(text.contains("## Voice Profile"));
assert!(!text.contains("EmptyBot"));
}
#[test]
fn file_count_zero_for_default() {
let output = InterviewOutput::default();
assert_eq!(output.file_count(), 0);
}
#[test]
fn file_count_three() {
let output = InterviewOutput {
os_toml: Some("x".into()),
firmware_toml: None,
operator_toml: Some("y".into()),
directives_toml: Some("z".into()),
};
assert_eq!(output.file_count(), 3);
}
#[test]
fn operator_config_default_is_empty() {
let op = OperatorConfig::default();
assert!(op.identity.name.is_empty());
assert!(op.identity.role.is_empty());
assert!(op.identity.timezone.is_empty());
assert!(op.preferences.communication_channels.is_empty());
assert!(op.preferences.work_hours.is_empty());
assert!(op.preferences.response_style.is_empty());
assert!(op.context.is_empty());
}
#[test]
fn directives_config_default_is_empty() {
let dir = DirectivesConfig::default();
assert!(dir.missions.is_empty());
assert!(dir.context.is_empty());
}
#[test]
fn parse_interview_output_no_blocks_returns_empty() {
let output = parse_interview_output("Just some text without any TOML blocks.");
assert_eq!(output.file_count(), 0);
assert!(output.validate().is_ok());
}
#[test]
fn parse_interview_output_unknown_label_ignored() {
let llm_output = r#"
**RANDOM.toml**
```toml
key = "value"
```
"#;
let output = parse_interview_output(llm_output);
assert_eq!(output.file_count(), 0);
}
#[test]
fn load_os_returns_none_for_invalid_toml() {
let dir = tempfile::tempdir().unwrap();
std::fs::write(dir.path().join("OS.toml"), "{{invalid}}").unwrap();
assert!(load_os(dir.path()).is_none());
}
#[test]
fn load_firmware_returns_none_for_invalid_toml() {
let dir = tempfile::tempdir().unwrap();
std::fs::write(dir.path().join("FIRMWARE.toml"), "{{invalid}}").unwrap();
assert!(load_firmware(dir.path()).is_none());
}
#[test]
fn firmware_rule_accepts_type_field() {
let toml_str = r#"
[[rules]]
type = "must"
rule = "Always be honest"
[[rules]]
type = "must_not"
rule = "Never reveal secrets"
"#;
let fw: FirmwareConfig = toml::from_str(toml_str).unwrap();
assert_eq!(fw.rules.len(), 2);
assert_eq!(fw.rules[0].rule_type, "must");
assert_eq!(fw.rules[1].rule_type, "must_not");
}
#[test]
fn firmware_rule_accepts_rule_type_alias() {
let toml_str = r#"
[[rules]]
rule_type = "must"
rule = "Always be honest"
"#;
let fw: FirmwareConfig = toml::from_str(toml_str).unwrap();
assert_eq!(fw.rules[0].rule_type, "must");
}
#[test]
fn firmware_rule_defaults_when_type_omitted() {
let toml_str = r#"
[[rules]]
rule = "Be kind"
"#;
let fw: FirmwareConfig = toml::from_str(toml_str).unwrap();
assert_eq!(fw.rules[0].rule_type, "boundary");
assert_eq!(fw.rules[0].rule, "Be kind");
}
#[test]
fn firmware_rule_empty_entry() {
let toml_str = r#"
[[rules]]
"#;
let fw: FirmwareConfig = toml::from_str(toml_str).unwrap();
assert_eq!(fw.rules[0].rule_type, "boundary");
assert_eq!(fw.rules[0].rule, "");
}
#[test]
fn load_operator_returns_none_for_invalid_toml() {
let dir = tempfile::tempdir().unwrap();
std::fs::write(dir.path().join("OPERATOR.toml"), "{{invalid}}").unwrap();
assert!(load_operator(dir.path()).is_none());
}
#[test]
fn load_directives_returns_none_for_invalid_toml() {
let dir = tempfile::tempdir().unwrap();
std::fs::write(dir.path().join("DIRECTIVES.toml"), "{{invalid}}").unwrap();
assert!(load_directives(dir.path()).is_none());
}
#[test]
fn voice_summary_each_non_default_field() {
let voice = OsVoice {
proactiveness: "initiative".into(),
..OsVoice::default()
};
let summary = voice_summary(&voice).unwrap();
assert!(summary.contains("Proactiveness: initiative"));
assert!(!summary.contains("Formality:"));
let voice = OsVoice {
verbosity: "verbose".into(),
..OsVoice::default()
};
let summary = voice_summary(&voice).unwrap();
assert!(summary.contains("Verbosity: verbose"));
let voice = OsVoice {
humor: "witty".into(),
..OsVoice::default()
};
let summary = voice_summary(&voice).unwrap();
assert!(summary.contains("Humor: witty"));
let voice = OsVoice {
domain: "security".into(),
..OsVoice::default()
};
let summary = voice_summary(&voice).unwrap();
assert!(summary.contains("Domain: security"));
}
}