← 全部新闻
dependency-hygiene5 分钟阅读

Your AI Assistant Forgot the Lockfile. Your Build Will Remember.

作者:Seaworthy · 2026年11月3日

A person's hand typing on a black computer keyboard

Photo by Mohammad Rahmani on Unsplash

AI coding assistants are very good at one thing that should worry you: adding dependencies. Ask for a date picker, a retry helper, a YAML parser, and you get an import plus a fresh npm install, pip install, or cargo add before you have finished reading the diff. What you often do not get is a committed lockfile. That omission is small, boring, and one of the most common ways a working repo turns into a build that fails on a colleague's machine three weeks later.

I see this constantly in review. A pull request touches two files: package.json and a new component. No package-lock.json. Or a Python repo gains a line in pyproject.toml with no uv.lock or poetry.lock anywhere. The assistant did its job from its own narrow point of view. It made the code run. It did not do the ops half, and nobody asked it to.

Why the missing file matters more than it looks

A manifest says what you would like to install, using ranges. A lockfile says what you did install, pinned to exact versions and checksums. Without the lockfile, every install is a fresh negotiation with the registry. You get whatever satisfies ^4.2.0 today. That is not the same graph you tested, and it may not be the same graph your CI built yesterday.

The failure modes are mundane, which is why they get ignored:

  • A transitive dependency ships a breaking patch. Your local install picks it up. CI, with its cache, does not. You spend an afternoon on a bug that does not exist in either commit.
  • A package is yanked or its maintainer account is compromised. Without pinned hashes, you have no fixed point to compare against.
  • A new machine installs 300 packages you never audited, because the resolution drift pulled in fresh transitive code.
  • Security scanning reports findings against versions you cannot even confirm you use.

AI assistants make this worse in a specific way. They optimize for the immediate task and are generous with dependencies. They will reach for a library when twelve lines of standard code would do. Each of those additions is a chance to skip the lockfile, and the assistant will rarely mention that it did.

The pattern, and the fix

Here is the shape of the problem. The manifest changed, the lockfile did not, and the diff looks innocent.

# package.json
"dependencies": {
  "express": "^4.19.0",
+  "node-fetch": "^3.3.2"
}

# package-lock.json
(no changes)

The fix is to make the lockfile part of the same change, and to make CI refuse the mismatch. Most package managers will do the right thing if you let them regenerate rather than hand-edit.

# Node: refresh the lockfile and commit it with the manifest
npm install
# or, for a clean resolution that matches the manifest exactly:
npm install --package-lock-only

git add package.json package-lock.json

# Python with uv: the lockfile is the source of truth
uv lock
uv sync --locked
git add pyproject.toml uv.lock

Then add the guard that catches the next assistant. In CI, install with the frozen flag so a stale lockfile fails loudly instead of drifting silently.

npm ci            # fails if package.json and package-lock.json disagree
uv sync --locked  # fails if uv.lock is out of date

npm ci is the part people skip. It is the difference between a lockfile that exists and a lockfile that is enforced.

Prompt your assistant for the boring half

The durable fix is to change what you ask for. When you request a dependency, ask for the manifest change, the regenerated lockfile, and the install command in the same breath. Add a line to your repo instructions (AGENTS.md, CLAUDE.md, whatever your tool reads) that says lockfiles are never optional and that npm ci must pass before a task is done. Assistants follow explicit rules far more reliably than they infer unstated ops conventions.

Check for these in review, every time:

  • Did the manifest change without its lockfile?
  • Did the lockfile change without a manifest change? (That can be fine, but ask why.)
  • Is the lockfile committed, or is it sitting in .gitignore because someone found it noisy years ago?
  • Does the CI install use the frozen or clean-install path?

My reaction to the "the assistant did it" excuse is simple: the assistant does not own the build. You do. A dependency you cannot reproduce is not really a dependency you have chosen. It is one you will meet again at the worst possible time.

None of this is glamorous. It is a file, a flag, and a review habit. That is the whole point. Dependency hygiene is mostly refusing to let small omissions slide because the code ran on your laptop.

Seaworthy reviews dependency and build hygiene in repositories that lean on AI-assisted development.

本文由 AI 生成,总结了公开可用的来源。

来自 Seaworthy 团队

Seaworthy 会扫描你的代码仓库,发现类似本文提到的各种问题。

安全漏洞、泄露的密钥和配置错误——在部署前捕获。免费运行,无需账户。

$ npx seaworthycode