---
stepsCompleted:
  - step-01-validate-prerequisites
  - step-02-design-epics
  - step-03-create-stories
inputDocuments:
  - /Users/sepehr/dev/Entropyk/_bmad-output/planning-artifacts/prd.md
  - /Users/sepehr/dev/Entropyk/_bmad-output/planning-artifacts/architecture.md
---

# Entropyk - Epic Breakdown

## Overview

This document provides the complete epic and story breakdown for Entropyk, decomposing the requirements from the PRD and Architecture requirements into implementable stories.

## Requirements Inventory

### Functional Requirements

**FR1:** The system can model a Compressor according to AHRI 540 standard with manufacturer coefficients

**FR2:** The system can model a Condenser with heat transfer calculation

**FR3:** The system can model an Expansion Valve (isenthalpic expansion)

**FR4:** The system can model an Evaporator with phase change

**FR5:** The system can model an Economizer (internal heat exchanger) with Bypass mode

**FR6:** Each component can be in OperationalState (On, Off, Bypass)

**FR7:** In Off mode, an active component contributes zero mass flow to the system

**FR8:** In Bypass mode, a component behaves as an adiabatic pipe (P_in = P_out, h_in = h_out)

**FR9:** User can define a Machine containing N independent fluid circuits

**FR10:** User can connect components via Ports (inlet/outlet)

**FR11:** System supports connections between circuits (thermal coupling)

**FR12:** System can solve N circuits simultaneously or sequentially

**FR13:** System mathematically handles zero-flow branches without division by zero

**FR14:** System can solve equations using Newton-Raphson method

**FR15:** System can solve equations using Sequential Substitution (Picard) method

**FR16:** Solver automatically switches to Sequential Substitution if Newton-Raphson diverges

**FR17:** Solver respects configurable time budget (timeout)

**FR18:** On timeout, solver returns best known state with NonConverged status

**FR19:** Solver can freeze Jacobian calculation to accelerate (Jacobian Freezing)

**FR20:** Convergence criterion checks Delta Pressure < 1 Pa (1e-5 bar)

**FR21:** For multi-circuits, global convergence is achieved when ALL circuits converge

**FR22:** User can define output constraints (e.g., Superheat = 5K)

**FR23:** System calculates necessary inputs (e.g., valve opening) respecting Bounded Constraints (0.0 ≤ Valve ≤ 1.0). If solution is out of bounds, solver returns "Saturation" or "ControlLimitReached" error

**FR24:** Inverse Control is solved simultaneously with cycle equations (One-Shot)

**FR25:** System can load fluid properties via CoolProp

**FR26:** System supports Tabular Interpolation tables for 100x performance

**FR27:** System handles pure fluids and mixtures (R32/R125, R454B)

**FR28:** System handles Temperature Glide for zeotropic mixtures

**FR29:** System uses automatic damping near critical point (CO2 R744)

**FR30:** Native Rust API with types and ownership safety

**FR31:** Python bindings via PyO3 with tespy-compatible API

**FR32:** C FFI for integration with external systems (PLC, LabView)

**FR33:** WebAssembly compilation support for web interfaces

**FR34:** CLI for batch simulation execution

**FR35:** System automatically checks mass balance (Σ ṁ_in - Σ ṁ_out < 1e-9 kg/s)

**FR36:** System automatically checks energy balance (Σ Q̇ + Ẇ - Σ (ṁ · h) < 1e-6 kW)

**FR37:** Each result contains traceability metadata (solver version, fluid version, SHA-256 input hash)

**FR38:** Debug Verbose mode to display residuals and convergence history

**FR39:** Error handling via Result<T, ThermoError> (Zero-Panic Policy)

**FR40:** System handles Incompressible Fluids (Water, Glycol, Humid Air simplified) via lightweight models (constant Cp or polynomial) for heat sources and sinks

**FR41:** Complete graph (Topology + Parameters + Fluid State) is serializable/deserializable to JSON (or TOML)

