@@ -683,6 +683,59 @@ describe("runtime rotation proxy", () => {
683683 ] ) ;
684684 } ) ;
685685
686+ it ( "stores null blocked thread goal fallbacks by snake-case body thread id" , async ( ) => {
687+ const now = Date . now ( ) ;
688+ const accountManager = new AccountManager ( undefined , createStorage ( now ) ) ;
689+ const { calls, fetchImpl } = createRecordingFetch (
690+ ( ) =>
691+ new Response ( "<html>blocked</html>" , {
692+ status : HTTP_STATUS . FORBIDDEN ,
693+ headers : { "content-type" : "text/html" } ,
694+ } ) ,
695+ ) ;
696+ const proxy = await startProxy ( { accountManager, fetchImpl } ) ;
697+
698+ const setResponse = await postThreadGoal (
699+ proxy ,
700+ { thread_id : "thread-snake" } ,
701+ "/thread/goal/set" ,
702+ ) ;
703+ const getResponse = await getThreadGoal (
704+ proxy ,
705+ "/thread/goal/get?threadId=thread-snake" ,
706+ ) ;
707+
708+ expect ( setResponse . status ) . toBe ( HTTP_STATUS . OK ) ;
709+ expect ( await setResponse . json ( ) ) . toEqual ( { ok : true , goal : null } ) ;
710+ expect ( getResponse . status ) . toBe ( HTTP_STATUS . OK ) ;
711+ expect ( await getResponse . json ( ) ) . toEqual ( { goal : null } ) ;
712+ expect ( calls ) . toHaveLength ( 2 ) ;
713+ } ) ;
714+
715+ it ( "prioritizes workspace-disabled 403 handling over thread goal fallback" , async ( ) => {
716+ const now = Date . now ( ) ;
717+ const accountManager = new AccountManager ( undefined , createStorage ( now , 1 ) ) ;
718+ const { calls, fetchImpl } = createRecordingFetch ( ( ) =>
719+ new Response ( JSON . stringify ( { error : { code : "workspace_disabled" } } ) , {
720+ status : HTTP_STATUS . FORBIDDEN ,
721+ headers : { "content-type" : "application/json" } ,
722+ } ) ,
723+ ) ;
724+ const proxy = await startProxy ( { accountManager, fetchImpl } ) ;
725+
726+ const response = await postThreadGoal (
727+ proxy ,
728+ { threadId : "thread-disabled" , goal : "ship it" } ,
729+ "/thread/goal/set" ,
730+ ) ;
731+ const payload = ( await response . json ( ) ) as { error : { reason : string } } ;
732+
733+ expect ( response . status ) . toBe ( HTTP_STATUS . SERVICE_UNAVAILABLE ) ;
734+ expect ( payload . error . reason ) . toBe ( "deactivated" ) ;
735+ expect ( calls ) . toHaveLength ( 1 ) ;
736+ expect ( accountManager . getAccountByIndex ( 0 ) ?. enabled ) . toBe ( false ) ;
737+ } ) ;
738+
686739 it ( "passes through non-fallback thread goal client errors" , async ( ) => {
687740 const now = Date . now ( ) ;
688741 const accountManager = new AccountManager ( undefined , createStorage ( now ) ) ;
0 commit comments