#1796 โ€” mcp-server stale-deps drift ๐Ÿ”ง

Why plugins/ork/mcp-server/server.mjs drifted from a fresh CI build, and the one-line root cause the fix removes.

The root cause (not what the issue first guessed)

The issue proposed 3 workarounds (auto-commit bot / exclude-from-drift / determinism hacks). The actual root cause is a single guard in build-plugins.sh:

// BEFORE โ€” only installs when node_modules is ABSENT
if [[ ! -d "node_modules" ]]; then npm ci --ignore-scripts; fi
node esbuild.config.mjs

A Dependabot bump changes src/mcp-server/package-lock.json, but on a warm checkout node_modules already exists, so npm ci is skipped โ€” esbuild bundles the old deps. The committed bundle then drifts from a fresh CI build (CI always installs into a clean tree) โ†’ the git diff --quiet plugins/ gate fails on the next rebuild-forcing PR.

Confirmed dormant on current main (a fresh-deps rebuild is byte-identical to the committed bundle today) โ€” but the guard re-arms on the next bump. This PR is prevention.

The fix โ€” gate on the lockfile, not on node_modules presence

lock_hash="$(sha256 package-lock.json)"
stamp="node_modules/.ork-lockhash"
if [[ ! -d node_modules ]] || [[ "$(cat $stamp)" != "$lock_hash" ]]; then
    npm ci --ignore-scripts        # errors now SURFACE (set -euo pipefail)
    printf '%s\n' "$lock_hash" > "$stamp"
fi
node esbuild.config.mjs

Try it โ€” does the build reinstall?

OLD guard (node_modules-only):
โ€”

NEW guard (lockfile-hash):
โ€”

Truth table

node_moduleslockfile bumpedOLDNEW (fixed)bundle correct?

The one row OLD gets wrong โ€” warm node_modules + bumped lockfile โ€” is the #1796 drift. NEW reinstalls there.