**FR42:** System includes Automatic Initialization Heuristic (Smart Guesser) proposing coherent initial pressure values based on source/sink temperatures

### NonFunctional Requirements

**NFR1:** Steady State convergence time < **1 second** for standard cycle in Cold Start

**NFR2:** Simple cycle (Single-stage) solved in **< 100 ms**

**NFR3:** Complex cycle (Multi-circuits) solved in **< 1 second**

**NFR4:** No dynamic allocation in solver loop (pre-calculated allocation only)

**NFR5:** Guaranteed determinism: same inputs → same results within 1e-9 precision on all platforms (x86, ARM, WASM)

**NFR6:** HIL latency < **20 ms** for real-time integration with PLC

**NFR7:** Zero-Panic Policy: no crash even with invalid inputs or impossible states

**NFR8:** Memory Safety guaranteed by Rust ownership system (no memory leaks, no use-after-free)

**NFR9:** Capability to run **48h+** without interruption or degradation (HIL/Embedded)

**NFR10:** Graceful error handling: timeout, non-convergence, saturation return explicit Result<T, Error>

**NFR11:** CoolProp 6.4+ compatibility for fluid properties

**NFR12:** Stable C FFI: auto-generated .h headers via cbindgen, C99/C++ compatible

**NFR13:** Deterministic WebAssembly: same behavior as native, no non-determinism sources

**NFR14:** Python bindings PyO3: tespy-compatible API for facilitated migration

**NFR15:** 100% documentation of public APIs (rustdoc)

**NFR16:** Automated CI/CD: tests, benchmarks, memory checks (Valgrind + Miri)

**NFR17:** Zero tolerance warnings: `cargo clippy -- -D warnings`

### Additional Requirements

**Architecture Requirements:**

- Workspace-based multi-crate architecture with 4 crates (core, solver, components, fluids) and 3 bindings (python, c, wasm)
- Trait-based static polymorphism with enum dispatch for zero-cost abstraction
- NewType pattern for all physical quantities (Pressure, Temperature, Enthalpy, MassFlow) - never bare f64 in public APIs
- Type-State pattern for connection safety at compile-time
- Pre-allocated buffers only - no heap allocation in hot paths
- `#![deny(warnings)]` in lib.rs for all crates
- KaTeX configuration in `.cargo/config.toml` for mathematical documentation
- `tracing` for structured logging (never println!)
- `thiserror` for error handling with ThermoError enum
- `approx` crate for floating-point assertions with explicit tolerances
- Sys-crate pattern for CoolProp C++ integration
- cbindgen for C header generation
- Miri validation in CI for undefined behavior detection
- Mass balance tolerance: 1e-9 kg/s
- Energy balance tolerance: 1e-6 kW
- Convergence pressure tolerance: 1 Pa

**Standards Compliance:**

- AHRI 540 standard implementation for compressor modeling with manufacturer coefficients (Bitzer, Copeland, Danfoss)
- NIST REFPROP as gold standard for fluid properties
- CoolProp as open-source reference
- Tabular interpolation achieving < 0.01% deviation from NIST while being 100x faster than direct EOS calls

**Domain-Specific Requirements:**

- Critical Point handling (CO2 R744) with automatic damping to prevent NaN in partial derivatives
- Temperature Glide handling for zeotropic mixtures (R454B, R32/R125) integrating Bubble Point → Dew Point without approximation
- Traçability: Each SimulationResult contains solver_version, fluid_backend version, input_hash (SHA-256)
- Smart initialization heuristic for initial pressure guesses based on source/sink temperatures

**CI/CD Requirements:**

- `cargo test`: Unit tests
- `cargo bench`: Performance regression (failure if > 5% degradation)
- `valgrind`: Memory leaks (FFI)
- `cargo clippy -- -D warnings`: Zero tolerance style
- `miri test`: Undefined behavior detection
- 100% public documentation coverage
- Compiled and tested examples in CI

**Packaging & Distribution:**

