Bug
In src/lib/onboard-session.ts, acquireOnboardLock detects a stale lock (dead PID) and calls fs.unlinkSync(LOCK_FILE) before recreating it. Two concurrent processes can both read the same stale file, and the slower one can unlink the fresh lock the faster one just created, then win on its next retry. This breaks mutual exclusion.
Fix
Use an atomic stale-claim approach: write a temp file, then fs.linkSync(tempPath, LOCK_FILE) (succeeds only if LOCK_FILE doesn't exist). Only remove stale files after successfully claiming the lock.
Found by
CodeRabbit review on #1272. Pre-existing from original JS.
Bug
In
src/lib/onboard-session.ts,acquireOnboardLockdetects a stale lock (dead PID) and callsfs.unlinkSync(LOCK_FILE)before recreating it. Two concurrent processes can both read the same stale file, and the slower one can unlink the fresh lock the faster one just created, then win on its next retry. This breaks mutual exclusion.Fix
Use an atomic stale-claim approach: write a temp file, then
fs.linkSync(tempPath, LOCK_FILE)(succeeds only if LOCK_FILE doesn't exist). Only remove stale files after successfully claiming the lock.Found by
CodeRabbit review on #1272. Pre-existing from original JS.