lcpfs 2026.1.102

LCP File System - A ZFS-inspired copy-on-write filesystem for Rust
// Copyright 2025 LunaOS Contributors
// SPDX-License-Identifier: Apache-2.0
//
// LunaOS Integration Layer
// Hook points for CCU proprioception and PI scheduler integration.

//! # LunaOS Integration
//!
//! This module provides integration points between LCPFS and LunaOS kernel subsystems:
//!
//! - **CCU Proprioception**: System state sensing (CPU, memory, thermal)
//! - **PI Scheduler**: Purposive Imperative decision context
//! - **Epsilon Recording**: Conceptual error tracking (dε/dt ≤ 0)
//!
//! ## Integration Pattern
//!
//! LCPFS uses trait-based callbacks that LunaOS implements when the `lunaos` feature is enabled.
//! For other kernels, these methods return None/default values.

/// LunaOS Coherence Control Unit (CCU) integration
///
/// # Purpose
///
/// CCU monitors system proprioception - internal state awareness including:
/// - CPU utilization per core
/// - Memory pressure
/// - Thermal state
/// - Disk I/O bandwidth
/// - Network saturation
///
/// # Integration
///
/// When running in LunaOS, scrubber queries CCU to adjust scrub intensity:
/// - High CPU load → reduce scrub rate
/// - Low CPU idle → increase scrub rate
/// - Thermal warning → pause scrub
///
/// # Example Implementation (LunaOS)
///
/// ```rust,ignore
/// // luna_core/src/ccu/proprioception.rs
/// pub fn cpu_utilization() -> f64 {
///     let idle_time = IDLE_TRACKER.read().total_idle_ns();
///     let total_time = rdtsc() - BOOT_TIMESTAMP;
///     1.0 - (idle_time as f64 / total_time as f64)
/// }
/// ```
pub trait CcuProprioception {
    /// Get current CPU utilization (0.0 = idle, 1.0 = saturated)
    ///
    /// # LunaOS Implementation
    ///
    /// Queries `luna_core/src/ccu/proprioception.rs` for aggregate CPU usage.
    /// Calculated from scheduler idle time counters.
    fn cpu_utilization(&self) -> Option<f64> {
        None
    }

    /// Get current memory pressure (0.0 = plenty free, 1.0 = OOM imminent)
    fn memory_pressure(&self) -> Option<f64> {
        None
    }

    /// Get current thermal state (0.0 = cool, 1.0 = thermal throttling)
    fn thermal_state(&self) -> Option<f64> {
        None
    }

    /// Get current disk I/O bandwidth utilization (0.0 = idle, 1.0 = saturated)
    fn disk_io_utilization(&self) -> Option<f64> {
        None
    }
}

/// LunaOS Purposive Imperative (PI) scheduler integration
///
/// # Purpose
///
/// PI scheduler makes scheduling decisions based on minimizing conceptual error (ε).
/// LCPFS scrubber integrates with PI to:
/// - Record ε before/after scrub (measures impact on system coherence)
/// - Access predicted error rate (PI forecasts when scrub is needed)
/// - Coordinate with PI for scrub scheduling decisions
///
/// # Conceptual Error (ε)
///
/// ε measures system's deviation from desired state (in Joules):
/// - Data corruption → increases ε (loss of information integrity)
/// - Successful scrub repair → decreases ε (restoration of integrity)
/// - dε/dt ≤ 0 enforced by PI (First Law of Computational Physics)
///
/// # Example Implementation (LunaOS)
///
/// ```rust,ignore
/// // luna_core/src/lcp/pi/scheduler.rs
/// pub fn epsilon_current() -> f64 {
///     PI_SCHEDULER.read().current_epsilon_joules()
/// }
///
/// pub fn predicted_error_rate() -> f64 {
///     PI_SCHEDULER.read().forecaster.predict_corruption_rate()
/// }
/// ```
pub trait PiSchedulerIntegration {
    /// Get current conceptual error (ε) in Joules
    ///
    /// # LunaOS Implementation
    ///
    /// Queries `luna_core/src/lcp/pi/scheduler.rs` for current ε.
    /// This is recorded before/after scrub to measure impact.
    fn epsilon_current(&self) -> Option<f64> {
        None
    }

