@@ -905,7 +905,8 @@ describe("same-turn failover after inference.error", () => {
905905 wireKeys : false ,
906906 run : "idle" ,
907907 } ) ;
908- const bridge = attachSessionBridge ( shell , createRecordingPort ( ) ) ;
908+ const port = createRecordingPort ( ) ;
909+ const bridge = attachSessionBridge ( shell , port ) ;
909910 try {
910911 bridge . handle ( { type : "inference.start" , data : { } } ) ;
911912 bridge . handle ( {
@@ -927,6 +928,47 @@ describe("same-turn failover after inference.error", () => {
927928
928929 expect ( errorRows ( shell ) ) . toEqual ( [ ] ) ;
929930 expect ( shell . streamLog . map ( ( r ) => r . text ) . join ( "\n" ) ) . toContain ( "recovered" ) ;
931+ // Same-turn failover, not an operator stop — recovery must not borrow interrupt.
932+ expect ( port . calls . some ( ( c ) => c . op === "interrupt" ) ) . toBe ( false ) ;
933+ expect ( shell . streamLog . some ( ( r ) => r . meta === "stop" ) ) . toBe ( false ) ;
934+ } finally {
935+ bridge . dispose ( ) ;
936+ shell . dispose ( ) ;
937+ }
938+ } ,
939+ { width : 80 , height : 24 } ,
940+ ) ;
941+ } ) ;
942+
943+ test ( "interrupt then a new prompt keeps the prompt and the classified error" , async ( ) => {
944+ await withTestRenderer (
945+ async ( h ) => {
946+ const shell = createAppShell ( h . renderer , {
947+ terminal : { columns : 80 , rows : 24 } ,
948+ wireKeys : false ,
949+ run : "idle" ,
950+ } ) ;
951+ const port = createRecordingPort ( ) ;
952+ const bridge = attachSessionBridge ( shell , port ) ;
953+ try {
954+ bridge . handle ( { type : "inference.start" , data : { } } ) ;
955+ bridge . handle ( {
956+ type : "inference.error" ,
957+ data : {
958+ error : { category : "credential_failure" , message : "Forbidden" , statusCode : 403 } ,
959+ } ,
960+ } ) ;
961+ bridge . interrupt ( ) ;
962+ bridge . submit ( "next prompt" , "immediate" ) ;
963+ bridge . handle ( {
964+ type : "message.received" ,
965+ data : { message : { content : "next prompt" } } ,
966+ } ) ;
967+ bridge . handle ( { type : "inference.start" , data : { } } ) ;
968+
969+ const text = shell . streamLog . map ( ( r ) => r . text ) . join ( "\n" ) ;
970+ expect ( text ) . toContain ( "next prompt" ) ;
971+ expect ( errorRows ( shell ) ) . toContain ( "Session expired — re-authenticating…" ) ;
930972 } finally {
931973 bridge . dispose ( ) ;
932974 shell . dispose ( ) ;
@@ -995,7 +1037,7 @@ describe("same-turn failover after inference.error", () => {
9951037 bridge . handle ( event ) ;
9961038 }
9971039
998- expect ( errorRows ( shell ) . length ) . toBeGreaterThan ( 0 ) ;
1040+ expect ( errorRows ( shell ) ) . toContain ( "Session expired — re-authenticating…" ) ;
9991041 } finally {
10001042 bridge . dispose ( ) ;
10011043 shell . dispose ( ) ;
0 commit comments