#![allow(unused)]
#![cfg_attr(coverage_nightly, coverage(off))]
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use std::time::{Duration, SystemTime};
pub struct ErrorBudgetEnforcer {
budgets: HashMap<TeamId, QualityBudget>,
history: TimeSeriesDB,
rules: EnforcementRules,
config: EnforcerConfig,
}
pub type TeamId = String;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct QualityBudget {
pub complexity_budget: i32,
pub satd_budget: u32,
pub coverage_floor: f64,
pub regeneration_rate: f64,
pub grace_period: Duration,
pub current_consumption: BudgetConsumption,
pub started_at: SystemTime,
}
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
pub struct BudgetConsumption {
pub complexity_used: i32,
pub satd_used: u32,
pub coverage_reduction: f64,
pub last_updated: Option<SystemTime>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum Decision {
Approved,
Warning(String),
RequiresApproval {
approvers: Vec<String>,
reason_required: bool,
},
Blocked {
suggestion: String,
refactor_targets: Vec<RefactorTarget>,
},
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RefactorTarget {
pub file: String,
pub complexity: u32,
pub estimated_reduction: u32,
pub priority: Priority,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum Priority {
Low,
Medium,
High,
Critical,
}
pub struct TimeSeriesDB {
data: HashMap<TeamId, Vec<TimeSeries>>,
}
#[derive(Debug, Clone)]
struct TimeSeries {
timestamp: SystemTime,
metrics: TeamMetrics,
}
#[derive(Debug, Clone)]
pub struct TeamMetrics {
avg_complexity: f64,
total_satd: u32,
avg_coverage: f64,
quality_score: f64,
}
#[derive(Debug, Clone, Default)]
pub struct EnforcementRules {
approvers: HashMap<TeamId, Vec<String>>,
escalation: EscalationPolicy,
overrides: HashMap<String, OverridePermission>,
}
#[derive(Debug, Clone)]
struct EscalationPolicy {
warning_threshold: f64,
approval_threshold: f64,
block_threshold: f64,
}
impl Default for EscalationPolicy {
fn default() -> Self {
Self {
warning_threshold: 0.5,
approval_threshold: 0.8,
block_threshold: 1.0,
}
}
}
#[derive(Debug, Clone)]
enum OverridePermission {
None,
Limited,
Full,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct EnforcerConfig {
pub enabled: bool,
pub default_budget: QualityBudget,
pub regeneration_interval: Duration,
pub history_retention: Duration,
}
impl Default for EnforcerConfig {
fn default() -> Self {
Self {
enabled: true,
default_budget: QualityBudget::default(),
regeneration_interval: Duration::from_secs(24 * 60 * 60), history_retention: Duration::from_secs(30 * 24 * 60 * 60), }
}
}
impl Default for QualityBudget {
fn default() -> Self {
Self {
complexity_budget: 100,
satd_budget: 20,
coverage_floor: 0.7,
regeneration_rate: 5.0,
grace_period: Duration::from_secs(7 * 24 * 60 * 60), current_consumption: BudgetConsumption::default(),
started_at: SystemTime::now(),
}
}
}
#[derive(Debug, Clone)]
pub struct DiffAnalysis {
pub complexity_change: i32,
pub satd_change: i32,
pub coverage_change: f64,
pub files_changed: Vec<String>,
}
impl ErrorBudgetEnforcer {
#[must_use]
#[provable_contracts_macros::contract("pmat-core.yaml", equation = "check_compliance")]
pub fn new(config: EnforcerConfig) -> Self {
Self {
budgets: HashMap::new(),
history: TimeSeriesDB::new(),
rules: EnforcementRules::default(),
config,
}
}
#[provable_contracts_macros::contract("pmat-core.yaml", equation = "check_compliance")]
pub fn register_team(&mut self, team_id: TeamId, budget: Option<QualityBudget>) {
let budget = budget.unwrap_or_else(|| self.config.default_budget.clone());
self.budgets.insert(team_id, budget);
}
#[must_use]
#[provable_contracts_macros::contract("pmat-core.yaml", equation = "check_compliance")]
pub fn check_commit(&self, team: &TeamId, diff: &DiffAnalysis) -> Decision {
if !self.config.enabled {
return Decision::Approved;
}
let budget = match self.budgets.get(team) {
Some(b) => b,
None => return Decision::Approved, };
let consumption = self.calculate_consumption(budget, diff);
match consumption {
c if c < self.rules.escalation.warning_threshold => Decision::Approved,
c if c < self.rules.escalation.approval_threshold => Decision::Warning(format!(
"Approaching budget limit ({:.0}% consumed). Consider refactoring.",
c * 100.0
)),
c if c < self.rules.escalation.block_threshold => Decision::RequiresApproval {
approvers: self.rules.approvers_for(team),
reason_required: true,
},
_ => Decision::Blocked {
suggestion: "Budget exceeded. Refactor existing code first.".to_string(),
refactor_targets: self.suggest_refactor_targets(team),
},
}
}
#[provable_contracts_macros::contract("pmat-core.yaml", equation = "check_compliance")]
pub fn update_consumption(&mut self, team: &TeamId, diff: &DiffAnalysis) {
if let Some(budget) = self.budgets.get_mut(team) {
budget.current_consumption.complexity_used += diff.complexity_change;
budget.current_consumption.satd_used =
(budget.current_consumption.satd_used as i32 + diff.satd_change).max(0) as u32;
budget.current_consumption.coverage_reduction += diff.coverage_change;
budget.current_consumption.last_updated = Some(SystemTime::now());
}
}
#[provable_contracts_macros::contract("pmat-core.yaml", equation = "check_compliance")]
pub fn regenerate_budgets(&mut self) {
let now = SystemTime::now();
for budget in self.budgets.values_mut() {
if let Some(last_updated) = budget.current_consumption.last_updated {
if let Ok(elapsed) = now.duration_since(last_updated) {
if elapsed >= self.config.regeneration_interval {
let days_elapsed = elapsed.as_secs() / (24 * 60 * 60);
let regeneration = (budget.regeneration_rate * days_elapsed as f64) as i32;
budget.current_consumption.complexity_used =
(budget.current_consumption.complexity_used - regeneration).max(0);
budget.current_consumption.satd_used =
budget.current_consumption.satd_used.saturating_sub(5);
budget.current_consumption.coverage_reduction =
(budget.current_consumption.coverage_reduction - 0.01).max(0.0);
budget.current_consumption.last_updated = Some(now);
}
}
}
}
}
#[must_use]
#[provable_contracts_macros::contract("pmat-core.yaml", equation = "check_compliance")]
pub fn get_budget_status(&self, team: &TeamId) -> Option<BudgetStatus> {
self.budgets.get(team).map(|budget| {
let consumption = self.calculate_consumption_percentage(budget);
BudgetStatus {
team: team.clone(),
consumption_percentage: consumption,
complexity_remaining: budget.complexity_budget
- budget.current_consumption.complexity_used,
satd_remaining: budget.satd_budget - budget.current_consumption.satd_used,
days_until_regeneration: self.days_until_regeneration(budget),
}
})
}
fn calculate_consumption(&self, budget: &QualityBudget, diff: &DiffAnalysis) -> f64 {
let complexity_ratio =
f64::from(budget.current_consumption.complexity_used + diff.complexity_change)
/ f64::from(budget.complexity_budget);
let satd_ratio = f64::from(budget.current_consumption.satd_used as i32 + diff.satd_change)
/ f64::from(budget.satd_budget);
let coverage_impact = if diff.coverage_change < 0.0 {
(-diff.coverage_change) / (1.0 - budget.coverage_floor)
} else {
0.0
};
(complexity_ratio * 0.5 + satd_ratio * 0.3 + coverage_impact * 0.2)
.max(0.0)
.min(1.0)
}
fn calculate_consumption_percentage(&self, budget: &QualityBudget) -> f64 {
let complexity_ratio = f64::from(budget.current_consumption.complexity_used)
/ f64::from(budget.complexity_budget);
let satd_ratio =
f64::from(budget.current_consumption.satd_used) / f64::from(budget.satd_budget);
((complexity_ratio * 0.6 + satd_ratio * 0.4) * 100.0)
.max(0.0)
.min(100.0)
}
fn days_until_regeneration(&self, budget: &QualityBudget) -> u32 {
if let Some(last_updated) = budget.current_consumption.last_updated {
if let Ok(elapsed) = SystemTime::now().duration_since(last_updated) {
let remaining = self.config.regeneration_interval.as_secs() - elapsed.as_secs();
return (remaining / (24 * 60 * 60)) as u32;
}
}
0
}
fn suggest_refactor_targets(&self, _team: &TeamId) -> Vec<RefactorTarget> {
vec![
RefactorTarget {
file: "src/complex_module.rs".to_string(),
complexity: 35,
estimated_reduction: 15,
priority: Priority::High,
},
RefactorTarget {
file: "src/legacy_code.rs".to_string(),
complexity: 28,
estimated_reduction: 10,
priority: Priority::Medium,
},
]
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct BudgetStatus {
pub team: TeamId,
pub consumption_percentage: f64,
pub complexity_remaining: i32,
pub satd_remaining: u32,
pub days_until_regeneration: u32,
}
impl TimeSeriesDB {
fn new() -> Self {
Self {
data: HashMap::new(),
}
}
#[provable_contracts_macros::contract("pmat-core.yaml", equation = "check_compliance")]
pub fn record(&mut self, team: TeamId, metrics: TeamMetrics) {
let entry = TimeSeries {
timestamp: SystemTime::now(),
metrics,
};
self.data.entry(team).or_default().push(entry);
}
#[provable_contracts_macros::contract("pmat-core.yaml", equation = "check_compliance")]
pub fn record_measurement(&mut self, team: &TeamId, timestamp: SystemTime, value: f64) {
let metrics = TeamMetrics {
avg_complexity: value,
total_satd: 0,
avg_coverage: value,
quality_score: value,
};
let entry = TimeSeries { timestamp, metrics };
self.data.entry(team.clone()).or_default().push(entry);
}
#[must_use]
#[provable_contracts_macros::contract("pmat-core.yaml", equation = "check_compliance")]
pub fn get_recent_measurements(&self, team: &TeamId, duration: Duration) -> Vec<f64> {
let now = SystemTime::now();
let cutoff = now.checked_sub(duration).unwrap_or(SystemTime::UNIX_EPOCH);
self.data
.get(team)
.map(|entries| {
entries
.iter()
.filter(|e| e.timestamp >= cutoff)
.map(|e| e.metrics.quality_score)
.collect()
})
.unwrap_or_default()
}
}
impl EnforcementRules {
fn approvers_for(&self, team: &TeamId) -> Vec<String> {
self.approvers
.get(team)
.cloned()
.unwrap_or_else(|| vec!["tech-lead".to_string()])
}
}
include!("enforcement_tests.rs");