use chrono::Utc;
use reputation_types::{AgentData, PriorBreakdown};
pub(crate) fn calculate_prior_detailed(
agent: &AgentData,
prior_base: f64,
prior_max: f64,
) -> PriorBreakdown {
let base_score = prior_base;
let mcp_bonus = if let Some(level) = agent.mcp_level {
match level {
1 => 5.0,
2 => 10.0,
3 => 15.0,
_ => 0.0,
}
} else {
0.0
};
let identity_bonus = if agent.identity_verified { 5.0 } else { 0.0 };
let security_audit_bonus = if agent.security_audit_passed { 7.0 } else { 0.0 };
let open_source_bonus = if agent.open_source { 3.0 } else { 0.0 };
let age_days = (Utc::now() - agent.created_at).num_days();
let age_bonus = if age_days > 365 { 5.0 } else { 0.0 };
let uncapped_total = base_score + mcp_bonus + identity_bonus +
security_audit_bonus + open_source_bonus + age_bonus;
let total = uncapped_total.min(prior_max);
PriorBreakdown {
base_score,
mcp_bonus,
identity_bonus,
security_audit_bonus,
open_source_bonus,
age_bonus,
total,
}
}
#[cfg(test)]
pub(crate) fn calculate_prior(
agent: &AgentData,
prior_base: f64,
prior_max: f64,
) -> f64 {
calculate_prior_detailed(agent, prior_base, prior_max).total
}
#[cfg(test)]
mod tests {
use super::*;
use chrono::Duration;
fn create_test_agent() -> AgentData {
AgentData {
did: "did:test:123".to_string(),
created_at: Utc::now() - Duration::days(1),
mcp_level: None,
identity_verified: false,
security_audit_passed: false,
open_source: false,
total_interactions: 0,
total_reviews: 0,
average_rating: None,
positive_reviews: 0,
negative_reviews: 0,
}
}
#[test]
fn test_base_prior_score() {
let agent = create_test_agent();
let score = calculate_prior(&agent, 50.0, 80.0);
assert_eq!(score, 50.0);
}
#[test]
fn test_mcp_level_bonuses() {
let mut agent = create_test_agent();
agent.mcp_level = Some(1);
assert_eq!(calculate_prior(&agent, 50.0, 80.0), 55.0);
agent.mcp_level = Some(2);
assert_eq!(calculate_prior(&agent, 50.0, 80.0), 60.0);
agent.mcp_level = Some(3);
assert_eq!(calculate_prior(&agent, 50.0, 80.0), 65.0);
agent.mcp_level = Some(4); assert_eq!(calculate_prior(&agent, 50.0, 80.0), 50.0);
}
#[test]
fn test_identity_bonuses() {
let mut agent = create_test_agent();
agent.identity_verified = true;
assert_eq!(calculate_prior(&agent, 50.0, 80.0), 55.0);
agent.security_audit_passed = true;
assert_eq!(calculate_prior(&agent, 50.0, 80.0), 62.0);
agent.open_source = true;
assert_eq!(calculate_prior(&agent, 50.0, 80.0), 65.0);
}
#[test]
fn test_age_bonus() {
let mut agent = create_test_agent();
agent.created_at = Utc::now() - Duration::days(100);
assert_eq!(calculate_prior(&agent, 50.0, 80.0), 50.0);
agent.created_at = Utc::now() - Duration::days(400);
assert_eq!(calculate_prior(&agent, 50.0, 80.0), 55.0);
}
#[test]
fn test_prior_cap() {
let mut agent = create_test_agent();
agent.mcp_level = Some(3); agent.identity_verified = true; agent.security_audit_passed = true; agent.open_source = true; agent.created_at = Utc::now() - Duration::days(400);
assert_eq!(calculate_prior(&agent, 50.0, 80.0), 80.0);
}
#[test]
fn test_custom_base_and_cap() {
let agent = create_test_agent();
assert_eq!(calculate_prior(&agent, 60.0, 90.0), 60.0);
let mut agent = create_test_agent();
agent.mcp_level = Some(3);
agent.identity_verified = true;
agent.security_audit_passed = true;
assert_eq!(calculate_prior(&agent, 60.0, 90.0), 87.0);
assert_eq!(calculate_prior(&agent, 60.0, 85.0), 85.0);
}
#[test]
fn test_detailed_breakdown() {
let mut agent = create_test_agent();
agent.mcp_level = Some(2); agent.identity_verified = true; agent.open_source = true;
let breakdown = calculate_prior_detailed(&agent, 50.0, 80.0);
assert_eq!(breakdown.base_score, 50.0);
assert_eq!(breakdown.mcp_bonus, 10.0);
assert_eq!(breakdown.identity_bonus, 5.0);
assert_eq!(breakdown.security_audit_bonus, 0.0);
assert_eq!(breakdown.open_source_bonus, 3.0);
assert_eq!(breakdown.age_bonus, 0.0);
assert_eq!(breakdown.total, 68.0); }
#[test]
fn test_breakdown_with_cap() {
let mut agent = create_test_agent();
agent.mcp_level = Some(3); agent.identity_verified = true; agent.security_audit_passed = true; agent.open_source = true; agent.created_at = Utc::now() - Duration::days(400);
let breakdown = calculate_prior_detailed(&agent, 50.0, 80.0);
assert_eq!(breakdown.mcp_bonus, 15.0);
assert_eq!(breakdown.identity_bonus, 5.0);
assert_eq!(breakdown.security_audit_bonus, 7.0);
assert_eq!(breakdown.open_source_bonus, 3.0);
assert_eq!(breakdown.age_bonus, 5.0);
assert_eq!(breakdown.total, 80.0); }
}