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

273 lines
9.2 KiB
Markdown

# 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
```rust
// 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
```rust
// 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
- [x] Logging au niveau WARN (pas DEBUG)
- [x] Message inclut le nom et type du composant
- [x] Résumé final avec liste des composants skippés
- [x] Test que le warning est bien émis
---
## Tests Requis
```rust
#[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`](crates/solver/src/system.rs:1855):
```rust
_ => {
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 RefrigerantSource/RefrigerantSink 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
- [Coherence Audit Report](./coherence-audit-remediation-plan.md)
- [Story 7-2 Energy Balance Validation](./7-2-energy-balance-validation.md)
- [Rust tracing crate docs](https://docs.rs/tracing/latest/tracing/)
- [std::any::type_name_of_val](https://doc.rust-lang.org/std/any/fn.type_name_of_val.html)
---
## 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)