* fix(state): acquireStateLock retries on transient Docker/NFS errno codes
Expands retry allowlist to ENOENT/EINVAL/EIO/ESTALE/EAGAIN/EINTR in addition
to existing EPERM/EBUSY. Truly fatal codes (EMFILE/ENOSPC/EROFS/EACCES) still
throw. Resolves the locking-bugs regression seen across all 8 open
consolidation PRs (#3738, #3741, #3752, #3754, #3756, #3759, #3760, #3769).
Closes#3776
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* chore(changeset): update pr number to 3777 in retry-allowlist fragment
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix(state): acquireStateLock throws on non-EEXIST openSync errors
Closes#3772
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* chore(changeset): update pr reference to #3773
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix(state): retry on EPERM/EBUSY in acquireStateLock and withPlanningLock
Resolves state update TOCTOU failure on macos-22 and config-set
concurrency failure on windows-24.
Root cause: openSync(O_CREAT|O_EXCL) can return EPERM or EBUSY
transiently on some CI OS+AV combinations when the lock file is
briefly held open by the deleting process; the new throw-on-non-EEXIST
guard from #3772 propagated these transient errors, killing child
processes and causing lost updates in the concurrency tests.
Fix: guard EPERM/EBUSY with an explicit continue before the
throw-on-non-EEXIST line in both acquireStateLock and withPlanningLock;
the C1 source-audit test still passes because the throw pattern is
preserved for all other non-EEXIST codes.
Refs #3772
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>