@@ -443,17 +443,26 @@ export async function runCodexAppServerAttempt(
443443
444444 const agentDir = params . agentDir ?? resolveAgentDir ( params . config ?? { } , sessionAgentId ) ;
445445 preDynamicStartupStages . mark ( "session-agent" ) ;
446+ const activeContextEngine = isActiveHarnessContextEngine ( params . contextEngine )
447+ ? params . contextEngine
448+ : undefined ;
449+ const isInactiveThreadBootstrapBinding = ( binding : CodexAppServerThreadBinding | undefined ) =>
450+ ! activeContextEngine && binding ?. contextEngine ?. projection ?. mode === "thread_bootstrap" ;
446451 let startupBinding = await readCodexAppServerBinding ( params . sessionFile ) ;
447452 preDynamicStartupStages . mark ( "read-binding" ) ;
448453 const startupBindingAuthProfileId = startupBinding ?. authProfileId ;
454+ const initialStartupBindingHadInactiveThreadBootstrap =
455+ isInactiveThreadBootstrapBinding ( startupBinding ) ;
449456 startupBinding = await rotateOversizedCodexAppServerStartupBinding ( {
450457 binding : startupBinding ,
451458 sessionFile : params . sessionFile ,
452459 agentDir,
453460 codexHome : appServer . start . env ?. CODEX_HOME ,
454461 config : params . config ,
455- contextEngineActive : isActiveHarnessContextEngine ( params . contextEngine ) ,
462+ contextEngineActive : Boolean ( activeContextEngine ) ,
456463 } ) ;
464+ const initialInactiveThreadBootstrapBindingForcedFreshStart =
465+ initialStartupBindingHadInactiveThreadBootstrap && ! startupBinding ?. threadId ;
457466 preDynamicStartupStages . mark ( "rotate-binding" ) ;
458467 const startupAuthProfileCandidate =
459468 params . runtimePlan ?. auth . forwardedAuthProfileId ??
@@ -520,9 +529,6 @@ export async function runCodexAppServerAttempt(
520529 for ( const diagnostic of bundleMcpThreadConfig . diagnostics ) {
521530 embeddedAgentLog . warn ( `bundle-mcp: ${ diagnostic . pluginId } : ${ diagnostic . message } ` ) ;
522531 }
523- const activeContextEngine = isActiveHarnessContextEngine ( params . contextEngine )
524- ? params . contextEngine
525- : undefined ;
526532 if ( activeContextEngine ) {
527533 assertContextEngineHostSupport ( {
528534 contextEngine : activeContextEngine ,
@@ -684,6 +690,8 @@ export async function runCodexAppServerAttempt(
684690 let contextEngineProjection : CodexContextEngineThreadBootstrapProjection | undefined ;
685691 let precomputedStaleBindingContinuityProjectionApplied = false ;
686692 let staleBindingContinuityForcedFreshStart = false ;
693+ let inactiveThreadBootstrapBindingForcedFreshStart =
694+ initialInactiveThreadBootstrapBindingForcedFreshStart ;
687695 const applyFreshThreadContinuityProjection = ( ) => {
688696 const projection = projectContextEngineAssemblyForCodex ( {
689697 assembledMessages : historyMessages ,
@@ -875,6 +883,10 @@ export async function runCodexAppServerAttempt(
875883 if ( activeContextEngine || ! binding ?. threadId ) {
876884 return false ;
877885 }
886+ if ( isInactiveThreadBootstrapBinding ( binding ) ) {
887+ inactiveThreadBootstrapBindingForcedFreshStart = true ;
888+ return false ;
889+ }
878890 const projected = applyResumeStaleBindingContinuityProjection ( binding ) ;
879891 precomputedStaleBindingContinuityProjectionApplied = projected ;
880892 return projected ;
@@ -892,6 +904,12 @@ export async function runCodexAppServerAttempt(
892904 if ( action === "started" && staleBindingContinuityForcedFreshStart ) {
893905 return true ;
894906 }
907+ if ( action === "started" && inactiveThreadBootstrapBindingForcedFreshStart ) {
908+ // A retired thread-bootstrap context engine already forced Codex onto a
909+ // clean native thread; without that engine active, mirrored history would
910+ // re-inject stale bootstrap context as a new user turn.
911+ return false ;
912+ }
895913 if ( action === "resumed" && binding ) {
896914 return applyResumeStaleBindingContinuityProjection ( binding ) ;
897915 }
@@ -909,6 +927,7 @@ export async function runCodexAppServerAttempt(
909927 return ;
910928 }
911929 const previousThreadId = startupBinding . threadId ;
930+ const hadInactiveThreadBootstrapBinding = isInactiveThreadBootstrapBinding ( startupBinding ) ;
912931 const projectedTurnTokens = estimateCodexAppServerProjectedTurnTokens ( {
913932 prompt : codexTurnPromptText ,
914933 developerInstructions : buildRenderedCodexDeveloperInstructions ( ) ,
@@ -925,7 +944,10 @@ export async function runCodexAppServerAttempt(
925944 if ( startupBinding ?. threadId ) {
926945 return ;
927946 }
928- staleBindingContinuityForcedFreshStart = precomputedStaleBindingContinuityProjectionApplied ;
947+ inactiveThreadBootstrapBindingForcedFreshStart = hadInactiveThreadBootstrapBinding ;
948+ staleBindingContinuityForcedFreshStart =
949+ precomputedStaleBindingContinuityProjectionApplied &&
950+ ! inactiveThreadBootstrapBindingForcedFreshStart ;
929951 if ( activeContextEngine ) {
930952 contextEngineProjection = undefined ;
931953 try {
0 commit comments