dx(check): fail fast when node_modules lags the lockfile - #1967
Conversation
Size Report
npm unpacked components
Startup median (7 runs, lower is better):
Top changed chunks: no changes in the largest emitted chunks. Top changed packed files
|
|
Not ready at Keep the source-worktree preflight for |
Add a doctor probe and a check:affected preflight that compare node_modules/.pnpm/lock.yaml (the exact lockfile snapshot pnpm installed from) against pnpm-lock.yaml via a content hash — no subprocess. On mismatch both surfaces report the same one-liner: "node_modules was installed from a different lockfile; run pnpm install", so a stale install names its own cause instead of surfacing as bogus format diffs on files a change never touched (the #1956 incident). Closes #1963
The probe ran unconditionally from findProjectRoot(), so it fired in two contexts it cannot diagnose: - Packaged installs. Published packages ship neither pnpm-lock.yaml (not in the package.json `files` allowlist) nor an installed snapshot, so every end user's `doctor` gained a spurious node-modules line and a degraded overall status. - `--remote`, where the daemon's own root describes the server deployment rather than the caller's worktree, so the answer could not address #1963 at all. Whether a root is a source checkout is now decided by the presence of pnpm-lock.yaml itself rather than a heuristic about install location, and 'no-source-checkout' is a distinct result rather than a warning, so the packaged case cannot be represented as a defect. The probe returns undefined there and the route appends no check, matching how doctor already models an out-of-scope question (the device family is likewise absent under --remote). The fresh-worktree catch is preserved: a lockfile with no installed snapshot is still a hard failure. The check:affected preflight is unchanged in behavior. Route-level assertions cover all three contexts (source, packaged, remote); each was verified to fail against the pre-fix wiring.
45c417b to
3f02d56
Compare
|
Code-review clean at |
|
Thanks — PR body refreshed at All 29 checks are now green. Coverage went red once on Context gatingThe discriminator is the presence of
I followed doctor's existing vocabulary for an out-of-scope question — absence, as with the device-inventory family under The fresh-worktree catch is intact: a lockfile with no installed snapshot is still a hard failure, and Route-level assertionsThree, in Two details aimed at keeping them from going vacuous:
I verified each is load-bearing by planting the pre-fix behavior: restoring the unconditional/remote-inclusive wiring fails the One honest gap: the CLI
|
|
|
Updated in 33030f6: the stale-install check now lives only in the worktree-owned check:affected preflight. The daemon/doctor integration and its packaged/remote special cases are removed, and the internal probe is excluded from the published package. It is subprocess-free and measured 0.056 ms median / 0.085 ms p95 across 1,000 warm runs on the real lockfiles. Focused preflight tests pass 62/62; package verification passes. The broad affected gate passed 7,735 related tests but twice hit the same untouched tmpdir lifecycle race under full-suite load; that owning suite passes 24/24 in isolation. I removed the stale ready-for-human label pending fresh exact-head review/CI. |
Summary
Fail
pnpm check:affected --runbefore any gate when the current worktree'snode_modules/.pnpm/lock.yamlis missing or differs frompnpm-lock.yaml.Keep this repository-development diagnostic entirely under
scripts/check-affected;agent-device doctorremains scoped to runtime, toolchain, and device diagnostics. The preflight uses no subprocess and adds no code or weight to the published package.Closes #1963
Validation
agent-device doctorguidance and missing worktree path.pnpm check:affected:test— 62 passed.pnpm check:affected --runpassed the affected implementation and 7,735 related tests; the broad run twice stopped later on the same untouched tmpdir process-lifecycle race. Its owningpnpm check:tmpdir-leaks:testsuite passed 24/24 in isolation.