- Rust: crates.io
- Python: pip install rust-thermo-cycle (Wheels PyPI, manylinux)
- C/C++: Headers + dynamic libraries
- Docker: Image rust-thermo-lab (JupyterLab + Rust kernel + CoolProp)

### FR Coverage Map

| FR | Epic | Description |
|----|------|-------------|
| FR1 | Epic 1 | Compressor AHRI 540 modeling |
| FR2 | Epic 1 | Condenser heat transfer |
| FR3 | Epic 1 | Expansion valve isenthalpic |
| FR4 | Epic 1 | Evaporator phase change |
| FR5 | Epic 1 | Economizer with bypass |
| FR6 | Epic 1 | Component states ON/OFF/BYPASS |
| FR7 | Epic 1 | Zero mass flow in OFF mode |
| FR8 | Epic 1 | Adiabatic pipe in BYPASS mode |
| FR9 | Epic 3 | Multi-circuit machine definition |
| FR10 | Epic 3 | Component connection via Ports |
| FR11 | Epic 3 | Thermal coupling between circuits |
| FR12 | Epic 3 | Simultaneous/sequential circuit solving |
| FR13 | Epic 3 | Zero-flow branch handling |
| FR14 | Epic 4 | Newton-Raphson solver |
| FR15 | Epic 4 | Sequential Substitution solver |
| FR16 | Epic 4 | Auto-fallback solver switching |
| FR17 | Epic 4 | Configurable timeout |
| FR18 | Epic 4 | Best state on timeout |
| FR19 | Epic 4 | Jacobian freezing |
| FR20 | Epic 4 | Delta Pressure < 1 Pa convergence |
| FR21 | Epic 4 | Global multi-circuit convergence |
| FR22 | Epic 5 | Output constraints definition |
| FR23 | Epic 5 | Bounded input calculation |
| FR24 | Epic 5 | One-shot inverse control |
| FR25 | Epic 2 | CoolProp integration |
| FR26 | Epic 2 | Tabular interpolation tables |
| FR27 | Epic 2 | Pure fluids and mixtures support |
| FR28 | Epic 2 | Temperature glide handling |
| FR29 | Epic 2 | Critical point damping |
| FR30 | Epic 6 | Native Rust API |
| FR31 | Epic 6 | Python PyO3 bindings |
| FR32 | Epic 6 | C FFI bindings |
| FR33 | Epic 6 | WebAssembly support |
| FR34 | Epic 6 | CLI for batch execution |
| FR35 | Epic 7 | Mass balance validation |
| FR36 | Epic 7 | Energy balance validation |
| FR37 | Epic 7 | Traceability metadata |
| FR38 | Epic 7 | Debug verbose mode |
| FR39 | Epic 7 | Zero-panic error handling |
| FR40 | Epic 2 | Incompressible fluids support |
| FR41 | Epic 7 | JSON serialization |
| FR42 | Epic 4 | Smart initialization heuristic |

## Epic List

### Epic 1: Extensible Component Framework
**Goal:** Create the foundation that allows adding any component (VFD, Battery, Pump, Pipe) by simply implementing a Rust Trait, without touching the calculation engine.

**Innovation:** Trait-based "Lego" architecture to add Compressors, Pumps, VFDs, Pipes, etc.

**FRs covered:** FR1, FR2, FR3, FR4, FR5, FR6, FR7, FR8

---

### Epic 2: Fluid Properties Backend
**Goal:** Provide precise thermodynamic properties via CoolProp, tabular tables, mixture handling, and critical point management.

**Innovation:** 100x performance with tabular tables, automatic CO2 damping.

**FRs covered:** FR25, FR26, FR27, FR28, FR29, FR40

---

### Epic 3: System Topology (Graph)
**Goal:** Enable component assembly via Ports and manage multi-circuits with thermal coupling.

**Innovation:** Multi-fluid directed graph in a single model.

**FRs covered:** FR9, FR10, FR11, FR12, FR13

---

### Epic 4: Intelligent Solver Engine
**Goal:** Solve any system with < 1s guarantee, Newton-Raphson ↔ Sequential Substitution fallback.

