Skip to content

test(ui): repository walkers tolerate tsup's transient bundled config vanishing mid-walk - #30357

Merged
objectstack-fleet[bot] merged 1 commit into
mainfrom
claude/project-thread-7kne1o
Nov 5, 2026
Merged

objectstack-fleet[bot] merged 1 commit into
mainfrom
claude/project-thread-7kne1o

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Requested by Yibo Wang · project thread

Fixes #30256

Clause-②: no
Metadata-protocol: none

维护者速读

  • 改了什么:三个扫描整个仓库的测试,读文件时不再因为 tsup 构建临时写入又删掉的 tsup.config.bundled_*.mjs 而报 ENOENT;只改测试文件,不改产品代码。
  • 为什么改:strict-authoring-face-8345 在合并队列里与并行分片的 tsup 构建竞态(队列构建 41962914067,Test UI (4/16)),把无关 PR 踢出队列。
  • 风险与回滚:只容忍 ENOENT(读之前文件消失);其他读错误照样抛出,scanned > 1000 和唯一导入者断言一字未改。回滚即还原本 PR。
  • 先看:strict-authoring-face-8345.test.ts 中提取出的 scanForImporters / readIfPresent 和新增的竞态钉子测试。
  • 两分钟验证:cd ui && pnpm exec vitest run packages/types/src/__tests__/strict-authoring-face-8345.test.ts,预期 33 例全绿。
  • 需要你做的:无,席位审阅并落地。

What changes

Why

tsup bundles each package's tsup.config.ts to tsup.config.bundled_<hash>.mjs beside it and deletes it when the build ends. A walk that lists the directory during a concurrent build can name that file and then fail to read it. readdirSync was already guarded; the per-file readFileSync was not.

Verification

  • cd ui && pnpm exec vitest run on the three touched files: 3 files, 58 tests passed (under os-verify-lock, exit 0).
  • CONTROL: the importer test still finds exactly packages/types/src/zod/index.zod.ts.
  • Ablations on the race pin (each restored byte-identical after):
    1. ENOENT guard removed (throw err unconditionally) → pin red.
    2. Name skip removed → pin red (on-disk bundle read as an importer).
    3. Guard widened to every error → pin red (EISDIR no longer thrown).
  • Sweep findings not fixed (read only; none reaches a tsup package root with an .mjs read): machineLocaleCensus-9909 reads [cm]?[jt]sx? at package roots, but its population (packages depending on @object-ui/i18n) excludes cli, create-plugin, data-objectstack; page-node-headings-drawn-11436 walks examples only (no tsup there); sidebarGroupLabel.callSites-12795 (tsx?|jsx?|mts, no .mjs); product-neutral-renderer.ratchet lists paths but does not read them; the rest walk src/ only or filter to .ts/.tsx/.json.
  • dispatch-gates --commands (26 commands) run on the final diff: see --ran record below.
dispatch-gates --ran record (26 derived, 26 run, 0 NOT-MEASURED, 0 UNRUN)
node scripts/check-closing-keyword-parity.mjs :: exit 0
node scripts/check-closing-keyword-parity.mjs --self-test :: exit 0
node scripts/check-comment-mask-corpus.mjs :: exit 0
node scripts/check-sdui-manifest.mjs :: exit 0
node scripts/check-sdui-manifest.mjs --self-test :: exit 0
pnpm --dir ui exec vitest run scripts/ :: exit 0
pnpm --filter @objectstack/spec run check:duration-unit-keys :: exit 0
pnpm check:cross-package-test-inputs :: exit 0
pnpm check:dispatcher-error-vocabulary :: exit 0
pnpm check:driver-memory-census :: exit 0
pnpm check:engine-double-contract :: exit 0
pnpm check:gitlink-declared :: exit 0
pnpm check:nul-bytes :: exit 0
pnpm check:published-files :: exit 0
pnpm check:query-options-erasure :: exit 0
pnpm check:refd-timer-probe :: exit 0
pnpm check:registry-log-declared :: exit 0
pnpm check:rest-log-spy-declared :: exit 0
pnpm check:skill-identifier-liveness :: exit 0
pnpm check:test-source-alias :: exit 0
pnpm check:tier-file-adoption :: exit 0
pnpm check:type-check-coverage :: exit 0
pnpm check:type-check-debt :: exit 0
pnpm check:undeclared-dep-imports :: exit 0
pnpm check:watch-hint-literal :: exit 0
pnpm check:where-matcher :: exit 0
  • Whole-package vitest under os-verify-lock: packages/types/ 387 files / 10,464 tests passed; packages/app-shell/ 2,176 files passed, 1 skipped (pre-existing) / 19,426 tests passed.
  • eslint on the three files: exit 0. tsc -p ui/packages/types/tsconfig.test.json --noEmit: exit 0.

