""" Resolve and write a merged scenario config for native-run-single. Usage: python -m src.shared.resolve_scenario_config Finds the scenario in matrix.yaml's experiment_matrix.scenarios, deep-merges its overrides onto the base config (config.yaml), writes the result to matrix_configs/, and prints the output path. Prints an empty string if SCENARIO_ID is empty or not found (caller falls back to the default config.yaml). """ import copy import sys import yaml from datetime import datetime from pathlib import Path def _deep_merge(base: dict, override: dict) -> dict: for key, value in override.items(): if key in base and isinstance(base[key], dict) and isinstance(value, dict): _deep_merge(base[key], value) else: base[key] = value return base def main() -> None: scenario_id = sys.argv[1].strip() if len(sys.argv) > 1 else "" if not scenario_id: print("") return here = Path(__file__).resolve().parent project_root = here.parent.parent config_path = project_root / "config.yaml" matrix_path = project_root / "matrix.yaml" with open(config_path, "r", encoding="utf-8") as f: root_cfg = yaml.safe_load(f) or {} with open(matrix_path, "r", encoding="utf-8") as f: matrix_raw = yaml.safe_load(f) or {} scenarios = matrix_raw.get("experiment_matrix", {}).get("scenarios", []) scenario = next( (s for s in scenarios if str(s.get("id", "")).strip() == scenario_id), None, ) if scenario is None: print( f"[resolve_scenario_config] WARNING: scenario '{scenario_id}' not found " f"in experiment_matrix.scenarios — using default config.yaml", file=sys.stderr, ) print("") return run_cfg = copy.deepcopy(root_cfg) overrides = scenario.get("overrides", {}) if isinstance(overrides, dict) and overrides: _deep_merge(run_cfg, overrides) configs_dir = project_root / "results" / "matrix_configs" configs_dir.mkdir(exist_ok=True) stamp = datetime.now().strftime("%Y%m%d_%H%M%S") out_path = configs_dir / f"{stamp}_{scenario_id}_native.yaml" with open(out_path, "w", encoding="utf-8") as f: yaml.safe_dump(run_cfg, f, sort_keys=False) print(str(out_path)) if __name__ == "__main__": main()