run_parameter_sweep/run_monte_carlo write each variant .cir into a work_dir,
then call run_netlist with that same work_dir -- which tried to shutil.copy2
the file onto itself (SameFileError), so every batch run failed before
simulating. Add _safe_copy() that skips when src and dst resolve to the same
path, used at all four staging-copy sites in run_simulation/run_netlist.
Caught by headless claude-cli testing of the batch tools (no batch test
existed). Adds test_runner.py (_safe_copy unit tests) and a TestBatchSweeps
integration class.