Skip to content

ci(test725): agent-node 依赖钉死 —— 提交 lockfile 并改用 npm ci(需要改一行 .gitignore) - #841

Open
vansin wants to merge 2 commits into
mainfrom
ci/agent-node-lockfile
Open

ci(test725): agent-node 依赖钉死 —— 提交 lockfile 并改用 npm ci(需要改一行 .gitignore)#841
vansin wants to merge 2 commits into
mainfrom
ci/agent-node-lockfile

Conversation

@vansin

@vansin vansin commented Aug 13, 2026

Copy link
Copy Markdown
Contributor

做了什么

tests/test725-agent-node-unit-ci/Dockerfile 里,agent-network 用 npm ci(它有 lockfile),而紧挨着的同一条 RUN 里 agent-node 用 npm install:

RUN cd agent-node && npm install --include=optional \
  && cd ../agent-network && npm ci

install 按 caret 解析「当下最新的兼容版本」。意味着同一个 commit 在不同时间会构建出不同的依赖图 —— 上游发一个兼容版本就能让这道门变红、或改变被测行为,而仓库一个字节都没动。agent-node 三个依赖全是 caret(claude-agent-sdk ^0.3.226 / undici ^6.27.0 / zod ^4.4.3)。

这是 #801 给 server 做过的同一件事。两个都合了之后,main 上 5 个包全部有 lockfile。

🔴 但这次多一步,请重点看

agent-node/.gitignore 第 4 行显式写着 package-lock.json

我第一次 git add 时它被静默拒收,于是那个提交只带上了 Dockerfile —— 一个引用着仓里不存在的文件的提交,而提交信息还写着「新增 lockfile」。那个提交已经撤掉(没推出去)。

我没有用 git add -f 绕过去。查了来历和横向对照:

