A manifest declares what you want; a lockfile records what you got. The manifest holds ranges like ^1.2.0 while the lockfile pins the exact resolved version of every direct and transitive package, which is what makes builds reproducible across machines and time (lock file drift explained). Because the lockfile is machine-written, reviewers treat it as noise and skip it. That is exactly the gap attackers use.
Liran Tal's often-cited demonstration replaced a single [email protected] entry in a yarn.lock with a tarball served from a personal GitHub repository, in a pull request whose visible manifest changes looked entirely ordinary (Snyk on lockfile blind spots). The pull request passed the usual human checklist: known package, no typosquat, valid version. The malicious part lived in a few lines of a file nobody read, in a diff GitHub folds by default once it grows past a couple of hundred lines.
Two structural facts make this worse. First, lockfile designs differ wildly across package managers in what they record and how they record it, so a reviewer who is fluent in one ecosystem misreads another (the lockfile design space study). Second, lockfile drift means the file you review may not describe what CI installs, unless you use strict install modes (sbomify on drift).
Google's review guidance says the purpose of review is to keep overall code health improving, and that reviewers should favor approving a change once it clearly improves things, even if imperfect (Google's review standard). That principle cuts both ways here: a 4,000-line lockfile diff does not improve code health in any reviewable sense, and a budget is how you make the principle operational instead of aspirational.
A budget is not a ban. It is a written prior about what a healthy dependency diff looks like, so that the exception is visible rather than invisible.



