feat(web-shell): group scheduled task run sessions - #10611
Conversation
|
|
|
Re-run at the current head — this PR went through five autofix rounds and a maintainer live validation since the first review, so restating the gate verdict for the diff as it stands now.
Moving on to code review. 🔍 中文说明在当前 head 上重跑——本 PR 自初审后经历了五轮 autofix 与维护者真机验证,此处按当前 diff 重述门禁结论。
进入代码审查 🔍 — Qwen Code · qwen3.8-max Reviewed at |
Code reviewMy independent proposal is unchanged from the first review: key the group by the task id behind the Things I verified against the code at this head:
Non-blocking, noted for follow-up:
Testing evidenceThe PR's own CI on the reviewed commit, fetched via API (I do not run PR code). The two red checks below are infrastructure, not this PR:
Final CI results for
One row per check name (latest run); skipped checks omitted; failures sort first. / 每个检查名一行(取最新一次运行),省略 skipped,失败项排在最前。 Sandboxed verification is already in flight: this triage run carries a 中文说明代码评审:我的独立方案与初审一致——以 在该 head 上核实:后缀正则与截断行为与生产端 非阻塞跟进: 测试证据:来自 PR 自身 CI(我不运行 PR 代码)。两个红色检查均为基础设施问题: — Qwen Code · qwen3.8-max Reviewed at |
🖼️ web-shell visual previewRendered against a mock daemon (no real backend): the PR base vs this PR head Screenshots · before / afterFull-resolution recordings (.webm) are attached to the workflow run. — Qwen Code · web-shell visuals |
|
Confidence: 4/5 — consistent with the maintainer's own verdict after live validation: every claim in the PR reproduces end-to-end against a real daemon, and what remains is non-blocking (a test gap the approver accepted, and a one-line description note). Going back to my independent proposal: the PR matches it, and after five review rounds I found nothing I would have done differently — one small single-purpose helper plus wiring into the existing section components, no parallel machinery. The diff grew since the first review, but every addition answers a named finding: the latch re-arms, the label-preference rule and its pinning tests, the deflake timeouts. No scope creep. The single out-of-scope item is the Reservations, none blocking: CI on this head landed red but clearly from infrastructure (runner shutdown signal, 120-minute ECS timeout with the suite green before the kill, main red in the same window — evidence in Stage 2). I queued a rerun of the two red jobs, so approval is deferred until CI lands green on 中文说明Confidence: 4/5 —— 与维护者真机验证后的结论一致:PR 的每项声明都能在真实 daemon 上端到端复现,剩余事项均不阻塞(批准者已接受的测试缺口,以及一行描述补充)。 对照我的独立方案:PR 与之一致,五轮评审后仍没有想换的做法——一个小的单一职责 helper 加上对现有分组组件的接线,没有平行机制。初审后 diff 有增长,但每处增量都对应具体评审发现:latch 重置、标题优先规则及其钉住测试、deflake 超时,无范围蔓延。唯一超出声明范围的是 非阻塞保留意见: 该 head 的 CI 红色为基础设施问题(runner 关机信号、120 分钟 ECS 超时且套件被杀前全绿、main 同窗口同样红——证据见 Stage 2)。两个红色任务的重跑已排队,待 CI 在受审提交上变绿后批准。 — Qwen Code · qwen3.8-max Reviewed at |
qwen-code-ci-bot
left a comment
There was a problem hiding this comment.
LGTM, looks ready to ship — CI landed green after the review. ✅
|
@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. This is a fork PR, so the first round comes from the next scheduled scan (usually within minutes). Remove the 中文说明🤝 已接管:autofix 循环现在管理此 PR —— 将持续处理新的评审反馈与 base 冲突,直到移除标签或达到轮次上限。本 PR 来自 fork,首轮处理将由下一次定时扫描执行(通常几分钟内)。移除 |
|
🤖 Addressed the latest review feedback (round 1/100). What changed, and what I pushed back on: · 已处理最新评审反馈(第 1/100 轮)。改动内容与我反驳保留之处如下: Autofix review round (same-run verification repair) — PR #10611The previous commit (
Per the same-run repair rule, the rejected commit is preserved and this round DiagnosisEvidence, not guesswork:
Conclusion: pre-existing slow tests (heavy locked-secondary interaction FixGave exactly those two tests an explicit 15000 ms timeout via the No mutation probe applies to this change: it adds no guard or branch to Round-1 ledger findings (re-listed in this round's feedback)The rejected commit already addressed these; they were re-verified at the
Issue-level comments
Changed files
VerificationAll commands actually run this round, with results:
中文说明Autofix 评审轮次(同轮验证修复)— PR #10611上一个提交(
按同轮修复规则,被拒提交予以保留,本轮追加一个修复该拒绝的后续提交 诊断基于证据而非猜测:
结论:既有的慢测试(重量级的锁定次工作区交互场景)在并行 CI 负载下超出默认 修复恰好给这两个测试通过 本轮改动不适用变异探针:未向产品代码添加任何守卫或分支,只是超时参数。上文证据 第 1 轮清单发现(在本轮反馈中重新列出)被拒提交已处理这些发现;本轮在现有 HEAD 上通过门禁命令运行重新验证(14 个文件、
议题级评论
变更文件
验证本轮实际运行的全部命令及结果:
Base-conflict check · 基分支冲突检查: no conflict with main. · 与 main 无冲突。 🧵 Resolved all 7 selected review thread(s). · 已关闭全部选中的 7 条评审线程。 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.
Reviewed — no blockers. Suggestions are inline.
Deferred under the convergence posture (round 2, not a blocker) — recorded, not requested in this round:
packages/web-shell/client/components/sidebar/WebShellSidebar.tsx:3875 — [probe] D2-1 settle-gate rewrite is inert in the tests (revert mutant leaves 156/156 green) — code unchanged since the round-1 reviewed headpackages/web-shell/client/components/sidebar/WebShellSidebar.tsx:2052 — [probe] D2-2 in-flight reloadGroups clobbers the org-revoke clear; PR's early-return removals make the stale state visible — race code unchanged since the round-1 revie…
中文说明
已审查——无阻断问题。 建议见行内评论。
收敛姿态下延后(第 2 轮,非阻断)——已记录,本轮不要求修改:共 2 条(原文未翻译,列表见上方英文部分)。
— qwen3.8-max via Qwen Code /review (v0.22.3)
|
@qwen-code /takeover from 2 |
|
🔄 Takeover re-armed: the round counter starts a fresh window (earlier rounds count toward the cap only via this seed); management continues. This window's round counter restarts at 2 (rounds already spent on this PR), so the Critical-only brake engages after 3 more change-producing round(s) instead of a full fresh 5. 中文说明🔄 已重新武装:轮次计数开启新窗口(此前轮次仅通过该种子计入上限),托管继续。本窗口轮次计数从 2 重启(即本 PR 已消耗的轮次),因此再经过 3 个产生改动的轮次即进入 Critical-only,而非重新计满 5 轮。 |
QwenLM#10611) Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
|
🤖 Addressed the latest review feedback (round 2/100). What changed, and what I pushed back on: · 已处理最新评审反馈(第 2/100 轮)。改动内容与我反驳保留之处如下: Autofix address-review summary — PR #10611 (round 4, same-run verification repair)New commit: Same-run verification repair — deterministic rejection fixedThe previous round was rejected because Reproduced locally before changing anything: running the gate's exact command ( Root cause: both are fully-mocked tests whose wall time is dominated by jsdom rendering (the overview test renders 50 table rows plus a select-all re-render; it already takes ~1s unloaded, the slowest in its file) and by the cold Fix (allowed deflake class: raise the per-test timeout budget; every assertion and input preserved verbatim): a 15000ms third argument on the two affected Feedback points and dispositions
Mutation probes (witness verification)
Changed files
VerificationCommands actually run and their results:
中文说明Autofix address-review 摘要 — PR #10611(第 4 轮,同轮验证修复)新提交: 同轮验证修复 — 已修复确定性拒绝上一轮被拒的原因是 改动前已在本地复现:在同一台自托管运行器上执行门禁的原始命令(在 根因:两者都是全 mock 测试,其耗时主要来自 jsdom 渲染(概览测试渲染 50 行表格并触发一次全选重渲染;无负载时已约 1 秒,是该文件中最慢的用例)以及冷 修复方式(允许的 deflake 类别:提高单测超时预算;所有断言与输入逐字保留):为受影响的两个 反馈点及处置
变异探针(见证验证)
变更文件
验证实际执行的命令及结果:
Base-conflict check · 基分支冲突检查: no conflict with main. · 与 main 无冲突。 🧵 Resolved all 3 selected review thread(s). · 已关闭全部选中的 3 条评审线程。 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.
Reviewed — no blockers. Suggestions are inline.
Convergence: round 3 posted 1 inline comment(s), 1 of them reported for the first time; the previous round posted 3 (3 new). Findings keep coming back to the same files: packages/web-shell/client/components/sidebar/scheduled-task-session-groups.ts (findings in round 2; 1 more now). A cluster that keeps producing siblings usually means the fixes are treating instances of a shared root cause — triaging that cause before the next round, or splitting an independent cluster into its own pull request, tends to end the loop faster than fixing them one at a time. No Critical finding is open on this round, so merging and moving the remaining Suggestion threads to a follow-up issue is available as an ending — a merged pull request cannot diverge further. (Observation only — nothing was withheld from this review because of this observation.)
中文说明
已审查——无阻断问题。 建议见行内评论。
收敛情况:第 3 轮发布了 1 条行内评论,其中 1 条是首次提出;上一轮发布了 3 条(其中 3 条首次提出)。发现反复回到同一批文件:packages/web-shell/client/components/sidebar/scheduled-task-session-groups.ts(第 2 轮已出过发现,本轮又有 1 条)。一个不断再生兄弟发现的簇,通常意味着逐条修复只在处理同一根因的实例——先定位并处理该根因,或把独立的簇拆成单独的 PR,通常比逐条修复更快结束循环。本轮没有未决的 Critical,因此"合入后把剩余 Suggestion 线程转到后续 issue"是一个可选的结束方式——已合入的 PR 不会继续发散。(仅为观察——本轮评审未因此扣留任何内容。)
— qwen3.8-max via Qwen Code /review (v0.22.3)
…QwenLM#10611) A user rename ending in the generated run-name suffix shape is indistinguishable from a generated name at the rendered-string layer. Document that limit above SCHEDULED_TASK_RUN_TIME_SUFFIX and pin the current classification with a test; the structural fix (persisting the task title alongside the run) is tracked as a follow-up.
|
🤖 Addressed the latest review feedback (round 3/100). What changed, and what I pushed back on: · 已处理最新评审反馈(第 3/100 轮)。改动内容与我反驳保留之处如下: Address review summary — PR #10611One feedback item this round; no failed or still-red checks; Feedback points[rv:5070553093] Review — "no blockers, suggestions inline"No action required; the single inline suggestion is handled below. [rc:3897838328] [Suggestion] R2-2 (fix-induced): shape-based label preference cannot tell a user rename from a generated run nameVerification — reproduced on HEAD ffd8266. A scratch vitest probe (deleted after recording) ran the pure function with the finding's scenarios:
The finding stands: at the rendered-string layer a rename and a generated name that share the Disposition — addressed in scope now; structural fix deferred to the follow-up queue (
Changed files (commit
Verification
中文说明处理评审摘要 — PR #10611本轮共 1 条反馈;无失败检查项,无遗留未通过的检查项; 反馈点[rv:5070553093] 评审 —"无阻断问题,建议见行内"无需处理;唯一的行内建议在下方处理。 [rc:3897838328] [Suggestion] R2-2(修复引发):按格式优先的标签规则无法区分用户重命名与生成的运行名验证——已在 HEAD ffd8266 上复现。 用一个临时 vitest 探针(记录输出后已删除)对该纯函数执行了发现中的场景:
该发现成立:在渲染字符串层,共享 处置——本轮在范围内处理;结构性修复转入后续跟进队列(记录于
变更文件(提交
验证
🦷 Gate advisory — this round's changed tests all pass on the pre-round tree (machine-measured, not agent-authored). Expected for a refactor or coverage addition; if this round was meant to FIX a defect, that defect did not reproduce. · 本轮改动的测试在轮前树上全部通过(门自动测量,非 agent 文本)。对重构或补充覆盖属正常;若本轮意在修复缺陷,则该缺陷未能复现。 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.
Deferred under the convergence posture (round 4, not a blocker) — recorded, not requested in this round:
packages/web-shell/client/components/sidebar/scheduled-task-session-groups.ts:66 — [probe] D4-1 label-retention guard's blocking direction is untested — probe-confirmed mutant removing .some() survives the whole shipped suitepackages/web-shell/client/components/sidebar/WebShellSidebar.tsx:3806 — [review] D4-2 stale manual groups paint one frame after org flips off — sessionSections memo's group branch ungated, unlike WorkspaceSectionpackages/web-shell/client/components/sidebar/WebShellSidebar.tsx:3824 — [probe] D4-3 scheduled-task section header flips while searching — label derived from search-filtered membership, probe-reproduced
中文说明
收敛姿态下延后(第 4 轮,非阻断)——已记录,本轮不要求修改:共 3 条(原文未翻译,列表见上方英文部分)。
— qwen3.8-max via Qwen Code /review (v0.22.3)
|
🔀 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.
Reviewed.
2 Suggestion-level finding(s) this review confirmed are already reported on this PR and are not repeated:
- Round-5 label-recovery altitude finding — already reported (R1-3, comment 3892948357; R2-2 cluster, comments 3895671437 and 3897838328)
- Round-5 producer-mirror coupling finding — already reported (R1-4, comment 3892948363)
Not explored to full depth (tool budget reached): "agent 6a": none — no check was cut short..
Deferred under the convergence posture (round 5, not a blocker) — recorded, not requested in this round:
packages/web-shell/client/components/sidebar/WorkspaceSection.tsx:820 — [probe] all-pinned scheduled sections keep the grouped view via an untested scheduledSections.some(...) clause — mutant survives the whole shipped suitepackages/web-shell/client/components/sidebar/WebShellSidebar.tsx:3824 — [probe] org-disabled grouped path drops the flat path's creation-descending sort for Ungrouped rows — order flips when the first scheduled run appears
中文说明
已审查。
本轮确认的 2 条建议级发现已在 PR 上报告过,不再重复发布(列表见上方英文部分)。
未探索到全部深度(达到工具调用预算):"agent 6a":none — no check was cut short.。
收敛姿态下延后(第 5 轮,非阻断)——已记录,本轮不要求修改:共 2 条(原文未翻译,列表见上方英文部分)。
— qwen3.8-max via Qwen Code /review (v0.22.3)
|
🤖 AutoFix updated a stale base — the fix did not pass verification, but this PR was behind What I found before stopping: See the Qwen Autofix agent step logs for model/tool output. 中文说明🤖 AutoFix 更新了一个过期的 base —— 修复未通过验证,但本 PR 落后于 Run log: https://github.com/QwenLM/qwen-code/actions/runs/33463003729 🧠 Handled by Qwen Code · model/模型 |
qwen-code-ci-bot
left a comment
There was a problem hiding this comment.
Reviewed.
7 Suggestion-level finding(s) this review confirmed are already reported on this PR and are not repeated:
- Label recovery via reverse-parsing the rendered displayName vs a structured task title — already reported (R1-3, comment 3892948357; R2-2 cluster, comments 3895671437 and 3897838328)
- First-wins label instability across divergent generated titles in collectScheduledTaskSession — already reported (R2-2, comment 3895671437)
- Suffix-regex producer/consumer drift coupling and contract-test angle — already reported (R1-4, comment 3892948363; its minimal fix, the consumer-side mirror comment, landed in the current diff)
- Producer-side back-pointer comment for the suffix mirror — already reported (R1-4, comment 3892948363)
- Stale manual groups paint one frame after org flips off (sessionSections memo group branch ungated) — already reported (D4-2, round-4 deferred list, review 5072186698)
- Untested scheduledSections.some(...) clause in the WorkspaceSection empty-label guard — already reported (D5-1, round-5 deferred list, review 5073326594)
- Org-disabled grouped path drops the flat path's creation-descending sort for Ungrouped rows — already reported (D5-2, round-5 deferred list, review 5073326594)
2 Suggestion(s) were drafted inline past the resolved critical posting floor; the CLI moved them into the deferral list below (floor enforcement).
Deferred under the convergence posture (round 6, not a blocker) — recorded, not requested in this round:
packages/web-shell/client/components/sidebar/WebShellSidebar.tsx:1284 — [review] R6-1: The first-sync latch is re-armed only when the session_organization capability flips ON; when it flips OFF mid-session, the newly formed Ungrouped ( re…packages/web-shell/client/components/sidebar/scheduled-task-session-groups.ts:69 — [review] R6-2: collectScheduledTaskSession re-scans the whole section with a regex test on every generated-name run, even though the label decision is perm…
中文说明
已审查。
本轮确认的 7 条建议级发现已在 PR 上报告过,不再重复发布(列表见上方英文部分)。
2 条 Suggestion 在已解析的 critical 发布下限之外被起草为行内评论;CLI 已将其移入下方延后清单(下限强制执行)。
收敛姿态下延后(第 6 轮,非阻断)——已记录,本轮不要求修改:共 2 条(原文未翻译,列表见上方英文部分)。
— qwen3.8-max via Qwen Code /review (v0.22.3)
|
🤖 Reviewed the latest feedback — no changes needed. Why, point by point: · 已审阅最新反馈——无需改动。逐点说明原因如下: Autofix review round — no action takenAll feedback newer than the last evaluation (2026-08-31T19:51:32Z) was triaged. Nothing actionable was found this round, so no code changes were made and the branch remains at Feedback triage
Cancelled check:
|
…led-task-session-groups # Conflicts: # packages/web-shell/client/components/sidebar/WebShellSidebar.tsx
|
🤖 Addressed the latest review feedback (round 5/100). What changed, and what I pushed back on: · 已处理最新评审反馈(第 5/100 轮)。改动内容与我反驳保留之处如下: Autofix review-response summaryNo new review feedback arrived this window (no reviews, inline comments, issue-level comments, or failed checks), so this round's work was the requested base-conflict resolution: merging Conflict resolution
Resolution keeps both intents: the PR's split stays, and main's Mutation probePer the witness rule, the merged gate was probed: temporarily removing Verification
中文说明Autofix 评审响应总结本轮窗口内没有新的评审反馈(没有评审、行内评论、issue 级评论或失败的检查),因此本轮的工作是按要求解决与基础分支的冲突:将 冲突解决
解决方案同时保留双方意图:保留本 PR 的拆分,并将 main 的 变更探测(Mutation probe)按照"每个新增守卫必须有测试见证"的规则,对合并进来的门控做了探测:临时移除 验证
Base-conflict check · 基分支冲突检查: conflicted with main — resolved in this push. · 与 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.
Reviewed.
5 Suggestion-level finding(s) this review confirmed are already reported on this PR and are not repeated:
- Primary-catalog group-over-scheduled precedence untested — already reported (R1-6, comment 3892948374)
- O(k^2) .some() re-scan in collectScheduledTaskSession — already reported (R6-2, round-6 deferred list, review 5074548763)
- All-pinned scheduled-sections empty-label guard untested — already reported (D5-1, round-5 deferred list, review 5073326594)
- Divergent generated-title label precedence untested — already reported (R2-2, comment 3895671437)
- Stale manual groups rendered after org revoke — already reported (D2-2, round-2 deferred list, review 5067998490)
Deferred under the convergence posture (round 7, not a blocker) — recorded, not requested in this round:
packages/web-shell/client/components/sidebar/WebShellSidebar.tsx:3894 — [review] No test pins scheduled-task sections rendering below manual groups; section order survives a push-order swap mutation
中文说明
已审查。
本轮确认的 5 条建议级发现已在 PR 上报告过,不再重复发布(列表见上方英文部分)。
收敛姿态下延后(第 7 轮,非阻断)——已记录,本轮不要求修改:共 1 条(原文未翻译,列表见上方英文部分)。
— qwen3.8-max via Qwen Code /review (v0.22.3)
|
@qwen-code /takeover stop |
|
👋 Takeover released: the autofix loop will no longer engage this PR (an in-flight round, if any, completes its bounded work). Re-apply 中文说明👋 已释放:autofix 循环不再介入此 PR(在飞的一轮如有,将完成其有界工作)。重新打上 |
# Conflicts: # packages/web-shell/client/main-boot.test.tsx
qwen-code-ci-bot
left a comment
There was a problem hiding this comment.
Reviewed.
3 Suggestion-level finding(s) this review confirmed are already reported on this PR and are not repeated:
- Structural task title vs display-name reverse-parse label recovery — already reported (R1-3, comment 3892948357; R2-2 cluster, comments 3895671437 and 3897838328)
- First-wins label precedence across divergent generated titles / pinned older run pinning a stale task title — already reported (R2-2, comment 3895671437)
- Org-disabled grouped path drops the flat path's creation-descending sort for Ungrouped rows — already reported (D5-2, round-5 deferred list, review 5073326594)
Deferred under the convergence posture (round 8, not a blocker) — recorded, not requested in this round:
packages/web-shell/client/components/sidebar/WorkspaceSection.tsx:977 — [probe] scheduled-task section rows render via bare renderSession — secondary-workspace content-search snippets dropped (probe flips)packages/web-shell/client/components/sidebar/WorkspaceSection.tsx:969 — [review] fourth byte-identical copy of the 7-line collapse-toggle closure (905/931/969/989); extract a local helperpackages/web-shell/client/components/sidebar/WebShellSidebar.tsx:3907 — [probe] new organizationEnabled color-bucketing guard untested — delete-mutant survives 175/175 sidebar tests
中文说明
已审查。
本轮确认的 3 条建议级发现已在 PR 上报告过,不再重复发布(列表见上方英文部分)。
收敛姿态下延后(第 8 轮,非阻断)——已记录,本轮不要求修改:共 3 条(原文未翻译,列表见上方英文部分)。
— qwen3.8-max via Qwen Code /review (v0.22.3)
qwen-code-ci-bot
left a comment
There was a problem hiding this comment.
中文说明
— qwen3.8-max via Qwen Code /review (v0.22.3)
Local validation — real
|
| # | Claim | Result |
|---|---|---|
| 1 | Runs of one task group under the task title (primary workspace) | ✅ Fig 1 — 3 tasks grouped; before: one flat list capped at 5 rows + "Show all" |
| 2 | Same in a secondary workspace (WorkspaceSection) |
✅ ws2 groups its 2 runs; ordinary chat stays in Ungrouped |
| 3 | Works without session_organization |
✅ Fig 2 — capability stripped in flight: manual/color sections vanish (proving the gate really flipped), scheduled groups remain |
| 4 | Manual color + named groups keep precedence | ✅ Fig 3 left — "Green" ·1 and "Release triage" ·2 hold their runs; the auto group drops to ·1 |
| 5 | Group header uses the clock icon, not a color dot | ✅ [data-web-shell-scheduled-task-group] present, no sessionGroupDot |
| 6 | Collapse/expand + persistence | ✅ ids are exactly the documented scheduled-task:839s5f8p and ws:f37e922f499c81d3|group:scheduled-task:8f3362wz; survives reload |
| 7 | Label = task title with the run-time suffix removed | ✅ incl. producer truncation (Reconcile the nightly artifact manifests acro…) and a title that itself ends in a date (Snapshot · 01-02 03:04) |
| 8 | Missing displayName → falls back to the task id |
✅ header renders alm3h5hv (matches how unnamed session rows already render) |
| 9 | Sidebar search | ✅ only matching runs form a section; counts adjust |
Repo checks at head: packages/web-shell 5589/5589 unit tests pass, tsc --noEmit clean, eslint clean on all changed files, 47/47 test:e2e:smoke Playwright tests pass locally (incl. web-shell.collapsed-groups-persist.spec.ts). Trial-merging current main is conflict-free; after rebuilding sdk-typescript + web-shell on the merged tree, 5642/5642 pass and typecheck is clean.
On the two red CI checks: both are infrastructure, not this PR. web-shell E2E Smoke ends with The runner has received a shutdown signal … The operation was canceled, and Test (ubuntu-latest) is cancelled at the 2 h cap with its only logged failure in packages/core/src/hooks/hook-runner.process.test.ts — unrelated to web-shell. Both suites pass locally at this head.
F1 — the PR also fixes a pre-existing trust-gate bug; please say so in the description
WorkspaceSection.groupedSessions gains if (channelGroupingEnabled || readOnly) return null;. That is not just defensive: on the merge-base, an untrusted secondary workspace that had any manual session group rendered its sessions through the grouped branch, which has no trust gate — the rows came out as role="button", and clicking one fired POST /session/:id/load → 403 Workspace is not trusted, leaving a red toast and a dead-end conversation view. With the PR the same rows are back to role="note" / "Trust this workspace to open the session" and issue no request at all (Fig 4).
The daemon always enforced trust, so this is a UX bug rather than data exposure — but it is a user-visible fix outside the PR's stated scope, and the "Risk & Scope" section currently says the change is limited to grouping. Worth one sentence (and a Fixes #… if an issue exists).
F2 — WebShellSidebar precedence over the new auto group is entirely untested (the one thing I'd fix)
WorkspaceSection has keeps a manually grouped scheduled-task run under its manual group. WebShellSidebar has no equivalent, and its bucketing order is what makes precedence work. Two mutants against the PR's own production code:
- M7 — move
collectScheduledTaskSession(...)above thesession.groupId && validGroupIds.has(...)branch. - M11 — skip the color branch for scheduled runs.
Both leave 174/174 tests green across the four touched suites, yet visibly break the UI: the "Green" color section disappears entirely and "Release triage" drops from 2 members to 1, because the auto group swallows them (Fig 3, right — that panel is a real build of the mutated source driven through the same daemon).
Suggested: one test in WebShellSidebar.workspace-removal.test.tsx with a scheduled run carrying color and another carrying groupId, asserting they render in the color/manual sections and not in section[aria-label="<task title>"].
For the record, 9 of the 12 mutants I ran were killed — M1 sourceType guard, M2 empty-taskId guard, M3 label || taskId, M4 suffix strip, M6 never-collect, M8 the readOnly gate, M9 the removed org-disabled early return, M10 the icon slot, M12 the assigned check. Coverage on the new module itself is good; only the sidebar's precedence ordering is unguarded.
F3 — the "first generated name wins" guard is unpinned, and picks the worse label in a real case (minor)
Deleting !section.sessions.some(hasGeneratedRunName) (mutant M5) also keeps 174/174 green. The documented shape-based limit then bites in a way the tests don't show: I renamed one run of Nightly deploy check to Follow-up · 12-31 23:59 while its sibling still carried the genuine generated name Nightly deploy check · 09-02 06:52, and the whole group header became "Follow-up" — first-wins hands the header to the rename precisely because the rename sorts first after being touched. A "most common generated title wins" rule would have kept Nightly deploy check. Not a blocker; either pin the current rule with a test or consider the majority rule.
F4 — two tasks with the same title render two identical headers (nit)
Two distinct scheduled tasks both named Review PRs produce two adjacent Review PRs · 1 / Review PRs · 3 groups (visible in Fig 1). Grouping is correct — they are different taskIds and collapse independently — but there is nothing on screen to tell them apart.
F5 — ChatEditor.test.tsx duplicates an upstream fix (nit)
868683029a removes the duplicate language binding, which main already fixed in 5282abea22 (#10729). Harmless — the trial merge resolves it cleanly — just expect that hunk to vanish on rebase.
F6 — isScheduledTaskSession narrows for an empty task id (informational)
Base treated sourceId === "scheduled_task_run:" as a scheduled-task session (row clock icon); the new getScheduledTaskSessionGroup rejects it. generateCronTaskId() never returns an empty id, so this is unreachable through the daemon — noting it only because the helper is now the single source of truth for two different questions.
On the }, 15000) timeout bumps
Checked that they are not masking a slowdown introduced here: SessionOverviewPanel.test.tsx runs 3.52 s of test time on merge-base sources and 3.55 s on the PR head (96 tests, same file, same machine), and all three bumped tests pass locally with the bumps removed. They read as pure CI-load insurance.
(Unrelated, for whoever owns it: prettier --check packages/web-shell fails on 5 files that this PR does not touch — 4 .module.css plus client/index.html.)
中文版报告
本地验证 —— 真实 qwen serve daemon + Chromium 中的真实 Web Shell
以维护者身份在 head 868683029a 上验证(merge-base b27deb634d,当前 main 为 61697df9b0),Linux,Node 22.22.2。
结论:建议合并。 PR 描述中的每一条主张都在真实 daemon 上端到端复现,没有发现功能缺陷。但有 一个测试覆盖缺口希望补上(F2),另外这个 PR 顺带修复了一个既有的信任门 UX bug,值得在描述里写一句(F1)。
验证方式(不是 jsdom)
对 packages/web-shell 做了两份 vite build:一份是 PR head,另一份只把改动的 6 个源文件回退到 merge-base。两份产物分别换入同一个 qwen serve 二进制的 dist/web-shell,因此两个对照组的 daemon 完全一致。会话数据也是真实的:由活跃 daemon 创建 sessionMode: "per_run" 的持久化定时任务,并通过 POST /scheduled-tasks/:id/run 触发,因此每一个 scheduled_task_run:<taskId> 来源标识和每一个 <title> · MM-DD HH:mm 展示名都由 scheduledTaskRunSessionName 真实生成,而非手工构造。共 6 个任务 / 11 个运行会话 / 2 个工作区 / 1 个未受信任的次级工作区。
结果
| # | 主张 | 结果 |
|---|---|---|
| 1 | 同一任务的多次运行按任务标题归组(主工作区) | ✅ 图 1 —— 3 个任务成功归组;改动前是一个平铺列表,被 5 行上限 + "Show all" 截断 |
| 2 | 次工作区同样生效(WorkspaceSection) |
✅ ws2 的 2 次运行归为一组,普通会话仍在 Ungrouped |
| 3 | 不依赖 session_organization 能力 |
✅ 图 2 —— 在网络层剥离该能力后,手动分组/颜色分组消失(证明开关确实翻转了),定时任务分组仍在 |
| 4 | 手动颜色与命名分组优先级更高 | ✅ 图 3 左 —— "Green" ·1 与 "Release triage" ·2 保住成员,自动分组降到 ·1 |
| 5 | 分组头用时钟图标而非颜色点 | ✅ 存在 [data-web-shell-scheduled-task-group],无 sessionGroupDot |
| 6 | 折叠/展开与持久化 | ✅ id 与注释完全一致:scheduled-task:839s5f8p 和 ws:f37e922f499c81d3|group:scheduled-task:8f3362wz;刷新后保持 |
| 7 | 标题 = 任务标题去掉运行时间后缀 | ✅ 含生产端截断(Reconcile the nightly artifact manifests acro…)以及标题本身以日期结尾的情况(Snapshot · 01-02 03:04) |
| 8 | 缺失 displayName 时回退到任务 id |
✅ 分组头显示 alm3h5hv(与无名会话行的既有渲染方式一致) |
| 9 | 侧边栏搜索 | ✅ 只有命中的运行会形成分组,计数同步调整 |
仓库层面检查(在该 head 上):packages/web-shell 单测 5589/5589 通过,tsc --noEmit 干净,改动文件 eslint 干净,test:e2e:smoke 的 47/47 Playwright 用例本地全过(含 web-shell.collapsed-groups-persist.spec.ts)。与当前 main 试合并无冲突;在合并后的树上重建 sdk-typescript 与 web-shell 后,5642/5642 通过且类型检查干净。
关于两个红色 CI: 都是基础设施问题,与本 PR 无关。web-shell E2E Smoke 的日志结尾是 The runner has received a shutdown signal … The operation was canceled;Test (ubuntu-latest) 状态是 cancelled(2 小时上限),日志中唯一真实失败是 packages/core/src/hooks/hook-runner.process.test.ts,与 web-shell 无关。两套用例在本地该 head 上都能通过。
F1 —— 本 PR 还修复了一个既有的信任门 bug,建议在描述里说明
WorkspaceSection.groupedSessions 新增了 if (channelGroupingEnabled || readOnly) return null;。这不只是防御性写法:在 merge-base 上,一个未受信任的次级工作区只要存在任意手动会话分组,其会话就会走分组分支,而该分支没有信任门 —— 行渲染为 role="button",点击会发出 POST /session/:id/load 并返回 403 Workspace is not trusted,留下一个红色 toast 和一个走不通的会话视图。应用本 PR 后,同样的行恢复为 role="note" / "Trust this workspace to open the session",并且完全不会发请求(图 4)。
daemon 侧一直是强制校验的,所以这属于 UX 缺陷而非数据泄露;但它是 PR 声明范围之外的用户可见修复,而 "Risk & Scope" 目前写的是改动仅限于归组。建议补一句(如果有对应 issue,也可以加 Fixes #…)。
F2 —— WebShellSidebar 的优先级顺序完全没有测试覆盖(唯一希望补上的点)
WorkspaceSection 有 keeps a manually grouped scheduled-task run under its manual group 这条用例;WebShellSidebar 没有对应用例,而它的分桶顺序正是优先级得以成立的原因。我对 PR 自己的生产代码做了两个变异:
- M7 —— 把
collectScheduledTaskSession(...)移到session.groupId && validGroupIds.has(...)分支之前; - M11 —— 让定时任务运行跳过颜色分支。
两者都让四个被改动测试文件的 174/174 全绿,但界面明显坏掉:"Green" 颜色分组整个消失,"Release triage" 从 2 个成员掉到 1 个,成员被自动分组吞掉(图 3 右 —— 那一栏是变异源码的真实构建产物,跑在同一个 daemon 上)。
建议:在 WebShellSidebar.workspace-removal.test.tsx 里加一条用例,构造一个带 color 的运行会话和一个带 groupId 的运行会话,断言它们出现在颜色/手动分组里,而不在 section[aria-label="<任务标题>"] 中。
作为参考,我跑的 12 个变异体中 9 个被杀死:M1 sourceType 守卫、M2 空 taskId 守卫、M3 label || taskId、M4 后缀剥离、M6 永不收集、M8 readOnly 门、M9 恢复 org-disabled 早退、M10 图标插槽、M12 assigned 判断。新模块自身的覆盖是好的,只有侧边栏的优先级顺序没有防护。
F3 —— "首个生成名优先" 的守卫没有测试固定,而且在真实场景下选出了更差的标题(次要)
删掉 !section.sessions.some(hasGeneratedRunName)(变异体 M5)同样保持 174/174 全绿。此时代码里已记录的"按形状判定"限制会以测试看不到的方式发作:我把 Nightly deploy check 的一次运行重命名为 Follow-up · 12-31 23:59,而它的兄弟运行仍保留真正的生成名 Nightly deploy check · 09-02 06:52,结果整个分组头变成了 "Follow-up" —— 因为重命名会刷新时间戳而排到最前,首个优先就把标题让给了它。若改成"出现最多的生成标题优先",则会保留 Nightly deploy check。这不是阻塞项;要么用一条测试把当前规则钉住,要么考虑改成多数规则。
F4 —— 两个同名任务会渲染出两个一模一样的分组头(吹毛求疵)
两个不同的定时任务都叫 Review PRs 时,会产生相邻的 Review PRs · 1 和 Review PRs · 3 两个分组(图 1 可见)。归组本身是正确的 —— 它们是不同的 taskId,折叠状态也各自独立 —— 但界面上没有任何可区分的信息。
F5 —— ChatEditor.test.tsx 与上游修复重复(吹毛求疵)
868683029a 移除了重复的 language 绑定,而 main 已经在 5282abea22(#10729)修过。无害 —— 试合并能干净解决 —— 只是 rebase 后这个 hunk 会消失。
F6 —— isScheduledTaskSession 对空任务 id 的判定收窄了(仅供参考)
改动前 sourceId === "scheduled_task_run:" 会被判定为定时任务会话(行上带时钟图标),新的 getScheduledTaskSessionGroup 则拒绝它。generateCronTaskId() 不会返回空 id,所以通过 daemon 无法触达;提一句只是因为这个 helper 现在同时承担了两个不同问题的判定职责。
关于 }, 15000) 超时上调
已确认这些上调没有掩盖本 PR 引入的变慢:SessionOverviewPanel.test.tsx 在 merge-base 源码下测试耗时 3.52 s,在 PR head 下为 3.55 s(同一文件 96 条用例,同一台机器),并且把三处上调全部移除后本地依然全过。它们读起来就是纯粹的 CI 负载保险。
(与本 PR 无关,供相关同学参考:prettier --check packages/web-shell 在 5 个本 PR 未触及的文件上失败 —— 4 个 .module.css 加 client/index.html。)
|
@qwen-code /triage |
|
Sandboxed verification: ✅ passed — merge-ready (agent verdict) - workflow run Ran the PR in an isolated, token-free container: A/B against the base build, mock-free harness assertions, targeted gates. Advisory evidence for human reviewers — not a review, an approval, or a CI check. Scripted assertions: 6005 passed · 0 failed · 6005 total Flakiness gate: ✅ 6 changed test file(s) x 5 identical rounds, no divergence 中文 — 判定:✅ 通过 · 可合入(agent 判定)沙箱验证在隔离、无凭证的容器中执行了该 PR 的代码(与 base 构建 A/B 对照、无 mock harness 断言、定向门禁)。仅作为评审证据,不构成评审、批准或 CI 检查。 脚本断言:6005 通过 · 0 失败 · 6005 总计 抖动门:✅ 6 changed test file(s) x 5 identical rounds, no divergence Verification reportPR #10611 Deep Verification — feat(web-shell): group scheduled task run sessionsVerdict: 中文摘要
Scope selectionCentral claim: sessions created by per-run scheduled-task fires ( Secondary claims (verified):
Out of scope (listed under Not covered): visual rendering, per-commit attribution, E2E browser reproduction, trial merge into current A/B: central claim is load-bearingEnvironment: head tree = CI merge-ref checkout at Harness
Witnesses: Cross-arm oracle sensitivity (the PR's own new tests executed against the other arm's source):
Wire oracle: producer ↔ client label round trip
146/146 pass; ladder timings flat (0.007–0.016 ms per parse, no superlinear growth — the pattern is fixed-length, input is daemon/user-authored, not cross-trust-boundary). Witness: The client-side mirror constant Mutation matrix (no survivors)Every guard the PR introduces was reverted/crippled in a scratch edit, the pinned suite run, and the edit reverted (
M5/M6 separate cleanly: the re-arm is required by both latch scenarios, the source-switch gate only by the channel one — two load-bearing guards, not redundant defence. Every red quoted was the intended behavioral assertion (e.g. missing Targeted gates (head)
Base-tip note: at FindingsN1 — suffix-only display names keep a N2 — Reviewer Test Plan step "collapse and re-expand the automatic group" is not pinned by any test (Suggestion). No test toggles a scheduled-task section collapsed and back, on either surface. The persistence machinery itself is shared and pinned for other section kinds ( Observation (not a finding): on the primary surface a brand-new task section appearing mid-session starts collapsed (the established "new sections mid-session start collapsed" semantics, shared with manual groups), while Not covered
MethodologyCI Flakiness gate logEvidence imagesHarness scripts and raw logs are in the workflow run artifacts (7-day retention). — Qwen Code · sandboxed verification |
|
Triage re-run completed without a new review.
The stage comments above were updated with the latest result. View workflow run. 上方各阶段评论已更新为最新结果。查看工作流运行。 |
qwen-code-dev-bot
left a comment
There was a problem hiding this comment.
Reviewed at head 868683029a.
- The round-1 Critical (auto-collapse consuming the initial-catalog latch against a stale pre-organized list when
organizationEnabledflips mid-session) is fixed: the flip now re-gates during the same render and re-arms the default-source latch so the first organized settle registers scheduled-task sections as initial instead of collapsing them — pinned by the new workspace-removal test. - The grouping helper is a well-bounded pure module: membership keys off the structured
sourceIdprefix (not display text), the mirrored producer constants are documented with their source files and the known rename-shape collision is called out with its consequence, and label precedence favors generated run names over renames deterministically. - 12/12 threads resolved; the remaining review rounds' Suggestions were addressed in
17e6808e. No new Critical issues found. CI on this head has no failures; per the channel convention the call is on the review itself.
yiliang114
left a comment
There was a problem hiding this comment.
Review passed.
- Grouping identity is server-derived (sourceType + sourceId prefix), not name guessing; the label-recovery regex for generated run names carries an explicit documented limit (a user rename shaped like a run name is classified generated) and the label-stability logic (generated-name preference, first-wins among generated) prevents header flipping when catalog order shifts.
- The sidebar changes keep the right guards: color sections stay gated on organizationEnabled, the grouped branch in WorkspaceSection falls back to the flat read-only rows for untrusted secondaries (no trust gate needed in the grouped branch itself), and the collapse-state id convention is documented for scheduled-task sections.
- The first-sync latch handling is the subtle part and it is handled: org-disable settle re-arms the default source, and switching Channels→Tasks closes the catalog gate in the same render so the settle cannot consume the latch against the emptied group catalog.
- Removal/rename across groups, search interplay, and the org-disabled path all have dedicated tests; the module's own grouping tests cover prefix/suffix/label edge cases.
CI: ubuntu Test green; the web-shell E2E Smoke failure is the known main-level flake (no assertion failure in the log), seen across recent PRs.
|
Released in v0.23.0. |











What this PR does
Automatically groups Web Shell sessions created by repeated runs of the same scheduled task. The virtual group is keyed by the stable scheduled-task source identity, uses the scheduled task title as its label, and displays the scheduled-task clock icon instead of a color marker. Existing manual color and named groups keep precedence, and the same behavior applies to primary and secondary workspaces without requiring session-organization support.
Why it's needed
Per-run scheduled tasks create a fresh session each time. Those sessions currently accumulate as a flat list, making the sidebar noisy and making runs from the same automation harder to scan.
Reviewer Test Plan
How to verify
Open Web Shell with at least two sessions created by separate runs of the same scheduled task. Confirm that both sessions appear under one expanded group named after the scheduled task, that the group header uses the scheduled-task clock icon, and that an ordinary session remains under Ungrouped. Collapse and re-expand the automatic group to confirm the existing collapsed-section behavior still works.
Evidence (Before & After)
Before: every scheduled-task run appeared as a separate top-level session. After: runs sharing a scheduled-task identity appear under one task-title group. The rendered validation screenshot is attached in the first PR comment.
Tested on
Environment (optional)
Node.js 22.17.0; Web Shell Vite development build; Chrome driven by Playwright with the repository mock daemon.
Risk & Scope
· MM-DD HH:mmrun suffix; if that daemon naming convention changes, grouping remains stable by task identity but the label may retain the new suffix.Linked Issues
None.
中文说明
这个 PR 做了什么
自动归组 Web Shell 中由同一个定时任务多次运行创建的会话。虚拟分组使用稳定的定时任务来源标识,标题取定时任务标题,并用定时任务时钟图标替代颜色标记。已有的手动颜色分组和命名分组优先级更高;主工作区和次工作区都会生效,也不依赖会话组织能力。
为什么需要
按次运行的定时任务每次都会创建一个新会话。当前这些会话会平铺累积,侧边栏容易变得拥挤,也不方便快速查看同一个自动任务的多次运行。
Reviewer Test Plan
如何验证
在 Web Shell 中准备至少两个由同一个定时任务不同运行创建的会话。确认它们位于同一个默认展开的分组中,分组标题是定时任务标题,分组头使用定时任务时钟图标,普通会话仍位于“未分组”。折叠并重新展开自动分组,确认现有的折叠状态行为仍然正常。
证据(改动前后)
改动前:每次定时任务运行都作为顶层会话平铺。改动后:共享同一定时任务标识的运行会话位于同一个任务标题分组下。实际渲染的验证截图附在 PR 首条评论中。
测试平台
环境(可选)
Node.js 22.17.0;Web Shell Vite 开发构建;Chrome 由 Playwright 驱动,并使用仓库内的 mock daemon。
风险与范围
· MM-DD HH:mm运行时间后缀;如果 daemon 的命名约定发生变化,仍会按任务标识稳定分组,但标题可能保留新的后缀。关联 Issue
无。