@@ -567,31 +567,24 @@ routing.layer("ProviderServiceLive routing", (it) => {
567567 } ) ;
568568
569569 yield * provider . stopSession ( { threadId : session . threadId } ) ;
570- routing . codex . startSession . mockClear ( ) ;
571- routing . codex . sendTurn . mockClear ( ) ;
572-
573- yield * provider . sendTurn ( {
574- threadId : session . threadId ,
575- input : "after-stop" ,
576- attachments : [ ] ,
577- } ) ;
578-
579- assert . equal ( routing . codex . startSession . mock . calls . length , 1 ) ;
580- const resumedStartInput = routing . codex . startSession . mock . calls [ 0 ] ?. [ 0 ] ;
581- assert . equal ( typeof resumedStartInput === "object" && resumedStartInput !== null , true ) ;
582- if ( resumedStartInput && typeof resumedStartInput === "object" ) {
583- const startPayload = resumedStartInput as {
584- provider ?: string ;
585- cwd ?: string ;
586- resumeCursor ?: unknown ;
587- threadId ?: string ;
588- } ;
589- assert . equal ( startPayload . provider , "codex" ) ;
590- assert . equal ( startPayload . cwd , "/tmp/project" ) ;
591- assert . deepEqual ( startPayload . resumeCursor , session . resumeCursor ) ;
592- assert . equal ( startPayload . threadId , session . threadId ) ;
593- }
594- assert . equal ( routing . codex . sendTurn . mock . calls . length , 1 ) ;
570+ const sendAfterStop = yield * Effect . result (
571+ provider . sendTurn ( {
572+ threadId : session . threadId ,
573+ input : "after-stop" ,
574+ attachments : [ ] ,
575+ } ) ,
576+ ) ;
577+ assert . equal ( sendAfterStop . _tag , "Failure" ) ;
578+ if ( sendAfterStop . _tag !== "Failure" ) return ;
579+ assert . equal ( sendAfterStop . failure . _tag , "ProviderValidationError" ) ;
580+ if ( sendAfterStop . failure . _tag !== "ProviderValidationError" ) return ;
581+ assert . equal ( sendAfterStop . failure . operation , "ProviderService.sendTurn" ) ;
582+ assert . equal (
583+ sendAfterStop . failure . issue . includes (
584+ `Cannot route thread '${ session . threadId } ' because no persisted provider binding exists.` ,
585+ ) ,
586+ true ,
587+ ) ;
595588 } ) ,
596589 ) ;
597590
@@ -635,55 +628,46 @@ routing.layer("ProviderServiceLive routing", (it) => {
635628 } ) ,
636629 ) ;
637630
638- it . effect ( "preserves the persisted binding when stopping a session" , ( ) =>
639- Effect . gen ( function * ( ) {
640- const provider = yield * ProviderService ;
641- const runtimeRepository = yield * ProviderSessionRuntimeRepository ;
631+ it . effect (
632+ "removes the persisted binding when stopping a session so the next start is fresh" ,
633+ ( ) =>
634+ Effect . gen ( function * ( ) {
635+ const provider = yield * ProviderService ;
636+ const runtimeRepository = yield * ProviderSessionRuntimeRepository ;
642637
643- const initial = yield * provider . startSession ( asThreadId ( "thread-reap-preserve " ) , {
644- provider : "codex" ,
645- threadId : asThreadId ( "thread-reap-preserve " ) ,
646- cwd : "/tmp/project-reap-preserve " ,
647- runtimeMode : "full-access" ,
648- } ) ;
638+ const initial = yield * provider . startSession ( asThreadId ( "thread-stop-removes " ) , {
639+ provider : "codex" ,
640+ threadId : asThreadId ( "thread-stop-removes " ) ,
641+ cwd : "/tmp/project-stop-removes " ,
642+ runtimeMode : "full-access" ,
643+ } ) ;
649644
650- yield * provider . stopSession ( { threadId : initial . threadId } ) ;
645+ yield * provider . stopSession ( { threadId : initial . threadId } ) ;
651646
652- const persistedAfterStop = yield * runtimeRepository . getByThreadId ( {
653- threadId : initial . threadId ,
654- } ) ;
655- assert . equal ( Option . isSome ( persistedAfterStop ) , true ) ;
656- if ( Option . isSome ( persistedAfterStop ) ) {
657- assert . equal ( persistedAfterStop . value . status , "stopped" ) ;
658- assert . deepEqual ( persistedAfterStop . value . resumeCursor , initial . resumeCursor ) ;
659- }
647+ const persistedAfterStop = yield * runtimeRepository . getByThreadId ( {
648+ threadId : initial . threadId ,
649+ } ) ;
650+ assert . equal ( Option . isNone ( persistedAfterStop ) , true ) ;
660651
661- routing . codex . startSession . mockClear ( ) ;
662- routing . codex . sendTurn . mockClear ( ) ;
652+ routing . codex . startSession . mockClear ( ) ;
663653
664- yield * provider . sendTurn ( {
665- threadId : initial . threadId ,
666- input : "resume after reap" ,
667- attachments : [ ] ,
668- } ) ;
654+ const restarted = yield * provider . startSession ( initial . threadId , {
655+ provider : "codex" ,
656+ threadId : initial . threadId ,
657+ cwd : "/tmp/project-stop-removes" ,
658+ runtimeMode : "full-access" ,
659+ } ) ;
669660
670- assert . equal ( routing . codex . startSession . mock . calls . length , 1 ) ;
671- const resumedStartInput = routing . codex . startSession . mock . calls [ 0 ] ?. [ 0 ] ;
672- assert . equal ( typeof resumedStartInput === "object" && resumedStartInput !== null , true ) ;
673- if ( resumedStartInput && typeof resumedStartInput === "object" ) {
674- const startPayload = resumedStartInput as {
675- provider ?: string ;
676- cwd ?: string ;
677- resumeCursor ?: unknown ;
678- threadId ?: string ;
679- } ;
680- assert . equal ( startPayload . provider , "codex" ) ;
681- assert . equal ( startPayload . cwd , "/tmp/project-reap-preserve" ) ;
682- assert . deepEqual ( startPayload . resumeCursor , initial . resumeCursor ) ;
683- assert . equal ( startPayload . threadId , initial . threadId ) ;
684- }
685- assert . equal ( routing . codex . sendTurn . mock . calls . length , 1 ) ;
686- } ) ,
661+ assert . equal ( restarted . provider , "codex" ) ;
662+ assert . equal ( routing . codex . startSession . mock . calls . length , 1 ) ;
663+ const restartedInput = routing . codex . startSession . mock . calls [ 0 ] ?. [ 0 ] ;
664+ if ( restartedInput && typeof restartedInput === "object" ) {
665+ const startPayload = restartedInput as {
666+ resumeCursor ?: unknown ;
667+ } ;
668+ assert . equal ( startPayload . resumeCursor , undefined ) ;
669+ }
670+ } ) ,
687671 ) ;
688672
689673 it . effect ( "routes explicit claudeAgent provider session starts to the claude adapter" , ( ) =>
0 commit comments