@@ -667,6 +667,48 @@ describe('ChatStateMachine', () => {
667667 } ) ;
668668} ) ;
669669
670+ // ── Issue #590 regression: shared INITIAL_CONTEXT must not be mutated ─────────
671+ describe ( 'chatStateMachine race condition regression (#590)' , ( ) => {
672+ it ( 'two independent machines do not share context state' , ( ) => {
673+ const machineA = createChatStateMachine ( ) ;
674+ machineA . transition ( ChatEvent . INITIALIZE_SESSION ) ;
675+ machineA . updateContext ( { messageCount : 7 , hasUserCancelled : true } ) ;
676+
677+ const machineB = createChatStateMachine ( ) ;
678+ machineB . transition ( ChatEvent . INITIALIZE_SESSION ) ;
679+
680+ // Machine B must start clean — not polluted by machine A's mutations
681+ expect ( machineB . getState ( ) . context . messageCount ) . toBe ( 0 ) ;
682+ expect ( machineB . getState ( ) . context . hasUserCancelled ) . toBe ( false ) ;
683+ } ) ;
684+
685+ it ( 'action callbacks on machine A do not corrupt machine B context' , ( ) => {
686+ const machineA = createChatStateMachine ( ) ;
687+ machineA . transition ( ChatEvent . INITIALIZE_SESSION ) ;
688+ machineA . transition ( ChatEvent . SEND_MESSAGE ) ;
689+ machineA . transition ( ChatEvent . ANALYSIS_COMPLETE ) ; // → ANALYZING
690+ machineA . transition ( ChatEvent . ENCOUNTER_ERROR ) ; // → ERROR
691+ machineA . updateContext ( { errorMessage : 'A failed' } ) ;
692+
693+ const machineB = createChatStateMachine ( ) ;
694+ machineB . transition ( ChatEvent . INITIALIZE_SESSION ) ;
695+
696+ expect ( machineB . getState ( ) . context . errorMessage ) . toBeNull ( ) ;
697+ expect ( machineB . getState ( ) . state ) . toBe ( ChatState . INITIALIZED ) ;
698+ } ) ;
699+
700+ it ( 'many machines created in sequence all start with zero messageCount' , ( ) => {
701+ for ( let i = 0 ; i < 5 ; i ++ ) {
702+ const m = createChatStateMachine ( ) ;
703+ m . transition ( ChatEvent . INITIALIZE_SESSION ) ;
704+ m . updateContext ( { messageCount : i + 10 } ) ;
705+ const fresh = createChatStateMachine ( ) ;
706+ fresh . transition ( ChatEvent . INITIALIZE_SESSION ) ;
707+ expect ( fresh . getState ( ) . context . messageCount ) . toBe ( 0 ) ;
708+ }
709+ } ) ;
710+ } ) ;
711+
670712describe ( 'chatStateMachine clipboard snapshot helpers' , ( ) => {
671713 it ( 'formats a stable snapshot string' , ( ) => {
672714 const context : ChatMachineContext = {
0 commit comments