TestFSMOccupancyAndRollback covers the invariants that prevent orphaned
exchange orders — the production failure mode where multiple positions
accumulated because slot state wasn't rolled back on submit failure:
- ENTRY_WORKING blocks new ENTER (different trade_id → SLOT_BUSY)
- POSITION_OPEN blocks new ENTER
- venue.submit raise → synthetic REJECTED → FSM back to IDLE
- After rollback slot immediately reusable
- N consecutive submit failures never strand the slot
- submit-fail then success → exactly 1 position, not N
- 20 rapid enter→exit cycles leave no residual state
- EXIT on IDLE always rejected (no phantom closes)
- 5 assets, 1 slot → only first accepted, rest SLOT_BUSY
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>