Entropyk/_bmad-output/implementation-artifacts/9-6-energy-validation-logging-improvement.md

9.2 KiB

Story 9.6: Amélioration Logging Validation Énergie

Status: done

Epic: 9 - Coherence Corrections (Post-Audit)
Priorité: P2-IMPORTANTE
Estimation: 1h
Dépendances: Stories 9.3, 9.4, 9.5 (all done)


Story

En tant que développeur debuggant une simulation,
Je veux un avertissement explicite quand des composants sont ignorés dans la validation énergétique,
Afin d'identifier rapidement les implémentations manquantes.


Contexte

L'audit de cohérence a révélé que check_energy_balance() utilise un logging de niveau DEBUG pour les composants skippés, ce qui les rend invisibles en configuration par défaut.


Problème Actuel

// crates/solver/src/system.rs:1873-1879
_ => {
    components_skipped += 1;
    tracing::debug!(  // ← Niveau DEBUG, pas WARNING
        node_index = node_idx.index(),
        "Component lacks full energy transfer or enthalpy data - skipping energy balance check"
    );
}

Conséquence : Les développeurs ne sont pas avertis que certains composants sont ignorés dans la validation.


Solution Proposée

Changements

  1. Passer de DEBUG à WARN pour les composants skippés
  2. Inclure le type du composant dans le message
  3. Ajouter un résumé final si des composants ont été skippés

Implémentation

// crates/solver/src/system.rs

pub fn check_energy_balance(&self, state: &SystemState) -> Result<(), ValidationError> {
    let mut total_heat_in = Power::from_watts(0.0);
    let mut total_heat_out = Power::from_watts(0.0);
    let mut total_work_in = Power::from_watts(0.0);
    let mut total_work_out = Power::from_watts(0.0);
    let mut components_validated = 0;
    let mut components_skipped = 0;
    let mut skipped_components: Vec<String> = Vec::new();

    for node_idx in self.graph.node_indices() {
        let component = &self.graph[node_idx];
        
        let energy_transfers = component.energy_transfers(state);
        let mass_flows = component.port_mass_flows(state);
        let enthalpies = component.port_enthalpies(state);

        match (energy_transfers, mass_flows, enthalpies) {
            (Some((heat, work)), Ok(m_flows), Ok(h_flows)) if m_flows.len() == h_flows.len() => {
                // ... existing validation logic ...
                components_validated += 1;
            }
            _ => {
                components_skipped += 1;
                let component_info = format!(
                    "{} (type: {})",
                    component.name(),
                    std::any::type_name_of_val(component)
                        .split("::")
                        .last()
                        .unwrap_or("unknown")
                );
                skipped_components.push(component_info.clone());
                
                tracing::warn!(
                    component = %component_info,
                    node_index = node_idx.index(),
                    "Component lacks energy_transfers() or port_enthalpies() - SKIPPED in energy balance validation"
                );
            }
        }
    }

    // Résumé final si des composants ont été skippés
    if components_skipped > 0 {
        tracing::warn!(
            components_validated = components_validated,
            components_skipped = components_skipped,
            skipped = ?skipped_components,
            "Energy balance validation incomplete: {} component(s) skipped. \
             Implement energy_transfers() and port_enthalpies() for full validation.",
            components_skipped
        );
    }

    // ... rest of validation ...
}

Fichiers à Modifier

Fichier Action
crates/solver/src/system.rs Modifier check_energy_balance()

Critères d'Acceptation

  • Logging au niveau WARN (pas DEBUG)
  • Message inclut le nom et type du composant
  • Résumé final avec liste des composants skippés
  • Test que le warning est bien émis

Tests Requis

#[cfg(test)]
mod tests {
    use super::*;
    use tracing::subscriber;
    use tracing_subscriber::layer::SubscriberExt;
    
