
    @pytest.mark.unit
    def test_mechanical_decider_exit_is_byte_identical_to_no_decider():
        """The base decide_exit is identity — a MechanicalDecider changes nothing vs no decider on the exit path."""
        a = run_day(_trail_ctx(), [ROLLOVER], SimConfig())
        b = run_day(_trail_ctx(), [ROLLOVER], SimConfig(), decider=MechanicalDecider())
>       assert a["legs"] == b["legs"] and a["transitions"] == b["transitions"]
E       AssertionError: assert ([{'direction'...:00:00', ...}] == [{'direction'...:00:00', ...}]
E         
E         Full diff:
E           [
E               {
E                   'direction': 'long',
E                   'entry_decided_by': 'mechanical',
E                   'entry_decider_reason': 'mechanical',...
E         
E         ...Full output truncated (16 lines hidden), use '-vv' to show and [{'action': '...'close', ...}] == [{'action': '...w', ...}, ...]
E         
E         At index 1 diff: {'et': '12:00:00', 'event': 'close', 'action': 'trail-stop', 'gen': 1, 'source': 'rollover', 'direction': 'long', 'return_pct': -2.0, 'exit_decided_by': 'mechanical', 'exit_decider_reason': ''} != {'et': '10:15:00', 'event': 'time_exit_review', 'action': 'hold', 'source': 'rollover', 'unrealized_pct': -100.0, 'reasoner_said': 'time_review'}
E         Right contains 7 more items, first extra item: {'action': 'hold', 'et': '10:30:00', 'event': 'time_exit_review', 'reasoner_said': 'time_review', ...}
E         
E         Full diff:
E           [
E               {...
E         
E         ...Full output truncated (80 lines hidden), use '-vv' to show)

tests/services/test_backtest_live_parity.py:581: AssertionError