    /// Get PI scheduler's predicted data corruption error rate
    ///
    /// # LunaOS Implementation
    ///
    /// PI maintains a predictive model of when corruption is likely.
    /// Based on:
    /// - Time since last scrub
    /// - Historical error patterns
    /// - Hardware wear indicators (SMART data)
    /// - Cosmic ray flux predictions (for bit flips)
    ///
    /// Returns predicted errors per TB per hour.
    fn predicted_error_rate(&self) -> Option<f64> {
        None
    }

    /// Notify PI scheduler that a scrub is starting
    ///
    /// # LunaOS Implementation
    ///
    /// PI records scrub start in decision log for learning.
    fn notify_scrub_start(&mut self) {}

    /// Notify PI scheduler that a scrub completed
    ///
    /// # LunaOS Implementation
    ///
    /// PI records outcome (errors found, repairs made) to improve predictions.
    fn notify_scrub_complete(&mut self, _errors_found: u64, _repairs_made: u64) {}
}

use alloc::boxed::Box;
/// Global LunaOS integration hooks
///
/// # Usage
///
/// Register kernel integration at boot:
///
/// ```rust,ignore
/// // luna_core/src/fs/lcpfs_init.rs
/// use lcpfs::lunaos_integration::{LUNAOS_CCU, LUNAOS_PI};
///
/// pub fn init_lcpfs_integration() {
///     *LUNAOS_CCU.lock() = Some(Box::new(LunaOsCcuImpl));
///     *LUNAOS_PI.lock() = Some(Box::new(LunaOsPiImpl));
/// }
/// ```
use spin::Mutex;

lazy_static::lazy_static! {
    /// Global CCU integration hook (None if not running in LunaOS)
    pub static ref LUNAOS_CCU: Mutex<Option<Box<dyn CcuProprioception + Send>>> = Mutex::new(None);

    /// Global PI scheduler integration hook (None if not running in LunaOS)
    pub static ref LUNAOS_PI: Mutex<Option<Box<dyn PiSchedulerIntegration + Send>>> = Mutex::new(None);
}

/// Helper: Query CPU utilization from CCU if available
///
/// # Returns
///
/// CPU utilization (0.0-1.0), or 0.0 if not running in LunaOS
pub fn get_cpu_utilization() -> f64 {
    LUNAOS_CCU
        .lock()
        .as_ref()
        .and_then(|ccu| ccu.cpu_utilization())
        .unwrap_or(0.0)
}

/// Helper: Query epsilon from PI if available
///
/// # Returns
///
/// Current ε in Joules, or 0.0 if not running in LunaOS
pub fn get_epsilon_current() -> f64 {
    LUNAOS_PI
        .lock()
        .as_ref()
        .and_then(|pi| pi.epsilon_current())
        .unwrap_or(0.0)
}

/// Helper: Query predicted error rate from PI if available
///
/// # Returns
///
/// Predicted errors/TB/hour, or 0.0 if not running in LunaOS
pub fn get_predicted_error_rate() -> f64 {
    LUNAOS_PI
        .lock()
        .as_ref()
        .and_then(|pi| pi.predicted_error_rate())
        .unwrap_or(0.0)
}

/// Helper: Get I/O latency from device driver if available
///
/// # Arguments
///
/// * `dev_id` - Device ID to query
///
/// # Returns
///
/// Average I/O latency in microseconds, or 0.0 if not available
pub fn get_io_latency_us(dev_id: usize) -> f64 {
    use crate::BLOCK_DEVICES;

    BLOCK_DEVICES
        .lock()
        .get(dev_id)
        .and_then(|dev| dev.io_latency_avg_us())
        .unwrap_or(0.0)
}

/// Helper: Notify PI that scrub is starting
pub fn notify_scrub_start() {
    if let Some(ref mut pi) = *LUNAOS_PI.lock() {
        pi.notify_scrub_start();
    }
}

/// Helper: Notify PI that scrub completed
pub fn notify_scrub_complete(errors_found: u64, repairs_made: u64) {
    if let Some(ref mut pi) = *LUNAOS_PI.lock() {
        pi.notify_scrub_complete(errors_found, repairs_made);
    }
}

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

    #[test]
    fn test_no_integration_returns_defaults() {
        // Without LunaOS integration, should return safe defaults
        assert_eq!(get_cpu_utilization(), 0.0);
        assert_eq!(get_epsilon_current(), 0.0);
        assert_eq!(get_predicted_error_rate(), 0.0);
    }

    #[test]
    fn test_notify_without_integration_no_panic() {
        // Should not panic when PI not registered
        notify_scrub_start();
        notify_scrub_complete(10, 5);
    }
}