* test(#1884): reproduce phantom lock timeout from swallowed mkdir failure withPlanningLock swallows a platformEnsureDir failure at src/planning-workspace.cts:210, so an EACCES/ENOSPC/EROFS creating .planning/ is misreported as a 10s "held by a live process" lock-contention timeout instead of the real filesystem error. These tests pin the corrected contract and currently fail against the unfixed source (RED). Also proves the pre-existing Docker overlay-fs lock-write retry race is unaffected by this change. * fix(#1884): surface mkdir failures instead of a phantom lock timeout withPlanningLock swallowed platformEnsureDir failures (EACCES/ENOSPC/EROFS/EMFILE) creating .planning/, so the subsequent lock write failed with ENOENT (parent missing), which is retryable (PLANNING_LOCK_RETRY_ERRNOS, added for a Docker overlay-fs race). The loop then spun the full 10s budget and threw a phantom "held by a live process" contention error pointing at a nonexistent holder. The mkdir failure now propagates immediately with its real errno and message. The Docker overlay-fs ENOENT lock-write race (directory present) is unaffected, as is every path where .planning/ already exists or is creatable. Per docs/adr/1411-resolution-provenance.md's 2026-07-26 amendment, this is the one site in epic #1879 that legitimately throws (ADR-227's genuinely-fatal carve-out) -- its defect was throwing the wrong error after swallowing the real one, not that it threw at all. * chore(#1884): backfill changeset PR number --------- Co-authored-by: sim <sim@local>
This commit is contained in:
6
.changeset/1884-planning-lock-mkdir-failure.md
Normal file
6
.changeset/1884-planning-lock-mkdir-failure.md
Normal file
@@ -0,0 +1,6 @@
|
||||
---
|
||||
type: Fixed
|
||||
pr: 3472
|
||||
---
|
||||
|
||||
**`withPlanningLock` no longer reports a phantom "held by a live process" timeout when `.planning/` cannot be created** — a best-effort `try { platformEnsureDir(...) } catch { /* ok */ }` swallowed the real mkdir failure (EACCES/ENOSPC/EROFS), so the subsequent lock write failed with ENOENT (parent missing), and because ENOENT is in the lock's retry set (added for a Docker overlay-fs race) the loop spun the full 10 s budget before throwing a misattributed contention error that pointed operators at a nonexistent lock-holder. The mkdir failure now propagates immediately with its real filesystem errno and message, so an unwritable or full disk is reported as itself, not as concurrent-writer contention. The Docker overlay-fs ENOENT *lock-write* race (directory present) is still retried as before, and every code path where `.planning/` already exists or can be created is unchanged. Part of epic #1879 (distinguish "absent" from "corrupt/permission-denied" across engine read paths). (#1884)
|
||||
Reference in New Issue
Block a user