**Innovation:** Solver-agnostic with intelligent fallback - guaranteed convergence.

**FRs covered:** FR14, FR15, FR16, FR17, FR18, FR19, FR20, FR21, FR42

---

### Epic 5: Inverse Control & Optimization
**Goal:** Transform component parameters (VFD speed, Valve position) into simultaneously solved unknowns.

**Innovation:** Native Inverse Control via Residual Embedding - "One-Shot".

**FRs covered:** FR22, FR23, FR24

---

### Epic 6: Multi-Platform APIs
**Goal:** Distribute the library via Python (PyO3), WebAssembly, C FFI, and CLI.

**Innovation:** Multi-target without code duplication (Rust → Python/WASM/C).

**FRs covered:** FR30, FR31, FR32, FR33, FR34

---

### Epic 7: Validation & Persistence
**Goal:** Guarantee trust via mass/energy balances, SHA-256 traceability, and JSON persistence.

**Innovation:** Complete traceability and scientific reproducibility.

**FRs covered:** FR35, FR36, FR37, FR38, FR39, FR41

---

<!-- ALL EPICS AND STORIES -->

## Epic 1: Extensible Component Framework

### Story 1.1: Component Trait Definition

**As a** library developer,
**I want** to define a generic Component trait with methods for residuals, ports, and state management,
**So that** future components can be implemented by simply implementing this trait.

**Acceptance Criteria:**

**Given** a new component struct
**When** it implements the Component trait
**Then** it must provide compute_residuals(), get_ports(), and get_state() methods
**And** the trait must be object-safe for dynamic dispatch

---

### Story 1.2: Physical Types (NewType Pattern)

**As a** simulation user,
**I want** type-safe physical quantities (Pressure, Temperature, Enthalpy, MassFlow),
**So that** I cannot accidentally mix units.

**Acceptance Criteria:**

**Given** a function accepting Pressure and Temperature
**When** I try to pass Temperature where Pressure is expected
**Then** the code must not compile (compile-time safety)
**And** conversions must be explicit (e.g., pressure_bar.to_pascals())

---

### Story 1.3: Port and Connection System

**As a** system modeler,
**I want** to define inlet/outlet ports for components and connect them bidirectionally,
**So that** I can build fluid circuit topologies.

**Acceptance Criteria:**

**Given** two components with compatible ports
**When** I call connect(port_a, port_b)
**Then** the connection is established with state validation
**And** attempting to connect incompatible ports fails at compile-time

---

### Story 1.4: Compressor Component (AHRI 540)

**As a** thermodynamic engineer,
**I want** to model a compressor using AHRI 540 standard coefficients,
**So that** I can simulate real compressor behavior with manufacturer data.

**Acceptance Criteria:**

**Given** a compressor with 10 AHRI 540 coefficients
**When** I compute residuals for a given operating point
**Then** the power consumption and mass flow are calculated per AHRI 540 equations
**And** the result matches certified AHRI test data within 1%

---

### Story 1.5: Generic Heat Exchanger Framework

**As a** thermal systems engineer,
**I want** a pluggable heat exchanger framework supporting multiple calculation models (Pinch point, LMTD, ε-NTU),
**So that** I can add new exchanger types without modifying the solver.

**Acceptance Criteria:**

**Given** a heat exchanger component
**When** I plug in a calculation model (Pinch, LMTD, or ε-NTU)
**Then** the residuals are computed using the selected model
**And** new models can be added by implementing a HeatTransferModel trait
**And** Condenser, Evaporator, and Economizer are implemented as specific configurations

---

### Story 1.6: Expansion Valve Component

**As a** control engineer,
**I want** to model an expansion valve with isenthalpic expansion,
**So that** I can simulate pressure reduction in the refrigeration cycle.

**Acceptance Criteria:**

**Given** an expansion valve with inlet subcooled liquid at high pressure
**When** I compute residuals
**Then** the outlet is two-phase or saturated liquid at lower pressure
**And** enthalpy is conserved (h_in = h_out)

---