.gitignorepackage-lock.json lockfile 已提交
agent-node
server 否(#801 在补)
agent-network
docs-site
prototype/anet-client-app

agent-node 是 5 个里唯一挡它的。那一行来自初始发布提交 21bc690a(2026-05-10)的模板化 dependencies 块 —— 而 agent-network 的同一个块只挡 bun.lock,不挡 package-lock.json

所以它看起来是模板不一致,不是有论证的决定。但它毕竟是签进仓的规则,我改了就该说清楚:本 PR 删掉那一行并在原处留注释说明理由。

如果当初那行是有意为之而我没找到依据,直接驳回这个 PR —— 撤销只需要还原一行。

验证

带 lockfile 重建后跑完整套件,SOURCE_COMMIT 用的是含本次改动的 SHA:

source_commit=16e4879536d3e89c58898fc3e383aadc6a04c537
 1281 pass
 0 fail
Ran 1281 tests across 91 files. [117.81s]
MUTATION_RED readable-attachment-runtime-disconnected rc=1
RESULT: PASS       退出码 0

lockfile 细节

npm install --package-lock-only --include=optional 生成,1665 行 / 121 个包 / found 0 vulnerabilities,lockfileVersion 3(与已提交的 agent-network lockfile 一致)。锁到的直接依赖:

@anthropic-ai/claude-agent-sdk  0.3.231
undici                          6.28.0
zod                             4.4.3

--include=optional 不可省:18 个包带 os/cpu 标记(SDK 与 @openai/codex 的各平台二进制),lockfile 里覆盖了全部平台而不只是生成机那一个。

test725 的 Dockerfile 里,agent-network 用 npm ci(它有 lockfile),而紧挨着的
agent-node 用 npm install —— 同一条 RUN 里两种语义。install 按 caret 解析
"当下最新的兼容版本",意味着同一个 commit 在不同时间构建出不同依赖图:上游发
一个兼容版本就能让这道门变红、或改变被测行为,而仓库一个字节都没动。
agent-node 三个依赖全是 caret(claude-agent-sdk ^0.3.226 / undici ^6.27.0 /
zod ^4.4.3)。这是 #801 给 server 做过的同一件事。

🔴 但这次比 server 那次多一步,请审查者重点看这一步:

agent-node/.gitignore 第 4 行显式写着 package-lock.json。git add 因此拒收,
我第一次提交只带上了 Dockerfile —— 一个引用着仓里不存在的文件的提交,而提交
信息还写着"新增 lockfile"。那个提交已撤(未推出去)。

我没有用 git add -f 绕过去。查了这条规则的来历与横向对照:

  包                          .gitignore 挡 package-lock.json   lockfile 已提交
  agent-node                  有                                 否
  server                      无                                 否(#801 在补)
  agent-network               无                                 是
  docs-site                   无                                 是
  prototype/anet-client-app   无                                 是

agent-node 是 5 个里唯一挡它的。那一行来自初始发布提交 21bc690(2026-05-10)
的模板化 dependencies 块 —— 而 agent-network 的同一个块只挡 bun.lock。
所以它看起来是模板不一致,不是有论证的决定。

但它毕竟是签进仓的规则,我改了它就该说清楚:本次删掉 agent-node/.gitignore
里的 package-lock.json 一行,并在原处留注释说明理由。如果当初那行是有意为之
而我没找到依据,请直接驳回这个 PR —— 撤销它只需要还原一行。

本次改动:
- 删 agent-node/.gitignore 的 package-lock.json 一行(留注释)
- npm install --package-lock-only --include=optional 生成
  agent-node/package-lock.json(1665 行 / 121 个包 / 0 vulnerabilities,
  lockfileVersion 3,与已提交的 agent-network lockfile 一致)
  锁到:@anthropic-ai/claude-agent-sdk 0.3.231 / undici 6.28.0 / zod 4.4.3
  --include=optional 不可省:18 个包带 os/cpu 标记(SDK 与 @openai/codex 的
  各平台二进制),lockfile 覆盖全部平台而不只是生成机那个
- Dockerfile:COPY 带上 package-lock.json,npm install → npm ci --include=optional

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 16e4879536

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

# install 会按 caret 解析"当下最新的兼容版本",意味着同一个 commit 在不同
# 时间构建出不同依赖图:上游发一个兼容版本就能让这道门变红或改变被测行为,
# 而仓库一个字节都没动。
RUN cd agent-node && npm ci --include=optional \

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Record the npm-ci Docker run in the test725 report

Because this line changes the dependency graph used by test725, its Docker validation needs to be preserved in the tracked report. However, docs/tests/report-test725-agent-node-unit-ci.txt still records SOURCE_COMMIT c01e205b..., the previous npm install image, and the commit does not update that report; consequently the repository has no durable evidence that this lockfile and npm ci path produced the claimed green and mutation-red results. Update the report with the exact-source image, commit, and results from this run.

AGENTS.md reference: AGENTS.md:L7-L8

Useful? React with 👍 / 👎.

审查(#841)指出:这个 PR 换掉了 test725 的依赖装法(npm install → npm ci),
改变了被测的依赖图,而 docs/tests/report-test725-agent-node-unit-ci.txt 仍记着
npm install 那版镜像的 SOURCE_COMMIT c01e205 —— 仓里没有新路径的留存证据。
指控成立。我在 test812 上做对了这件事(先建套件再留报告),这里漏了检查
「这个套件是不是已经有一份被跟踪的报告」。

新增一节,记录 SOURCE_COMMIT=16e48795 那次:
  image id sha256:eede6a7e…
  镜像内读回 TEST725_SOURCE_COMMIT=16e48795…(比对过,不是参数复述)
  镜像内实装 @anthropic-ai/claude-agent-sdk = 0.3.231,与 lockfile 锁的一致
  1281 pass / 0 fail / Ran 1281 tests across 91 files
  MUTATION_RED readable-attachment-runtime-disconnected rc=1
  RESULT: PASS 退出码 0

SDK 版本那一步不是凑数:套件全绿本身不证明 npm ci 走了 lockfile —— 构建缓存
没失效、或 Dockerfile 没 COPY lockfile,都会给出一模一样的绿。

建门那次的记录整段保留为附录,没有覆盖掉 —— 它记的是这道门当初为什么长成
这样,不是过期垃圾。
@vansin

vansin commented Aug 13, 2026

Copy link
Copy Markdown
Contributor Author

P1 成立,已补(46bd56b2)

docs/tests/report-test725-agent-node-unit-ci.txt 确实还记着 npm install 那版镜像的 SOURCE_COMMIT c01e205b。我换了依赖装法却没刷新它 —— 仓里因此没有新路径的留存证据。

值得记一笔:我在同一天的 #812 上做对了这件事(建套件 → 留报告 → 报告自带 blob 自校验),这里漏掉的是上一步:没有检查「这个套件是不是已经有一份被跟踪的报告」。新建套件我会想到留报告,改动既有套件反而忘了它可能已经有一份。

补的内容

image:    anet-test725:16e48795-exact
image id: sha256:eede6a7efd28358c4b04cf41878018c7f323ab65fed4ac1aa308504fa0fcda28
镜像内读回 TEST725_SOURCE_COMMIT=16e4879536d3e89c58898fc3e383aadc6a04c537

source_commit=16e4879536d3e89c58898fc3e383aadc6a04c537
 1281 pass
 0 fail
 4365 expect() calls
Ran 1281 tests across 91 files. [118.67s]
MUTATION_RED readable-attachment-runtime-disconnected rc=1
RESULT: PASS      退出码 0

多加了一步你没要求但这条 PR 需要的

镜像内实装 @anthropic-ai/claude-agent-sdk = 0.3.231
agent-node/package-lock.json 锁的     = 0.3.231

这一步不能省。 这个 PR 的主张是「npm ci 走 lockfile」,而套件全绿不证明这件事 —— lockfile 改了但构建缓存没失效、或 Dockerfile 根本没 COPY lockfile,都会给出一模一样的绿。只有进容器看实装版本才能把主张和证据接上。

建门那次的记录没有被覆盖

原报告整段保留为文末附录(SOURCE_COMMIT c01e205b / Base 028be50f)。它记的是这道门当初为什么长成这样(Bun 钉版的由来、非 root 运行时目录、fixture 权限修复),不是过期垃圾。

另外报告里写明了一个已知的错位:它的 SOURCE_COMMIT 指向 16e48795,而提交报告本身产生了更新的 commit;二者之间只差这一个文件,run.sh 与 Dockerfile 的 blob 未变。

顺带一提

1281 pass 对比建门那次的 1277 pass(+4)。差异来自 main 在两次之间前进,不是本次改动引入 —— 本 PR 只动 lockfile、.gitignore、Dockerfile 三个文件。

vansin pushed a commit that referenced this pull request Aug 13, 2026
审查(#842)指出:这个 PR 改了 agent-network/package-lock.json,而 test745 用
npm ci 装依赖 —— 改动改变了这道门实际跑的依赖图,而报告仍记着 b4e13f4 那版
镜像。仓里因此没有新锁制品的留存证据。指控成立。

新增一节,记录 source 507bae6 那次:
  image id sha256:ac8b956a…
  镜像内读回 TEST745_SOURCE_COMMIT=507bae6f…
  镜像内实装 hono = 4.13.1     ← 这是本次改动的主张本身
  438 pass / 0 fail / executed_files=46 discovered_files=46
  MUTATION_RED stale-config-help rc=1  RESULT: PASS 退出码 0

hono 版本那一步不是凑数:套件全绿不证明 lockfile 生效 —— 构建缓存没失效、或
Dockerfile 没 COPY lockfile,都会给出一模一样的 438 绿。

建门那次的记录整段保留为附录。

自评:同一条审查意见我一小时前刚在 #841 上收到并修复,却没把同一个检查用到
同一次会话里创建的这个 PR 上 —— 修了实例,没修类。已对我全部 open PR 做了一遍
审计:改了套件输入且零报告更新的,只有这一个。
vansin pushed a commit that referenced this pull request Aug 13, 2026
同一条审查意见一天内提了三次(#841 / #842 / #844)。三次都是:我改动了某个
套件实际跑的东西,但 docs/tests/report-test<N>*.txt 还记着改动之前那次跑的
SOURCE_COMMIT 与结果。

连着犯三次的原因不是「不知道要留报告」——新建套件时我会想到,因为报告是我
从零写的;改既有套件时那份报告已经在仓里、我根本没去看它。盲点在「有没有
意识到已经有一份」。

三次的共同点是:没有一次我改了 run.sh。判断标准不是「动没动这个套件的目录」,
是「这个套件下次跑,看到的东西会不会不一样」——
  #841 以为只改 Dockerfile 一行,实际换掉了 agent-node 的整个依赖图
  #842 以为只改一个 lockfile,实际换掉了 test745 装到的 hono 版本
  #844 以为只改两个 md,实际改了 test831 扫到的 pin 数与断言预期值

另记一条更难看的:我在 #842 的回复里写「已记进 docs/pre-pr-selfcheck.md 的
待办」,那句话当时是假的,我没写。是第三次时回头核自己说过的话才发现。
汇报里出现「已记进某文档」时,要去把那个文档打开看一眼。
vansin pushed a commit that referenced this pull request Aug 13, 2026
审查(#844)指出:这个 PR 把套件的预期分母改成 53/107,而
docs/tests/report-test831.txt 还记着 a7b1278 那次(旧 run.sh blob 6d4dca…,
计数 70/141)。仓里因此没有「改过的套件跑绿了」的留存证据。指控成立。

  source_commit=b6168cc700268a30a4325f49832e894d35d17e55
  runsh_blob=8820cffe8cd3c95006e2389912bcb7263961a4cf
  pin_occurrences=107  unique_pins=53  broken_pins=23  baseline_entries=23
  MUTATION_RED new-out-of-range-pin rc=1
  MUTATION_RED stale-baseline-entry rc=1
  RESULT: PASS  exit_code=0

blob 与 git rev-parse b6168cc:tests/test831-doc-source-pins/run.sh 逐字相符。

这是同一条意见在一天内第三次(#841 / #842 / #844)。已在
docs/pre-pr-selfcheck.md 里补成 §12(#815 分支,提交 9fb311c)——
这次是真写了,上一次我在 #842 的回复里说「已记进待办」是假的。
vansin pushed a commit that referenced this pull request Aug 13, 2026
三条全部成立。

① P1 死链:失败信息指向 docs/pre-pr-selfcheck.md §14,而那个文件不在 main 上
   (它在 #815 的分支里,未合)。实测 git ls-tree origin/main 命中 0。
   改法不是等 #815 合,是把要点直接写进失败信息 —— 门的错误提示不该依赖另一个
   未合的 PR。文件头那处引用也去掉了。

② 未钉依赖:pip install --quiet pyyaml 每次冷跑都解析成当时最新版,同一个
   commit 在不同时间可能拿到不同解析器。这正是本仓在 npm 侧用 npm ci 取代
   npm install 的同一个理由(#841 / #842)—— 我上午刚给别的包做过这件事,
   转头在自己的 PR 里犯了。
   改为 --require-hashes 从 .github/scripts/requirements-workflow-structure.txt
   安装,钉 pyyaml==6.0.2,53 个 sha256 取自 PyPI 的 release 元数据(脚本拉的,
   不是手写的)。

③ 门无法自检:如果同一次合并把 workflow-structure.yml 自己的 structure job
   弄成空壳,那个 workflow 就再也不会被调用 —— 而空壳 job 正是它要抓的东西。
   审查这条抓得准。
   改法:把同一个检查也挂进 no-memory-slugs.yml。选它是因为它的触发含
   '**/*.yml',任何 workflow 文件的改动都会到那里,所以两个文件互为兜底。
   验证:把 workflow-structure.yml 的 structure job 抽成只剩 name(仍是合法
   YAML),同一个脚本报 [no-runs-on] + [empty-steps],退出 1;复原后回绿。

@vansin vansin left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

关于「需要改一行 .gitignore」这个待裁点 —— 我把判据查了,结论:删那行是对的

这条之前挂着没人拍,因为看上去像是在动一条别人有意加的规则。查下来不是。

那行的来历:样板,不是决策

agent-node/.gitignore:4package-lock.json初始发布那一次带进来的:

$ git log -S 'package-lock.json' -- agent-node/.gitignore
21bc690a 2026-05-10 vansin
  Initial release — Agent Network v2.1.0

同一段里还有 bun.lock。也就是说它来自建包时的默认 .gitignore 模板,
没有一次「我们决定 agent-node 不锁依赖」的提交可循。

它是全仓唯一的孤例

origin/main:

已提交的 lockfile .gitignore 忽略哪些
agent-network package-lock.json bun.lock
docs-site package-lock.json
server bun.lock
agent-node bun.lock + package-lock.json

agent-network 已经在提交 package-lock.json 了,而且它的 .gitignore 忽略这个文件。
所以这个 PR 删掉 agent-node 那一行,不是引入新约定,是让它和已有的约定对齐

提交它不会影响已发布的包

agent-node/package.jsonfiles 是白名单:

"files": ["dist", "README.md"]

package-lock.json 不在里面,进不了发布 tarball(npm 本身也默认排除它)。
agent-node 没有 .npmignore,不存在另一套规则。这一点和 agent-network
(files: ["dist"],同样已提交 lockfile)是同一形状。

保留不动的部分

bun.lock 在三个包里都仍然被忽略,仓根 .gitignore:9 还有一条 *.lock ——
这次没碰,也不该碰:改的只是「npm 的锁文件要不要进版本库」,
和 bun 那套是两回事。


综上:删 agent-node/.gitignore:4 这一行,来历清楚(样板)、方向清楚(向 agent-network 对齐)、
影响面清楚(发布产物中性)。我认为可以合。

补一句方法上的:我最初提交这个改动时,git add 因为这行 ignore 静默拒绝了 lockfile,
于是那次 commit 的信息说加了 lockfile、实际只有 Dockerfile。用 git show --name-only 复核才发现。
所以这里没有用 git add -f 绕过 —— 绕过会让「为什么这个文件不该被忽略」这个问题永远不被回答。

@vansin

vansin commented Aug 13, 2026

Copy link
Copy Markdown
Contributor Author

补记一条,免得后面有人按「评审滞后」把这个 PR 打回:

Codex 那条评审写的是 Reviewed commit: 16e4879536,而当前 head 是 46bd56b2da —— 确实滞后一个提交。
但滞后的那个提交是 docs-only:

$ git show --name-status 46bd56b2
M  docs/tests/report-test725-agent-node-unit-ci.txt

本 PR 只有两个提交,代码全在 16e4879536 里,正是 Codex 评的那个;
46bd56b2 只刷新了 test725 的报告文本。所以没有未经评审的代码

(Codex 那条本身没有给出任何 finding,只有模板正文。)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants