You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit d13f070
Browse filesBrowse the repository at this point in the historyBrowse files
fix(drivers): keep harvested roots inside the trust boundary, and make the install lock hold
Review findings on #1201, grouped by what they actually break.
**Harvested roots crossed a deliberate security boundary.** `driverSearchRoots()`
refuses project and ancestor `node_modules` because importing a workspace-
controlled SDK during a warehouse read/test bypasses the permission boundary and
can expose resolved credentials. `searchRootsFromError()` mined any absolute path
an error quoted and prepended it, so an ambient failure naming a project-local
`node_modules` routed straight around that invariant. Harvested roots are now
filtered through the same exclusion.
**They also preempted the managed installation.** Prepending meant a stale or
broken copy the runtime happened to name won over the driver we installed, which
inverts the documented "managed install dir comes first" ordering. Trusted roots
now come first and harvested roots are appended, which still recovers the
original failure: a harvested root is reached whenever the roots ahead of it
resolve nothing.
**Windows never harvested anything.** The extraction regex accepts `C:/…` and
`C:\…`, but the `node_modules` marker is built from `path.sep`, so a
forward-slash path could never match a backslash marker. `enclosingNodeModulesRoot`
normalises separators, and takes `sep` as a parameter so the Windows behaviour is
tested from a POSIX host rather than asserted. `repairCwdPrefixedPath` now also
handles the two Windows concatenation shapes, which have no separator to carry.
**The lock silently degraded to unlocked in exactly the cold-start case it exists
for.** `<dir>.lock` sits beside the managed directory, and on a fresh machine
nothing has created the XDG data directory yet — `performInstall` is the first
thing that does, and it runs after the lock attempt. The non-recursive `mkdir`
failed ENOENT, took the "cannot lock" branch, and dropped every concurrent CLI
into an unlocked install. The parent is now created first.
**Stale-lock recovery could admit two installers.** Two processes could both
judge a lock stale, and deleting by pathname let the loser delete the winner's
fresh lock. Claiming is now a `rename`, which exactly one process can win.
**A lock could be released out from under its successor.** An owner whose lock
was broken as stale would, on the way out, delete the lock a peer had since
taken. Release now only removes a lock still carrying its own token.
**Age aged out live installs.** `isStaleLock` applied the age check
unconditionally, so a live same-host owner running a slow native build past
`staleAfterMs` had its lock broken and a peer entered — reintroducing the very
ENOTEMPTY race. Where liveness is decidable (owner on this host) it is now the
only signal; age applies only where it cannot be (no readable owner, or another
host sharing a home directory).
**The lock path was outside the approved permission pattern.** The tool asks for
`external_directory` on `<dir>/*`, but the lock is the sibling `<dir>.lock` — so
creating, writing and removing it mutated an external path the user never
approved. It is now included in the request.
**Two unrelated cwd faults on the failure path.** `process.cwd()` throws once the
working directory is removed, and both `loadDiagnostics` and — pre-existing —
`resolveOptionalPackage`'s `createRequire` anchor called it unguarded while a
driver failure was being formatted, replacing the real diagnosis with an
unrelated `uv_cwd` ENOENT. Both are guarded; the anchor never needed cwd, since
resolution is driven by the explicit `paths`.
Tests. The two end-to-end resolution tests used the specifier `duckdb`, which the
repository's own `packages/drivers/node_modules` can satisfy no matter what the
harvesting code does — they passed while proving nothing, and would have kept
passing after the reordering above. They now use specifiers that exist nowhere
but the tree the test builds, and assert on an export marker, so they establish
which root actually satisfied the load. The cross-process exclusion test gained a
start barrier: without one, a scheduler that ran the four children serially
satisfied the no-overlap assertion even with a completely broken lock. The
control confirms the barriered test still bites — four unlocked children
interleave completely (enter 1, enter 2, enter 3, enter 0) and the assertion
rejects on the second enter. 9 repeat runs, 72/72 green.
Not verified: Windows on hardware. The separator handling is now unit-tested
through the `sep` parameter, but nothing here ran on Windows.
Co-Authored-By: Claude Opus 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01VqnuBDGkh1ZT65Ti7e6DHZ
0 commit comments