### Story 1.7: Component State Machine

**As a** simulation user,
**I want** components to support ON, OFF, and BYPASS states,
**So that** I can simulate system configurations and failures.

**Acceptance Criteria:**

**Given** a component in ON state
**When** I switch it to OFF
**Then** it contributes zero mass flow to the system
**And** when in BYPASS, it behaves as an adiabatic pipe (P_in = P_out, h_in = h_out)

---

### Story 1.8: Auxiliary & Transport Components

**As a** system integrator,
**I want** to model Pumps, VFDs, and Pipes,
**So that** I can simulate complete HVAC systems.

**Acceptance Criteria:**

**Given** a Pump with specified hydraulic efficiency
**When** I compute residuals
**Then** power consumption and pressure rise match the pump curve
**And** a VFD can modify Pump or Compressor speed via affinity laws
**And** a Pipe calculates pressure drop via Darcy-Weisbach

---

## Epic 2: Fluid Properties Backend

### Story 2.1: Fluid Backend Trait Abstraction

**As a** library developer,
**I want** to define a FluidBackend trait,
**So that** the solver can switch between CoolProp, tabular, and mock backends.

**Acceptance Criteria:**

**Given** a fluid property query
**When** I call backend.property(fluid, property, state)
**Then** it returns correct values regardless of backend implementation
**And** CoolPropBackend, TabularBackend, and TestBackend all implement the trait

---

### Story 2.2: CoolProp Integration (sys-crate)

**As a** simulation user,
**I want** CoolProp as the primary backend,
**So that** I get NIST-quality thermodynamic data.

**Acceptance Criteria:**

**Given** a refrigerant and thermodynamic state
**When** I query via CoolPropBackend
**Then** results match CoolProp 6.4+ within machine precision
**And** C++ CoolProp is statically linked via sys-crate

---

### Story 2.3: Tabular Interpolation Backend

**As a** performance-critical user,
**I want** pre-computed NIST tables with fast interpolation,
**So that** queries are 100x faster than direct EOS.

**Acceptance Criteria:**

**Given** a tabular data file for a fluid
**When** I query via TabularBackend
**Then** results deviate < 0.01% from NIST REFPROP
**And** query time is < 1μs

---

### Story 2.4: LRU Cache for Fluid Properties

**As a** solver developer,
**I want** lock-free or thread-local caching,
**So that** redundant calculations are avoided without mutex contention.

**Acceptance Criteria:**

**Given** repeated property queries
**When** cache is enabled
**Then** Thread-Local or lock-free (dashmap) caching is used
**And** no mutex contention under high parallelism (Rayon)
**And** cache invalidates on state changes

---

### Story 2.5: Mixture and Temperature Glide Support

**As a** refrigeration engineer,
**I want** robust (P, h) and (P, x) inputs for zeotropic mixtures,
**So that** the solver handles temperature glide reliably.

**Acceptance Criteria:**

**Given** a zeotropic mixture at constant pressure
**When** calculating evaporation
**Then** temperature glide from bubble to dew point is correct
**And** backend supports (P, h) and (P, x) inputs robustly
**And** (P, h) is preferred over (P, T) for two-phase mixtures

---

### Story 2.6: Critical Point Damping (CO2 R744)

**As a** CO2 systems designer,
**I want** smooth, differentiable damping near critical point,
**So that** Newton-Raphson converges without discontinuities.

**Acceptance Criteria:**

**Given** CO2 near critical point (Tc=304.13K, Pc=7.3773 MPa)
**When** querying within 5% of critical point
**Then** damping is applied to partial derivatives
**And** no NaN values
**And** damping function is C1-continuous (sigmoid transition)

---

### Story 2.7: Incompressible Fluids Support

**As a** HVAC engineer,
**I want** water, glycol, and moist air as incompressible fluids,
**So that** heat sources/sinks are fast to compute.

**Acceptance Criteria:**

**Given** an incompressible fluid
**When** querying density, Cp, or enthalpy
**Then** lightweight polynomial models are used
**And** results match references within 0.1%
**And** computation is 1000x faster than compressible EOS

