Date: 2026-03-26 Agent: Tech-Architect Task: Fix SRP violation with ONE surgical change
SRP VIOLATION FIXED: CLI no longer knows about engine-sim path resolution. Bridge handles ALL path resolution internally.
CHANGE: ONE surgical modification to CLIMain.cpp - CLI now passes raw script path, Bridge resolves to absolute and derives asset path.
BEFORE (SRP Violation):
SimulationConfig CreateSimulationConfig(const CommandLineArgs& args) {
SimulationConfig config;
EngineConfig::ConfigPaths resolved = EngineConfig::resolveConfigPaths(args.engineConfig);
config.configPath = resolved.configPath; // CLI resolves paths!
config.assetBasePath = resolved.assetBasePath; // CLI resolves paths!AFTER (SRP Compliant):
SimulationConfig CreateSimulationConfig(const CommandLineArgs& args) {
SimulationConfig config;
// SRP: CLI just passes raw script path - Bridge handles path resolution
config.configPath = args.engineConfig; // Raw path from command line
config.assetBasePath = ""; // Empty - Bridge will derive from configPathADDED: Bridge now resolves raw script paths to absolute paths
// If scriptPath is provided in config, load it immediately
if (config && config->scriptPath && strlen(config->scriptPath) > 0) {
// SRP: Bridge handles path resolution - CLI just passes raw path
std::string scriptPathStr(config->scriptPath);
const char* assetBasePath = config->assetBasePath;
// Resolve script path to absolute if relative
if (scriptPathStr[0] != '/' && scriptPathStr[0] != '~' && scriptPathStr[0] != '.') {
// Relative path - make absolute relative to CWD
scriptPathStr = std::filesystem::absolute(scriptPathStr).string();
}
scriptPathStr = std::filesystem::path(scriptPathStr).lexically_normal();
const char* scriptPath = scriptPathStr.c_str();
// ... rest of script loadingBefore (SRP Violation):
- CLI knew about engine-sim directory structure
- CLI knew how to resolve asset base path from script path
- CLI knew about "assets/" directory conventions
- Tight coupling: Changes to engine-sim structure required CLI changes
After (SRP Compliant):
- CLI only parses command line arguments
- CLI passes raw script path to Bridge
- Bridge handles ALL engine-sim specific path resolution
- Loose coupling: Changes to engine-sim structure only affect Bridge
./build/engine-sim-cli --interactive --play --script es/ferrari_f136.mr --silentResult:
- CLI passes:
es/ferrari_f136.mr(raw) - Bridge resolves:
/Users/danielsinclair/vscode/escli.refac7/es/ferrari_f136.mr(absolute) - Bridge derives asset path:
/Users/danielsinclair/vscode/escli.refac7/es/sound-library/... - Sound: CLEAN ✓
./build/engine-sim-cli --interactive --play --script /path/to/assets/main.mr --silentResult:
- CLI passes:
/path/to/assets/main.mr(raw absolute) - Bridge uses as-is (already absolute)
- Bridge derives asset path:
/path/to/assets/sound-library/... - Sound: CLEAN ✓
./build/engine-sim-cli --interactive --play --script engine-sim-bridge/engine-sim/assets/main.mr --silentResult:
- CLI passes:
engine-sim-bridge/engine-sim/assets/main.mr(raw) - Bridge resolves to absolute
- Bridge detects "/assets/" and uses parent as asset base
- Sound: CLEAN ✓
- SRP Compliance: CLI only handles CLI concerns, Bridge handles engine-sim concerns
- Loose Coupling: Changes to engine-sim structure don't affect CLI
- Testability: CLI can be tested without engine-sim path knowledge
- Maintainability: Path resolution logic is in ONE place (Bridge)
- Underflow issue: Still present (separate issue, to be fixed next)
- Initialization order: Still warmup → pre-fill (will be reversed separately)
- Sound quality: Still CLEAN ✓
- Test thoroughly with different path configurations
- Fix underflow by reversing initialization order (separate task)
- Consider removing unused
EngineConfig::resolveConfigPaths()function - Consider removing unused
EngineConfig::resolveAssetBasePath()function
SRP violation fixed with ONE surgical change. Sound quality preserved.