Summary
The focused Windows Kibitzer wake-slot soak intermittently rejects queued wake admissions while another waiter is transitioning its FIFO ticket. The failing test then exits without cancelling the remaining waiters, so their later rejections leak into unrelated memory tests.
Reproduction
- Dispatch
.github/workflows/windows-flake-soak.yml on Windows with target=paths.
- Set
paths=packages/omo-senpi/src/components/memory/kibitzer/wake-slot.test.ts and iterations=10.
- Observe an intermittent failure in the FIFO test.
Focused reproduction: https://github.com/code-yeongyu/oh-my-openagent/actions/runs/36320480068 (iteration 6).
Expected
- A transient Windows sharing violation while reading the current head ticket keeps that ticket in place and retries through the existing bounded poll path.
- Queue waiters do not reject for expected
EPERM/EBUSY/EACCES sharing states.
- FIFO order and the configured maximum concurrent wake count remain unchanged.
- The FIFO test cancels and joins every waiter and releases every acquired lease even when an assertion fails.
- Three focused Windows soaks of 10 iterations each pass.
Actual
The third waiter rejects in reapDeadHead, while the test reports only that the promise was already settled:
EPERM: operation not permitted, open ...recall-wake.tickets/<ticket>
at retryOnEintr (.../packages/memory-core/src/fs/retry.ts:11)
at reapDeadHead (.../packages/memory-core/src/locks/recall-wake-domain.ts:108)
at acquireRecallWakeLease (.../packages/memory-core/src/locks/recall-wake-domain.ts:179)
at acquire (.../packages/omo-senpi/src/components/memory/kibitzer/wake-slot.ts:62)
Expected: false
Received: true
at .../wake-slot.test.ts:81
After the assertion exits, pending admissions continue running. Runs https://github.com/code-yeongyu/oh-my-openagent/actions/runs/36312352680 and https://github.com/code-yeongyu/oh-my-openagent/actions/runs/36300728869 later report expected an acquired admission, got busy with stacks back into wake-slot.test.ts, including an unhandled error between tests.
Evidence
packages/memory-core/src/locks/recall-wake-domain.ts:104-112: reapDeadHead treats only ENOENT as a moved ticket. Its documented contract says unreadable or unparsable tickets keep their place, but Windows sharing errors currently propagate.
packages/omo-senpi/src/components/memory/kibitzer/wake-slot.test.ts:24-28: settledAlready deliberately maps both fulfillment and rejection to settled, hiding the EPERM cause behind a pending-state assertion.
- The focused macOS stress run passed 300/300 adapter tests, and the direct memory-core stress run passed 450/450 tests. The failing condition is the Windows file-sharing path.
Root cause
Confirmed product defect: Windows can return EPERM, EBUSY, or EACCES while another waiter is publishing or withdrawing a ticket. reapDeadHead propagates that expected sharing state instead of retaining the head ticket and waiting for the next normal poll. The apparent FIFO failure is a rejected waiter, not evidence that more than two leases were live.
Confirmed test defect: the FIFO test does not abort and join remaining waits or release every acquired lease when an assertion fails, allowing asynchronous work to contaminate later tests.
Scope
- Fix ticket-head reads to fail closed on Windows sharing errors without adding sleeps, retries outside the existing poll loop, timeout increases, or platform skips.
- Add deterministic coverage for the sharing-error branch.
- Make the FIFO test teardown unconditional and event/state based.
Related
Summary
The focused Windows Kibitzer wake-slot soak intermittently rejects queued wake admissions while another waiter is transitioning its FIFO ticket. The failing test then exits without cancelling the remaining waiters, so their later rejections leak into unrelated memory tests.
Reproduction
.github/workflows/windows-flake-soak.ymlon Windows withtarget=paths.paths=packages/omo-senpi/src/components/memory/kibitzer/wake-slot.test.tsanditerations=10.Focused reproduction: https://github.com/code-yeongyu/oh-my-openagent/actions/runs/36320480068 (iteration 6).
Expected
EPERM/EBUSY/EACCESsharing states.Actual
The third waiter rejects in
reapDeadHead, while the test reports only that the promise was already settled:After the assertion exits, pending admissions continue running. Runs https://github.com/code-yeongyu/oh-my-openagent/actions/runs/36312352680 and https://github.com/code-yeongyu/oh-my-openagent/actions/runs/36300728869 later report
expected an acquired admission, got busywith stacks back intowake-slot.test.ts, including an unhandled error between tests.Evidence
packages/memory-core/src/locks/recall-wake-domain.ts:104-112:reapDeadHeadtreats onlyENOENTas a moved ticket. Its documented contract says unreadable or unparsable tickets keep their place, but Windows sharing errors currently propagate.packages/omo-senpi/src/components/memory/kibitzer/wake-slot.test.ts:24-28:settledAlreadydeliberately maps both fulfillment and rejection tosettled, hiding theEPERMcause behind a pending-state assertion.Root cause
Confirmed product defect: Windows can return
EPERM,EBUSY, orEACCESwhile another waiter is publishing or withdrawing a ticket.reapDeadHeadpropagates that expected sharing state instead of retaining the head ticket and waiting for the next normal poll. The apparent FIFO failure is a rejected waiter, not evidence that more than two leases were live.Confirmed test defect: the FIFO test does not abort and join remaining waits or release every acquired lease when an assertion fails, allowing asynchronous work to contaminate later tests.
Scope
Related