---

## Epic 3: System Topology (Graph)

### Story 3.1: System Graph Structure

**As a** system modeler,
**I want** edges to index the solver's state vector,
**So that** P and h unknowns assemble into the Jacobian.

**Acceptance Criteria:**

**Given** components with ports
**When** adding to System graph
**Then** edges serve as indices into solver's state vector
**And** each flow edge represents P and h unknowns
**And** solver traverses graph to assemble Jacobian
**And** cycles are detected and validated

---

### Story 3.2: Port Compatibility Validation

**As a** system designer,
**I want** port connection validation at build time,
**So that** incompatible connections are caught early.

**Acceptance Criteria:**

**Given** two ports with incompatible fluids
**When** attempting to connect
**Then** connection fails with clear error
**And** valid connections are accepted
**And** pressure/enthalpy continuity is enforced

---

### Story 3.3: Multi-Circuit Machine Definition

**As a** R&D engineer (Marie),
**I want** machines with N independent circuits,
**So that** I simulate complex heat pumps.

**Acceptance Criteria:**

**Given** a machine with 2+ circuits
**When** defining topology
**Then** each circuit is tracked independently
**And** circuits can be solved simultaneously or sequentially
**And** supports up to N=5 circuits

---

### Story 3.4: Thermal Coupling Between Circuits

**As a** systems engineer,
**I want** thermal coupling with circular dependency detection,
**So that** solver knows to solve simultaneously vs sequentially.

**Acceptance Criteria:**

**Given** two circuits with a heat exchanger
**When** defining thermal coupling
**Then** heat transfer equations link circuits
**And** energy is conserved (Q_hot = -Q_cold)
**And** circular dependencies force simultaneous solving
**And** coupling represented as additional residuals

---

### Story 3.5: Zero-Flow Branch Handling

**As a** simulation user,
**I want** zero-flow handling with regularization,
**So that** OFF components don't cause numerical instabilities.

**Acceptance Criteria:**

**Given** a branch with mass flow = 0
**When** computing residuals
**Then** no division-by-zero
**And** regularization applied (ε minimum in divisions)
**And** auto-switch to pressure continuity when OFF
**And** Jacobian remains well-conditioned

---

## Epic 4: Intelligent Solver Engine

### Story 4.1: Solver Trait Abstraction

**As a** numerical developer,
**I want** a generic Solver trait,
**So that** strategies are interchangeable.

**Acceptance Criteria:**

**Given** a system of equations
**When** instantiating solver strategies
**Then** all implement common Solver trait
**And** provides solve() and with_timeout() methods
**And** zero-cost abstraction via enum dispatch

---

### Story 4.2: Newton-Raphson Implementation

**As a** simulation engineer,
**I want** Newton-Raphson with analytical Jacobian support,
**So that** HIL performance is optimized.

**Acceptance Criteria:**

**Given** a system with residuals
**When** running Newton-Raphson
**Then** quadratic convergence near solution
**And** line search prevents overshooting
**And** supports both numerical and analytical Jacobian
**And** components provide analytical Jacobian entries

---

### Story 4.3: Sequential Substitution (Picard) Implementation

**As a** fallback solver user,
**I want** Sequential Substitution for robust convergence,
**So that** when Newton diverges, I have a stable alternative.

**Acceptance Criteria:**

**Given** a system where Newton diverges
**When** using Sequential Substitution
**Then** it converges reliably
**And** variables updated sequentially
**And** relaxation factors configurable

---

### Story 4.4: Intelligent Fallback Strategy

**As a** simulation user,
**I want** automatic fallback with smart return conditions,
**So that** convergence is guaranteed without solver oscillation.

**Acceptance Criteria:**

**Given** Newton-Raphson diverging
**When** divergence detected (> 3 increasing residuals)
**Then** auto-switch to Sequential Substitution
**And** return to Newton ONLY when convergence radius reached
**And** prevent oscillation by requiring stable Picard first