Human Minimum

  • 1. Schemas start as Zod; packages/spec holds no runtime logic. (not touched)
  • 2. Every name I added uses the casing for its kind.
  • 3. No formatter ran; eslint on the touched files passes (full pnpm lint not run locally).
  • 4. One issue, one branch off an up-to-date main, one pull request.
  • 5. A change that publishes carries a changeset — this diff is test-only and publishes nothing (skip-changeset); both declaration lines are filled in above.
  • 6. packages/spec touched: n/a.
  • 7. No hand edits to generated references, changelogs or release notes.
  • 8. Title, body and comments are in English (the 维护者速读 block excepted, per project convention).
  • The Before Submitting list in CONTRIBUTING.md is done.

🤖 Generated with Claude Code

https://claude.ai/code/session_01WGufziNut2sBjutK3Sers8

… vanishing mid-walk (#30256)

strict-authoring-face-8345's importer walk listed a tsup.config.bundled_*.mjs that a
concurrent tsup build deleted before the read (ENOENT, Test UI 4/16). The walk now
skips that transient name and treats ENOENT on read as not-present; every other read
fault still throws. Same guard in the two sibling walkers that reach a tsup package
root and read .mjs: block-config-i18n and select-placeholder-literal-11252.

A race pin drives the extracted walker with a doctored listing (vanished bundle,
vanished module, on-disk bundle with a specifier, directory listed as a file).

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WGufziNut2sBjutK3Sers8
@objectstack-fleet objectstack-fleet Bot added the skip-changeset PR has no user-facing published change; bypasses the changeset gate label Nov 5, 2026
@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

domain:ui#1 · os-support-ai · session_01WGufzfE4V9fzZgJLrLDmMC

维护者速读(席位终稿)

  • 改了什么:三个会遍历整个仓库读文件的测试,遇到构建过程中临时生成又删除的 tsup.config.bundled_*.mjs 不再报错:按文件名跳过它,并且只对「文件已消失」(ENOENT) 放行。
  • 为什么改:这个竞争曾让合并队列为一个无关 PR 整组重建(strict-authoring-face-8345 test walks the repo with an unguarded readFileSync and races tsup temp bundles (queue flake) #30256)。
  • 风险与回滚:极低。只改测试,原有断言一条不放宽;除 ENOENT 外的读取错误仍然报错。回滚即 revert 本 PR。
  • 先看:ui/packages/types/src/__tests__/strict-authoring-face-8345.test.ts 的 readIfPresent。
  • 两分钟验证:pnpm --dir ui exec vitest run packages/types/src/__tests__/strict-authoring-face-8345.test.ts。
  • 需要你做的:无。不是受管面,席位直接落地。
  • 席位意见:ACCEPT。

席位核对 · ACCEPT · head 4ab343b0 · 2026-11-05T07:30Z

  1. Shape: draft, base main, Fixes #30256, skip-changeset (test-only). 3 test files, +108/−12. check-governed-merges --pr 30357: NOT governed.
  2. Read by the seat: the walker skips /\.bundled_[^./]+\.mjs$/ by name and reads through readIfPresent, which swallows ENOENT only and rethrows anything else; the listing is injectable so a race pin can name a vanished file. scanned > 1000 and the importer assertion (packages/types/src/zod/index.zod.ts only) are unchanged. The two sibling walkers with the same race (block-config-i18n, select-placeholder-literal-11252) get the same two guards, as the order's sweep allowed.
  3. Accepted deviations: two sibling test files beyond the first site (in the order's sweep clause). First push was refused by check:commit-card-trailers; amended before publishing.
  4. Evidence: race pin red under each of 3 ablations, restored; types (387 files) and app-shell (2176 files) suites green; dispatch-gates 26/26 exit 0 with --ran clean. CI on this head running at review time; auto-merge waits on it.
  5. Out of scope: none. Skills-docs: n/a.
  6. Landing: ordinary queue, now: relay pr_ready + automerge_enable, follow to MERGED, landing record on strict-authoring-face-8345 test walks the repo with an unguarded readFileSync and races tsup temp bundles (queue flake) #30256.

@objectstack-fleet
objectstack-fleet Bot marked this pull request as ready for review November 5, 2026 07:31
@objectstack-fleet
objectstack-fleet Bot enabled auto-merge November 5, 2026 07:31
@objectstack-fleet
objectstack-fleet Bot added this pull request to the merge queue Nov 5, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Nov 5, 2026
@github-actions

github-actions Bot commented Nov 5, 2026

Copy link
Copy Markdown
Contributor

⛔ merge queue 构建失败 — 先分诊,再决定要不要重排

队列构建 41989312226 红了。队列跑的是全量套件(PR 侧 CI 只跑 affected 子集),
所以失败的测试可能在本 PR 没碰过的包里 —— 那不是重排能修的。每次盲目重排都会让排在后面的所有 PR 重建一轮。

分类:failure —— 按下面的日志分诊。

失败的 job(日志抽取,best effort):

  • Lint UI — 失败步骤: Spec Liveness Check — Check the liveness ledger's citations, ui/ included

    ✗ 1 'live' / 'planned' / 'experimental' / 'live-elsewhere' citation(s) name a file that never names the property:
    

↳ 失败原因 是判读的关键:超时(Test timed out in … / Hook timed out in …)多半是负载/时序,不是本 PR 的回归;
断言(AssertionError: …)才指向真实的行为改变。两者的 FAIL 行长得一模一样,只有这一行能区分。

⚠️ 断言这一侧有一类例外,判据是断言在测什么,不是它是不是 AssertionError。 断言的对象是产品行为(一个值、一个形状、一次拒收)⇒ 照上面读:真实的行为改变,去查,⛔ 不要重排掉;
断言的对象是这次实验自身的有效性前提(跑完的耗时、负载下的先后、任何只在时间预算内才成立的条件)⇒ 它跟超时是同一类,同样对负载敏感,重排一次是合法的判别手段。
识别是机械的:断言的消息或它比较的值本身点名了一段时长、一个时间戳、一个耗时计数。实测过的一对 —— AssertionError: SecurityPlugin.init() ran: expected false to be true 测的是产品行为(真回归);
AssertionError: this run took over a second, so second-precision stamps could have differed too: expected 1006 to be less than 1000 测的是实验前提:它守护的那条不变式当时是绿的,同一个 head 原样重排一次即成功。
穿着 AssertionError 外衣的时间测量,仍然是时间测量。(⛔ 这只改「怎么读一次红」,不改「哪些测试可以重排」——后者由别处管。)

跨 PR 相同签名(24h,按失败测试文件聚合):

  • ⚠️ 本次没有可用的聚合签名(日志里没有能解析出测试文件名的 FAIL 行)—— 这不是「没有同签名的其他 PR」,是这一轮没测到。跨 PR 聚合本次不可用,请手工比对其他 PR 的同类评论。
  • ⚠️ 24h 评论账本没读完(超过 5 页仍未读到窗口尽头),所以上面的「不同 PR 数」是下界,不是全量。

历史信号:

  • 本 PR 过去 24h 无队列失败记录(首次)。
  • 过去 24h 队列共有 9 个失败构建(不含本次)。

分诊清单:

  1. 失败测试在本 PR 改动的包里 → 真回归,修 PR。
  2. 失败测试与本 PR 无关 → 看上面的「跨 PR 相同签名」;已有汇总 issue ⇒ flaky/环境问题实锤,去那张 issue 上谈,修好前重排只会再烧一轮全队列。
  3. 两者都不是 → 可能与同组 PR 语义冲突;等前面的 PR 落地或失败出队后再重排一次即可,不要连续重排。

Generated by Claude Code · merge-queue-triage workflow (#4859)

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

domain:ui#1 · os-support-ai · session_01WGufzfE4V9fzZgJLrLDmMC

Queue ejection read · held until main is green · 2026-11-05T08:22Z

@objectstack-fleet
objectstack-fleet Bot added this pull request to the merge queue Nov 5, 2026
@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

domain:ui#1 · os-support-ai · session_01WGufzfE4V9fzZgJLrLDmMC

Re-queued once: the ejection was main's own liveness red (#30367), fixed by #30368 (merged 38717d34a4). No change to this PR; git merge-tree against current main is clean.

Merged via the queue into main with commit dbf53ef Nov 5, 2026
61 checks passed
@objectstack-fleet
objectstack-fleet Bot deleted the claude/project-thread-7kne1o branch November 5, 2026 10:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/m skip-changeset PR has no user-facing published change; bypasses the changeset gate tests

Projects

None yet

Development

Successfully merging this pull request may close these issues.

strict-authoring-face-8345 test walks the repo with an unguarded readFileSync and races tsup temp bundles (queue flake)

1 participant