collet 0.1.0

Relentless agentic coding orchestrator with zero-drop agent loops
Documentation
//! EGL (Evolutionary Generality Loss) convergence checking.
//!
//! Provides pure functions to determine whether the evolution loop should
//! stop because scores have plateaued.

/// Check whether the score curve has converged.
///
/// Returns `true` when the most recent `window` scores have all changed
/// by less than `epsilon` compared to the score immediately before them.
pub fn is_score_converged(scores: &[f64], window: usize, epsilon: f64) -> bool {
    if scores.len() < window + 1 {
        return false;
    }
    let baseline = scores[scores.len() - window - 1];
    scores[scores.len() - window..]
        .iter()
        .all(|s| (s - baseline).abs() < epsilon)
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_convergence_not_enough_data() {
        assert!(!is_score_converged(&[0.5, 0.6], 3, 0.05));
    }

    #[test]
    fn test_convergence_flat() {
        let scores = vec![0.5, 0.7, 0.71, 0.72, 0.72];
        assert!(is_score_converged(&scores, 3, 0.05));
    }

    #[test]
    fn test_convergence_still_improving() {
        let scores = vec![0.5, 0.6, 0.7, 0.8, 0.9];
        assert!(!is_score_converged(&scores, 3, 0.05));
    }
}