---

### Story 4.5: Time-Budgeted Solving

**As a** HIL engineer (Sarah),
**I want** strict timeout with graceful degradation,
**So that** real-time constraints are never violated.

**Acceptance Criteria:**

**Given** solver with timeout = 1000ms
**When** time budget exceeded
**Then** solver stops immediately
**And** returns best state with ComputationStatus::Timeout
**And** for HIL, returns previous state with ZOH

---

### Story 4.6: Smart Initialization Heuristic

**As a** R&D engineer (Marie),
**I want** automatic initial guesses from temperatures,
**So that** cold start convergence is fast.

**Acceptance Criteria:**

**Given** source and sink temperatures
**When** initializing system
**Then** pressures estimated via Antoine equation
**And** evaporator pressure < P_critical
**And** condenser pressure from T_sink + ΔT_approach

---

### Story 4.7: Convergence Criteria & Validation

**As a** simulation user,
**I want** strict criteria with sparse Jacobian for multi-circuit,
**So that** large systems remain tractable.

**Acceptance Criteria:**

**Given** system approaching solution
**When** checking convergence
**Then** max |ΔP| < 1 Pa
**And** mass error < 1e-9 kg/s, energy < 1e-6 kW
**And** ALL circuits converge for global convergence
**And** Jacobian uses sparse/block structure
**And** uncoupled circuits give block-diagonal

---

### Story 4.8: Jacobian-Freezing Optimization

**As a** performance-critical user,
**I want** to freeze Jacobian updates,
**So that** CPU time is reduced.

**Acceptance Criteria:**

**Given** nearly-converged system
**When** Jacobian freezing enabled
**Then** Jacobian computed once, reused
**And** speed increases ~80%
**And** auto-disabled if residuals increase

---

## Epic 5: Inverse Control & Optimization

### Story 5.1: Constraint Definition Framework

**As a** control engineer,
**I want** to define output constraints,
**So that** I specify target operating conditions.

**Acceptance Criteria:**

**Given** measurable outputs
**When** defining constraint (output - target = 0)
**Then** constraint added to residuals
**And** can reference any component output
**And** multiple constraints supported

---

### Story 5.2: Bounded Control Variables

**As a** control engineer,
**I want** Box Constraints or Step Clipping,
**So that** Newton steps stay physically possible.

**Acceptance Criteria:**

**Given** control variable with bounds [min, max]
**When** computing Newton step (Δx)
**Then** step scaled/clipped if exceeding bounds
**And** variable never outside bounds during iterations
**And** ControlSaturation error if converged solution exceeds bounds

---

### Story 5.3: Residual Embedding for Inverse Control

**As a** systems engineer,
**I want** constraints embedded with DoF validation,
**So that** system is well-posed.

**Acceptance Criteria:**

**Given** constraint and control variable
**When** solving system
**Then** residual added to residual vector
**And** control variable added to unknowns
**And** solved simultaneously (one-shot)
**And** Jacobian includes ∂constraint/∂control
**And** DoF validated (equations = unknowns)
**And** OverConstrainedSystem error if mismatch

---

### Story 5.4: Multi-Variable Control

**As a** control engineer,
**I want** to control multiple outputs simultaneously,
**So that** I optimize complete operation.

**Acceptance Criteria:**

**Given** multiple constraints
**When** defining control problem
**Then** each constraint maps to one control variable
**And** all solved simultaneously
**And** all constraints satisfied within tolerance

---

## Epic 6: Multi-Platform APIs

### Story 6.1: Rust Native API

**As a** Rust developer,
**I want** clean, idiomatic Rust API,
**So that** I integrate into Rust applications.

**Acceptance Criteria:**

**Given** a Rust application
**When** using entropyk crate
**Then** builder pattern for systems
**And** all functions return Result<T, ThermoError>
**And** follows Rust conventions
**And** KaTeX documentation

---

### Story 6.2: Python Bindings (PyO3)

**As a** Python data scientist (Alice),
**I want** zero-copy NumPy support,
**So that** 100x speedup isn't wasted on conversion.

