* dx(doctor): flag a worktree whose node_modules lags the lockfile
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
* fix(doctor): scope the node-modules probe to a local source checkout
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.
* refactor(check): keep stale-install probe worktree-local