Simulation Orchestrator
Goal
Provide tools to manage multi-simulation campaigns: generate parameter sweeps, track job execution status, and aggregate results from completed runs.
Requirements
- Python 3.10+
- No external dependencies (uses Python standard library only)
- Works on Linux, macOS, and Windows
Inputs to Gather
Before running orchestration scripts, collect from the user:
| Input |
Description |
Example |
| Base config |
Template simulation configuration |
base_config.json |
| Parameter ranges |
Parameters to sweep with bounds |
dt:[1e-4,1e-2],kappa:[0.1,1.0] |
| Sweep method |
How to sample parameter space |
grid, lhs, linspace |
| Output directory |
Where to store campaign files |
./campaign_001 |
| Simulation command |
Command to run each simulation |
python sim.py --config {config} |
Decision Guidance
Choosing a Sweep Method
Need every combination (full factorial)?
├── YES → Use grid (warning: exponential growth with parameters)
└── NO → Is space-filling coverage needed?
├── YES → Use lhs (Latin Hypercube Sampling)
└── NO → Use linspace for uniform sampling per parameter
| Method |
Best For |
Sample Count |
grid |
Low dimensions (1-3), need exact corners |
n^d (exponential) |
linspace |
1D sweeps, uniform spacing |
n per parameter |
lhs |
High dimensions, space-filling |
user-specified budget |
Campaign Size Guidelines
| Parameters |
Grid Points Each |
Total Runs |
Recommendation |
| 1 |
10 |
10 |
Grid is fine |
| 2 |
10 |
100 |
Grid acceptable |
| 3 |
10 |
1,000 |
Consider LHS |
| 4+ |
10 |
10,000+ |
Use LHS or DOE |
Script Outputs (JSON Fields)
| Script |
Output Fields |
scripts/sweep_generator.py |
configs, parameter_space, sweep_method, total_runs |
scripts/campaign_manager.py |
campaign_id, status, jobs, progress |
scripts/job_tracker.py |
job_id, status, start_time, end_time, exit_code |
scripts/result_aggregator.py |
summary, statistics, best_run, failed_runs |
Workflow
Step 1: Generate Parameter Sweep
Create configurations for all parameter combinations:
python3 scripts/sweep_generator.py \
--base-config base_config.json \
--params "dt:1e-4:1e-2:5,kappa:0.1:1.0:3" \
--method linspace \
--output-dir ./campaign_001 \
--json
Step 2: Initialize Campaign
Create campaign tracking structure:
python3 scripts/campaign_manager.py \
--action init \
--config-dir ./campaign_001 \
--command "python sim.py --config {config}" \
--json
Step 3: Track Job Status
Monitor running jobs:
python3 scripts/job_tracker.py \
--campaign-dir ./campaign_001 \
--update \
--json
Step 4: Aggregate Results
Combine results from completed runs:
python3 scripts/result_aggregator.py \
--campaign-dir ./campaign_001 \
--metric objective_value \
--json
CLI Examples
# Generate 5x3=15 runs varying dt (5 values) and kappa (3 values)
python3 scripts/sweep_generator.py \
--base-config sim.json \
--params "dt:1e-4:1e-2:5,kappa:0.1:1.0:3" \
--method linspace \
--output-dir ./sweep_001 \
--json
# Generate LHS samples for 4 parameters with budget of 20 runs
python3 scripts/sweep_generator.py \
--base-config sim.json \
--params "dt:1e-4:1e-2,kappa:0.1:1.0,M:1e-6:1e-4,W:0.5:2.0" \
--method lhs \
--samples 20 \
--output-dir ./lhs_001 \
--json
# Check campaign status
python3 scripts/campaign_manager.py \
--action status \
--config-dir ./sweep_001 \
--json
# Get summary statistics from completed runs
python3 scripts/result_aggregator.py \
--campaign-dir ./sweep_001 \
--metric final_energy \
--json
Conversational Workflow Example
User: I want to run a parameter sweep on dt and kappa for my phase-field simulation. I want to try 5 values of dt between 1e-4 and 1e-2, and 4 values of kappa between 0.1 and 1.0.
Agent workflow:
- Calculate total runs: 5 x 4 = 20 runs
- Generate sweep configurations:
python3 scripts/sweep_generator.py \
--base-config simulation.json \
--params "dt:1e-4:1e-2:5,kappa:0.1:1.0:4" \
--method linspace \
--output-dir ./dt_kappa_sweep \
--json
- Initialize campaign:
python3 scripts/campaign_manager.py \
--action init \
--config-dir ./dt_kappa_sweep \
--command "python phase_field.py --config {config}" \
--json
- After user runs simulations, aggregate results:
python3 scripts/result_aggregator.py \
--campaign-dir ./dt_kappa_sweep \
--metric interface_width \
--json
Error Handling
| Error |
Cause |
Resolution |
Base config not found |
Invalid file path |
Verify base config file exists |
Invalid parameter format |
Malformed param string |
Use format name:min:max:count or name:min:max |
Output directory exists |
Would overwrite |
Use --force or choose new directory |
No completed jobs |
No results to aggregate |
Wait for jobs to complete or check for failures |
Metric not found |
Result files missing field |
Verify metric name in result JSON |
Integration with Other Skills
The simulation-orchestrator works with other simulation-workflow skills:
parameter-optimization simulation-orchestrator
│ │
│ DOE samples ────────────────>│ Generate configs
│ │
│ │ Run simulations
│ │
│<──────────────────────────── │ Aggregate results
│ │
│ Sensitivity analysis │
│ Optimizer selection │
Typical Combined Workflow
- Use
parameter-optimization/doe_generator.py to get sample points
- Use
simulation-orchestrator/sweep_generator.py to create configs
- Run simulations (user's responsibility)
- Use
simulation-orchestrator/result_aggregator.py to collect results
- Use
parameter-optimization/sensitivity_summary.py to analyze
Security
Input Validation
- Metric names are validated against
[a-zA-Z_][a-zA-Z0-9_.]* to prevent traversal or injection via crafted keys
campaign_manager.py validates command templates to reject shell chaining operators (;, |, &, backticks, $)
--params format strings are parsed and validated (name:min:max:count with finite numeric bounds and positive integer counts)
--method is validated against a fixed allowlist (grid, linspace, lhs)
--samples is validated as a positive integer with an upper bound
--action is validated against a fixed allowlist (init, status)
File Access
sweep_generator.py reads a single base config file (JSON) specified by --base-config and writes generated configs to --output-dir
result_aggregator.py enforces a 10 MB file-size limit per result file, maximum JSON nesting depth, and strict numeric type checking (rejects bool, NaN, Inf)
- All string values from result files are sanitized (truncated, control characters stripped) before surfacing them
- Config paths interpolated into shell commands are validated against a safe-character allowlist and escaped with
shlex.quote()
Tool Restrictions
- Read: Used to inspect script source, references, base configs, and campaign status files
- Write: Used to save generated sweep configs, campaign manifests, and aggregated results; writes are scoped to the user's working directory
- Grep/Glob: Used to locate campaign files, result files, and search references
- The skill's
allowed-tools excludes Bash to prevent the agent from executing arbitrary commands when processing untrusted simulation outputs
Safety Measures
- No
eval(), exec(), or dynamic code generation
- All subprocess calls use explicit argument lists (no
shell=True)
- Reduced tool surface (no Bash) limits the agent to read/write operations only
- Command templates are validated but never executed by the skill itself; execution is the user's responsibility
Limitations
- Not a job scheduler: Does not submit jobs to SLURM/PBS; generates configs and tracks status
- No parallel execution: User must run simulations externally (can use GNU parallel, SLURM, etc.)
- File-based tracking: Status tracked via files; no database or real-time monitoring
- Local filesystem: Assumes all files accessible from local machine
References
references/campaign_patterns.md - Common campaign structures
references/sweep_strategies.md - Parameter sweep design guidance
references/aggregation_methods.md - Result aggregation techniques
Version History
- v1.0.0 (2024-12-24): Initial release with sweep, campaign, tracking, and aggregation
1---2name: simulation-orchestrator3description: Orchestrate multi-simulation campaigns — generate parameter sweep configurations (grid, linspace, or Latin Hypercube sampling), initialize and track batch job campaigns, monitor job completion status, and aggregate results with summary statistics across all runs. Use when running a parameter study across dt, kappa, or other simulation inputs, managing dozens or hundreds of simulation configurations, combining outputs from completed batch runs to find the best result, or automating the generate-run-collect workflow for systematic studies, even if the user only says "I need to try many parameter combinations" or "how do I organize a sweep."4---56# Simulation Orchestrator78## Goal910Provide tools to manage multi-simulation campaigns: generate parameter sweeps, track job execution status, and aggregate results from completed runs.1112## Requirements1314- Python 3.10+15- No external dependencies (uses Python standard library only)16- Works on Linux, macOS, and Windows1718## Inputs to Gather1920Before running orchestration scripts, collect from the user:2122| Input | Description | Example |23|-------|-------------|---------|24| Base config | Template simulation configuration | `base_config.json` |25| Parameter ranges | Parameters to sweep with bounds | `dt:[1e-4,1e-2],kappa:[0.1,1.0]` |26| Sweep method | How to sample parameter space | `grid`, `lhs`, `linspace` |27| Output directory | Where to store campaign files | `./campaign_001` |28| Simulation command | Command to run each simulation | `python sim.py --config {config}` |2930## Decision Guidance3132### Choosing a Sweep Method3334```35Need every combination (full factorial)?36├── YES → Use grid (warning: exponential growth with parameters)37└── NO → Is space-filling coverage needed?38 ├── YES → Use lhs (Latin Hypercube Sampling)39 └── NO → Use linspace for uniform sampling per parameter40```4142| Method | Best For | Sample Count |43|--------|----------|--------------|44| `grid` | Low dimensions (1-3), need exact corners | n^d (exponential) |45| `linspace` | 1D sweeps, uniform spacing | n per parameter |46| `lhs` | High dimensions, space-filling | user-specified budget |4748### Campaign Size Guidelines4950| Parameters | Grid Points Each | Total Runs | Recommendation |51|------------|------------------|------------|----------------|52| 1 | 10 | 10 | Grid is fine |53| 2 | 10 | 100 | Grid acceptable |54| 3 | 10 | 1,000 | Consider LHS |55| 4+ | 10 | 10,000+ | Use LHS or DOE |5657## Script Outputs (JSON Fields)5859| Script | Output Fields |60|--------|---------------|61| `scripts/sweep_generator.py` | `configs`, `parameter_space`, `sweep_method`, `total_runs` |62| `scripts/campaign_manager.py` | `campaign_id`, `status`, `jobs`, `progress` |63| `scripts/job_tracker.py` | `job_id`, `status`, `start_time`, `end_time`, `exit_code` |64| `scripts/result_aggregator.py` | `summary`, `statistics`, `best_run`, `failed_runs` |6566## Workflow6768### Step 1: Generate Parameter Sweep6970Create configurations for all parameter combinations:7172```bash73python3 scripts/sweep_generator.py \74 --base-config base_config.json \75 --params "dt:1e-4:1e-2:5,kappa:0.1:1.0:3" \76 --method linspace \77 --output-dir ./campaign_001 \78 --json79```8081### Step 2: Initialize Campaign8283Create campaign tracking structure:8485```bash86python3 scripts/campaign_manager.py \87 --action init \88 --config-dir ./campaign_001 \89 --command "python sim.py --config {config}" \90 --json91```9293### Step 3: Track Job Status9495Monitor running jobs:9697```bash98python3 scripts/job_tracker.py \99 --campaign-dir ./campaign_001 \100 --update \101 --json102```103104### Step 4: Aggregate Results105106Combine results from completed runs:107108```bash109python3 scripts/result_aggregator.py \110 --campaign-dir ./campaign_001 \111 --metric objective_value \112 --json113```114115## CLI Examples116117```bash118# Generate 5x3=15 runs varying dt (5 values) and kappa (3 values)119python3 scripts/sweep_generator.py \120 --base-config sim.json \121 --params "dt:1e-4:1e-2:5,kappa:0.1:1.0:3" \122 --method linspace \123 --output-dir ./sweep_001 \124 --json125126# Generate LHS samples for 4 parameters with budget of 20 runs127python3 scripts/sweep_generator.py \128 --base-config sim.json \129 --params "dt:1e-4:1e-2,kappa:0.1:1.0,M:1e-6:1e-4,W:0.5:2.0" \130 --method lhs \131 --samples 20 \132 --output-dir ./lhs_001 \133 --json134135# Check campaign status136python3 scripts/campaign_manager.py \137 --action status \138 --config-dir ./sweep_001 \139 --json140141# Get summary statistics from completed runs142python3 scripts/result_aggregator.py \143 --campaign-dir ./sweep_001 \144 --metric final_energy \145 --json146```147148## Conversational Workflow Example149150**User**: I want to run a parameter sweep on dt and kappa for my phase-field simulation. I want to try 5 values of dt between 1e-4 and 1e-2, and 4 values of kappa between 0.1 and 1.0.151152**Agent workflow**:1531. Calculate total runs: 5 x 4 = 20 runs1542. Generate sweep configurations:155 ```bash156 python3 scripts/sweep_generator.py \157 --base-config simulation.json \158 --params "dt:1e-4:1e-2:5,kappa:0.1:1.0:4" \159 --method linspace \160 --output-dir ./dt_kappa_sweep \161 --json162 ```1633. Initialize campaign:164 ```bash165 python3 scripts/campaign_manager.py \166 --action init \167 --config-dir ./dt_kappa_sweep \168 --command "python phase_field.py --config {config}" \169 --json170 ```1714. After user runs simulations, aggregate results:172 ```bash173 python3 scripts/result_aggregator.py \174 --campaign-dir ./dt_kappa_sweep \175 --metric interface_width \176 --json177 ```178179## Error Handling180181| Error | Cause | Resolution |182|-------|-------|------------|183| `Base config not found` | Invalid file path | Verify base config file exists |184| `Invalid parameter format` | Malformed param string | Use format `name:min:max:count` or `name:min:max` |185| `Output directory exists` | Would overwrite | Use `--force` or choose new directory |186| `No completed jobs` | No results to aggregate | Wait for jobs to complete or check for failures |187| `Metric not found` | Result files missing field | Verify metric name in result JSON |188189## Integration with Other Skills190191The simulation-orchestrator works with other simulation-workflow skills:192193```194parameter-optimization simulation-orchestrator195 │ │196 │ DOE samples ────────────────>│ Generate configs197 │ │198 │ │ Run simulations199 │ │200 │<──────────────────────────── │ Aggregate results201 │ │202 │ Sensitivity analysis │203 │ Optimizer selection │204```205206### Typical Combined Workflow2072081. Use `parameter-optimization/doe_generator.py` to get sample points2092. Use `simulation-orchestrator/sweep_generator.py` to create configs2103. Run simulations (user's responsibility)2114. Use `simulation-orchestrator/result_aggregator.py` to collect results2125. Use `parameter-optimization/sensitivity_summary.py` to analyze213214## Security215216### Input Validation217- Metric names are validated against `[a-zA-Z_][a-zA-Z0-9_.]*` to prevent traversal or injection via crafted keys218- `campaign_manager.py` validates command templates to reject shell chaining operators (`;`, `|`, `&`, backticks, `$`)219- `--params` format strings are parsed and validated (`name:min:max:count` with finite numeric bounds and positive integer counts)220- `--method` is validated against a fixed allowlist (`grid`, `linspace`, `lhs`)221- `--samples` is validated as a positive integer with an upper bound222- `--action` is validated against a fixed allowlist (`init`, `status`)223224### File Access225- `sweep_generator.py` reads a single base config file (JSON) specified by `--base-config` and writes generated configs to `--output-dir`226- `result_aggregator.py` enforces a 10 MB file-size limit per result file, maximum JSON nesting depth, and strict numeric type checking (rejects `bool`, `NaN`, `Inf`)227- All string values from result files are sanitized (truncated, control characters stripped) before surfacing them228- Config paths interpolated into shell commands are validated against a safe-character allowlist and escaped with `shlex.quote()`229230### Tool Restrictions231- **Read**: Used to inspect script source, references, base configs, and campaign status files232- **Write**: Used to save generated sweep configs, campaign manifests, and aggregated results; writes are scoped to the user's working directory233- **Grep/Glob**: Used to locate campaign files, result files, and search references234- The skill's `allowed-tools` excludes `Bash` to prevent the agent from executing arbitrary commands when processing untrusted simulation outputs235236### Safety Measures237- No `eval()`, `exec()`, or dynamic code generation238- All subprocess calls use explicit argument lists (no `shell=True`)239- Reduced tool surface (no Bash) limits the agent to read/write operations only240- Command templates are validated but never executed by the skill itself; execution is the user's responsibility241242## Limitations243244- **Not a job scheduler**: Does not submit jobs to SLURM/PBS; generates configs and tracks status245- **No parallel execution**: User must run simulations externally (can use GNU parallel, SLURM, etc.)246- **File-based tracking**: Status tracked via files; no database or real-time monitoring247- **Local filesystem**: Assumes all files accessible from local machine248249## References250251- `references/campaign_patterns.md` - Common campaign structures252- `references/sweep_strategies.md` - Parameter sweep design guidance253- `references/aggregation_methods.md` - Result aggregation techniques254255## Version History256257- **v1.0.0** (2024-12-24): Initial release with sweep, campaign, tracking, and aggregation