**Acceptance Criteria:**

**Given** Python script with rust_thermo_cycle
**When** creating components
**Then** API similar to tespy
**And** errors mapped to Python exceptions
**And** wheels on PyPI (manylinux)
**And** Buffer Protocol and NumPy arrays supported
**And** zero-copy for 10k+ element vectors
**And** 100x faster than tespy

---

### Story 6.3: C FFI Bindings (cbindgen)

**As a** HIL engineer (Sarah),
**I want** C headers with explicit memory management,
**So that** PLC integration has no memory leaks.

**Acceptance Criteria:**

**Given** C/C++ application
**When** including headers
**Then** extern "C" interface available
**And** headers auto-generated via cbindgen
**And** error codes as enum values
**And** opaque pointers for complex types
**And** every allocation has free function (e.g., entropyk_free_system)
**And** latency < 20ms

---

### Story 6.4: WebAssembly Compilation

**As a** web developer (Charlie),
**I want** WASM with TabularBackend default,
**So that** it works without CoolProp in browser.

**Acceptance Criteria:**

**Given** web application
**When** importing WASM module
**Then** can create and solve in browser
**And** results JSON-serializable
**And** deterministic performance
**And** package on npm
**And** defaults to TabularBackend (CoolProp unavailable in WASM)
**And** works out-of-box in Chrome/Edge
**And** cycle time < 100ms

---

### Story 6.5: CLI for Batch Execution

**As a** data engineer (David),
**I want** CLI for batch simulations,
**So that** I process millions of scenarios.

**Acceptance Criteria:**

**Given** JSON config file
**When** running entropyk-cli run config.json
**Then** simulation executes
**And** outputs results to JSON
**And** batch mode supports parallel execution
**And** progress reported
**And** exit codes indicate success/failure

---

## Epic 7: Validation & Persistence

### Story 7.1: Mass Balance Validation

**As a** simulation engineer,
**I want** automatic mass conservation verification,
**So that** I trust physical correctness.

**Acceptance Criteria:**

**Given** converged solution
**When** computing mass balance
**Then** error Σ ṁ_in - Σ ṁ_out < 1e-9 kg/s
**And** violations trigger validation error
**And** check performed after every solve

---

### Story 7.2: Energy Balance Validation

**As a** simulation engineer,
**I want** First AND Second Law verification,
**So that** thermodynamic consistency is guaranteed.

**Acceptance Criteria:**

**Given** converged solution
**When** computing balances
**Then** energy error < 1e-6 kW
**And** violations trigger error with breakdown
**And** Second Law check: entropy generation ≥ 0
**And** warning if negative entropy destruction
**And** violations flagged

---

### Story 7.3: Traceability Metadata

**As a** researcher (Robert),
**I want** complete traceability metadata,
**So that** simulations are reproducible.

**Acceptance Criteria:**

**Given** simulation result
**When** accessing metadata
**Then** includes solver_version, fluid_backend_version, input_hash (SHA-256)
**And** SHA-256 uniquely identifies input
**And** metadata in structured JSON

---

### Story 7.4: Debug Verbose Mode

**As a** researcher (Robert),
**I want** detailed convergence diagnostics,
**So that** I debug non-converging systems.

**Acceptance Criteria:**

**Given** non-converging system
**When** verbose mode enabled
**Then** residuals logged each iteration
**And** Jacobian condition number reported
**And** solver switches logged
**And** final state dumped

---

### Story 7.5: JSON Serialization & Deserialization

**As a** system designer,
**I want** complete system serialization with backend definition,
**So that** models are reproducible across machines.

**Acceptance Criteria:**

**Given** system with components, connections, parameters
**When** serializing to JSON
**Then** complete state saved (Topology + Parameters + Fluid State)
**And** fluid backend fully included (version, hash)
**And** deserialization reconstructs identical system
**And** round-trip produces identical results
**And** human-readable, versioned format
**And** explicit error if backend missing on load
**And** error specifies required backend version
