# CLAUDE.md This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. ## Build, Test, and Development Commands ### Core workflows - **Build library**: `cargo build` (debug) or `cargo build --release` (optimized) - **Build FFI shared library**: `cargo build --release --features ffi` (generates C header via cbindgen) - **Run tests**: `cargo test` (all tests) or `cargo test --test ` (single integration test file) - **Run examples**: `cargo run --example usage`, `cargo run --example patient`, `cargo run --example tracing_demo` - **Run demo monitor**: `cargo run --example demo_app --features demo-monitor` - **Benchmarks**: `cargo bench` (runs Criterion benchmarks; results in `target/criterion/`) - **Format code**: `cargo fmt --all` (run before committing) - **Lint**: `cargo clippy --all-targets -- -D warnings` (enforce before committing) ### Packaging binary distributions - **Linux/macOS**: Run `../scripts/package.sh [target-triple]` from `medicallib_rust/` - **Windows**: Run `..\scripts\package.ps1 [target-triple]` from `medicallib_rust\` - Artifacts placed in `medicallib_rust/dist/` as both `.tar.gz` and `.zip` ## Architecture Overview ### Core structure - **`src/lib.rs`**: Crate facade re-exporting public API (`Patient`, `Organ`, types, errors) - **`src/types.rs`**: Domain types (`Blood`, `BloodPressure`, `OrganType`, `VitalSign`) - **`src/error.rs`**: `MedicalError` enum using `thiserror` - **`src/patient.rs`**: `Patient` struct orchestrating `Vec>` with inter-organ signal routing - **`src/organs/mod.rs`**: `Organ` trait and `OrganInfo`; per-organ modules (heart, lungs, brain, etc.) - **`src/ekg/mod.rs`**: EKG monitoring system with configurable leads - **`src/ffi.rs`**: C-compatible FFI layer (feature `ffi`); header auto-generated to `ffi/medicallib.h` by `build.rs` using cbindgen ### Organ system - Each organ module implements the `Organ` trait (`id()`, `organ_type()`, `update(dt)`, `summary()`, `as_any()`, `as_any_mut()`) - `Patient` owns organs as trait objects, calls `update()` each tick, and routes signals between organs - Inter-organ communication examples: - Lungs SpO2 → Heart rate adjustment - Kidneys GFR → Bladder volume accumulation - Brain autonomic signals → Heart rate variability and respiratory drive - Bloodstream perfusion → multiple organ metabolic states ### FFI boundary - **Opaque handle**: `MLPatient` pointer to boxed `Patient` - **Functions**: `ml_patient_new/free/update`, `ml_patient_summary`, `ml_patient_organ_summary`, `medicallib_bmi` - **Memory**: All returned strings allocated by Rust must be freed via `ml_string_free` - **Build script**: `build.rs` runs cbindgen when `--features ffi` is enabled, updates `ffi/medicallib.h` if changed - **Validation**: Any change to `src/ffi.rs` must be tested against `examples/c/ffi_example.c` ### Testing and benchmarks - **Integration tests**: `tests/` directory (e.g., `tests/patient.rs`, `tests/ffi.rs`) - **Benchmarks**: `benches/heart.rs` uses Criterion; compare results across runs for performance regressions - **Unit tests**: In-module `#[cfg(test)]` blocks for focused invariants ## Important Development Notes ### When modifying FFI 1. Edit `src/ffi.rs` 2. Run `cargo build --features ffi` to regenerate `ffi/medicallib.h` via cbindgen 3. Verify C example still compiles: `gcc -o ffi_example examples/c/ffi_example.c -L target/release -lmedicallib_rust` 4. Update `cbindgen.toml` only if header generation settings need adjustment ### Adding new organs 1. Create module in `src/organs/.rs` 2. Define struct implementing `Organ` trait 3. Add module declaration and public re-export in `src/organs/mod.rs` 4. Update `Patient` signal structs and `couple_organs()` method if inter-organ communication needed 5. Add corresponding `OrganType` variant in `src/types.rs` 6. Update FFI constants in `src/ffi.rs` if organ needs FFI exposure ### Cargo features - **`serde`**: Enables serialization on public types - **`ffi`**: Exposes C ABI; triggers cbindgen in `build.rs` - **`demo-monitor`**: Required for `demo_app` example with colorized dashboard ### CI workflows - GitHub Actions: `.github/workflows/ci.yml` - Gitea Actions: `.gitea/workflows/ci.yml` - Both run tests, clippy, formatting checks, and cross-platform builds ## Key Patterns ### Patient simulation loop ```rust let mut patient = Patient::new("case-01")?.initialize_default(); loop { patient.update(dt_seconds); let summary = patient.patient_summary(); // Process vitals... } ``` ### Accessing specific organ ```rust let heart = patient.find_organ_typed::()?; println!("HR: {}", heart.heart_rate_bpm()); ``` ### Inter-organ signals Patient's `couple_organs()` method reads state from one organ (e.g., `Lungs::spo2_pct()`) and injects it into another (e.g., `Heart::receive_spo2_signal()`). Add new signal fields to the internal `*Signals` structs in `patient.rs` when coupling new organ interactions.