Every new worktree was born dirty

A lockfile carries the version twice. release-please was told to bump package.json and never told about package-lock.json, so both copies went stale. npm rewrites them on the next install, which means every fresh clone and every new worktree came up modified before anyone touched a line of code.

The three version fields

package.json $.version
9.7.0
lock $.version
9.7.0
lock $.packages[''].version
9.7.0

Why it kept coming back

A tree that is dirty on arrival trains everyone to ignore dirt. In one session this exact diff was reverted twice as "incidental churn" before anyone asked why it kept reappearing. That is the real cost: not the two stale numbers, but the habit of waving a modified file through because it is always modified.

Root cause, not symptom. Committing a resynced lockfile alone would have lasted exactly one release. .release-please-config.json now lists package-lock.json under both json paths, so release-please keeps them in step the same way it already did for package.json.

Backstopped. tests/manifests/test-version-consistency.mjs asserts the three fields agree AND that the two config entries still exist, so deleting the fix fails loudly at the gate instead of silently reopening the drift one release later.

Proven able to fail

A gate that cannot fail is worth nothing, so both halves were mutated and measured:

Mutation A set the lockfile back to 9.5.2 → gate exits 1, "$.version is 9.5.2, package.json is 9.7.0".
Mutation B removed the two config entries → gate exits 1, "the drift will silently return".
Both restored → green.

measured at origin/main 1f4cf6125· package.json 9.7.0 vs lockfile 9.5.2· two minor versions stale