Codex 加了包但 lockfile 没动:怎么强制同步更新

Codex 改了 package.json 但没跑 npm install,lockfile 和真实依赖分叉。用 setup.sh、CI、AGENTS.md 把锁文件强制同步。

你 review Codex 的 PR:package.json 加了 zod,代码 import 了 zod,看着没问题——直到 CI 跑 npm ci 直接挂:“lockfile out of sync with package.json”。Codex 把 dep 加进 package.json 之后没 npm installpackage-lock.json 里压根没 zod。更糟的变种:agent 跑了 npm install --no-save,或者手编辑 lockfile 写了个假 hash。

影响面不大但会破 npm ci、破可重现构建、还有风险是 agent 下次跑时挑了和你队友本地不同的 resolved 版本。

常见原因

1. Agent 跳过了 install 步骤

Codex sandbox 在 package.json 加了 "zod": "^3.22.0" 就走了,从没执行 npm install。Lockfile 一行没动。

如何判断git diff 显示 package.json 变了,package-lock.json / pnpm-lock.yaml / yarn.lock 没变。npm ci 挂。

2. Agent 跑了 npm install --no-save

Model 以为自己很谨慎——装上测试用,不改文件。包在 agent 的 node_modules 里,但永远不进 lockfile。

如何判断:transcript 里有 npm install <pkg> --no-savenpm install --no-save。Lockfile 没变。

3. Agent 用错了 package manager

你 repo 用 pnpm,Codex 跑了 npm install,生成 package-lock.json,而你出 pnpm-lock.yaml。现在两个 lockfile 并存,没明确 source of truth。

如何判断:在已有 pnpm-lock.yaml 旁边冒出新的 package-lock.json。两边 CI 都挂。

4. Agent 手编辑了 lockfile

Model 上次 run 看到 “lockfile out of sync” 错,决定直接改 package-lock.json。shasum 是假的;npm ci 在 integrity check 那挂。

如何判断package-lock.json diff 很大、看着像那么回事,但 npm ci 报 “integrity checksum failed” 或 “EINTEGRITY”。

5. setup.sh 跑了 install,但变化没 commit

.codex/setup.shnpm install 来准备环境,但产生的 lockfile 变化在 agent 进入编辑阶段前就发生了,没进 commit。

如何判断:agent sandbox 本地有 lockfile diff,PR 里没有。Transcript 显示 install 成功。

最短修复路径

Step 1:AGENTS.md “改完 package.json 必装” 规则

## 依赖规则

任何对 `package.json` 的改动(增、删、bump 版本)后:

1. 跑当前 package manager 的 install:
   -`package-lock.json``npm install`
   -`pnpm-lock.yaml``pnpm install`
   -`yarn.lock``yarn install`
2.`package.json` 和 lockfile 一起 stage 进同一个 commit。
3. 不许跑 `npm install --no-save`
4. 不许手编辑 lockfile。lockfile 看起来不对就删掉,再跑一次 install
   让 manager 重新生成。
5. 不许再加第二个 lockfile。只用 repo 里现有那个。

PR 描述里列出新增包及其原因。

短规则,附上 agent 应跑的具体命令。

Step 2:setup.sh 跑 install,让变化暴露出来

.codex/setup.sh 永远跑 install,并暴露 lockfile 变化:

#!/usr/bin/env bash
set -euo pipefail

# 检测 package manager
if [ -f pnpm-lock.yaml ]; then
  pnpm install --frozen-lockfile=false
elif [ -f yarn.lock ]; then
  yarn install
else
  npm install
fi

# 让 agent 看见 setup 改了哪些文件,提醒它一起 commit
git status --porcelain

然后 AGENTS.md 里:

setup 完成后,跑 `git status`,把 lockfile 变化和你的任务改动一起 commit。

Step 3:CI 检查 lockfile 与 package.json 同步

npm:

# .github/workflows/lockfile-check.yml
name: Lockfile check
on: [pull_request]
jobs:
  check:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with: { node-version: '20' }
      - name: 验证 lockfile 同步
        run: npm ci
      - name: 验证没有多余 lockfile
        run: |
          count=$(ls -1 package-lock.json pnpm-lock.yaml yarn.lock 2>/dev/null | wc -l)
          if [ "$count" -gt 1 ]; then
            echo "多个 lockfile 同时存在"
            ls -la package-lock.json pnpm-lock.yaml yarn.lock 2>/dev/null
            exit 1
          fi

package.jsonpackage-lock.json 不同步时 npm ci 挂。设 required status check,Codex 不更新 lockfile 就过不了。

pnpm:

- name: 验证 lockfile 同步
  run: pnpm install --frozen-lockfile

Step 4:「PR 显示 lockfile diff」规则

AGENTS.md

PR 改动了任何 lockfile 时,PR body 里加这一节:

## Lockfile 变化

`git diff --stat package-lock.json`(或 pnpm-lock.yaml)贴输出。然后:

- 新增的包
- 删除的包
- 主版本变化的包
- 每个都链对应 changelog / release notes

强制 agent 把依赖变动暴露给 reviewer。

Step 5:拦手编辑 lockfile

pre-commit hook 标可疑 lockfile 改动:

mkdir -p .git/hooks
cat > .git/hooks/pre-commit <<'EOF'
#!/usr/bin/env bash
set -euo pipefail

if git diff --cached --name-only | grep -qE '(package-lock\.json|pnpm-lock\.yaml|yarn\.lock)$'; then
  # lockfile 改了,package.json 必须也改(除非是整体 regen)
  if ! git diff --cached --name-only | grep -q 'package\.json$'; then
    echo "WARNING: lockfile 改了但 package.json 没变。"
    echo "故意的(如 dedupe)就 LOCKFILE_REGEN=1 再试。"
    [ "${LOCKFILE_REGEN:-0}" = "1" ] || exit 1
  fi
fi
EOF
chmod +x .git/hooks/pre-commit

抓 “agent 改 lockfile 来掩盖错误” 的反模式。

Step 6:用 packageManager 字段固定包管理器

package.json

{
  "packageManager": "pnpm@9.0.0"
}

.codex/setup.sh 里开 corepack,正确的 manager 才会跑:

corepack enable
corepack prepare --activate

Codex 没法不小心用别的 manager 而生成异类 lockfile。

预防

  • AGENTS.md 强制 package.json 改完必装、并明确用哪个 manager
  • .codex/setup.sh 跑 install,用 git status 暴露 lockfile 变化
  • CI 跑 npm ci / pnpm install --frozen-lockfile 当 required check
  • pre-commit hook 拦 “lockfile 变了但 package.json 没变”
  • package.json 里 pin packageManager;setup.sh 里开 corepack
  • PR body 要求一节 “Lockfile 变化” 列出 新增/删除/bump 的包

相关

标签: #Codex #agent #排查 #lockfile