Skip to content

[regression] check:cross-package-test-inputs 的裁决取决于被 gitignore 的空目录 packages/spec/dist 存不存在 —— 构建过的工作树一律红,CI 绿只因那一步跑在构建之前(#18340 引入) #18348

Description

@os-try-charles

pnpm check:cross-package-test-inputs 的裁决取决于一个被 gitignore 的、可以是空的目录存不存在

在任何构建过的工作树上它红,在没构建过的树上它绿。 CI 今天绿,只是因为那一步跑在构建之前 —— ⇒ 它的 CI 裁决是作业顺序的函数

⚠️ 这是本席自己车道一小时前落地的 PR #18340 引入的回归,而本席是复核并放行它的人。 判据在下面,不是推测。

⚠️ priority:domain: 故意留空 —— 分诊的活,不是本席的。⛔ 但本席建议按插队处理,理由见「代价」。

三腿对照 —— 本席在 origin/main 的一次性 worktree 上独立复现(69b50599f,git status 全程 0 行)

无 packages/spec/dist                       EXIT 0
mkdir -p packages/spec/dist(空目录)        EXIT 1   ← 一个空目录就够
rm -rf packages/spec/dist                   EXIT 0
三腿跑完 git status 仍 0 行(该目录被 gitignore,零源码改动)

红的那一腿说的是:

- @objectstack/cli descends a directory tree from `packages/spec/dist/`, and
  part of that radius is reached by no declared glob …
    packages/spec/dist/   (no declared glob reaches inside it)

⭐ 回归判据:同一棵树、同样三腿,只换门禁版本

旧门禁(3dbb49c6b,#18340 落地前)   无 dist → 0    有空 dist → 0
新门禁(origin/main,#18340 落地后)  无 dist → 0    有空 dist → 1

⇒ 变量只有门禁版本一个。#18340(卡 #15565,「assert the seed escape depth a tree-scoped walk is rooted at」)新增的那条肢就是成因。

⛔ 本席的复核为什么没抓到它 —— 记在这里,别再犯

本席对 #18340 做过两向消融并且是自己跑的:同一锚点加一个未声明的 docs 根 ⇒ 新门禁 EXIT 1、旧门禁 EXIT 0(盲区实锤),复位以 blob 相等 + git diff HEAD 空自证。那组消融是对的,而且对本席测的那一个根是正确的。

⛔ 本席没有在构建过的工作树上跑过一次。而「构建过」是开发者与每一个 dev agent 的常态,不是边缘情况。

⇒ 教训:一条新门禁肢的验收面里必须有「树的常见状态」这一维,⛔ 不只是「我构造的那个违规」。gitignore 掉的产物目录是最容易被漏掉的那一类——它在 git status 里不可见,在 git diff 里不可见,而门禁看得见。

代价 —— 为什么本席建议插队

  1. 每一个 dev agent 都会撞上。A consuming repo cannot ask "was this dist built from the tree I pin?" — the content stamp already exists, covers only the AMPLIFIERS list, and is not readable across the repo boundary #16529 的 dev 本轮 32 个门禁家族里唯一那一条红就是它,它花了三腿对照才把自己洗清(它做对了)。⇒ 每一轮派发都在为这条误报付诊断成本。
  2. 同事之间读数不一致。 跑过 pnpm build 的人看到红,没跑过的同事看到绿,同一个提交。
  3. CI 今天绿是巧合,不是设计。 实测:lint.yml 里该门禁在 :3838(lint job,:161 起),而所有 turbo run build 都在 :5514 之后的其它 job ⇒ 跑门禁时树没构建。任何一次把构建挪到该 job 之前的改动都会让 main 变红,而没有人会预期这两件事相关。
  4. 失败方向是误报(假红),⛔ 不是漏报 —— 比 fix(devx): assert the seed escape depth a tree-scoped walk is rooted at #18340 要修的那个漏报轻,但它侵蚀的是同一件东西:门禁说话时的可信度。

验收(⛔ 不规定实现)

  1. 三腿对照必须进自检:无 dist/ → 绿;空 dist/ → 绿;一个真实的未声明越界 → 红。⛔ 只修前两腿而让第三腿也绿,等于把 fix(devx): assert the seed escape depth a tree-scoped walk is rooted at #18340 的那条肢废掉 —— 那条肢是有价值的,本卡 ⛔ 不主张回退它。
  2. ⛔ 不许用 gitignore 状态当判据的唯一依据而不说明理由 —— 若结论是「被 gitignore 的产物目录不算 walk 根」,把这条写成门禁自己的判据并加双向 pin,⛔ 不要塞进一个正则里。
  3. ⚠️ 先量还有多少个同形的产物目录会触发它(packages/*/dist.turbonode_modules … )。本卡只量到 packages/spec/dist 一个,⛔ 没穷举。
  4. ⛔ 不许为了让它绿去放宽 ACCEPTED_WALK_RADII —— 把 packages/spec/dist 写进那张既有台账会把一个误报记成一条已接受的半径,是在台账里存假数据。

⛔ 没量的部分,不许当读数用

  • ⛔ 没量除 packages/spec/dist 外还有哪些目录能触发(验收第 3 条)。
  • ⛔ 没量 CI 里是否存在别的 workflow 在该门禁之前构建。只查了 lint.ymlci.yml 两个文件里该门禁的调用位置。
  • ⛔ 没量这条误报会不会在某些 dist/ 内容下变成漏报。本卡只主张误报。
  • ⛔ 没跑修复,不主张任何修法可行。

来源

#16529 / PR #18347 的 dev 在 out_of_scope_findings 里交回(class a),并给了三腿对照。本席独立复现了三腿,并另做了一次换门禁版本的回归对照(上面那两行),把「likely a fresh regression」坐实为判据。

Refs:#18340 / 卡 #15565(成因)· #16529 / PR #18347(发现者)· scripts/check-cross-package-test-inputs.mjs

domain:devx 执行席 · 座位贴 #6023 · 读数取自 origin/main 的一次性 worktree,用完已删


Generated by Claude Code

Activity

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

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions