fix(ci): give the macOS and Windows lanes a trigger again - #9370
Conversation
Both lanes are gated on `merge_group`, and no merge queue is enabled on this repository — the `main` ruleset carries only deletion, non-fast-forward and pull_request rules, no status check is required, and merges land as squashes. The last `merge_group` run of anything was 2026-07-02. So the gate was an off switch: the lanes reported as "skipped" on every pull request, which reads as agreement, and nothing ever reached them afterwards. The only signal this repository has about a host that is not Linux with a GNU userland had been silently off for six weeks, which is how #9220 shipped a GNU-only `realpath -m` in a workflow guard with the suite that pinned it red on every Mac. Three triggers now, in cost order. A pull request whose diff a new classifier recognises as platform-sensitive: shell scripts of every dialect, workflow and composite-action YAML and the scripts they call, the script layer and its tests, the test-runner configuration that decides which suites run where, the root manifests, and source paths whose segments name a platform-coupled subsystem. It is a net, not a proof — it cannot see a platform assumption inside an ordinary source file, and no path rule ever will — so every unknown answers "sensitive": an unreadable listing, an unparsable entry, a fork pull request, a truncated file list, or the classify job failing outright all end as "run the lanes". Only a confident `false` skips them. The merge queue, if it is ever enabled again, unchanged. And a nightly run on `main` for everything the path list cannot see. Every other job in the workflow excludes `schedule` explicitly, so a nightly is exactly two jobs, and 'Qwen Code CI' joins the workflows the main-failure watcher opens autofix issues for — a red lane nobody is told about is the same silence the queue gate produced. That watcher gains a trigger-level `branches: ['main']` filter so the CI workflow's pull-request completions do not raise an event there just to skip. The classifier runs in its own small hosted job rather than as a step in `classify_pr`: that job's outputs pick the Linux runner for the whole run, and this one needs a checkout — on a pool whose workspace other jobs have poisoned before. It checks out the pull request's BASE commit, never the head: it runs before any review and executes a script from the tree it checks out. Its listing goes through the existing classify-pr-profile.sh wrapper, extended with a mode argument, because that wrapper's whole point is that one PR is never listed twice and classified differently in two places. Twelve tests pin the wiring — the triggers, the fail-safe direction of the gate, the base-commit checkout, that a nightly stays two jobs, and the alerting — and ten more pin the classifier itself, including the substring traps (`Shellfish.tsx`, `cryptic.ts`, `plateauDetector.ts` must not drag both lanes in) and every fail-safe path. Mutation-checked: flipping the gate to `== 'true'`, dropping the schedule from a lane, dropping the nightly guard from the ubuntu job, pointing the checkout at the head, dropping the classifier's test from the helper list, and removing the schedule trigger are each caught.
|
|
The first thing the revived triggers hit was not a test failure but the lane's own plumbing. `test_windows` verifies its checkout with `verify-checkout-head`, and the input was written when this lane ran in the merge queue alone: `expected_sha: github.event.merge_group.head_sha`, with no event gate. On a pull request that expression is empty, the action refuses an empty SHA, and the lane went red in 63 seconds without running a test — the first Windows run in six weeks, failing on the trigger rather than on the code. Give it the event-aware shape the Ubuntu gate already uses, and skip it where there is nothing to verify: the scheduled and dispatch runs check out a branch by name, not a head commit. Pinned generally rather than by name: for both lanes, any step whose inputs read a `github.event.<event>` context must be gated to that event, in the step's own `if` or in the expression itself. Restoring the old spelling turns that test red.
|
Re-running the gate on the current head, as requested. Template still looks good ✓ — all required sections present, bilingual body.
Moving on to code review. 🔍 中文说明按要求在当前 head 上重新执行 gate。模板依旧完整 ✓ —— 必填小节齐全,正文双语。
进入代码审查。🔍 — Qwen Code · qwen3.8-max Reviewed at |
|
Code review — this pass reviews
No correctness blockers, no convention violations. Known non-blocking items from the review ledger (the round-9 Suggestion that the nightly-exclusion pin is presence-based, plus three deferred probes) remain tracked there; I re-verified the shipped YAML directly and it is correct even where the pin could be tighter. Test evidence — the PR's own CI. I did not run any PR code. The reviewed commit's CI was in flight at fetch time (table below, updated in place by the finalize job); the classification of the reds comes from the previous completed head
Trust boundary: that classification rests on the diff footprint and the failing test identities (GitHub metadata), not on anything the log body claims. Final CI results for
One row per check name (latest run); skipped checks omitted; failures sort first. / 每个检查名一行(取最新一次运行),省略 skipped,失败项排在最前。 No sandboxed lane applies here, and it is worth saying why rather than silently omitting it: the PR's central behavioural claim — the gate fires when the classifier recognises the diff — is substantiated by the PR's own checks (the classify job green and both lanes actually running, on two consecutive heads). The one claim no pre-merge lane can settle is the nightly cron itself: no 中文说明代码审查 —— 本次审查针对
无正确性阻塞项,无规范违规。审查台账中的已知非阻塞项(第 9 轮 Suggestion:nightly 排除钉住基于"存在性"检查;以及三条延后的 probe)仍在那里跟踪;凡钉住可以更紧的地方,我都直接复核了上线 YAML 本身,是正确的。 测试证据 —— PR 自身的 CI。未运行任何 PR 代码。被审 commit 的 CI 在获取时仍在运行(下表由 finalize job 落定后更新);红色判定来自上一个已完成 head
信任边界:上述判定基于 diff 足迹与失败测试的身份(GitHub 元数据),不基于日志正文的任何声称。 CI 表见上方标记区域(finalize job 更新)。无沙箱泳道适用于此,并值得说明原因而非静默省略:本 PR 的核心行为主张——分类器识别的 diff 会触发 gate——已由 PR 自身的 checks 证实(classify job 为绿、两条泳道真实运行,且连续两个 head 均如此)。唯一任何合并前泳道都无法验证的是 nightly cron 本身:没有任何 — Qwen Code · qwen3.8-max Reviewed at |
|
Confidence: 4/5 — clean review across every stage; the one point withheld is not about the code but about what happens next: the two revived lanes are red for pre-existing reasons, so the deferred approval below will almost certainly be withheld by the finalize job, and this PR will need a human approval call. Stepping back: my independent proposal for this problem — keep the queue trigger, add a classified pull-request trigger, add a nightly heartbeat everything else excludes, and make a red nightly visible — is materially identical to what landed, and every place the PR goes past it has an auditable reason in the diff. The piece I'd have missed twice now (the revived triggers tripping the Windows lane's stale merge-queue checkout guard; fork PRs reaching the persistent pool through the lane's runs-on) is in both cases fixed and turned into a standing invariant test. The review rounds converged: round 10 closed with no new findings, and the items still in the ledger are Suggestion-grade test-robustness notes, each one verified by me against the shipped YAML, which is correct. The red lanes are the whole point of this PR, not an argument against it. I classified them from the failing jobs' logs, not from the PR's framing: every Windows failure sits in a package suite the diff does not touch, and macOS's own tests all pass before an infra timeout takes the job down. Six weeks of silence surfaced in one run, exactly as predicted, and it went into #9481 where it belongs. Blocking this PR on those failures would reproduce the exact deadlock that switched the lanes off: unfixable until the lanes run, and the lanes not running until the fix lands. Two reservations, named rather than blocking. The nightly cron cannot be exercised by any pre-merge lane — its first run is the day it lands, and the watcher alerting is what keeps a red nightly from becoming another silence. And procedurally: approval is deferred until CI settles on the reviewed commit; when the two lanes land red for their documented pre-existing reasons, the finalize job will withhold the approval and flag it, at which point a maintainer needs to make the human call with that context. (The four stale changes-requested states on this PR are early bot review rounds whose threads are all resolved; they predate the current head.) 中文说明置信度:4/5 —— 各阶段审查全部干净;扣掉的一分不在代码本身,而在接下来会发生什么:两条复活的泳道正因预先存在的原因而红,下方的延迟批准几乎必然被 finalize job 拦下,本 PR 需要一次人工批准决定。 退一步看:我为这个问题给出的独立提案——保留队列触发器、增加带分类的 pull-request 触发器、增加排除其余一切 job 的 nightly 心跳、让红色 nightly 可见——与落地方案实质相同;PR 超出提案的每一处都能在 diff 中找到可审计的理由。连我两次都会漏掉的点(复活的触发器撞上 Windows 泳道陈旧的 merge-queue 检出守卫;fork PR 经由泳道的 runs-on 触达持久池)都已修复,并被升级为常驻不变量测试。评审轮次已收敛:第 10 轮无新发现收尾;台账中遗留的条目均为 Suggestion 级的测试健壮性注记,我逐一对照上线 YAML 核实过,是正确的。 红色泳道正是本 PR 的意义所在,而不是反对它的理由。判定来自失败 job 的日志,而非 PR 的自我陈述:Windows 的每一个失败都在 diff 未触及的包套件内,macOS 自身的测试全部通过、job 死于一个基础设施超时。六周沉默在一次运行中尽数暴露,与预言一致,并已归入 #9481。以这些失败为由阻塞本 PR,会复现当初让泳道关闭的那个死锁:不跑泳道就修不了,而泳道在修复落地前不会跑。 两点保留意见,点名而非阻塞。nightly cron 无法被任何合并前泳道演练——首次运行只能是落地当天,接好的监视器告警保证红色 nightly 不再沦为沉默。程序上:批准推迟到 CI 在被审 commit 上落定;当两条泳道因其已记录的预存原因落红时,finalize job 会拦下批准并标记,届时需要维护者带着这些上下文做出人工决定。(本 PR 上四个过期的 changes-requested 状态是早期机器人评审轮次留下的,相关线程均已解决;它们早于当前 head。) — Qwen Code · qwen3.8-max Reviewed at |
Code Coverage Summary
CLI Package - Full Text ReportCore Package - Full Text ReportFor detailed HTML reports, please see the 'coverage-reports-22.x-ubuntu-latest' artifact from the main CI run. |
|
@qwen-code /takeover |
|
🤝 Takeover engaged: the autofix loop now manages this PR — it will address new review feedback and resolve base conflicts until the label is removed or the round cap is reached. Remove the 中文说明🤝 已接管:autofix 循环现在管理此 PR —— 将持续处理新的评审反馈与 base 冲突,直到移除标签或达到轮次上限。移除 |
qwen-code-ci-bot
left a comment
There was a problem hiding this comment.
Partially reviewed — gaps disclosed.
Not reviewed: reverse audit — did not converge within the reverse-audit round cap of 10.
Not linted (tool limitation, not a blocker): the executable-script lint — .github/workflows/ci.yml: actionlint embedded-shell source mapping is not yet supported — not linted; the executable-script lint — .github/workflows/main-ci-failure-issue.yml: actionlint embedded-shell source mapping is not yet supported — not linted.
中文说明
仅完成部分审查,审查缺口已披露。
未审查:反向审计——在 10 轮的反审轮数上限内未收敛。
未检查(工具限制,非阻断):the executable-script lint — .github/workflows/ci.yml: actionlint embedded-shell source mapping is not yet supported — not linted; the executable-script lint — .github/workflows/main-ci-failure-issue.yml: actionlint embedded-shell source mapping is not yet supported — not linted。
— qwen3.8-max via Qwen Code /review (v0.21.13)
|
🔀 Base updated: red check(s) [Test (ubuntu-latest, Node 22.x)] pass on current main — merged current main via update-branch; CI will re-run. 中文说明🔀 已更新 base:红色检查 [Test (ubuntu-latest, Node 22.x)] 在当前 main 上通过 —— 已通过 update-branch 合入当前 main,CI 将重新运行。 |
qwen-code-ci-bot
left a comment
There was a problem hiding this comment.
Partially reviewed — gaps disclosed.
2 Suggestion-level finding(s) this review confirmed are already reported on this PR and are not repeated:
- R1-4 schedule clause applies to all three watched workflows — already reported (comment 3801128043)
- R1-5 queue-starvation silence on the nightly Windows lane — already reported (comment 3801128051)
Not reviewed: the executable-script lint — .github/scripts/ci/classify-pr-profile.sh: shellcheck is not installed.
Not linted (tool limitation, not a blocker): the executable-script lint — .github/workflows/ci.yml: actionlint embedded-shell source mapping is not yet supported — not linted; the executable-script lint — .github/workflows/main-ci-failure-issue.yml: actionlint embedded-shell source mapping is not yet supported — not linted.
Deferred under the convergence posture (round 2, not a blocker) — recorded, not requested in this round:
.github/scripts/ci/classify-platform-sensitivity.test.mjs:33 — [probe] D2-1 the ps1 and actions classifier branches are pinned by no test (shadowed fixtures) — confirmed by probe.github/scripts/ci/classify-platform-sensitivity.mjs:50 — [probe] D2-2 .gitattributes classifies insensitive though the Windows lane's EOL handling depends on it — confirmed by probe.github/workflows/ci.yml:1022 — [probe] D2-3 schedule/dispatch runs of test_windows are exempted from the stale-checkout guard — confirmed by probe
中文说明
仅完成部分审查,审查缺口已披露。
本轮确认的 2 条建议级发现已在 PR 上报告过,不再重复发布(列表见上方英文部分)。
未审查:the executable-script lint — .github/scripts/ci/classify-pr-profile.sh: shellcheck is not installed。
未检查(工具限制,非阻断):the executable-script lint — .github/workflows/ci.yml: actionlint embedded-shell source mapping is not yet supported — not linted; the executable-script lint — .github/workflows/main-ci-failure-issue.yml: actionlint embedded-shell source mapping is not yet supported — not linted。
收敛姿态下延后(第 2 轮,非阻断)——已记录,本轮不要求修改:共 3 条(原文未翻译,列表见上方英文部分)。
— qwen3.8-max via Qwen Code /review (v0.21.13)
|
🔀 Base updated: red check(s) [Test (ubuntu-latest, Node 22.x)] pass on current main — merged current main via update-branch; CI will re-run. 中文说明🔀 已更新 base:红色检查 [Test (ubuntu-latest, Node 22.x)] 在当前 main 上通过 —— 已通过 update-branch 合入当前 main,CI 将重新运行。 |
qwen-code-ci-bot
left a comment
There was a problem hiding this comment.
Partially reviewed — gaps disclosed.
Not reviewed: the executable-script lint — .github/scripts/ci/classify-pr-profile.sh: shellcheck is not installed.
Not linted (tool limitation, not a blocker): the executable-script lint — .github/workflows/ci.yml: actionlint embedded-shell source mapping is not yet supported — not linted; the executable-script lint — .github/workflows/main-ci-failure-issue.yml: actionlint embedded-shell source mapping is not yet supported — not linted.
中文说明
仅完成部分审查,审查缺口已披露。
未审查:the executable-script lint — .github/scripts/ci/classify-pr-profile.sh: shellcheck is not installed。
未检查(工具限制,非阻断):the executable-script lint — .github/workflows/ci.yml: actionlint embedded-shell source mapping is not yet supported — not linted; the executable-script lint — .github/workflows/main-ci-failure-issue.yml: actionlint embedded-shell source mapping is not yet supported — not linted。
— qwen3.8-max via Qwen Code /review (v0.21.13)
|
🔀 Base updated: red check(s) [Test (ubuntu-latest, Node 22.x)] pass on current main — merged current main via update-branch; CI will re-run. 中文说明🔀 已更新 base:红色检查 [Test (ubuntu-latest, Node 22.x)] 在当前 main 上通过 —— 已通过 update-branch 合入当前 main,CI 将重新运行。 |
qwen-code-ci-bot
left a comment
There was a problem hiding this comment.
Partially reviewed — gaps disclosed.
1 Suggestion-level finding(s) this review confirmed are already reported on this PR and are not repeated:
- reverse-audit round 4 finding: the unscoped
event == 'schedule'clause also files autofix issues for red E2E Tests nightlies (corroborated by a real red nightly on 2026-08-09) — already reported (comment 3801128043)
Not reviewed: the executable-script lint — .github/scripts/ci/classify-pr-profile.sh: shellcheck is not installed.
Not linted (tool limitation, not a blocker): the executable-script lint — .github/workflows/ci.yml: actionlint embedded-shell source mapping is not yet supported — not linted; the executable-script lint — .github/workflows/main-ci-failure-issue.yml: actionlint embedded-shell source mapping is not yet supported — not linted.
Deferred under the convergence posture (round 4, not a blocker) — recorded, not requested in this round:
scripts/tests/ci-platform-lanes.test.js:38 — [probe] the schedule-trigger test pins cron shape only, not the daily cadence the design depends on
中文说明
仅完成部分审查,审查缺口已披露。
本轮确认的 1 条建议级发现已在 PR 上报告过,不再重复发布(列表见上方英文部分)。
未审查:the executable-script lint — .github/scripts/ci/classify-pr-profile.sh: shellcheck is not installed。
未检查(工具限制,非阻断):the executable-script lint — .github/workflows/ci.yml: actionlint embedded-shell source mapping is not yet supported — not linted; the executable-script lint — .github/workflows/main-ci-failure-issue.yml: actionlint embedded-shell source mapping is not yet supported — not linted。
收敛姿态下延后(第 4 轮,非阻断)——已记录,本轮不要求修改:共 1 条(原文未翻译,列表见上方英文部分)。
— qwen3.8-max via Qwen Code /review (v0.21.13)
|
🤖 Addressed the latest review feedback (round 1/100). What changed, and what I pushed back on: · 已处理最新评审反馈(第 1/100 轮)。改动内容与我反驳保留之处如下: Review round summary — PR #9370This round implemented the three Critical findings plus five Suggestion-level Resolved
Deferred to the next round (batch bound, Criticals first)
Each has a reply on its thread in VerificationCommands actually run this round (working tree, then re-checked on the committed tree):
Pre-round reproduction evidence: R1-2's two failing pins were reproduced at the round-start tree (2 failed | 8 passed); R1-3's dead error path was reproduced with the runner's exact shell invocation (step exit 2, no 中文说明审查轮次总结 — PR #9370本轮实现了三条严重(Critical)发现与五条建议(Suggestion)级发现,遵守每轮批次上限(Critical 优先、最多约 8 条)。其余七条建议已通过 已解决
延后到下一轮(批次上限,Critical 优先)
每条都已在其线程中通过 验证本轮实际运行的命令(先在工作树上运行,提交后又在提交树上复核):
轮前复现证据:R1-2 的两处失败断言已在轮次开始时的树上复现(2 失败 | 8 通过);R1-3 的死错误路径已用 runner 的真实 shell 调用方式复现(步骤退出码 2、无 Base-conflict check · 基分支冲突检查: no conflict with main. · 与 main 无冲突。 Re-review when you have a moment. After round 100 this bot stops and leaves the PR for a human. · 有空请复审;第 100 轮后本 bot 停止并将 PR 交给人工。 🧠 Handled by Qwen Code · model/模型 |
qwen-code-ci-bot
left a comment
There was a problem hiding this comment.
Partially reviewed — gaps disclosed. Suggestions are inline.
4 Suggestion-level finding(s) this review confirmed are already reported on this PR and are not repeated:
- web-shell keyword overmatch in PLATFORM_SUBSYSTEM — already reported (comment 3801901563)
- parseChangedFiles/main() duplication vs sibling classify-profile.mjs — already reported (comment 3801901568)
- nightly-exclusion guard presence-check hole, incl. this round's demonstrated && → || connective mutant — already reported (comment 3801901554)
- watcher name binding pinned one-sidedly — already reported (comment 3801901559)
Not reviewed: the executable-script lint — .github/scripts/ci/classify-pr-profile.sh: shellcheck is not installed.
Not linted (tool limitation, not a blocker): the executable-script lint — .github/workflows/ci.yml: actionlint embedded-shell source mapping is not yet supported — not linted; the executable-script lint — .github/workflows/main-ci-failure-issue.yml: actionlint embedded-shell source mapping is not yet supported — not linted.
Deferred under the convergence posture (round 5, not a blocker) — recorded, not requested in this round:
scripts/tests/ci-platform-lanes.test.js:65 — [probe] !cancelled() connective unpinned — an || mutation makes the lane gate a tautology (probe-confirmed mutant survives 26/26).github/scripts/ci/classify-platform-sensitivity.mjs:58 — [probe] no docs carve-out — 76 of 540 docs files classify sensitive, contra the PR's own cost claim (probe-confirmed sweep)
中文说明
仅完成部分审查,审查缺口已披露。 建议见行内评论。
本轮确认的 4 条建议级发现已在 PR 上报告过,不再重复发布(列表见上方英文部分)。
未审查:the executable-script lint — .github/scripts/ci/classify-pr-profile.sh: shellcheck is not installed。
未检查(工具限制,非阻断):the executable-script lint — .github/workflows/ci.yml: actionlint embedded-shell source mapping is not yet supported — not linted; the executable-script lint — .github/workflows/main-ci-failure-issue.yml: actionlint embedded-shell source mapping is not yet supported — not linted。
收敛姿态下延后(第 5 轮,非阻断)——已记录,本轮不要求修改:共 2 条(原文未翻译,列表见上方英文部分)。
— qwen3.8-max via Qwen Code /review (v0.21.13)
|
🤖 Addressed the latest review feedback (round 2/100). What changed, and what I pushed back on: · 已处理最新评审反馈(第 2/100 轮)。改动内容与我反驳保留之处如下: Review round summary — PR #9370This round addressed the one new inline finding (the ECS trust-policy Resolved
Failed checks — investigated, blocked on CI logs
Not actioned this round
VerificationCommands actually run this round:
中文说明审查轮次总结 — PR #9370本轮处理了一条新的行内发现(ECS 信任策略的双重编码),并调查了两条失败的平台泳道。行内发现已实现并完成突变验证;泳道失败无法在本 runner 上定位根因——证据链与阻塞点记录如下。无 base 冲突( 已解决
失败检查 —— 已调查,阻塞于 CI 日志
本轮不处理
验证本轮实际执行的命令:
Base-conflict check · 基分支冲突检查: no conflict with main. · 与 main 无冲突。 Re-review when you have a moment. After round 100 this bot stops and leaves the PR for a human. · 有空请复审;第 100 轮后本 bot 停止并将 PR 交给人工。 🧠 Handled by Qwen Code · model/模型 |
qwen-code-ci-bot
left a comment
There was a problem hiding this comment.
Partially reviewed — gaps disclosed.
2 Suggestion-level finding(s) this review confirmed are already reported on this PR and are not repeated:
- parseChangedFiles/main() duplication vs sibling classify-profile.mjs — already reported (comment 3801901568)
- nightly-exclusion guard presence-check hole in scripts/tests/ci-platform-lanes.test.js — already reported (comment 3801901554)
Not reviewed: the executable-script lint — .github/scripts/ci/classify-pr-profile.sh: shellcheck is not installed.
Not linted (tool limitation, not a blocker): the executable-script lint — .github/workflows/ci.yml: actionlint embedded-shell source mapping is not yet supported — not linted; the executable-script lint — .github/workflows/main-ci-failure-issue.yml: actionlint embedded-shell source mapping is not yet supported — not linted.
中文说明
仅完成部分审查,审查缺口已披露。
本轮确认的 2 条建议级发现已在 PR 上报告过,不再重复发布(列表见上方英文部分)。
未审查:the executable-script lint — .github/scripts/ci/classify-pr-profile.sh: shellcheck is not installed。
未检查(工具限制,非阻断):the executable-script lint — .github/workflows/ci.yml: actionlint embedded-shell source mapping is not yet supported — not linted; the executable-script lint — .github/workflows/main-ci-failure-issue.yml: actionlint embedded-shell source mapping is not yet supported — not linted。
— qwen3.8-max via Qwen Code /review (v0.21.13)
Verification run (fixes + #9370's workflow) cut the Windows failures from 69 to 5 and left the macOS lane's infra error. Follow-ups: - daemon-git-worktree-guard resolvePhysicalPath: splitting an absolute Windows path yields the drive as a segment (C:), which path.join glued back onto the root as C:\C:. Walk only the part past the root. Exposed by the first round's tokenizer fix, which let intact drive paths reach this code for the first time. - scratch-tree tests: the git-created gitfile refuses in-place overwrite on Windows even after clearing the read-only attribute; delete and recreate instead. - bridge.test stderr audit assertion: the line prints the session id through JSON.stringify, escaping Windows backslashes; match the escaped spelling (test added this morning by #9543, landed after the baseline census). - managed-scratch 'root replaced' test: dev/ino identity is not reliably observable on every Windows volume; state the precondition and skip where the swap is indistinguishable. - scripts vitest suite: the unhandled onTaskUpdate worker RPC timeout is deterministic on the macOS runners with every test green; stop letting unhandled errors fail this suite while test failures stay fatal, and drop the stale claim that the pool override removal fixed it.
One conflict, resolved as the union of both sides: ci.yml's HELPER_TESTS keeps this branch's ci/classify-platform-sensitivity.test.mjs entry and gains main's WORKFLOW_SIZE_BASE_SHA env block (#9931/#9904) beneath it. Also bump ci.yml's .size-baseline entry 74315 -> 81137 in the same commit: main's workflow-size ratchet arrived while this branch was open, and this PR's growth of ci.yml is real — the schedule trigger, the classify_platform job, and the revived lane wiring. Without the bump the ratchet's vitest mirror fails `npm run test:scripts` on every lane and the shell gate fails the ubuntu gate step.
|
🤖 Addressed the latest review feedback (round 10/100). What changed, and what I pushed back on: · 已处理最新评审反馈(第 10/100 轮)。改动内容与我反驳保留之处如下: Autofix round report — merged
|
|
📊 Takeover milestone — round 10/100, in the current window. Census: 8 pushed fix(es), 5 no-change review(s), 0 timeout(s), 1 rejected attempt(s), 0 deliberate stop(s) under instruction (deferred to a human), 1 other round(s) (crash / model error / gate error / infra), 3 base update(s). This many rounds deserves a human look. Options: keep going (fine — nothing changes), split or reduce the PR if rounds keep accumulating, or release takeover (remove the 中文说明📊 接管里程碑 —— 第 10/100 轮(当前窗口)。统计:推送修复 8 次、审阅无需改动 5 次、超时 0 次、验证拒绝 1 次、按指示有意停止(移交人工)0 次、其他轮次(崩溃/模型错误/门错误/infra)1 次、base 更新 3 次。 轮次到这个量值得人工看一眼。可选:继续(无需操作);若轮次持续累积,考虑拆分或缩减 PR;或释放接管(移除 |
qwen-code-ci-bot
left a comment
There was a problem hiding this comment.
Not linted (tool limitation, not a blocker): the executable-script lint — .github/workflows/ci.yml: actionlint embedded-shell source mapping is not yet supported — not linted; the executable-script lint — .github/workflows/main-ci-failure-issue.yml: actionlint embedded-shell source mapping is not yet supported — not linted.
中文说明
未检查(工具限制,非阻断):the executable-script lint — .github/workflows/ci.yml: actionlint embedded-shell source mapping is not yet supported — not linted; the executable-script lint — .github/workflows/main-ci-failure-issue.yml: actionlint embedded-shell source mapping is not yet supported — not linted。
— qwen3.8-max via Qwen Code /review (v0.22.0)
|
🤖 Reviewed the latest feedback — no changes needed. Why, point by point: · 已审阅最新反馈——无需改动。逐点说明原因如下: No action this round — both failed checks re-triaged on NEW evidence; both stay routed to #9481Critical-only mode is active. The reviews, inline-comment, and issue-level Test (windows-latest, Node 22.x): FAILURE — the failure census CHANGED since the last lane observation; the three remaining failures are platform drift from main commits dated Aug 23–24Fresh evidence, gathered from the failing job itself (run 32809721070, job
Disposition: unchanged from maintainer triage (issue comment 5343315912, Test (macos-latest, Node 22.x): FAILURE — the recorded vitest-worker RPC timeout, reproduced at this head
Why no change this roundBoth red checks are documented, triaged to #9481 (still open), and Verification (commands actually run this round)
中文说明本轮无改动 —— 两个失败检查均基于新证据重新分诊;仍归入 #9481当前处于仅处理 Critical 的模式。评审、行内评论与议题级评论区域均无内容; Test (windows-latest, Node 22.x):失败 —— 失败清单自上次泳道观测以来已变化;剩余 3 个失败是 8 月 23–24 日 main 提交带来的平台漂移以下新证据直接取自失败 job 本身(run 32809721070,job 97686670053),经 GitHub 公开 API 只读获取:
处置:与维护者分诊一致(议题评论 5343315912,2026-08-19)——"恢复触发器正是它发现问题的方式,而修复……平台漂移应放在单独的变更中",已立为 #9481(仍 OPEN;其处理说明写明 #9370 的合入不依赖于此)。复活的泳道再次尽到职责:昨天进 main 的提交,今天就暴露在泳道之下。这 3 个失败属于 #9481 的按文件分诊,不属于本 PR。 Test (macos-latest, Node 22.x):失败 —— 已记录的 vitest-worker RPC 超时,本 head 上复现
本轮为何不做改动两个红色检查都有据可查、已由分诊归入 #9481(仍开放),且按维护者决定有意不阻塞本 PR;两者都不存在本 PR 足迹内的修复。Windows 清单从 59 个测试演变为 3 个,恰恰说明泳道在按设计工作 —— main 自身的日常漂移如今逐提交可见,而不是再无人察觉地累积六周。以泳道发现的问题阻塞本 PR,会恢复当初让泳道关闭的那个死锁。 验证(本轮实际执行的命令)
Deferred non-Critical feedbackCritical-only mode is active: 5 change-producing rounds are complete. The workflow excluded the non-Critical feedback below from this round's actionable sections; the items remain open for human follow-up. Maintainer feedback is deferred only after its author has used 2 regular feedback batches in this window's Critical-only tail; authors at that budget, if any, are named below. (
中文说明已进入仅处理 Critical 的模式:已完成 5 个产生改动的轮次。本轮可执行区域已排除下方非 Critical 反馈;这些条目保持开放,留待人工跟进。维护者反馈仅在其本人于本窗口 Critical-only 阶段已使用 2 批常规反馈预算后才会延后;达到预算的作者(如有)在下方点名。(评论 Base-conflict check · 基分支冲突检查: no conflict with main. · 与 main 无冲突。 🧠 Handled by Qwen Code · model/模型 |
|
Status at this head, and one thing I could not settle. All review threads are resolved. The last live Critical — the two mapfile-crossing siblings left ungated — is fixed and now pinned by a meta-test that reads the suite and asserts all three titles carry the host probe, so a dropped gate fails a test instead of reddening the lane. The two round-15 items are resolved as their review described. The macOS lane passes its tests and still fails the job. At this head: I had a candidate cause and it did not survive checking, so I am not shipping it as a fix: That leaves a decision rather than a patch:
My preference is 1 with a follow-up issue, since the lane is now producing exactly the signal this PR set out to restore and the remaining failure is vitest's, not the repo's. Happy to do 2 or 3 on request. |
* fix: repair the Windows and macOS test lane failures The platform lanes have been dark since 2026-07-02 (gated on a merge queue that is not enabled); reviving them in QwenLM#9370 exposed these pre-existing failures. 72 failing tests across 16 files, all traced to platform assumptions: Product fixes (2): - daemon-git-worktree-guard: on Windows a backslash is a path separator, not a POSIX escape. The shell-quote tokenizer consumed `\x` pairs, mangling `C:\repo\sub` into a relative word — false denials for legitimate commands AND undetected relocations for backslash-relative ones. Preserve unquoted backslashes before tokenisation on win32. - acpAgent isOwnerOnlyDirectory: hard-returning false on win32 disabled Live managed relocation entirely (Node exposes no ownership bits there). Rest on the structural checks — symlink rejection and dev/ino identity across the realpath round trip — the same trade-off serve/live/discovery.ts already makes. Test-fixture fixes (the product code was already Windows-correct): - server.test Live catalog roots use the host-native path shape (path.resolve equality proof fails for POSIX literals on win32) - review cleanup suite pins POSIX node:path semantics for its literal-keyed mocks; fetch-pr resume budget uses a native tmpdir; scratch-tree clears the DOS read-only attribute before overwriting a git-created gitfile; worktree-list assertions compare slash-normalized (git prints forward slashes on Windows) - mode-bit (0600) assertions skip on win32 (no POSIX permission bits; every read side already skips its mode check there) - O_NOFOLLOW symlink test and the unescapePath no-op test skip on win32; sidecar errno injection uses a portable NUL byte; Footer exact-hint text is platform-conditional (win32 indicator is 8 columns shorter, shifting the flex shrink by one) scripts vitest suite: drop the fixed 8-16 worker floor that oversubscribes the 3-core macOS runners — the main thread stalled past the 60s worker RPC timeout (onTaskUpdate), exiting 1 with every test green. * fix: second round of platform lane repairs from CI verification Verification run (fixes + QwenLM#9370's workflow) cut the Windows failures from 69 to 5 and left the macOS lane's infra error. Follow-ups: - daemon-git-worktree-guard resolvePhysicalPath: splitting an absolute Windows path yields the drive as a segment (C:), which path.join glued back onto the root as C:\C:. Walk only the part past the root. Exposed by the first round's tokenizer fix, which let intact drive paths reach this code for the first time. - scratch-tree tests: the git-created gitfile refuses in-place overwrite on Windows even after clearing the read-only attribute; delete and recreate instead. - bridge.test stderr audit assertion: the line prints the session id through JSON.stringify, escaping Windows backslashes; match the escaped spelling (test added this morning by QwenLM#9543, landed after the baseline census). - managed-scratch 'root replaced' test: dev/ino identity is not reliably observable on every Windows volume; state the precondition and skip where the swap is indistinguishable. - scripts vitest suite: the unhandled onTaskUpdate worker RPC timeout is deterministic on the macOS runners with every test green; stop letting unhandled errors fail this suite while test failures stay fatal, and drop the stale claim that the pool override removal fixed it. * fix(ci): skip coverage report generation on non-Linux CI CI consumes coverage only from the ubuntu lane: the artifact upload and the coverage comment both pin coverage-reports-*-ubuntu-latest. On the Windows runners the v8 report generation for 800+ files stalls the vitest main thread past the 60s worker RPC budget at the end of an all-green cli run, exiting the lane 1 (observed in verification run 32569004418). Skip coverage on non-Linux CI; local runs keep it. * fix(ci): stop all-green cli/core runs exiting red on RPC timeout The Windows lane's third verification round repeated the failure with coverage already disabled: 866 cli test files green, then the worker onTaskUpdate RPC budget (60s, hardcoded in vitest's bundled birpc) expired under runner resource pressure and the unhandled error exited the lane 1. Extend the scripts suite's treatment to the two big package suites: test failures stay fatal, unhandled errors do not. * fix: address review on the win32 guard pre-pass and lane configs R1-1 (Critical): the win32 pre-pass escaped the character after every unquoted backslash, so whitespace after a trailing separator glued the next word into the -C value — a second -C/--git-dir/-c parked there vanished from the analysis while cmd.exe still split the argv at the whitespace, allowing a destructive mutation outside the boundary. The tokenizer treats `\<space>` as an escaped space even after an even number of backslashes, so escaping forward can never express "literal backslash, then word boundary". Escape the backslash alone instead: a double-quoted backslash before whitespace and cmd boundary characters (; | & < > ( )) keeps them their separator role, and a plain escaped backslash elsewhere. Verified token boundaries for the attack shape, its tab variant, trailing-separator-before-flag, UNC, chained -C, and quoted paths; added win32-only guard tests for the boundary shapes. R1-2/3/4: gate dangerouslyIgnoreUnhandledErrors to non-Linux — the ubuntu lane and Linux local runs keep the unhandled-error signal. R1-5: pin the deterministic win32 footer truncation ('queu') instead of skipping the content assertion there. R1-6: build the Live conversations fixture root with the file's documented path.resolve(path.sep, ...) convention instead of a hardcoded C: literal. * fix: three Windows lane failures from recent main commits Verification of the revived lanes surfaced three failures introduced by commits that landed while the lanes were dark: - isSameFile compared dev/ino unconditionally; on volumes that report ino 0 (or a colliding value) for every file it equated distinct files. Treat an unverifiable inode like core's hasVerifiableInode convention and fall back to canonical spellings — losing hard-link identity there, but never equating distinct files. The hard-link test skips where the volume exposes no inode. - drive's bound-address recipe test rmSync'd its temp dir while the backgrounded service still held it (EBUSY on Windows); shorten the service's self-exit timer and retry the removal. - the FileReadCache seeding test collided under one dev:ino key when the volume reports the same inode for both MEMORY.md indexes; skip where inode identity is not real. * fix: address round-2 review on identity fail-closed checks and the win32 guard pre-pass * fix(cli): deny cmd.exe rewrite syntax in the daemon git-worktree guard (QwenLM#9728) * fix: address round-4 review on the cmd-rewrite denial reason and cmd-lane test gating Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * fix: address round-5 review by closing the divergent Windows shell surface structurally The win32 cmd/PowerShell lanes were analysed through a POSIX text model plus per-stage patches; each round closed one entrance of the divergence family and the next found new ones. Fail closed on syntax whose lane semantics diverge from the model (lone `&`, `( )`, cmd `#`/`;`/single quotes, /s outer-quote strip, PowerShell `--%`/`''` doubling), normalize the whole command text once before any stage reads it, drop the bash shadow model on lanes where the syntax defines nothing, and stop scoping PowerShell pipeline stages as subshells. Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * fix: address round-6 review by gating bash-semantics tests off the win32 lane and failing closed on nested Windows shells R6-1: the whole-text divergent-syntax gate denied ~20 ungated bash-semantics expectations on the real win32/cmd merge lane (41 failures reproduced under a lane-spoof harness). Gate those blocks off the win32 non-bash lanes, splitting mixed blocks so lane-safe pins keep running there, and commit the lane-spoof harness so the whole guard suite runs as the win32/cmd merge lane on every lane. R5-1 (partial): cmd/powershell/pwsh invocations now fail closed on the undecidable-payload denial on every lane — their payloads are parsed by a grammar the POSIX text model cannot read (closes the -EncodedCommand and nested cmd /c entrances probed at this head). The remaining class closure is escalated to the maintainer as a product/scope decision. * fix: address round-7 review by gating the Windows-shell fail-closed rule to the win32 platform R7-1: the round-6 WINDOWS_SHELL_PROGRAMS branch failed closed on every lane, which denied benign cross-platform PowerShell on POSIX daemons (pwsh -NoProfile -Command Write-Output hello reproduced denied on the unresolved reason at this head). Gate the rule to platform win32 — cmd.exe and Windows PowerShell only exist there, and they stay reachable from win32 Git Bash sessions, so the gate is platform-wide rather than windowsNative; on POSIX the same names keep the base stance of ordinary unmodelled programs. Move the fail-closed pins onto spoofed win32 lanes, add a win32 Git Bash lane pin so the entrance stays closed there, and add the POSIX benign-pwsh regression test. * fix(cli): close the cmd.exe state-persisting entrances in the daemon guard Probe-verified bypasses (review R5-1): cmd.exe builtins persist state into every later &&-chained command, and the analysis modelled none of them — `set GIT_WORK_TREE=<outside>&& git reset --hard` and `chdir <outside> && git reset --hard` both analysed cwd-local while the executed command relocated outside the boundary. cmd's state-persisting builtins are a closed set, so this enumerates them instead of chasing individual shapes: - `set VAR=value` / `setx VAR value` carry the semantics of a POSIX `export VAR=value` for every later segment; route them through that machinery (GIT_* keys become relocations, unresolvable keys fail closed). Non-assignment forms (`set /p`, dynamic operands) fail closed. - `chdir` joins the cd family (cmd's synonym), `/D` consumed as the drive-switch option. - `path` and `doskey` rewrite which executable a bare name resolves to — unresolvable, failed closed. - copy/mklink/move/robocopy/xcopy join the relinking programs on win32, and the text relocation markers learn `chdir`. PowerShell-only entrances (function definitions, New-Item function:, @-splatting) already fail closed through the unmodelled-syntax gate; the new branches stay gated off Git-Bash sessions, where these words are ordinary POSIX commands. Pinned by new tests in the win32-lane harness, which spoofs win32/cmd on every platform. * Revert "fix(cli): close the cmd.exe state-persisting entrances in the daemon guard" This reverts commit a8f137a. * Reapply "fix(cli): close the cmd.exe state-persisting entrances in the daemon guard" This reverts commit b888a42. * fix: address round-10 review by closing the Windows-lane guard entrances and the ino-0 case fold * fix(cli): repair the round-10 build rejection by mapping chdir variants exhaustively * fix(cli): make the /MIR relink-switch denial assertion lane-independent The assertion spelled the unresolvable target as POSIX '/MIR', but the win32 lane resolves it through path.win32/realpathNearestExistingAsync into a backslash spelling ('\\MIR'/'C:\\MIR'), so the new test failed only on the merge_group-gated test_windows lane. Match either separator spelling. Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> --------- Co-authored-by: qwen-code-ci-bot <qwen-code-ci-bot@users.noreply.github.com> Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
|
🤖 Reviewed the latest feedback — no changes needed. Why, point by point: · 已审阅最新反馈——无需改动。逐点说明原因如下: 🤖 Reviewed the latest feedback — no changes needed. Why, point by point: No action this round — all three inline items re-verified as fixed; the macOS worker timeout is left as the maintainer's explicit decisionCritical-only mode is active (5 change-producing rounds complete; growth window at 36/321 of the 400/400 budgets). No code was changed, no commit was made, no base merge was performed ( The three inline comments are confirmations — each re-verified at the current head (
|
|
Released in v0.22.2. |
What this PR does
Gives the macOS and Windows test lanes a way to run again, and a way for a failure on them to be seen. They keep their merge-queue trigger and gain two more: a pull request whose diff a new platform-sensitivity classifier recognises, and a nightly run on
main. The classifier's answer is fail-safe in every direction — only a confident "no" skips the lanes — and every other job in the workflow now excludes the schedule explicitly, so a nightly run is exactly those two jobs. A red nightly opens an autofix-ready issue through the existing main-failure watcher.Why it's needed
Both lanes are gated on
merge_group, and no merge queue is enabled on this repository: themainruleset carries only deletion, non-fast-forward and pull_request rules, no status check is required, and merges land as squashes. The lastmerge_grouprun of any workflow was 2026-07-02. The gate was therefore an off switch — the lanes reported as "skipped" on every pull request, which reads as agreement, and nothing ever reached them afterwards. The only signal this repository has about a host that is not Linux with a GNU userland had been silently off for six weeks.That is how the defect behind this work shipped: a workflow guard was hardened with
realpath -m, a GNU-only flag that a BSD userland exits 1 on, and the test written to pin that canonicalization was red on every Mac. Eight review rounds on Linux runners created it, blessed it, and merged it, because the lane that would have contradicted them could not run. The path-based gate here catches that class before merge; the nightly catches what a path list cannot see, one day later.Reviewer Test Plan
How to verify
Two things are worth confirming separately: what the classifier decides, and what the wiring does with that decision.
The classifier is a pure function over a changed-file list, so its judgement is readable in its tests —
node --test .github/scripts/ci/classify-platform-sensitivity.test.mjs. The interesting cases are the negative ones: an ordinary source-and-docs diff must stay off the lanes (that is the entire cost argument), and the substring traps must not drag them in — a component namedShellfish.tsx, acryptic.ts, aplateauDetector.ts. The positive list is shell in every dialect, workflow and composite-action YAML and the scripts they call, the script layer and its tests, the runner configuration, the root manifests, and path segments naming a platform-coupled subsystem. Every unknown — an unreadable listing, an entry with no usable name, a fork pull request, a truncated file list, the classify job failing outright — answers "sensitive", and the lanes' gate skips only on a literalfalse.The wiring is pinned by
npx vitest run --config ./scripts/tests/vitest.config.ts scripts/tests/ci-platform-lanes.test.js: the schedule trigger exists, both lanes name all four triggers, the gate is spelled in the fail-safe direction and survives a skipped or failed classifier job, every other job in the workflow is excluded from the nightly, the classify job checks out the pull request's base commit rather than its head, and the main-failure watcher lists this workflow and fires on a scheduled main run. That the tests bite was measured rather than assumed: flipping the gate to== 'true', dropping the schedule clause from a lane, dropping the nightly guard from the ubuntu job, pointing the checkout at the head, dropping the new classifier's test from the helper-test list, and removing the schedule trigger are each caught by a named test.Two design points to weigh rather than verify. The classify job is its own small hosted job instead of a step in
classify_prbecause that job's outputs pick the Linux runner for the whole run, and this one needs a checkout — on a pool whose workspace other jobs have poisoned before; here a failure costs one classification, which the gate reads as "run the lanes". And its listing goes through the existingclassify-pr-profile.shwrapper, extended with a mode argument rather than copied, because that wrapper exists precisely so one pull request is never listed twice and classified differently in two places.This PR is itself platform-sensitive by its own classifier, so its checks are where the gate first proves it fires.
Evidence (Before & After)
N/A — CI infrastructure, no user-visible output. Before:
Test (macos-latest, Node 22.x)andTest (windows-latest, Node 22.x)reported "skipping" on every pull request and had not run since 2026-07-02. After: they run on this pull request, on any pull request whose diff the classifier recognises, nightly onmain, and on a manual dispatch.Tested on
Environment (optional)
Unit tests and the repository's workflow linter, on Linux. The lanes themselves are what this PR is for — their first real run is on this pull request's own checks, and the nightly's first run is the day it lands.
Risk & Scope
Linked Issues
None — observed while verifying #9220; the merge-queue gate's effect is visible in
gh run list --event merge_group.中文说明
这个 PR 做了什么
让 macOS 与 Windows 两条测试 lane 重新有机会运行,并让它们的失败能被看见。原有的 merge queue 触发保留,另外新增两个:diff 被新的"平台敏感性"分类器识别的 PR,以及
main上的每日定时运行。分类器的判定在各个方向上都是 fail-safe——只有明确的"否"才会跳过 lane——同时 workflow 里其他每个 job 都显式排除了 schedule,因此一次 nightly 恰好只有这两个 job。nightly 变红会通过既有的 main 失败监听器自动开一个可交给 autofix 的 issue。为什么需要
两条 lane 都以
merge_group为门,而本仓库并未启用 merge queue:main的 ruleset 只有 deletion、non-fast-forward、pull_request 三条规则,没有任何 required status check,合入全部是 squash。任何 workflow 的最后一次merge_group运行是 2026-07-02。于是这个门实际上是一个关闭开关——两条 lane 在每个 PR 上显示为 "skipped"(读起来像"通过"),而此后再也没有任何事件能触达它们。本仓库对"非 Linux、非 GNU userland 主机"的唯一信号,已经静默关闭了六周。促成本次工作的缺陷正是这样上线的:一处 workflow guard 被用
realpath -m加固,而这是 GNU 独有参数、BSD userland 上直接以 1 退出;为钉住这次规范化而写的测试在所有 Mac 上都是红的。八轮跑在 Linux runner 上的评审造出了它、放行了它、并合入了它,因为本该反驳它们的那条 lane 根本跑不了。本 PR 的路径门能在合入前拦住这一类问题,nightly 则覆盖路径清单看不见的部分,代价是晚一天。Reviewer 测试计划
如何验证
有两件事值得分开确认:分类器判定什么,以及 wiring 拿这个判定做什么。
分类器是对"改动文件列表"的纯函数,判定直接体现在它的测试里——
node --test .github/scripts/ci/classify-platform-sensitivity.test.mjs。真正有意思的是否定用例:普通的源码 + 文档改动必须不触发 lane(这就是全部的成本论证),以及子串陷阱不能把 lane 拖进来——名为Shellfish.tsx的组件、cryptic.ts、plateauDetector.ts。肯定清单则是:各种方言的 shell、workflow 与 composite action YAML 及它们调用的脚本、脚本层及其测试、runner 配置、根 manifest,以及路径中以完整片段命名平台耦合子系统的源文件。所有"未知"一律判为敏感——列表读不出来、条目没有可用名字、fork PR、被截断的文件列表、分类 job 整个失败——而 lane 的门只在字面量false时才跳过。wiring 由
npx vitest run --config ./scripts/tests/vitest.config.ts scripts/tests/ci-platform-lanes.test.js钉住:schedule 触发存在、两条 lane 都写全了四个触发、门的写法是 fail-safe 方向且能在分类 job 被跳过或失败时存活、workflow 里其他每个 job 都被排除在 nightly 之外、分类 job checkout 的是 PR 的 base commit 而非 head、以及 main 失败监听器已列入本 workflow 且会在定时的 main 运行上触发。"测试真的会咬人"是实测而非假设:把门翻成== 'true'、从某条 lane 去掉 schedule 分句、去掉 ubuntu job 的 nightly 守卫、把 checkout 指向 head、把新分类器的测试从 helper 列表里删掉、删掉 schedule 触发——每一个都被某条具名测试抓住。另有两个设计点值得掂量而非验证。分类放在自己的小型 hosted job 里而不是
classify_pr的一个步骤,因为后者的输出决定了整个 run 的 Linux runner 选择,而这件事需要 checkout——而那个池的 workspace 曾被其他 job 污染过;放在这里,失败的代价只是少一次分类,而门会把它读作"跑 lane"。它的文件列表走既有的classify-pr-profile.shwrapper(扩展了一个 mode 参数,而不是复制一份),因为那个 wrapper 存在的全部意义就是:同一个 PR 不会被列两次、并在两个地方得到不同的分类。本 PR 按它自己的分类器就是平台敏感的,因此它自身的 checks 就是这个门第一次证明自己会触发的地方。
证据(Before & After)
N/A——CI 基础设施改动,无用户可见输出。之前:
Test (macos-latest, Node 22.x)与Test (windows-latest, Node 22.x)在每个 PR 上显示 "skipping",且自 2026-07-02 起没有运行过。之后:它们会在本 PR 上运行、在任何被分类器识别的 PR 上运行、每日在main上运行,以及手动 dispatch 时运行。测试平台
环境(可选)
单元测试与仓库自带的 workflow linter,运行在 Linux 上。两条 lane 本身正是本 PR 的目的——它们的第一次真实运行就是本 PR 自己的 checks,nightly 的第一次运行则在合入当天。
风险与范围
关联 Issue
无——在验证 #9220 的过程中发现;merge-queue 门的实际效果可用
gh run list --event merge_group直接看到。