I had a similar (but not as good) thought which was to separate out the action from the planning in code then inject the action system. So —-dry-run would pass the ConsoleOutput() action interface but without it passes a LiveExecutor() (I’m sure there’s a better name).

Assuming our system is complex enough. I guess it sits between if dry_run and execute(plan()) in its complexity.