@@ -122,6 +122,7 @@ type MemorySessionDeltaState = { lastSize: number; pendingBytes: number; pending
122122
123123type MemoryReindexRetryState = {
124124 dirty : boolean ;
125+ memoryFullRetryDirty : boolean ;
125126 sessionsDirty : boolean ;
126127 sessionsFullRetryDirty : boolean ;
127128 sessionsDirtyFiles : Set < string > ;
@@ -275,6 +276,9 @@ export abstract class MemoryManagerSyncOps {
275276 protected memoryWatchPressureStartupTimer : NodeJS . Timeout | null = null ;
276277 protected closed = false ;
277278 protected dirty = false ;
279+ // Failed full memory reindexes must retry as full rebuilds, not incremental
280+ // dirty syncs that can skip unchanged files against the still-live index.
281+ protected memoryFullRetryDirty = false ;
278282 protected pendingWatchPaths : MemoryWatchSettleQueue = new Map ( ) ;
279283 protected sessionsDirty = false ;
280284 // Failed full reindexes can start with no per-file dirty set. Keep a
@@ -324,6 +328,7 @@ export abstract class MemoryManagerSyncOps {
324328 private snapshotReindexRetryState ( ) : MemoryReindexRetryState {
325329 return {
326330 dirty : this . dirty ,
331+ memoryFullRetryDirty : this . memoryFullRetryDirty ,
327332 sessionsDirty : this . sessionsDirty ,
328333 sessionsFullRetryDirty : this . sessionsFullRetryDirty ,
329334 sessionsDirtyFiles : new Set ( this . sessionsDirtyFiles ) ,
@@ -335,6 +340,7 @@ export abstract class MemoryManagerSyncOps {
335340
336341 private restoreReindexRetryState ( snapshot : MemoryReindexRetryState ) : void {
337342 this . dirty = snapshot . dirty || this . dirty ;
343+ this . memoryFullRetryDirty = snapshot . memoryFullRetryDirty || this . memoryFullRetryDirty ;
338344 this . sessionsFullRetryDirty = snapshot . sessionsFullRetryDirty || this . sessionsFullRetryDirty ;
339345 this . sessionsDirtyFiles = new Set ( [ ...snapshot . sessionsDirtyFiles , ...this . sessionsDirtyFiles ] ) ;
340346 const currentDeltas = this . sessionDeltas ;
@@ -354,6 +360,7 @@ export abstract class MemoryManagerSyncOps {
354360 private markFailedFullReindexRetry ( params : { memory : boolean ; sessions : boolean } ) : void {
355361 if ( params . memory ) {
356362 this . dirty = true ;
363+ this . memoryFullRetryDirty = true ;
357364 }
358365 if ( params . sessions ) {
359366 this . sessionsDirty = true ;
@@ -367,6 +374,11 @@ export abstract class MemoryManagerSyncOps {
367374 this . sessionsDirtyFiles . clear ( ) ;
368375 }
369376
377+ private clearMemoryRetryState ( ) : void {
378+ this . dirty = false ;
379+ this . memoryFullRetryDirty = false ;
380+ }
381+
370382 private refreshSessionDirtyFlag ( ) : void {
371383 this . sessionsDirty = this . sessionsFullRetryDirty || this . sessionsDirtyFiles . size > 0 ;
372384 }
@@ -428,6 +440,7 @@ export abstract class MemoryManagerSyncOps {
428440 shouldSyncMemory : boolean ;
429441 shouldSyncSessions : boolean ;
430442 needsFullReindex : boolean ;
443+ needsFullSessionReindex ?: boolean ;
431444 targetSessionFiles ?: string [ ] ;
432445 progress ?: MemorySyncProgressState ;
433446 } ) : Promise < void > {
@@ -440,7 +453,7 @@ export abstract class MemoryManagerSyncOps {
440453 : this . emptySourceSyncPlan ( ) ;
441454 if ( params . shouldSyncSessions ) {
442455 await this . syncSessionFiles ( {
443- needsFullReindex : params . needsFullReindex ,
456+ needsFullReindex : params . needsFullSessionReindex ?? params . needsFullReindex ,
444457 targetSessionFiles : params . targetSessionFiles ,
445458 progress : params . progress ,
446459 deferIndex : true ,
@@ -2169,7 +2182,9 @@ export abstract class MemoryManagerSyncOps {
21692182 ( params ?. force && ! hasTargetSessionFiles ) ||
21702183 needsInitialIndex ||
21712184 needsMissingIdentityReindex ||
2172- needsExplicitIdentityReindex ;
2185+ needsExplicitIdentityReindex ||
2186+ this . memoryFullRetryDirty ;
2187+ const needsFullSessionReindex = needsFullReindex || this . sessionsFullRetryDirty ;
21732188 if ( indexIdentity . status !== "valid" && ! needsFullReindex ) {
21742189 this . dirty = true ;
21752190 const sessionsDirty = markMemoryTargetSessionFilesDirty ( {
@@ -2181,12 +2196,13 @@ export abstract class MemoryManagerSyncOps {
21812196 }
21822197 return ;
21832198 }
2184- if ( ! needsFullReindex ) {
2199+ if ( ! needsFullSessionReindex ) {
21852200 const targetedSessionSync = await runMemoryTargetedSessionSync ( {
21862201 hasSessionSource : this . sources . has ( "sessions" ) ,
21872202 targetSessionFiles,
21882203 reason : params ?. reason ,
21892204 progress : progress ?? undefined ,
2205+ sessionsFullRetryDirty : this . sessionsFullRetryDirty ,
21902206 sessionsDirtyFiles : this . sessionsDirtyFiles ,
21912207 syncSessionFiles : async ( targetedParams ) => {
21922208 await this . syncSessionFiles ( targetedParams ) ;
@@ -2230,11 +2246,12 @@ export abstract class MemoryManagerSyncOps {
22302246 shouldSyncMemory,
22312247 shouldSyncSessions,
22322248 needsFullReindex,
2249+ needsFullSessionReindex,
22332250 targetSessionFiles : targetSessionFiles ? Array . from ( targetSessionFiles ) : undefined ,
22342251 progress : progress ?? undefined ,
22352252 } ) ;
22362253 if ( shouldSyncMemory ) {
2237- this . dirty = false ;
2254+ this . clearMemoryRetryState ( ) ;
22382255 }
22392256 if ( shouldSyncSessions ) {
22402257 this . clearSessionRetryState ( ) ;
@@ -2244,12 +2261,12 @@ export abstract class MemoryManagerSyncOps {
22442261 } else {
22452262 if ( shouldSyncMemory ) {
22462263 await this . syncMemoryFiles ( { needsFullReindex, progress : progress ?? undefined } ) ;
2247- this . dirty = false ;
2264+ this . clearMemoryRetryState ( ) ;
22482265 }
22492266
22502267 if ( shouldSyncSessions ) {
22512268 await this . syncSessionFiles ( {
2252- needsFullReindex,
2269+ needsFullReindex : needsFullSessionReindex ,
22532270 targetSessionFiles : targetSessionFiles ? Array . from ( targetSessionFiles ) : undefined ,
22542271 progress : progress ?? undefined ,
22552272 } ) ;
@@ -2430,7 +2447,7 @@ export abstract class MemoryManagerSyncOps {
24302447 progress : params . progress ,
24312448 } ) ;
24322449 if ( shouldSyncMemory ) {
2433- this . dirty = false ;
2450+ this . clearMemoryRetryState ( ) ;
24342451 }
24352452 if ( shouldSyncSessions ) {
24362453 this . clearSessionRetryState ( ) ;
@@ -2440,7 +2457,7 @@ export abstract class MemoryManagerSyncOps {
24402457 } else {
24412458 if ( shouldSyncMemory ) {
24422459 await this . syncMemoryFiles ( { needsFullReindex : true , progress : params . progress } ) ;
2443- this . dirty = false ;
2460+ this . clearMemoryRetryState ( ) ;
24442461 }
24452462
24462463 if ( shouldSyncSessions ) {
@@ -2538,7 +2555,7 @@ export abstract class MemoryManagerSyncOps {
25382555 progress : params . progress ,
25392556 } ) ;
25402557 if ( shouldSyncMemory ) {
2541- this . dirty = false ;
2558+ this . clearMemoryRetryState ( ) ;
25422559 }
25432560 if ( shouldSyncSessions ) {
25442561 this . clearSessionRetryState ( ) ;
@@ -2548,7 +2565,7 @@ export abstract class MemoryManagerSyncOps {
25482565 } else {
25492566 if ( shouldSyncMemory ) {
25502567 await this . syncMemoryFiles ( { needsFullReindex : true , progress : params . progress } ) ;
2551- this . dirty = false ;
2568+ this . clearMemoryRetryState ( ) ;
25522569 }
25532570
25542571 if ( shouldSyncSessions ) {
0 commit comments