    #[test]
    fn test_warn_emitted_for_skipped_component() {
        // Setup tracing capture
        let (layer, handle) = tracing_subscriber::layer::with_test_writer();
        let _guard = subscriber::set_default(tracing_subscriber::registry().with(layer));
        
        // Create system with component that lacks energy methods
        let mut system = System::new();
        // ... add component without energy_transfers() ...
        
        let state = SystemState::default();
        let _ = system.check_energy_balance(&state);
        
        // Verify warning was emitted
        let logs = handle.read();
        assert!(logs.contains("SKIPPED in energy balance validation"));
    }
}

Exemple de Sortie

Avant correction

DEBUG entropyk_solver::system: Component lacks full energy transfer or enthalpy data - skipping energy balance check node_index=2

Après correction

WARN entropyk_solver::system: Component lacks energy_transfers() or port_enthalpies() - SKIPPED in energy balance validation component="EV-01 (type: ExpansionValve)" node_index=2
WARN entropyk_solver::system: Energy balance validation incomplete: 1 component(s) skipped. Implement energy_transfers() and port_enthalpies() for full validation. components_validated=4 components_skipped=1 skipped=["EV-01 (type: ExpansionValve)"]

Dev Notes

Architecture Patterns

  • Tracing crate: The project uses tracing for structured logging with spans
  • Log levels: DEBUG for detailed diagnostics, WARN for actionable issues
  • Pattern: Use structured fields (node_index = value) for searchable logs

Current Implementation Analysis

The current code at crates/solver/src/system.rs:1855-1861:

_ => {
    components_skipped += 1;
    tracing::debug!(
        node_index = node_idx.index(),
        "Component lacks full energy transfer or enthalpy data - skipping energy balance check"
    );
}

Key observations:

  1. Uses tracing::debug! - invisible with default RUST_LOG=info
  2. Missing component type information
  3. No summary at the end of validation

Implementation Notes

  1. Getting component type: Use std::any::type_name_of_val(component) (stabilized in Rust 1.76)
  2. Component name: Access via component.name() method from Component trait
  3. Tracking skipped components: Add Vec<String> to collect skipped component info

Dependencies Status

Story Status Notes
9-3 ExpansionValve Energy Methods done ExpansionValve now has energy_transfers()
9-4 FlowSource/FlowSink Energy Methods review Implementation complete, pending review
9-5 FlowSplitter/FlowMerger Energy Methods ready-for-dev Depends on this story

Note: This story can be implemented independently - it improves logging regardless of whether other components have complete energy methods.

Testing Strategy

  1. Unit test: Create a mock component without energy methods, verify warning is emitted
  2. Integration test: Run check_energy_balance() on a system with mixed components
  3. Manual verification: Run with RUST_LOG=warn and verify warnings appear

Project Structure Notes

  • File to modify: crates/solver/src/system.rs
  • Function: check_energy_balance(&self, state: &StateSlice)
  • Line range: ~1855-1861 (the _ => match arm)

References


Dev Agent Record

Agent Model Used

z-ai/glm-5:free

Debug Log References

  • Build succeeded with cargo build --package entropyk-solver
  • All tests passed with cargo test --package entropyk-solver

Completion Notes List

  • Implementation: Modified check_energy_balance() in crates/solver/src/system.rs to:
    1. Use tracing::warn! instead of tracing::debug! for skipped components
    2. Include component signature and type name in the warning message using component.signature() and std::any::type_name_of_val()
    3. Track skipped components in a Vec<String> and emit a summary warning at the end if any components were skipped
  • Note: Used component.signature() instead of component.name() because the Component trait doesn't have a name() method - signature() provides component identification information
  • Tests: Added three unit tests with proper tracing capture using tracing_subscriber:
    • test_energy_balance_warns_for_skipped_components: Verifies warning is emitted with "SKIPPED in energy balance validation"
    • test_energy_balance_includes_component_type_in_warning: Verifies component type is included in warning
    • test_energy_balance_summary_warning: Verifies summary warning with "Energy balance validation incomplete"
  • Code Review Fix: Added tracing-subscriber to dev-dependencies for proper log capture in tests
  • All acceptance criteria satisfied

File List

  • crates/solver/src/system.rs (modified)