Skip to content

fix(web-shell): realign two test suites with shipped behavior to unbreak main CI (#11539) - #11549

Closed
qwen-code-dev-bot wants to merge 2 commits into
mainfrom
autofix/issue-11539
Closed

fix(web-shell): realign two test suites with shipped behavior to unbreak main CI (#11539)#11549
qwen-code-dev-bot wants to merge 2 commits into
mainfrom
autofix/issue-11539

Conversation

@qwen-code-dev-bot

Copy link
Copy Markdown
Collaborator

What this PR does

Realigns two packages/web-shell test suites with the behavior that actually ships on main, unbreaking the Test (ubuntu-latest, Node 22.x) CI lane. Both suites were written against only one side of a feature combination and fail deterministically on main today; the fix is test-only (+17/−1) and changes no production behavior. The workspace-provider loading suite now answers the provider's GET /brand request with a 404 in its mock daemon — the definitive "old daemon has no brand route" answer that settles the fetch instead of arming the provider's retry timer — and expects the brand request alongside the capabilities request in the boot sequence (twice under StrictMode's effect remount). The sidebar brand suite mounts above the compact-footer breakpoint (344px) by seeding the sidebar-width storage key, so the footer version label that carries the brand tooltip renders as its assertions expect.

Why it's needed

Main CI failed at b1ac3e2970 (#11539) and is still red at the current tip. The brand-configuration feature (#11244) added a GET /brand fetch beside GET /capabilities in the workspace provider, while the loading suite still asserted a capabilities-only boot sequence and its mock daemon threw on the unknown route — an answer the provider treats as a transport failure worthy of a retry timer. Independently, the compact-footer change (#11470) removes the footer version label below a 344px sidebar width, while the brand suite mounts at the default 260px and queries that label's tooltip. Neither is a product defect; the tests simply no longer describe shipped behavior, and every main push reds until they do.

A second, independent main-side red — the qwen-autofix.yml workflow-size baseline drift — is deliberately not touched here: it has its own issue (#11529) and open repair PR (#11537), and the ratchet's stale-baseline leniency keeps PR lanes green for branches that do not modify the workflow file (verified locally with the PR-lane base SHA: 208/208 pass).

Reviewer Test Plan

How to verify

On main without this PR, run cd packages/web-shell && npx vitest run client/components/WorkspaceSessionProvider.loading.test.tsx client/components/sidebar/WebShellSidebar.brand.test.tsx and observe 8 failures: the loading suite reports expected [ 'GET /capabilities', 'GET /brand' ] to deeply equal [ 'GET /capabilities' ] (plus a second brand call under StrictMode), and the brand suite's two version-tooltip queries return null. With this PR the same command passes 16/16, and the full web-shell package suite passes 302 files / 7148 tests. Confirm the loading suite's new expectation matches the provider source: fetchBrand in DaemonWorkspaceProvider.tsx issues GET /brand per client effect run, and a 404 settles it without a retry. Confirm the brand suite's 360px seed exceeds SIDEBAR_FOOTER_COMPACT_WIDTH (344) in WebShellSidebar.tsx, where the version label renders only when the footer is not compact.

Evidence (Before & After)

N/A — test-only change; before/after is the failing vs passing suite output described above.

Tested on

OS Status
🍏 macOS ⚠️
🪟 Windows ⚠️
🐧 Linux

Environment (optional)

N/A — unit tests only (vitest, jsdom).

Risk & Scope

  • Main risk or tradeoff: the loading suite now pins the exact brand-fetch count (once, twice under StrictMode); a future provider change that legitimately re-fetches the brand must update this expectation. The mock's 404 matches the "daemon without the brand route" contract the provider already handles, so no retry timer is armed and no stray calls leak into later assertions.
  • Not validated / out of scope: the qwen-autofix.yml workflow-size baseline drift on the main push lane (owned by Main CI failed: Qwen Code CI on 21951941d726 #11529 / PR fix(ci): record the qwen-autofix.yml size drift two in-allowance PRs accumulated (#11529) #11537); macOS and Windows lanes, left to CI.
  • Breaking changes / migration notes: none — no production code changed.

Linked Issues

Fixes #11539

中文说明

本 PR 做了什么

packages/web-shell 的两个测试套件与 main 上实际发布的行为对齐,修复 Test (ubuntu-latest, Node 22.x) CI 通道。这两个套件编写时只覆盖了某个功能组合的一侧,如今在 main 上确定性失败;本次修复仅涉及测试(+17/−1),不改变任何生产行为。workspace provider 的 loading 套件现在让其 mock daemon 对 GET /brand 请求返回 404——即"旧 daemon 没有品牌路由"的确定性应答,使该 fetch 立即落定,而不再触发 provider 的重试定时器——并在启动序列断言中预期品牌请求与 capabilities 请求并存(StrictMode 的 effect 重挂载下为两次)。侧边栏品牌套件通过写入侧边栏宽度存储键,以高于紧凑页脚断点(344px)的宽度挂载,使携带品牌 tooltip 的页脚版本标签按断言预期渲染。

为什么需要

主分支 CI 在 b1ac3e2970 失败(#11539),且在当前顶端仍为红。品牌配置功能(#11244)在 workspace provider 中于 GET /capabilities 之外新增了 GET /brand 请求,而 loading 套件仍断言只有 capabilities 的启动序列,其 mock daemon 对未知路由直接抛错——provider 将其视为传输失败并启动重试定时器。另一方面,紧凑页脚改动(#11470)在侧边栏宽度小于 344px 时移除页脚版本标签,而品牌套件以默认 260px 挂载并查询该标签的 tooltip。两者都不是产品缺陷;只是测试不再描述已发布行为,在其修复之前每次 main 推送都会变红。

第二个相互独立的 main 侧红色项——qwen-autofix.yml 的 workflow-size 基线漂移——本 PR 刻意不涉及:它有自己的 issue(#11529)和在途修复 PR(#11537),且 ratchet 的过期基线宽免机制会让不修改该 workflow 文件的分支在 PR 通道保持绿色(已在本地用 PR 通道的 base SHA 验证:208/208 通过)。

Reviewer 测试计划

如何验证

在不含本 PR 的 main 上运行 cd packages/web-shell && npx vitest run client/components/WorkspaceSessionProvider.loading.test.tsx client/components/sidebar/WebShellSidebar.brand.test.tsx,可观察到 8 个失败:loading 套件报告 expected [ 'GET /capabilities', 'GET /brand' ] to deeply equal [ 'GET /capabilities' ](StrictMode 下还有一次额外的品牌请求),品牌套件的两条版本 tooltip 查询返回 null。应用本 PR 后,同一命令 16/16 通过,web-shell 全量套件 302 个文件 / 7148 个测试通过。可对照 provider 源码确认 loading 套件的新预期:DaemonWorkspaceProvider.tsxfetchBrand 在每个 client effect 运行时发起 GET /brand,404 会使其落定且不重试。可对照 WebShellSidebar.tsx 确认品牌套件写入的 360px 高于 SIDEBAR_FOOTER_COMPACT_WIDTH(344),版本标签仅在页脚非紧凑时渲染。

证据(前后对比)

N/A —— 纯测试改动;前后对比即上文所述的失败与通过的套件输出。

测试平台

OS 状态
🍏 macOS ⚠️
🪟 Windows ⚠️
🐧 Linux

环境(可选)

N/A —— 仅单元测试(vitest,jsdom)。

风险与范围

关联 Issue

Fixes #11539

…eak main CI (#11539)

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
@qwen-code-dev-bot

Copy link
Copy Markdown
Collaborator Author

Autofix E2E Report — Issue #11539

What failed

Main CI (Qwen Code CI, job Test (ubuntu-latest, Node 22.x), step Run tests and generate reports) failed at b1ac3e2970 and kept failing at the current main tip 1097b9fe0a. Job logs are not readable without repository credentials, so the failure was identified by reproducing the step's test surface locally at the exact HEAD.

Two packages/web-shell test suites fail deterministically on main — both are test-environment misalignments left behind by the interaction of two shipped features, not product bugs:

  1. WorkspaceSessionProvider.loading.test.tsx (6 failing variants). The brand-configuration feature (feat(web-shell): make the product name and logo configurable #11244) made DaemonWorkspaceProvider fetch GET /brand beside GET /capabilities (DaemonWorkspaceProvider.tsx, fetchBrand). The suite's mock daemon had no /brand route — its fallback throws Unexpected request, which the provider reads as a transport failure and answers by arming its 2s retry timer — and the suite still asserted the boot sequence issues exactly ['GET /capabilities']. Observed pre-fix: expected [ 'GET /capabilities', 'GET /brand' ] to deeply equal [ 'GET /capabilities' ] (and one more GET /brand under StrictMode's effect remount).
  2. WebShellSidebar.brand.test.tsx (2 failing tests). The compact-footer change (fix(web-shell): hide the sidebar version label at the compact footer breakpoint #11470) removes the footer version label — the element carrying the title="<Brand> v<version>" tooltip — when the sidebar is narrower than 344px (SIDEBAR_FOOTER_COMPACT_WIDTH, WebShellSidebar.tsx:2108, render guard at :6309). The brand suite mounts at the default 260px width, so its two tooltip assertions queried an element that intentionally no longer renders.

The fix

Test-only realignment, +17/−1 lines across the two suites:

  • The loading suite's mock daemon now answers GET /brand with a 404 — the "old daemon without the brand route" answer the provider treats as definitive, so the fetch settles immediately instead of arming its retry timer — and the boot-sequence assertion expects the brand fetch (once, twice under StrictMode's remount), matching observed provider behavior.
  • The brand suite seeds the sidebar-width storage key (qwen-code-web-shell-sidebar-width) to 360px in beforeEach, above the compact-footer breakpoint, so the version label and its brand tooltip render as the assertions expect.

No production code changed; shipped behavior is untouched. The suites now pin the real behavior: they were red before the alignment (8 failures, output above) and green after — that pre/post run is the mutation probe for a test-only change.

Deliberately not in this PR

The main push lane has a second, independent red: scripts/tests/workflow-size.test.js reports .github/workflows/qwen-autofix.yml 6169 bytes over its recorded baseline. That is main-side drift with its own issue (#11529) and open repair PR (#11537), and the ratchet's stale-baseline leniency (#9904) keeps PR lanes green for branches that do not touch the workflow file — verified here with WORKFLOW_SIZE_BASE_SHA=<HEAD>: 208/208 pass. This PR does not touch .github/, so its lane is unaffected; duplicating #11537's baseline bump would only conflict with it.

Verification

  • npx vitest run client/components/WorkspaceSessionProvider.loading.test.tsx client/components/sidebar/WebShellSidebar.brand.test.tsx (packages/web-shell), pre-fix — 8 failed / 8 passed (the reproduction; probe evidence)
  • Same command, post-fix — 16 passed (2 files)
  • npx vitest run --config vitest.config.ts (packages/web-shell full package suite) — 302 files / 7148 tests passed
  • npm run build — passed
  • npm run typecheck — passed
  • npm run lint — passed
  • npx vitest run src/serve/rest-integration-docs-contract.test.ts (packages/cli; the failing commit's own new test) — 6 passed, unrelated to the failure
  • WORKFLOW_SIZE_BASE_SHA=$(git rev-parse HEAD) npx vitest run --config ./scripts/tests/vitest.config.ts scripts/tests/workflow-size.test.js208 passed (proves the workflow-size ratchet passes on this PR lane by base-leniency)
  • Integration tests — not run: no bundled-CLI or integration-harness behavior is touched (test-only change in the web-shell package)
中文说明

Autofix E2E 报告 — Issue #11539

失败内容

主分支 CI(Qwen Code CI,任务 Test (ubuntu-latest, Node 22.x),步骤 Run tests and generate reports)在 b1ac3e2970 失败,并在当前 main 顶端 1097b9fe0a 持续失败。没有仓库凭据无法读取任务日志,因此通过在精确的 HEAD 上本地复现该步骤的测试面来定位失败。

packages/web-shell 的两个测试套件在 main 上确定性失败——两者都是两个已合入功能相互叠加后留下的测试环境错位,而非产品缺陷:

  1. WorkspaceSessionProvider.loading.test.tsx(6 个失败变体)。 品牌配置功能(feat(web-shell): make the product name and logo configurable #11244)让 DaemonWorkspaceProviderGET /capabilities 之外同时请求 GET /brand(DaemonWorkspaceProvider.tsxfetchBrand)。该套件的 mock daemon 没有 /brand 路由——其兜底分支抛出 Unexpected request,provider 将其视为传输错误并据此启动 2 秒重试定时器——而套件仍断言启动序列恰好只有 ['GET /capabilities']。修复前实测:expected [ 'GET /capabilities', 'GET /brand' ] to deeply equal [ 'GET /capabilities' ](StrictMode 的 effect 重挂载下还会再多一次 GET /brand)。
  2. WebShellSidebar.brand.test.tsx(2 个失败测试)。 紧凑页脚改动(fix(web-shell): hide the sidebar version label at the compact footer breakpoint #11470)在侧边栏宽度小于 344px 时移除页脚版本标签——即携带 title="<品牌> v<版本>" 提示的元素(SIDEBAR_FOOTER_COMPACT_WIDTH,WebShellSidebar.tsx:2108,渲染守卫在 :6309)。品牌套件以默认 260px 宽度挂载,因此它的两条 tooltip 断言查询的是一个有意不再渲染的元素。

修复内容

仅测试对齐,两个套件合计 +17/−1 行:

  • loading 套件的 mock daemon 现在对 GET /brand 返回 404——即 provider 认定为确定性答案的"旧 daemon 没有品牌路由"响应,fetch 随即落定,不再启动重试定时器——同时启动序列断言改为预期包含品牌请求(一次;StrictMode 重挂载下两次),与实测的 provider 行为一致。
  • 品牌套件在 beforeEach 中将侧边栏宽度存储键(qwen-code-web-shell-sidebar-width)设为 360px,高于紧凑页脚断点,使版本标签及其品牌 tooltip 按断言预期渲染。

未改动任何生产代码;已发布行为保持不变。套件现在锁定的是真实行为:对齐前为红(8 个失败,输出如上),对齐后为绿——对纯测试改动而言,这组前后运行即变异探针。

刻意不纳入本 PR 的内容

主分支 push 通道还有第二个相互独立的红:scripts/tests/workflow-size.test.js 报告 .github/workflows/qwen-autofix.yml 超出其记录基线 6169 字节。这属于 main 侧漂移,已有自己的 issue(#11529)和在途修复 PR(#11537);且 ratchet 的过期基线宽免机制(#9904)会让不改动该 workflow 文件的分支在 PR 通道保持绿色——已在本地用 WORKFLOW_SIZE_BASE_SHA=<HEAD> 验证:208/208 通过。本 PR 不触碰 .github/,其通道不受影响;重复 #11537 的基线更新只会与之冲突。

验证

  • npx vitest run client/components/WorkspaceSessionProvider.loading.test.tsx client/components/sidebar/WebShellSidebar.brand.test.tsx(packages/web-shell),修复前 —— 8 失败 / 8 通过(复现;探针证据)
  • 同一命令,修复后 —— 16 通过(2 个文件)
  • npx vitest run --config vitest.config.ts(packages/web-shell 全量套件)—— 302 个文件 / 7148 个测试通过
  • npm run build —— 通过
  • npm run typecheck —— 通过
  • npm run lint —— 通过
  • npx vitest run src/serve/rest-integration-docs-contract.test.ts(packages/cli;失败提交自身新增的测试)—— 6 通过,与本次失败无关
  • WORKFLOW_SIZE_BASE_SHA=$(git rev-parse HEAD) npx vitest run --config ./scripts/tests/vitest.config.ts scripts/tests/workflow-size.test.js —— 208 通过(证明 workflow-size ratchet 在本 PR 通道因基线宽免而通过)
  • 集成测试 —— 未运行:本次为 web-shell 包的纯测试改动,不涉及任何仅经打包 CLI 或集成测试桩触达的行为

🧠 Handled by Qwen Code · model/模型 kimi-k3 · CLI 0.23.2

@github-actions github-actions Bot added the review/self-reported The linked issue was opened by the PR author (self-reported) label Sep 10, 2026
@qwen-code-ci-bot

qwen-code-ci-bot commented Sep 10, 2026

Copy link
Copy Markdown
Collaborator

Qwen Triage finishedview run. See the stage comments in this thread for the result.

Qwen Triage 已完成 —— 查看运行。结果见本线程中的各阶段评论。

@qwen-code-ci-bot

Copy link
Copy Markdown
Collaborator

Thanks for the PR — the fix is correct, but it is already on main, and I think this should be closed rather than merged.

Template looks good ✓

Problem: real and observed when it was written. Main CI was red on Test (ubuntu-latest, Node 22.x), tracked as #11539, and the body quotes actual failure output. No doubt the failure happened.

But it has already been fixed. #11530 merged at 2026-09-10T07:51:32Z (commit 2488d12d), touching the same two files with the same change. This PR was opened 28 minutes later at 08:19:59Z, from a branch cut before that merge — both diffs start from the identical base blob fb54b0fe5e6. Comparing them line by line, every code line this PR adds already exists on main:

  • if (url.pathname === '/brand') { return new Response('not found', { status: 404 }); } → main WorkspaceSessionProvider.loading.test.tsx:111
  • the ['GET /capabilities', 'GET /brand', 'GET /brand'] / ['GET /capabilities', 'GET /brand'] boot-sequence assertion → main :209-210
  • window.localStorage.setItem('qwen-code-web-shell-sidebar-width', '360') → main WebShellSidebar.brand.test.tsx:168

The only remaining delta is three words inside comments — "the 404" vs "a 404", "StrictMode's effect remount", "compact**-**footer". There is no behavioural or test-logic difference left to merge.

#11539 and #11525 are the same failure reported against two different commits: both name job Test (ubuntu-latest, Node 22.x), step Run tests and generate reports. #11530 closed #11525, and that lane is green on main at 2488d12d — so #11539 is stale as well. GitHub also reports this PR as CONFLICTING / DIRTY; it cannot merge in its current state.

Direction: the approach is right, because it is literally what main ships. I checked the constants the body cites rather than taking them on faith: SIDEBAR_FOOTER_COMPACT_WIDTH = 344 at WebShellSidebar.tsx:154, render guard at :2109, and the storage key qwen-code-web-shell-sidebar-width. The reasoning about the mock's 404 settling the brand fetch instead of arming the retry timer also holds.

Size: not applicable — no core paths touched. Tests-only, +17/−1 across 2 files, 0 production logic lines.

Approach: minimal and correctly scoped for the problem it was written against. Nothing to cut, no drive-by changes.

Risk: no elevated risk signals — the high-risk path scan matched nothing, both files being web-shell test suites.

Why I'm escalating rather than closing it myself: this gate's duplicate-close path only fires when the linked issue is already closed as completed. #11539 is still OPEN, so that precondition is not met, and closing a PR is the one irreversible act in this workflow — I would rather a human make that call than stretch the rule to fit. I flag it here and hand the decision over in the Stage 3 comment.

中文说明

感谢贡献 —— 修复本身是正确的,但它已经在 main 上了,我认为这个 PR 应该关闭而不是合并。

模板完整 ✓

问题: 撰写时是真实且已观测到的。主分支 CI 在 Test (ubuntu-latest, Node 22.x) 上变红,记录为 #11539,PR 描述中引用了真实的失败输出。失败确实发生过,这一点没有疑问。

但它已经被修复了。 #115302026-09-10T07:51:32Z 合入(提交 2488d12d),改动的是同样的两个文件同样的内容。本 PR 在 28 分钟后(08:19:59Z)从一个早于该合并的分支上开启 —— 两个 diff 的基线 blob 完全相同,都是 fb54b0fe5e6。逐行对比后,本 PR 新增的每一行代码都已存在于 main:

  • if (url.pathname === '/brand') { return new Response('not found', { status: 404 }); } → main 的 WorkspaceSessionProvider.loading.test.tsx:111
  • ['GET /capabilities', 'GET /brand', 'GET /brand'] / ['GET /capabilities', 'GET /brand'] 启动序列断言 → main 的 :209-210
  • window.localStorage.setItem('qwen-code-web-shell-sidebar-width', '360') → main 的 WebShellSidebar.brand.test.tsx:168

剩下的差异只有注释里的三个词 —— "the 404" 与 "a 404"、"StrictMode's effect remount"、"compact**-**footer"。已经没有任何行为或测试逻辑上的差异可供合并。

#11539#11525 是同一个失败在两个不同提交上的重复上报:都指向任务 Test (ubuntu-latest, Node 22.x)、步骤 Run tests and generate reports#11530 关闭了 #11525,而该通道在 main 的 2488d12d 上已经是绿的 —— 所以 #11539 同样已经过期。GitHub 也将本 PR 标记为 CONFLICTING / DIRTY,当前状态下无法合并。

方向: 方案是对的,因为它就是 main 上实际发布的内容。我没有直接采信描述中引用的常量,而是逐一核对:WebShellSidebar.tsx:154SIDEBAR_FOOTER_COMPACT_WIDTH = 344:2109 的渲染守卫,以及存储键 qwen-code-web-shell-sidebar-width。关于 mock 返回 404 使品牌请求立即落定、而不触发重试定时器的推理同样成立。

规模: 不适用 —— 未触及核心路径。纯测试改动,2 个文件 +17/−1,生产逻辑 0 行。

方案: 针对其撰写时的问题,改动最小且范围准确。没有可砍的部分,也没有夹带无关改动。

风险: 无升级风险信号 —— 高风险路径扫描未命中任何文件,两个文件都是 web-shell 测试套件。

为什么我选择上报而不是自行关闭: 本关卡的重复关闭路径只在关联 issue 已被标记为 completed 关闭时才触发。#11539 仍处于 OPEN 状态,该前置条件不成立,而关闭 PR 是整个流程中唯一不可逆的动作 —— 我宁愿由人来做这个决定,也不愿为了套用规则而勉强扩张它。我在这里标记出来,并在 Stage 3 评论中把决定权交出去。

Qwen Code · qwen3.8-max-2026-09-02

Reviewed at 4de010c06239983bb5282c323fef2ffc790e0558 · re-run with @qwen-code /triage

@qwen-code-ci-bot

Copy link
Copy Markdown
Collaborator

Code review

I formed a view before reading the diff. Given "#11244 added a GET /brand fetch beside GET /capabilities, and #11470 hides the footer version label below 344px", the two suites need different kinds of repair, and there is a right and a wrong way to do each:

  • Loading suite. The mock daemon has to answer /brand somehow. Returning a real brand payload would work but would test a path nobody asked about; returning 404 is the better call, because it exercises the "daemon without the brand route" contract the provider already supports and — the part that actually matters — settles the fetch immediately instead of arming the 2s retry timer, so no timer-driven call leaks into later assertions. The boot-sequence expectation then has to include the brand call, twice under StrictMode's effect remount.
  • Brand suite. The tooltip lives on the footer version label that fix(web-shell): hide the sidebar version label at the compact footer breakpoint #11470 intentionally removes below the breakpoint. The wrong fix is to relax the assertion and lose brand coverage; the right one is to mount above the breakpoint by seeding the persisted sidebar-width key, leaving the assertion testing the real tooltip.

That is exactly what this PR does, and exactly what #11530 did. The one alternative I considered — dropping the two tooltip queries and the strict call-count — would have quietly deleted coverage of a shipped feature, so I am glad neither PR took it.

Findings: no critical blockers, no AGENTS.md violations. I verified the claims the reasoning rests on rather than accepting them: SIDEBAR_FOOTER_COMPACT_WIDTH = 344 at WebShellSidebar.tsx:154 with the render guard at :2109, and the storage key qwen-code-web-shell-sidebar-width at WebShellSidebar.brand.test.tsx:168. The three added comments each carry a non-obvious why (the retry-timer semantics, the StrictMode double-fetch, the 344px breakpoint), which is what the house style asks for — not narration.

One trade-off worth naming, which the body already names itself: the loading suite now pins the exact brand-fetch count, so a future provider that legitimately re-fetches the brand has to update this expectation. That is the correct price for a strict boot-sequence assertion, not a defect.

Since main already contains this code byte-for-byte, reviewing it here is really reviewing #11530's content — which shipped and is green.

CI test evidence

This is the part a maintainer should look at, and it is not what the PR body implies. The PR's own CI never ran the unit suite. At head 4de010c0 there are 16 check-runs and not one of them is Test, Lint & Static, or Build — only bot orchestration. That follows from the CONFLICTING / DIRTY state: Qwen Code CI cannot compute a merge, so the lane never started. There is no failing job to quote and no green suite to credit.

Check Status Conclusion
Test (ubuntu-latest, Node 22.x) never ran (PR is CONFLICTING)
Lint & Static (ubuntu-latest, Node 22.x) never ran (PR is CONFLICTING)
assign completed success
authorize completed success
label completed success
triage in_progress
delay-automatic-review waiting
tmux-testing, verify, precheck-pr, review-config, ack-review-request, + 4 more completed skipped

The substitute evidence is main's CI at 2488d12d, which runs byte-identical code — that is what makes it a fair stand-in rather than a hand-wave:

  • Test (ubuntu-latest, Node 22.x)success (this is the exact lane the PR set out to unbreak, and it is green)
  • Lint & Static (ubuntu-latest, Node 22.x)success
  • Build for E2Esuccess; Identify the failing testssuccess
  • Test (macos-latest, Node 22.x) and Test (windows-latest, Node 22.x)skipped on the push lane, so Windows/macOS remain unexercised either way
  • E2E Test (Linux sandbox:none / sandbox:docker, macOS shards 1–2) — in_progress at time of review; not verified: still running, and unrelated to a test-only web-shell change

The body's numbers — 8 failed / 8 passed pre-fix, 16 passed post-fix, 302 files / 7148 tests for the full package, plus build/typecheck/lint — are the author's own claim, not independently re-run, and on an unattended run I will not execute PR code to check them. That gap does not need a sandboxed lane to close, though: main's green Test (ubuntu-latest, Node 22.x) at 2488d12d already executes these two suites in their identical merged form, which substantiates the assertions far more directly than an A/B against a base build could. So there is no behavioural claim left resting on the author's word, and /verify or /tmux would add nothing here — this is a test-only change with no production surface.

Real-scenario testing: N/A — unattended CI run, and nothing user-visible to drive.

中文说明

代码审查

我在看 diff 之前先形成了自己的判断。已知「#11244GET /capabilities 之外新增了 GET /brand#11470 在 344px 以下隐藏页脚版本标签」,这两个套件需要的是不同性质的修补,而且各自都有对错两种做法:

  • loading 套件。 mock daemon 必须以某种方式应答 /brand。返回真实的品牌数据也能跑通,但那测的是没人关心的路径;返回 404 是更好的选择,因为它走的是 provider 本就已支持的「daemon 没有品牌路由」契约,而且——这才是真正关键的一点——它让 fetch 立即落定,不会启动 2 秒重试定时器,因此不会有定时器触发的调用渗入后续断言。随后启动序列的预期就必须包含品牌请求,StrictMode 的 effect 重挂载下为两次。
  • 品牌套件。 tooltip 挂在 fix(web-shell): hide the sidebar version label at the compact footer breakpoint #11470 有意在断点以下移除的页脚版本标签上。错误的修法是放宽断言、丢掉品牌覆盖;正确的修法是写入持久化的侧边栏宽度存储键,让套件以高于断点的宽度挂载,从而使断言仍然测的是真实的 tooltip。

这正是本 PR 的做法,也正是 #11530 的做法。我考虑过的另一种方案——删掉两条 tooltip 查询和严格的调用次数断言——会悄悄抹掉一个已发布功能的覆盖率,所以两个 PR 都没有采用它,这一点我很认同。

结论:无阻断性问题,无 AGENTS.md 违规。 我没有直接采信推理所依赖的前提,而是逐一核对:WebShellSidebar.tsx:154SIDEBAR_FOOTER_COMPACT_WIDTH = 344:2109 的渲染守卫,以及 WebShellSidebar.brand.test.tsx:168 的存储键 qwen-code-web-shell-sidebar-width。新增的三处注释各自承载了一个不显然的 why(重试定时器语义、StrictMode 双次请求、344px 断点),符合本仓库的注释规范——而不是在复述代码。

有一个取舍值得点明,PR 描述本身也已经点明:loading 套件现在锁定了品牌请求的确切次数,因此未来若 provider 合理地重新获取品牌信息,就必须同步更新该预期。这是严格启动序列断言应付出的正确代价,不是缺陷。

由于 main 上已经逐字节包含了这些代码,在这里审查它实际上就是在审查 #11530 的内容——而它已经合入并且是绿的。

CI 测试证据

这是维护者应该关注的部分,而且它与 PR 描述给人的印象并不一致。本 PR 自己的 CI 从未运行单元测试套件。 在 head 4de010c0 上有 16 个 check-run,其中没有一个是 TestLint & StaticBuild——只有机器人编排类检查。这是 CONFLICTING / DIRTY 状态的直接结果:Qwen Code CI 无法计算合并结果,因此该通道根本没有启动。既没有可引用的失败任务,也没有可采信的绿色套件。

替代证据是 main 在 2488d12d 上的 CI,它运行的是逐字节相同的代码——这正是它能作为公允替代而非含糊搪塞的原因:

  • Test (ubuntu-latest, Node 22.x) —— success(这恰好就是本 PR 想要修绿的通道,它已经是绿的)
  • Lint & Static (ubuntu-latest, Node 22.x) —— success
  • Build for E2E —— successIdentify the failing tests —— success
  • Test (macos-latest, Node 22.x)Test (windows-latest, Node 22.x) —— 在 push 通道上为 skipped,因此无论哪种情况 Windows/macOS 都未被验证
  • E2E Test(Linux sandbox:none / sandbox:docker、macOS 分片 1–2)—— 审查时仍为 in_progress;未验证:仍在运行,且与纯测试的 web-shell 改动无关

描述中的数字——修复前 8 失败 / 8 通过、修复后 16 通过、全包 302 文件 / 7148 测试,以及 build/typecheck/lint——都是作者自己的声明,未经独立复跑;在无人值守的运行中我不会执行 PR 代码去验证它们。不过这个缺口不需要沙箱通道来补:main 在 2488d12d 上绿色的 Test (ubuntu-latest, Node 22.x) 已经以完全相同的合并后形态执行了这两个套件,这比针对 base 构建做 A/B 更能直接印证这些断言。因此没有留下任何仅凭作者之言成立的行为性主张,/verify/tmux 在这里不会带来任何增量——这是一个没有生产面的纯测试改动。

真实场景测试:N/A —— 无人值守 CI 运行,且没有可见的用户行为需要驱动。

Qwen Code · qwen3.8-max-2026-09-02

Reviewed at 4de010c06239983bb5282c323fef2ffc790e0558 · re-run with @qwen-code /triage

@qwen-code-ci-bot

Copy link
Copy Markdown
Collaborator

Confidence: 3/5 — the code is clean and correct, but this is pure authority, not doubt: the gate has no path to close a duplicate whose linked issue is still open, so a human needs to make that call.

Stepping back, this is an unusual one. My independent proposal for the two broken suites was the same fix the PR carries, down to choosing 404 over a real brand payload and choosing to mount above the breakpoint rather than relax the assertion. There is nothing to improve in the diff. But "the diff is right" is not the question — the question is whether there is anything left to merge, and there isn't. Every code line is already on main via #11530; the residue is three words of comment wording. Rebasing this onto main and "reducing it to the remaining delta", which is what I would normally ask for on a duplicate, would mean opening a PR to change "a 404" into "the 404". That is churn with a straight face, so I am not going to ask for it.

Six months from now nobody would curse this change — they would just be confused about why it exists. Which points at the thing actually worth a maintainer's attention here, and it is not this PR:

The autofix lane filed two issues for one main CI failure — #11525 at commit 13b69b3313da and #11539 at b1ac3e297023, both naming job Test (ubuntu-latest, Node 22.x), step Run tests and generate reports. #11530 fixed #11525 and merged at 07:51:32Z; this PR, repairing #11539, was opened at 08:19:59Z from a branch cut before that merge. So the lane produced a second repair for an already-repaired failure roughly half an hour after the first one landed, and nothing in the path checked whether an equivalent fix had already merged. Per-commit issue filing is doing its job; the missing check is on the PR-opening side. That is a process gap, not a defect in this diff, and it will keep generating these until it is closed.

What I did not do, and why. I am not approving — a second approval on an obsolete, unmergeable PR is worse than none, and main wants two approvals, so mine would count. I am also not closing it, even though I think closing is the right outcome: this gate may close a duplicate only when its linked issue is already closed as completed, and #11539 is still OPEN. Closing a PR is the one irreversible act in this workflow, and I would rather flag the ambiguity than bend the rule to reach the answer I happen to agree with. I am not submitting a request-changes review either — GitHub already reports CONFLICTING / DIRTY, so the PR is blocked from merging without my help, and a formal block would only add noise to a thread whose problem is that it should not exist.

Suggested resolution for whoever picks this up:

  1. Close this PR as a duplicate of fix(web-shell): realign two suites with shipped behavior to unbreak main CI (#11525) #11530 — no rebase is worth doing.
  2. Close Main CI failed: Qwen Code CI on b1ac3e297023 #11539 as a duplicate of Main CI failed: Qwen Code CI on 13b69b3313da #11525; the failure it tracks is green on main at 2488d12d.
  3. Optionally, teach the autofix lane to check for an already-merged equivalent before opening a repair PR.

⏸️ Deferring to @yiliang114 — you merged the identical #11530 twenty-eight minutes before this PR was opened, so the duplicate call is yours rather than mine. Needs a human decision on closing both the PR and #11539.

中文说明

Confidence: 3/5 —— 代码干净且正确,但这纯粹是权限问题,而非存疑:本关卡没有路径去关闭一个关联 issue 仍然开启的重复 PR,因此需要人来做这个决定。

退一步看,这是个不太常见的案例。我对这两个损坏套件的独立方案与 PR 所载的修复一致,细到同样选择 404 而非真实品牌数据、同样选择以高于断点的宽度挂载而非放宽断言。diff 里没有可改进之处。但「diff 是对的」并不是问题所在——问题是还有没有东西可合并,而答案是沒有。每一行代码都已通过 #11530 进入 main;残留的只有三处注释措辞。把它 rebase 到 main 并「缩减到剩余差异」——这通常是我对重复 PR 会提的要求——在这里意味着开一个 PR 把 "a 404" 改成 "the 404"。那是正儿八经的无谓改动,所以我不会提这个要求。

六个月后没有人会因为这个改动而骂人——只会疑惑它为什么存在。这恰好指向此处真正值得维护者关注的东西,而它不是这个 PR:

autofix 通道为同一次 main CI 失败开了两个 issue——#11525(提交 13b69b3313da)与 #11539(提交 b1ac3e297023),两者都指向任务 Test (ubuntu-latest, Node 22.x)、步骤 Run tests and generate reports#11530 修复了 #11525,于 07:51:32Z 合入;而本 PR 修复 #11539,于 08:19:59Z 从一个早于该合并的分支上开启。也就是说,该通道在第一个修复合入约半小时后,又为一个已经修好的失败产出了第二份修复,而整条路径上没有任何环节检查过是否已有等效修复合入。按提交分别开 issue 是它在履行职责;缺失的检查在开 PR 那一侧。这是流程缺口,不是本 diff 的缺陷,在补上之前它会持续产生这类 PR。

我没有做的事,以及原因。 我没有批准——在一个已过时、无法合并的 PR 上再投一票比不投更糟,而且 main 需要两个批准,所以我这一票是算数的。我也没有关闭它,尽管我认为关闭才是正确结果:本关卡只有关联 issue 已被标记为 completed 关闭时才可以关闭重复 PR,而 #11539 仍是 OPEN。关闭 PR 是整个流程中唯一不可逆的动作,与其为了得到我恰好认同的结论而去扭曲规则,我更愿意把这种歧义标记出来。我也没有提交 request-changes 审查——GitHub 已经报告 CONFLICTING / DIRTY,这个 PR 不需要我帮忙就已经无法合并,而正式阻断只会给一个「问题在于它本不该存在」的线程增加噪音。

建议的处理方式(给接手的人):

  1. fix(web-shell): realign two suites with shipped behavior to unbreak main CI (#11525) #11530 重复为由关闭本 PR —— 没有任何 rebase 值得做。
  2. Main CI failed: Qwen Code CI on 13b69b3313da #11525 重复为由关闭 Main CI failed: Qwen Code CI on b1ac3e297023 #11539;它所追踪的失败在 main 的 2488d12d 上已经是绿的。
  3. 可选:让 autofix 通道在开启修复 PR 之前,先检查是否已有等效修复合入。

⏸️ 转交 @yiliang114 —— 你在本 PR 开启前 28 分钟合入了内容相同的 #11530,因此这个重复判定应由你来做,而不是我。需要人来决定是否同时关闭本 PR 与 #11539

Qwen Code · qwen3.8-max-2026-09-02

Reviewed at 4de010c06239983bb5282c323fef2ffc790e0558 · re-run with @qwen-code /triage

@wenshao

wenshao commented Sep 10, 2026

Copy link
Copy Markdown
Collaborator

@qwen-code /resolve

…ignment

The same two web-shell test suites were realigned independently on main by
#11530, so this branch's fix and the base branch's landed fix touched the
identical lines. The executable code agreed exactly on both sides; only three
comment lines differed in phrasing. Take main's already-landed wording, which
also matches the neighbouring footer-version suite's "compact footer" term and
the shipped SIDEBAR_FOOTER_COMPACT_WIDTH constant.

The merge therefore has no net delta against main.
@qwen-code-dev-bot

Copy link
Copy Markdown
Collaborator Author

Qwen Code resolved the merge conflicts and pushed the branch update.

Merge resolution — PR #11549

Merge commit cfcdbf4c4a (parents 4de010c062 + 0ef35351e9 origin/main); two conflicts, both in files this PR touched.

Root cause — a duplicate fix, not a feature collision. While this branch was open, main landed 2488d12d8b (#11530), an independent autofix for the same CI breakage, editing the same lines of the same two files.

Textual, not semantic. git diff HEAD origin/main showed three changed lines per file, all comments; every executable line was byte-identical. No logic was merged — only phrasing. I kept main's already-landed wording (a 404 settles, StrictMode's remount, compact footer), which also matches the sibling footer-version suite and SIDEBAR_FOOTER_COMPACT_WIDTH = 344.

Net effect: the merged tree is byte-identical to origin/main.

Load-bearing — the agreed code is the fix itself:

  • The /brand mock must return a terminal 404; that stops the provider arming its brand retry timer. A 5xx, or removing it, adds GET /brand entries and breaks the exact-count assertion.
  • expect(calls).toEqual(...) is strict equality on an ordered list, StrictMode-conditional (two brand fetches on remount, one otherwise).
  • The '360' width must stay above the 344px breakpoint; below it the version label leaves the row (fix(web-shell): hide the sidebar version label at the compact footer breakpoint #11470) and the tooltip assertions, which query its title, fail. It must also stay after localStorage.clear().

Not verified — no build/lint/tests run (out of scope); I edited only the conflicted files.

中文说明

合并提交 cfcdbf4c4a(父提交 4de010c062 + 0ef35351e9);两处冲突,都在本 PR 改动的测试文件里。

根因是重复修复,非功能相撞:本分支开着时 main 已合入 2488d12d8b#11530),针对同一次 CI 失败改了同样两文件的同样几行。

文本冲突,非语义冲突:两文件与 main 各只差三行注释,可执行代码逐字节相同。故无逻辑需合并,只选措辞——保留 main 已合入的写法,它与同目录 footer-version 测试及常量 SIDEBAR_FOOTER_COMPACT_WIDTH = 344 一致。保留后合并结果与 origin/main 逐字节相同

关键约束(一致的代码即修复本体):/brand mock 须返回终态 404,否则 provider 启动品牌重试定时器、多出 GET /brand 而破坏下方精确计数断言;expect(calls).toEqual(...) 是对有序列表的严格相等断言且区分 StrictMode(重挂载两次品牌请求,否则一次);宽度 '360'高于 344px 断点,否则版本标签离开该行(#11470)、查其 title 的 tooltip 断言失败,且须位于 localStorage.clear() 之后

未能验证:未运行构建/lint/测试(超出范围),只改动冲突的两个文件。相对 main 的空 diff 属正常,但期望 PR diff 非空的 CI 或评审者可能报警;把 #11549 作为 #11530 的重复项关闭很可能是正确处置(我无法变更 PR 状态)。另 main 有一处未冲突改动:WorkspaceSessionProvider.tsxb3d022b357#11495)透传 sessionSourceType,冲突的 loading 测试会挂载该 provider,可能扰动 calls 序列;从 diff 看无关但无法运行测试确认,若该测试失败请优先查它,修复应在本次合并之外。

@wenshao

wenshao commented Sep 10, 2026

Copy link
Copy Markdown
Collaborator

Verification report — local real-environment run

I built a real local harness for this PR (three git worktree arms off this repo, real vitest runs against real sources — nothing about the code under test is stubbed) and ran the A/B the description asks for.

Verdict: the fix is correct and it was genuinely needed — but it is already on main. Merging this PR changes nothing at all. Recommend closing rather than merging.

TL;DR

Arm Tree This PR applied? Result
A pre-fix main b74592785b no 8 failed / 8 passed (16) — exactly the failures the description predicts
B current origin/main fe7cf68644 no 16 passed (16)
C this PR's head cfcdbf4c4a yes 16 passed (16)

Arm B is the decisive one: main is already green on these two suites without this PR. Arm C is indistinguishable from arm B because the PR's content is byte-identical to main's.


1. The problem was real (arm A — pre-fix main)

Reproduced verbatim, including both failure signatures from the description: the loading suite's GET /brand mismatch (once without StrictMode, twice with) and the brand suite's two expected null not to be null tooltip queries.

Test Files  2 failed (2)
     Tests  8 failed | 8 passed (16)

arm A — pre-fix main fails

So the diagnosis in the description is accurate. No dispute there.

2. But main is already green without this PR (arm B)

Same command, same harness, on current origin/main with this PR not applied:

Test Files  2 passed (2)
     Tests  16 passed (16)

arm B — current main already passes

The fix landed 28 minutes before this PR was opened, via sibling PR #11530 (commit 2488d12d8b, merged 2026-09-10T07:51:32Z; this PR was opened 2026-09-10T08:19:59Z). That merge is also the first green Qwen Code CI run on main after the red streak.

3. Merging this PR is a literal no-op

git — merging the PR changes nothing

Three independent checks agree:

  • git diff --stat origin/main...pr11549empty. GitHub agrees: the PR reports changedFiles: 0, +0 −0.
  • A trial git merge --no-ff of this branch into a clean origin/main worktree produces tree 28d72c3c49d7d6d373bd31e0fc422bb3fec7c827byte-identical to origin/main's own tree.
  • sha256 of both touched files matches origin/main exactly (e540b0c20f96…, c286557d1147…).

The branch's own merge commit cfcdbf4c4a says as much in its subject — "collapsing a duplicate test realignment". Re-checked after main advanced to 585589ac67: still empty, still a no-op.

4. The landed fix is technically sound (spot-check of the invariants)

Since this content is what's on main, I confirmed the two claims it rests on rather than taking them on faith:

  • SIDEBAR_FOOTER_COMPACT_WIDTH = 344 (WebShellSidebar.tsx:154), and the footer goes compact when sidebarWidth < SIDEBAR_FOOTER_COMPACT_WIDTH (:2109). The seeded 360 clears it. ✅
  • DaemonWorkspaceProvider.tsx:330 treats DaemonHttpError && error.status === 404 as the definitive "no brand here" answer and returns before the bounded-retry path at :334. So the mock's 404 genuinely settles the fetch without arming a retry timer, and no stray call leaks into later assertions. ✅

5. Full web-shell package suite on current main

302 files / 7150 tests, all green. One harness caveat, stated plainly: in a bare worktree client/build-artifact.test.ts (17 tests) fails with ENOENT … /packages/web-shell/dist because it asserts over the built bundle; after npm run build it passes 17/17. That is my harness, not a main defect. (The description quotes 7148 tests; I measure 7150 at the newer tip — three commits of drift, immaterial.)

6. This is one of three identical open duplicates

PR Branch Opened Three-dot diff vs main Merge result Content vs main
#11542 autofix/issue-11534 07:25:44Z 2 files, +17 −1 no net change byte-identical
#11549 (this) autofix/issue-11539 08:19:59Z empty no net change byte-identical
#11557 autofix/issue-11543 09:04:03Z 2 files, +17 −1 no net change byte-identical

#11542 and #11557 still show a +17 −1 diff only because their merge-base predates #11530; I trial-merged both, and each also resolves to zero net change against main.

The root cause is upstream of any of these PRs: main stayed red across four pushes, and one autofix issue was filed per push — #11525, #11534, #11539, #11543 — all for the same two suites. #11525 was fixed and closed by #11530; #11534, #11539 and #11543 are still open even though every commit they name is an ancestor of the fix, so the pipeline kept generating a fresh PR for an already-solved failure.

Recommendation

  1. Close this PR (and fix(web-shell): realign two suites with shipped behavior to unbreak main CI (#11534) #11542, fix(web-shell): realign two suites with shipped behavior to unbreak main CI #11557) as already-fixed-on-main — there is nothing to merge.
  2. Close Main CI failed: Qwen Code CI on 53964ef7e272 #11534, Main CI failed: Qwen Code CI on b1ac3e297023 #11539, Main CI failed: Qwen Code CI on 1097b9fe0af3 #11543 as duplicates of Main CI failed: Qwen Code CI on 13b69b3313da #11525, fixed by fix(web-shell): realign two suites with shipped behavior to unbreak main CI (#11525) #11530.
  3. Worth considering as a follow-up: have the autofix pipeline dedupe before opening a PR — if an open issue or PR already targets the same failing job/suite, attach to it instead of forking a new branch. This incident cost three redundant PRs and four issues for one defect.

None of this is a criticism of the change itself; the analysis and the patch are both right. They just arrived second.


Harness details / how to reproduce
# three worktrees off this repo
git worktree add --detach arm-A b74592785b   # pre-fix main
git worktree add --detach arm-B fe7cf68644   # current origin/main, PR NOT applied
git worktree add --detach arm-C cfcdbf4c4a   # this PR's head

# per arm (local node_modules was stale and lacked the workspace link):
ln -s ../../packages/sdk-typescript node_modules/@qwen-code/sdk
(cd packages/acp-bridge   && node ../../scripts/build_package.js)
(cd packages/sdk-typescript && node scripts/build.js)

cd packages/web-shell && npx vitest run \
  client/components/WorkspaceSessionProvider.loading.test.tsx \
  client/components/sidebar/WebShellSidebar.brand.test.tsx

packages/sdk-typescript and packages/acp-bridge are byte-identical across all three arms (same tree hashes), so sharing one build between them is faithful. The @qwen-code/sdk symlink and those two builds are environmental repairs applied identically to every arm; they cannot bias the A/B.

Environment: Linux 6.12.63, Node v22.22.2, vitest 3.2.7, jsdom.

Merge simulation:

git worktree add --detach msim origin/main && cd msim
git merge --no-ff --no-edit pr11549
git diff --stat origin/main HEAD                 # empty
git rev-parse origin/main^{tree} HEAD^{tree}     # identical
中文版报告

验证报告 —— 本地真实环境运行

我为这个 PR 搭建了真实的本地验证环境(基于本仓库的三个 git worktree 分臂,跑真实的 vitest,被测代码本身没有任何 mock),并执行了描述中要求的 A/B 对比。

结论:这个修复是正确的,当初也确实需要它 —— 但它已经在 main 上了。合并本 PR 不会带来任何变化。建议关闭而非合并。

结论速览

分臂 代码树 是否应用本 PR 结果
A 修复前的 main b74592785b 8 失败 / 8 通过(共 16) —— 与描述预测的失败完全一致
B 当前 origin/main fe7cf68644 16 全部通过(16)
C 本 PR 的 head cfcdbf4c4a 16 全部通过(16)

B 分臂是决定性的:在不应用本 PR 的情况下,main 上这两个套件已经是绿的。C 分臂与 B 分臂无法区分,因为本 PR 的内容与 main 逐字节相同。

1. 问题当初是真实存在的(A 分臂 —— 修复前的 main)

完整复现,两种失败特征都与描述吻合:loading 套件的 GET /brand 不匹配(非 StrictMode 一次、StrictMode 两次),以及品牌套件两处 expected null not to be null 的 tooltip 查询。

Test Files  2 failed (2)
     Tests  8 failed | 8 passed (16)

(截图见英文版第 1 节)

所以描述中的诊断是准确的,这一点没有异议。

2. 但 main 在没有本 PR 的情况下已经是绿的(B 分臂)

同样的命令、同样的环境,在当前 origin/main 上、不应用本 PR

Test Files  2 passed (2)
     Tests  16 passed (16)

修复在本 PR 创建的 28 分钟之前就已经通过兄弟 PR #11530(提交 2488d12d8b,合并于 2026-09-10T07:51:32Z)落地;本 PR 创建于 2026-09-10T08:19:59Z。那次合并也正是红色连续失败后 main 上第一次变绿的 Qwen Code CI

3. 合并本 PR 在字面意义上是空操作

三项独立检查互相印证:

  • git diff --stat origin/main...pr11549。GitHub 也是同样的结论:本 PR 显示 changedFiles: 0, +0 −0
  • 在干净的 origin/main worktree 中试合并(git merge --no-ff),得到的树对象是 28d72c3c49d7d6d373bd31e0fc422bb3fec7c827origin/main 自身的树逐字节相同
  • 两个被改文件的 sha256origin/main 完全一致(e540b0c20f96…c286557d1147…)。

分支自身的合并提交 cfcdbf4c4a 的标题也已经说明了这一点 —— "collapsing a duplicate test realignment"。在 main 前进到 585589ac67 之后复查:依然为空,依然是空操作。

4. 已落地的修复在技术上是站得住的(不变量抽查)

既然这份内容就是 main 上的内容,我没有直接采信,而是核对了它依赖的两个前提:

  • SIDEBAR_FOOTER_COMPACT_WIDTH = 344WebShellSidebar.tsx:154),页脚在 sidebarWidth < SIDEBAR_FOOTER_COMPACT_WIDTH 时进入紧凑态(:2109)。写入的 360 高于该阈值。✅
  • DaemonWorkspaceProvider.tsx:330DaemonHttpError && error.status === 404 视为"此 daemon 无品牌路由"的确定性应答,并在 :334 的有界重试路径之前返回。因此 mock 的 404 确实会让该 fetch 立即落定、不启动重试定时器,也不会有杂散调用渗入后续断言。✅

5. 当前 main 上的 web-shell 全量套件

302 个文件 / 7150 个测试,全绿。有一处环境说明需要如实指出:在未构建的 worktree 中,client/build-artifact.test.ts(17 个测试)会因 ENOENT … /packages/web-shell/dist 失败,因为它断言的是构建产物;执行 npm run build 之后 17/17 通过。这是我的验证环境所致,不是 main 的缺陷。(描述中写的是 7148 个测试;我在更新的 tip 上测得 7150,相差三个提交的漂移,无实质影响。)

6. 这是三个完全相同的重复 PR 之一

PR 分支 创建时间 相对 main 的三点 diff 合并结果 main 的内容对比
#11542 autofix/issue-11534 07:25:44Z 2 文件,+17 −1 无净变化 逐字节相同
#11549(本 PR) autofix/issue-11539 08:19:59Z 无净变化 逐字节相同
#11557 autofix/issue-11543 09:04:03Z 2 文件,+17 −1 无净变化 逐字节相同

#11542#11557 之所以还显示 +17 −1,只是因为它们的 merge-base 早于 #11530;我对两者都做了试合并,结果同样是相对 main 零净变化。

根本原因在这几个 PR 之上:main 连续四次推送保持红色,每次推送都新建了一个 autofix issue —— #11525#11534#11539#11543,全部指向同样的两个套件。#11525 已由 #11530 修复并关闭;#11534#11539#11543 至今仍处于 open,尽管它们所指向的每一个提交都是该修复的祖先,于是流水线持续为一个已解决的失败生成新的 PR。

建议

  1. 关闭本 PR(以及 fix(web-shell): realign two suites with shipped behavior to unbreak main CI (#11534) #11542fix(web-shell): realign two suites with shipped behavior to unbreak main CI #11557),理由是修复已在 main 上 —— 没有任何内容可供合并。
  2. 关闭 Main CI failed: Qwen Code CI on 53964ef7e272 #11534Main CI failed: Qwen Code CI on b1ac3e297023 #11539Main CI failed: Qwen Code CI on 1097b9fe0af3 #11543,作为 Main CI failed: Qwen Code CI on 13b69b3313da #11525 的重复项(已由 fix(web-shell): realign two suites with shipped behavior to unbreak main CI (#11525) #11530 修复)。
  3. 值得作为后续改进考虑:让 autofix 流水线在开 PR 之前先去重 —— 如果已有 open 的 issue 或 PR 指向同一个失败的 job/套件,就挂靠到它上面,而不是另开分支。本次事故为一个缺陷付出了三个冗余 PR 和四个 issue 的代价。

以上都不是对这份改动本身的批评;分析和补丁都是对的,只是来晚了一步。

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

Labels

review/self-reported The linked issue was opened by the PR author (self-reported)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Main CI failed: Qwen Code CI on b1ac3e297023

4 participants