@@ -34,6 +34,7 @@ const lockOptions = {
3434const tempDirs : string [ ] = [ ] ;
3535
3636afterEach ( async ( ) => {
37+ vi . restoreAllMocks ( ) ;
3738 resetEmbeddedAttemptSessionFileOwnersForTest ( ) ;
3839 resetSessionWriteLockStateForTest ( ) ;
3940 for ( const dir of tempDirs . splice ( 0 ) ) {
@@ -136,7 +137,7 @@ describe("embedded attempt session lock lifecycle", () => {
136137 expect ( releases ) . toEqual ( [ "held" ] ) ;
137138 } ) ;
138139
139- it ( "releases the eagerly-held lock even when the fence read throws during prompt release (FAD-845) " , async ( ) => {
140+ it ( "releases the eagerly-held lock when the fence read throws during prompt release" , async ( ) => {
140141 const release = vi . fn ( async ( ) => { } ) ;
141142 const acquireSessionWriteLockLocalFad845 = vi . fn ( async ( ) => ( { release } ) ) ;
142143 const controller = await createEmbeddedAttemptSessionLockController ( {
@@ -151,14 +152,15 @@ describe("embedded attempt session lock lifecycle", () => {
151152 const statError = Object . assign ( new Error ( "simulated I/O failure" ) , { code : "EIO" } ) ;
152153 const statSpy = vi . spyOn ( fs , "stat" ) . mockRejectedValueOnce ( statError ) ;
153154
154- await expect ( controller . releaseForPrompt ( ) ) . rejects . toThrow ( ) ;
155+ try {
156+ await expect ( controller . releaseForPrompt ( ) ) . rejects . toThrow ( ) ;
155157
156- // The underlying file lock MUST still be released; otherwise it is orphaned on the
157- // live gateway process for the full maxHoldMs lease (~17 min), wedging every
158- // subsequent interactive turn with SessionWriteLockTimeoutError. See FAD-845.
159- expect ( release ) . toHaveBeenCalledTimes ( 1 ) ;
160-
161- statSpy . mockRestore ( ) ;
158+ // The underlying file lock must still be released so later turns do not wait for
159+ // the full maxHoldMs watchdog before the stale lease is reclaimed.
160+ expect ( release ) . toHaveBeenCalledTimes ( 1 ) ;
161+ } finally {
162+ statSpy . mockRestore ( ) ;
163+ }
162164 } ) ;
163165
164166 it ( "releaseHeldLockForAbort and dispose are idempotent in succession (#86816)" , async ( ) => {
0 commit comments