use bcode_model::judgement::{Feature, SetupSelection};
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum JudgementMode {
#[default]
Auto,
Off,
}
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
#[serde(default, deny_unknown_fields)]
pub struct JudgementConfig {
pub mode: JudgementMode,
pub selection: Option<SetupSelection>,
pub tool_result_triage: JudgementMode,
pub context_reranking: JudgementMode,
pub progress_monitoring: JudgementMode,
pub recommendations: JudgementMode,
pub session_categorization: JudgementMode,
pub eval_categorization: JudgementMode,
}
impl JudgementConfig {
#[must_use]
pub const fn enabled(&self, feature: Feature) -> bool {
let mode = match feature {
Feature::ToolResultTriage => self.tool_result_triage,
Feature::ContextReranking => self.context_reranking,
Feature::ProgressMonitoring => self.progress_monitoring,
Feature::Recommendations => self.recommendations,
Feature::SessionCategorization => self.session_categorization,
Feature::EvalCategorization => self.eval_categorization,
};
matches!(self.mode, JudgementMode::Auto) && matches!(mode, JudgementMode::Auto)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn defaults_and_opt_outs() {
let features = [
Feature::ToolResultTriage,
Feature::ContextReranking,
Feature::ProgressMonitoring,
Feature::Recommendations,
Feature::SessionCategorization,
Feature::EvalCategorization,
];
let mut config = JudgementConfig::default();
assert!(features.iter().all(|feature| config.enabled(*feature)));
config.context_reranking = JudgementMode::Off;
assert!(!config.enabled(Feature::ContextReranking));
assert!(config.enabled(Feature::Recommendations));
config.mode = JudgementMode::Off;
assert!(features.iter().all(|feature| !config.enabled(*feature)));
}
#[test]
fn policy_round_trip_and_unknown_modes_fail_closed() {
let config: JudgementConfig =
toml::from_str("mode = 'off'\nrecommendations = 'off'").unwrap();
assert_eq!(config.mode, JudgementMode::Off);
assert_eq!(
toml::from_str::<JudgementConfig>(&toml::to_string(&config).unwrap()).unwrap(),
config
);
assert!(toml::from_str::<JudgementConfig>("mode = 'future'").is_err());
}
}