Entropyk/_bmad-output/implementation-artifacts/6-5-cli-for-batch-execution.md

267 lines
9.4 KiB
Markdown

# Story 6.5: CLI for Batch Execution
Status: done
## Story
As a **data engineer (David)**,
I want **a command-line interface for batch thermodynamic simulations**,
So that **I can process millions of scenarios programmatically without manual intervention**.
## Acceptance Criteria
1. **Given** a JSON configuration file defining a thermodynamic system
**When** running `entropyk-cli run config.json`
**Then** the simulation executes successfully
**And** results are written to a JSON output file
2. **Given** a directory of multiple configuration files
**When** running `entropyk-cli batch ./scenarios/`
**Then** all simulations execute in parallel
**And** progress is reported to stdout
**And** individual failures don't stop the batch
3. **Given** a simulation execution
**When** the process completes
**Then** exit code 0 indicates success
**And** exit code 1 indicates simulation error
**And** exit code 2 indicates configuration error
4. **Given** the CLI binary
**When** running `entropyk-cli --help`
**Then** comprehensive usage documentation is displayed
**And** all commands and options are documented
5. **Given** a large batch job
**When** running with `--parallel N` option
**Then** N simulations run concurrently
**And** CPU utilization scales appropriately
## Tasks / Subtasks
- [x] Task 1: Create CLI crate structure (AC: #1, #4)
- [x] 1.1 Create `crates/cli/Cargo.toml` with clap and workspace dependencies
- [x] 1.2 Create `crates/cli/src/main.rs` with clap-based argument parsing
- [x] 1.3 Create `crates/cli/src/lib.rs` for shared CLI logic
- [x] 1.4 Add `crates/cli` to workspace members in root Cargo.toml
- [x] 1.5 Configure binary target `name = "entropyk-cli"`
- [x] Task 2: Implement configuration parsing (AC: #1)
- [x] 2.1 Create `crates/cli/src/config.rs` - JSON configuration schema
- [x] 2.2 Define `ScenarioConfig` struct with serde derive
- [x] 2.3 Implement system construction from config (map components, edges, fluids)
- [x] 2.4 Add validation for required fields and sensible defaults
- [x] Task 3: Implement single simulation command (AC: #1, #3)
- [x] 3.1 Create `run` subcommand handler
- [x] 3.2 Load config, build system, run solver
- [x] 3.3 Serialize `ConvergedState` to JSON output
- [x] 3.4 Implement proper exit codes (success=0, sim-error=1, config-error=2)
- [x] Task 4: Implement batch execution command (AC: #2, #5)
- [x] 4.1 Create `batch` subcommand handler
- [x] 4.2 Scan directory for `.json` config files
- [x] 4.3 Implement parallel execution with Rayon
- [x] 4.4 Add `--parallel N` option for concurrency control
- [x] 4.5 Collect and aggregate results
- [x] Task 5: Implement progress reporting (AC: #2)
- [x] 5.1 Add progress bar using `indicatif` crate
- [x] 5.2 Show current file, completed count, error count
- [x] 5.3 Support `--quiet` flag to suppress output
- [x] 5.4 Support `--verbose` flag for detailed logging
- [x] Task 6: Implement help and documentation (AC: #4)
- [x] 6.1 Add comprehensive `--help` with clap derive
- [x] 6.2 Create `crates/cli/README.md` with usage examples
- [x] 6.3 Add example configuration files in `examples/`
- [x] Task 7: Write tests and examples (AC: #1, #2, #3)
- [x] 7.1 Create `crates/cli/tests/config_parsing.rs`
- [x] 7.2 Create `crates/cli/tests/single_run.rs`
- [x] 7.3 Create `crates/cli/tests/batch_execution.rs`
- [x] 7.4 Add example configs in `examples/` directory
## Dev Notes
### Architecture Compliance
- **Crate Location**: `crates/cli/` (follows workspace structure)
- **Binary Name**: `entropyk-cli` (installable via `cargo install entropyk-cli`)
- **Dependencies**: Reuse `entropyk` facade crate for all simulation logic
- **Error Handling**: Use `anyhow` for CLI errors, map `ThermoError` appropriately
- **Observability**: Use `tracing-subscriber` with optional file logging
### CLI Structure Pattern
Follow clap derive pattern for clean argument parsing:
```rust
#[derive(Parser)]
#[command(name = "entropyk-cli")]
#[command(about = "Batch thermodynamic simulation CLI", long_about = None)]
struct Cli {
#[command(subcommand)]
command: Commands,
}
#[derive(Subcommand)]
enum Commands {
Run {
#[arg(short, long)]
config: PathBuf,
#[arg(short, long)]
output: Option<PathBuf>,
},
Batch {
#[arg(short, long)]
directory: PathBuf,
#[arg(short, long, default_value = "4")]
parallel: usize,
},
}
```
### Configuration Schema
```json
{
"fluid": "R134a",
"components": [
{
"type": "Compressor",
"name": "comp1",
"ahri_coefficients": [1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
},
{
"type": "Condenser",
"name": "cond1",
"ua": 5000.0
}
],
"edges": [
{"from": "comp1:outlet", "to": "cond1:inlet"}
],
"solver": {
"strategy": "fallback",
"max_iterations": 100,
"tolerance": 1e-6
}
}
```
### Project Structure Notes
- Binary crate separate from library crates
- Use `entropyk` facade crate to access all simulation functionality
- Follow patterns from existing demo binaries in `demo/src/bin/`
- Use `serde_json` for configuration and output
### Critical Constraints
1. **No Panics**: All errors must return proper exit codes
2. **Memory Efficient**: Process large batches without memory growth
3. **Deterministic Output**: Same config → same JSON output
4. **Progress Visibility**: User must know batch progress
### References
- [Source: _bmad-output/planning-artifacts/epics.md#L1122-L1137] - Story 6.5 acceptance criteria
- [Source: _bmad-output/planning-artifacts/architecture.md#L36-L44] - Technical stack
- [Source: crates/entropyk/src/lib.rs] - Facade crate API
- [Source: demo/src/bin/chiller.rs] - Example simulation binary
- [Source: bindings/python/src/lib.rs] - Reference for JSON serialization patterns
### Previous Story Intelligence
From Story 6.1 (Rust Native API):
- Top-level `entropyk` crate provides unified facade
- `SystemBuilder` pattern for system construction
- `ThermoError` unified error handling
- All components implement serialization
From Story 6.4 (WebAssembly):
- JSON serialization pattern for results
- ConvergedState serialization approach
### Exit Code Convention
| Code | Meaning |
|------|---------|
| 0 | Success |
| 1 | Simulation error (non-convergence, validation failure) |
| 2 | Configuration error (invalid JSON, missing fields) |
| 3 | I/O error (file not found, permission denied) |
## Dev Agent Record
### Agent Model Used
zai-coding-plan/glm-5
### Debug Log References
- Pre-existing compilation errors in `entropyk-components/src/python_components.rs` blocking full test execution
- These errors are NOT related to the CLI crate implementation
- CLI crate (`cargo check -p entropyk-cli`) passes compilation successfully
### Completion Notes List
- Created complete CLI crate structure following Python/C binding patterns
- Implemented `run` subcommand for single simulation execution
- Implemented `batch` subcommand for parallel batch processing with Rayon
- Implemented `validate` subcommand for configuration validation
- Added progress bar with indicatif for batch processing
- Added comprehensive --help documentation with clap derive
- Created README.md with usage examples
- Added example configuration files (simple_cycle.json, heat_pump.json)
- Created unit tests for config parsing, single run, and batch execution
- Added proper exit codes per the specification (0=success, 1=sim-error, 2=config-error, 3=io-error)
### File List
- `crates/cli/Cargo.toml` (new)
- `crates/cli/src/lib.rs` (new)
- `crates/cli/src/main.rs` (new)
- `crates/cli/src/config.rs` (new)
- `crates/cli/src/error.rs` (new)
- `crates/cli/src/run.rs` (new)
- `crates/cli/src/batch.rs` (new)
- `crates/cli/README.md` (new)
- `crates/cli/examples/simple_cycle.json` (new)
- `crates/cli/examples/heat_pump.json` (new)
- `crates/cli/tests/config_parsing.rs` (new)
- `crates/cli/tests/single_run.rs` (new)
- `crates/cli/tests/batch_execution.rs` (new)
- `Cargo.toml` (modified - added cli to workspace members)
## Senior Developer Review (AI)
### Review Date: 2026-02-22
### Issues Found and Fixed
1. **[FIXED] HIGH - Solver strategy was ignored**: The `config.solver.strategy` field was parsed but not used. Now correctly uses `newton`, `picard`, or `fallback` based on config.
2. **[FIXED] MEDIUM - Edge validation incomplete**: Edge format validation checked `component:port` format but didn't verify component names exist. Now validates that all edge references point to existing components.
3. **[FIXED] MEDIUM - Example configs invalid**: Example configs contained `ExpansionValve` which requires connected ports and cannot be created via JSON config. Updated examples to use only supported components.
4. **[FIXED] LOW - Author hardcodé**: Changed from hardcoded author string to use clap's `#[command(author)]` which reads from Cargo.toml.
5. **[DOCUMENTED] Component Limitations**: `ExpansionValve` and `Compressor` require connected ports and are not supported in JSON configs. This is now clearly documented in README and error messages.
### Test Results
- All CLI lib tests pass (9 tests)
- Config parsing tests pass with new edge validation
- Batch execution tests pass
- Single run tests pass
### Recommendations for Future Work
- Add `Compressor` support with AHRI 540 coefficients
- Add `ExpansionValve` support with port auto-connection
- Add integration tests that execute actual simulations
- Consider recursive directory scanning for batch mode