test(cli): keep the redaction ReDoS guard asserting on the shared pool - #10912
Conversation
`channel-worker-supervisor.test.ts` pushes 66 KB of `a.` through the credential-redaction path and bounds it at 1000 ms. #10870 quarantined that bound without a `poolMultiplier`, so on the shared pool the case runs and asserts nothing about the property it exists to defend: a backtracking regression in the redaction regex shows up as time, and the sibling assertions in the case check truncation, which a slow-but-correct regex still satisfies. It is the same family as the 13 complexity guards that already carry a multiplier — it was missed because the sweep that found those matched on test names (`stays linear`, `ReDoS`, `runs in bounded time`) and this one is named for its behaviour, `handles long non-url worker log lines while applying credential redaction`. The adversarial signal is in the body, not the name. Kept at 20x, consistent with the other 1000 ms guards: well clear of the ~5x contention on that fleet, far under a quadratic blowup, and the enclosing case takes the package's 60s pool timeout, so the assertion still decides the outcome. That makes 19 of the 34 sites relaxed rather than skipped. Also corrects the criterion recorded in `latency-budget.test.ts` (both copies, kept byte-identical). It still said "three of the quarantined cases have no other expect()" — the count is stale, and more importantly that reading was the one the review showed to be too narrow: it left complexity guards asserting only what a quadratic regression still passes. The comment now states the criterion actually applied, that the duration *is* the property, and why the multiplier varies with the lane's timeout. Follow-up to #10870, raised there by doudouOUC (S3) and confirmed post-merge by wenshao.
|
|
qwen-code-ci-bot
left a comment
There was a problem hiding this comment.
@yiliang114 the description is genuinely thorough — but it doesn't follow the PR template, so the gate stops here on shape before content.
What's missing against the template: Why it's needed (the material is there, under "The guard" and "The stale criterion"), the whole Reviewer Test Plan block — How to verify / Evidence (Before & After) / Tested on — currently a free-form "Verification" section, Risk & Scope (currently just "Risk"), Linked Issues, and the bilingual Chinese <details> translation. Every recently merged PR follows the template — including your own #10870 — so this one stands out.
On the merits, nothing looks wrong: the supervisor case really did lose its bound on the pool lane (the helper returns without asserting when poolMultiplier is absent), the 20x choice is consistent with the sibling guards, and the "19 of 34" comment refresh matches the actual site count. Please restructure the body into the template headings and this can go back through review — @qwen-code /triage re-runs it.
中文说明
@yiliang114 描述写得很充分——但没有遵循 PR 模板,所以门禁在此先卡在格式上,再看内容。
相对模板缺失的部分:Why it's needed(内容实际在 "The guard" 和 "The stale criterion" 里)、整个 Reviewer Test Plan 块(How to verify / Evidence (Before & After) / Tested on,目前是一个自由格式的 "Verification" 小节)、Risk & Scope(目前只有 "Risk")、Linked Issues,以及双语的中文 <details> 翻译。最近合并的 PR 都遵循模板——包括你自己的 #10870——这一篇因此显得突兀。
就内容本身而言没有看出问题:supervisor 用例在池通道上确实丢了上限(缺少 poolMultiplier 时 helper 直接返回、不做任何断言),20 倍的选择与同类守卫一致,注释里 "19 of 34" 的更新也与实际站点数吻合。请把正文重排进模板标题,即可重新进入审查——回复 @qwen-code /triage 重新运行。
— Qwen Code · qwen3.8-max
|
Prerequisite is up: #10915. It turned out to be a wider gap than the four packages named in the review. A census of all 22 vitest projects that Once that lands, the seven budgets deferred here have room to take a |
🩺 serve daemon A/BBuilt the PR base vs this PR head ✅ No response changes against the PR base across 12 scenario(s). — Qwen Code · serve A/B |
|
@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: 37 passed · 0 failed · 37 total Flakiness gate: ✅ 3 changed test file(s) x 5 identical rounds, no divergence 中文 — 判定:✅ 通过 · 可合入(agent 判定)沙箱验证在隔离、无凭证的容器中执行了该 PR 的代码(与 base 构建 A/B 对照、无 mock harness 断言、定向门禁)。仅作为评审证据,不构成评审、批准或 CI 检查。 脚本断言:37 通过 · 0 失败 · 37 总计 抖动门:✅ 3 changed test file(s) x 5 identical rounds, no divergence Verification reportPR #10912 verification —
|
| cell | test arm | redaction | lane | expected | actual |
|---|---|---|---|---|---|
| C1 | head | wild type | pool | green | green |
| C7 | base | wild type | pool | green | green |
| C6 | head | wild type | local | green | green |
| C9 | base | wild type | local | green | green |
| C4 | head | M1 (1.4 s) | pool | green — gap measurement | green (1.4 s < 20 s) |
| C5 | head | M1 | local | red | red — expected 1445 to be less than 1000 |
| C3 | base | M2 (24 s) | pool | green — the hole | green |
| C2 | head | M2 (24 s) | pool | red on the new bound | red — expected 23646 to be less than 20000 at latency-budget.ts:52 (the multiplier branch), test line 3138, 23.7 s < 60 s lane timeout |
| C8 | base | M2 | local | red | red — expected 24060 to be less than 1000 |
The load-bearing flip is C3→C2: identical mutant, identical environment; the only difference is the hunk this PR adds. C5/C8 are the positive control (both arms still fail on the local lane — the PR does not touch it), and C4 is the tradeoff measurement (below). Witness captures: 01-ab-flip-base-green-head-red.png, 02-mutation-matrix.png, 04-mutant-timing-probes.png, 05-scripted-assertions-37-pass.png.
Corrections
The added comment's "far too tight for a quadratic regression" overstates the pool guard's discrimination at this site (correction to the description, not a request to change code). The new comment in both latency-budget.test.ts copies and the Reviewer Test Plan both say the relaxed bound sits "far too tight for a quadratic regression". Measured through the real module on the real 66 KB input (04-mutant-timing-probes.png): wild type redacts in 4.2 ms (×238 margin vs the 1 s local budget), while the canonical quadratic regression — removing the {0,31} scheme-cap, the precise cap whose comment exists to prevent quadratic backtracking — takes 1.5 s: ~360× the wild type, yet ~13× under the relaxed 20 s pool bound (≈7 s even at the fleet's cited ~5× contention). So on a pool-only run the pool guard catches regressions ≥20 s, and the canonical quadratic is caught by the local/GitHub lane's 1 s budget (C5 red at 1445 ms), not by the pool bound. The change remains a strict improvement — base asserted nothing on the pool — and the case runs on every lane, so the regression class is still pinned somewhere; but the comment's generalization is empirically too strong for this site's input shape, and a reader who trusts it will overestimate what the pool lane alone can catch.
Findings (non-blocking)
- Suggestion —
fzfWorkerHandle.test.ts:87is the one debatable site among the 15 non-multiplier guards. The sibling sweep of all 15 pool-skipped sites found: two FIFO hang guards (customBanner.test.ts:257,DualOutputBridge.test.ts:390) where a bound can never fire (a blockingopen()stalls the event loop forever; only the lane timeout catches it — multiplier buys nothing);git-ignore.test.ts:406whose property is still pinned on the pool by a raw>= 4000lower bound; and the rest carrying sibling correctness assertions. OnlyfzfWorkerHandle's 50 ms budget discriminates a property (worker spawn ≥10 ms vs in-thread µs) that a ×20 multiplier (1 s) could still discriminate. It is defensible either way — spawn latency under 5× contention is unpredictable, so a pool bound there risks false positives — and it predates this PR; noted for the ci: give every workspace the shared-pool test timeout, not just five #10915 follow-up rather than as a defect here.
Not covered
- Full
packages/cli/packages/coresuites were not run; the PR's own CI covers them, and this round ran the changed case (9 cells) plus both helper suites (12/12). - The fleet contention factor (~5×) is taken from the helper's own comment, not measured here (needs pool-host history; this container is not an
ecs-qwen-*runner —RUNNER_NAMEis empty). The 13× discriminability figure therefore inherits that uncertainty. - Regressions slower than the 60 s lane timeout were not exercised (M2 was placed in-band by design); for those, vitest's worker kill decides, on both arms.
- M1 is a no-op on the adversarial input but not on all inputs (corpus: 1/10 diff — schemes longer than 32 chars get redacted where WT leaves them). It models "slow but correct" for this test's input, which is what the guard sees; the corpus diff is documented in the probe log.
- Windows/macOS lanes not exercised (linux container).
- The seven deferred raw budgets were verified to exist and to match the PR's rationale (channels packages have no
testTimeout, dingtalk's comment documents the ~4.1 s quadratic), but not executed.
Methodology
Environment: the CI verify container at the merge commit (HEAD = merge, HEAD^1 = base tip, HEAD^2 = PR head; 1 reachable commit, matching the metadata snapshot). Harnesses live in tmp/pr10912-verify-20260903-122705/src/ (census.mjs, mutant-probe.ts, apply-mutant.mjs, run-cell.sh, verify-assertions.mjs, print-*.mjs); raw per-cell logs in .../logs/. Cells ran the real packages/cli vitest against the real production module (the cli vitest config aliases logRedaction to source; mutants were applied in place and restored, sha256-verified byte-identical, working tree left clean). All 37 assertions are re-checkable by rerunning node src/verify-assertions.mjs, which parses only saved logs.
Flakiness gate log
rounds=5 files=3 skipped=0
file packages/cli/src/serve/channel-worker-supervisor.test.ts: (cd packages/cli) npx --no-install vitest run ./src/serve/channel-worker-supervisor.test.ts
file packages/cli/src/test-utils/latency-budget.test.ts: (cd packages/cli) npx --no-install vitest run ./src/test-utils/latency-budget.test.ts
file packages/core/src/test-utils/latency-budget.test.ts: (cd packages/core) npx --no-install vitest run ./src/test-utils/latency-budget.test.ts
per-file results (P=pass F=fail I=infra-exit, one letter per run):
packages/cli/src/serve/channel-worker-supervisor.test.ts: PPPPP
packages/cli/src/test-utils/latency-budget.test.ts: PPPPP
packages/core/src/test-utils/latency-budget.test.ts: PPPPP
verdict: pass
summary: 3 changed test file(s) x 5 identical rounds, no divergence
--- per-invocation detail (full copy in the artifact) ---
round 1 · packages/cli/src/serve/channel-worker-supervisor.test.ts: P (exit 0)
round 1 · packages/cli/src/test-utils/latency-budget.test.ts: P (exit 0)
round 1 · packages/core/src/test-utils/latency-budget.test.ts: P (exit 0)
round 2 · packages/cli/src/serve/channel-worker-supervisor.test.ts: P (exit 0)
round 2 · packages/cli/src/test-utils/latency-budget.test.ts: P (exit 0)
round 2 · packages/core/src/test-utils/latency-budget.test.ts: P (exit 0)
round 3 · packages/cli/src/serve/channel-worker-supervisor.test.ts: P (exit 0)
round 3 · packages/cli/src/test-utils/latency-budget.test.ts: P (exit 0)
round 3 · packages/core/src/test-utils/latency-budget.test.ts: P (exit 0)
round 4 · packages/cli/src/serve/channel-worker-supervisor.test.ts: P (exit 0)
round 4 · packages/cli/src/test-utils/latency-budget.test.ts: P (exit 0)
round 4 · packages/core/src/test-utils/latency-budget.test.ts: P (exit 0)
round 5 · packages/cli/src/serve/channel-worker-supervisor.test.ts: P (exit 0)
round 5 · packages/cli/src/test-utils/latency-budget.test.ts: P (exit 0)
round 5 · packages/core/src/test-utils/latency-budget.test.ts: P (exit 0)
Evidence images
Harness scripts and raw logs are in the workflow run artifacts (7-day retention).
— Qwen Code · sandboxed verification
|
Welcome back, and thanks for restructuring this — the template is now fully in place, so the shape gate that stopped the last run is cleared and this can be judged on content. Template: ✓ — all required headings present ( Problem: Observed, not theoretical. The credential-redaction ReDoS guard in Direction: Aligned. This is test-reliability work squarely inside the #10490 flakiness effort — restoring assertion coverage a quarantine sweep accidentally dropped, not adding new surface. Size: Test-only. 0 production lines (all three files are Approach: Minimal and correct in scope — one call gets Risk: No elevated signals — every changed file is a Moving on to code review. 🔍 中文说明感谢重新整理 —— 模板现已完整,上一次卡住的格式门禁已解除,可以按内容来评审了。 模板: ✓ —— 所有必需标题齐全( 问题: 已观测到,而非理论性的。 方向: 对齐。这属于 #10490 flakiness 工作正中央的测试可靠性工作 —— 恢复一次隔离排查中意外丢掉的断言覆盖,而非新增功能面。 规模: 纯测试改动。生产代码 0 行(三个文件均为 方案: 范围上最小且正确 —— 一处调用补上 风险: 无升级信号 —— 所有改动文件都是 进入代码审查。🔍 — Qwen Code · qwen3.8-max Reviewed at |
|
Code review. I read the helper first, then the diff, and the change does exactly what a reviewer would ask for. Independent read of the problem: the supervisor case needs the same treatment as its sibling guards — pass a Verified against the actual implementation, not the PR's framing:
No correctness blockers, no convention violations — test-only, uses the existing helper, no duplication. The added why-comment on the supervisor call is the kind of comment that earns its place. Testing. This is the CI path, so I'm quoting the PR's own checks on the reviewed commit rather than running anything. The check that matters here is Final CI results for
One row per check name (latest run); skipped checks omitted; failures sort first. / 每个检查名一行(取最新一次运行),省略 skipped,失败项排在最前。 No user-visible behavior changes (test-only), so there is no live TUI/behavioral claim for a sandboxed lane to settle — the in-flight unit suite is the right oracle here. 中文说明代码审查。 我先读了 helper 实现,再看 diff,这个改动正是评审者会要求的样子。我对问题的独立判断是:supervisor 用例需要与同类守卫相同的处理 —— 传入 以下是对照真实实现核实过的,而不是照搬 PR 的说法:
无正确性阻塞项、无规范违规 —— 纯测试、复用现有 helper、无重复。supervisor 调用上新增的 why 注释是那种"值得存在"的注释。 测试。 这是 CI 通道,因此我引用该提交自身的 CI 检查结果,而非自行运行。这里最关键的检查是 (CI 表格见上方标记区域;用户可见行为无变化,属纯测试改动,故无需沙箱通道去验证任何 TUI / 行为断言 —— 在途的单元测试套件就是此处正确的裁判。) — Qwen Code · qwen3.8-max Reviewed at |
|
Confidence: 5/5 — clean across every stage; this is a small, verified-correct test fix that restores a guard the quarantine sweep silently disabled. This one earns its merge. The prior run stopped purely on the template, and with that addressed the substance is what I'd want to see: a real, named gap (the redaction ReDoS bound was asserting nothing on the shared pool), a fix that matches the pattern the siblings already use, and scope discipline — the seven sibling budgets outside Going back to my independent read, I'd have proposed exactly this: pass a The one thing I cannot yet attest is a green full-suite run — the author didn't run it locally (it needs a workspace build first), and the 中文说明置信度:5/5 —— 每个阶段都干净;这是一处小而正确、经过验证的测试修复,恢复了一个被隔离排查悄悄禁用的守卫。 这个 PR 值得合入。上一次运行纯粹卡在模板上;模板补齐后,其实质内容正是我希望看到的:一个真实且被点名指出的缺口(脱敏 ReDoS 上界在共享池上不作任何断言)、一个与同类守卫已有做法一致的修复,以及范围上的克制 —— 回到我的独立判断,我会提出的也正是这个方案:传入 我唯一尚不能背书的,是一次绿色的完整套件运行 —— 作者未在本地运行(需先做工作区构建),而那个会在池通道上真实执行此测试的 — Qwen Code · qwen3.8-max Reviewed at |
|
Triage re-run completed without a new review. The bot already has a review of its own on 机器人在 The stage comments above were updated with the latest result. View workflow run. 上方各阶段评论已更新为最新结果。查看工作流运行。 |
qwen-code-ci-bot
left a comment
There was a problem hiding this comment.
Reviewed. Suggestions are inline.
Test Plan (not a blocker): Tests 12 passed — this review observed 28107, 23147, 1919, 298, 1769, 504, 5732, 94 passed.
— qwen3.8-max via Qwen Code /review (v0.22.3)
qwen-code-ci-bot
left a comment
There was a problem hiding this comment.
Reviewed. Suggestions are inline.
1 Suggestion-level finding(s) this review confirmed are already reported on this PR and are not repeated:
- R2-1 criterion-comment sub-20x rationale — already reported as R1-1 (comment 3924537783)
Test Plan (not a blocker): Tests 12 passed — this review observed 23144, 1919, 298, 1772, 504 passed.
中文说明
已审查。 建议见行内评论。
本轮确认的 1 条建议级发现已在 PR 上报告过,不再重复发布(列表见上方英文部分)。
Test Plan(非阻断):Tests 12 passed — this review observed 23144, 1919, 298, 1772, 504 passed。
— qwen3.8-max via Qwen Code /review (v0.23.0)
The criterion comment's closing clause attributed every sub-20x poolMultiplier to a shorter per-test timeout, but only 2 of the 6 sub-20x sites fit that reading: cleanup.test.ts keeps 5x because the bound must sit under the ~5s no-cap drain (a larger multiple would clear the regression it exists to catch), and review-footer / compose-review keep 10x as a margin landing near 20s with no per-test timeout at all. Following the clause as a selection rule would pick 20x whenever budget x 20 fits the lane, reproducing the dead-guard hole this family closes. Reword the clause: 20x where the lane allows it and the bound still sits under the regression's own cost; a lower multiple where a shorter per-test timeout or the regression's own cost decides the outcome first. Both byte-identical copies updated in lockstep. Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> Patrol-Run: qwen-pr-closeout/jmtlz4ubdgq
qwen-code-ci-bot
left a comment
There was a problem hiding this comment.
No blocking issues. LGTM! ✅
Not explored to full depth (tool budget reached): "agent 4": none — no check was cut short..
Test Plan (not a blocker): Tests 12 passed — this review observed 28112, 23151, 1919, 298, 1772, 504, 5822, 94 passed.
Deferred under the convergence posture (round 3, not a blocker) — recorded, not requested in this round:
packages/core/src/test-utils/latency-budget.test.ts:45 — [probe] D3-1 hardcoded "19 of the 34" site census in the criterion comment drifts with routine site churn
中文说明
无阻断问题。LGTM!✅
未探索到全部深度(达到工具调用预算):"agent 4":none — no check was cut short.。
Test Plan(非阻断):Tests 12 passed — this review observed 28112, 23151, 1919, 298, 1772, 504, 5822, 94 passed。
收敛姿态下延后(第 3 轮,非阻断)——已记录,本轮不要求修改:共 1 条(原文未翻译,列表见上方英文部分)。
— qwen3.8-max via Qwen Code /review (v0.23.0)
|
E2E verification report (qqqys patrol, head Gate: ci-bot APPROVED 21:42Z + wenshao APPROVED 22:11Z, both at head. CI at head: 28 success / 112 skipped / 0 failure — What the diff does (verified against head, not just the description)
Load-bearing A/B (head tarball + symlinked deps, no build; helper read from source) Ran a probe alongside the real suites simulating the pool (
Real suites at head:
Conclusion: no Critical issues found; the change does what it claims and nothing else. Mergeable from this reviewer's perspective. |





What this PR does
Restores the missing pool bound on the one migrated ReDoS-shaped guard that was left asserting nothing on the shared ECS pool, and corrects the criterion recorded in the latency-budget helper's own test comment.
Why it's needed
channel-worker-supervisor.test.tspushes 66 KB ofa.through the credential-redaction path and bounds it at 1000 ms. #10870 quarantined that bound with nopoolMultiplier, so on the shared pool the case runs and asserts nothing about the property it exists to defend. A backtracking regression in the redaction regex shows up as time, while the sibling assertions in the same case check truncation, which a slow-but-correct regex still satisfies. On the pool lane the case was therefore green against exactly the regression it guards.The original sweep missed it because it matched on test names —
stays linear on pathological inputs,does not catastrophically backtrack … (ReDoS),runs in bounded time on pathological input. This one is named for its behaviour,handles long non-url worker log lines while applying credential redaction, and the adversarial signal is'a.'.repeat(33_000)in the body rather than in the name. Name-matching was the wrong instrument, and this is the site it missed.Separately,
latency-budget.test.tsstill described the selection rule as "Three of the quarantined cases have no otherexpect()". The count is stale, and more importantly that reading is the one the review showed to be too narrow: it is what left complexity guards asserting only things a quadratic regression still satisfies. The comment should record the criterion actually applied — whether the duration is the property under test.Reviewer Test Plan
How to verify
The change adds
poolMultiplier: 20to a single call, consistent with the other 1000 ms guards. A reviewer should confirm the multiplier is sound in three respects: 20x is well clear of the ~5x contention measured on that fleet; it stays far under a quadratic blowup, so the guard still catches what it exists for; and the enclosing case carries no per-test timeout, so it takes the package's 60s pool ceiling and the assertion — not vitest — still decides the outcome. That makes 19 of the 34 quarantined sites relaxed rather than skipped.The helper's own suites are self-contained and were run in isolation. The full package suites need
npm run buildfor workspacedist/output, which was not run here; the supervisor change adds an options object to a call whose signature already accepts it, in the same shape as the 18 sites CI has already run green.Evidence (Before & After)
N/A for user-visible behaviour — this is a test-only change.
Before, on the pool lane the helper returns early when no multiplier is supplied, so the 1000 ms bound was not evaluated at all. After, the pool lane asserts against 20 × 1000 ms = 20 s, which sits under the package's 60 s pool
testTimeout.Both copies of the helper suite pass, and remain byte-identical after the comment change:
Site census backing the corrected comment — 19
poolMultipliersites out of 34 total calls, at three values (13 × 20, 4 × 10, 2 × 5).prettier --checkclean on all three changed files.Tested on
Environment (optional)
Unit tests only (Node 22, vitest 3.2.4); the two helper suites run standalone without a workspace build.
Risk & Scope
packages/clisuite was not run here because it needs a workspace build first, so the supervisor file's green run comes from CI. Also deliberately out of scope are the seven raw wall-clock budgets in four workspaces outsidepackages/{cli,core}— see below.What this PR deliberately does not do, and why
@wenshao's post-merge verification also found seven raw wall-clock budgets outside
packages/{cli,core}—sdk-typescript×4,qwen-live,channels/base,channels/dingtalk×2 — all on the same pool hosts with no code path for the flag. I confirmed all seven, and that all four packages do run in thenpm run test:ci --workspaceslane. They are not fixed here because it is not the mechanical helper-copy it looks like.First, there is no shared home: only
sdk-typescriptdepends oncore,channels/basehas no qwen dependencies at all, and there is no root-level shared test-utils precedent in this repo. Adding achannels/base → coreedge for a test-only helper would be real coupling.Second, and decisively, for the two channels packages quarantining the budget first would have bought almost nothing. Neither package set
testTimeout, so both ran on vitest's 5000 ms default against 1000 ms budgets — a largest usable multiplier of about 4x, whiledingtalk's own comment measures the quadratic cost it guards at ~4.1 s, and the fleet's contention factor is itself ~5x. There was no room. #10915 is the prerequisite that creates it, by giving those packages a 60 s pool ceiling; once it lands, these budgets can take apoolMultiplierin a follow-up.sdk-typescript's four are unrelated and easy — all four are scaffolding upper bounds ("generous bound — just confirms the timer fired") that want a plain skip.Linked Issues
Follow-up to #10870, where this site was raised by @doudouOUC (S3) and confirmed post-merge by @wenshao. Prerequisite for the deferred half: #10915. Underlying flakiness umbrella: #10490.
中文说明
这个 PR 做了什么
为唯一一处迁移后在共享 ECS 池上不再断言任何东西的 ReDoS 型守卫补回池上的上界,并修正 latency-budget helper 自身测试注释中记录的判据。
为什么需要
channel-worker-supervisor.test.ts把 66 KB 的a.推过凭据脱敏路径,并以 1000 ms 为界。#10870 在隔离该上界时没有带poolMultiplier,因此在共享池上这个用例会运行,却对它本要守护的属性不作任何断言。脱敏正则的回溯回归表现为时间,而同一用例中的其它断言检查的是截断,而一个慢但正确的正则仍然满足截断。于是在池通道上,这个用例恰恰对它所守护的那种回归是绿的。最初的排查漏掉了它,因为那次是按测试名字匹配的 ——
stays linear on pathological inputs、does not catastrophically backtrack … (ReDoS)、runs in bounded time on pathological input。而这一处是按行为命名的:handles long non-url worker log lines while applying credential redaction,对抗性信号是函数体里的'a.'.repeat(33_000),不在名字里。按名字匹配这个方法本身就不对,这就是它漏掉的那处。另外,
latency-budget.test.ts仍把选取规则描述为「三处被隔离的用例没有别的expect()」。计数已过期,更重要的是这个判读正是评审证明过于狭窄的那一个:它导致复杂度守卫只保留了二次回归依然能满足的断言。注释应当记录实际采用的判据 —— 时长是否就是被测属性。评审验证方案
如何验证
改动为单个调用添加
poolMultiplier: 20,与其它 1000 ms 守卫一致。评审者应从三方面确认该倍数是合理的:20 倍远高于该机群实测的约 5 倍争抢;它仍远低于二次爆炸的量级,因此守卫仍能抓住它存在的意义所在;以及外层用例没有 per-test 超时,会采用该包 60 秒的池上限,因此仍由断言而非 vitest 决定结果。这使得 34 处被隔离站点中有 19 处是放宽而非跳过。helper 自身的两个套件是自包含的,已独立运行。完整的包级套件需要先
npm run build生成工作区dist/产物,此处未运行;supervisor 的改动只是为一个签名本就接受该参数的调用增加了选项对象,形状与 CI 已经跑绿的 18 处一致。证据(前后对比)
用户可见行为方面为 N/A —— 这是一处纯测试改动。
修改前:在池通道上,未提供倍数时 helper 会提前返回,因此 1000 ms 的上界根本没有被求值。修改后:池通道对 20 × 1000 ms = 20 秒作断言,该值位于该包 60 秒池
testTimeout之下。helper 的两份套件均通过,且在注释改动后仍逐字节一致:
支撑修正后注释的站点普查 —— 34 处调用中有 19 处带
poolMultiplier,取三种值(13 处 ×20、4 处 ×10、2 处 ×5)。三个改动文件的prettier --check干净。测试平台
运行环境(可选)
仅单元测试(Node 22、vitest 3.2.4);两个 helper 套件无需工作区构建即可独立运行。
风险与范围
packages/cli套件此处未运行,因为需要先做工作区构建,因此 supervisor 文件的绿色结果来自 CI。另外刻意排除在外的还有packages/{cli,core}之外四个工作区中的七处裸挂钟预算 —— 见下。本 PR 刻意不做什么,以及为什么
@wenshao 的合并后验证还发现了
packages/{cli,core}之外的七处裸挂钟预算 ——sdk-typescript4 处、qwen-live、channels/base、channels/dingtalk2 处 —— 全都跑在同样的池主机上,且没有该开关的任何代码路径。我确认了这七处全部存在,也确认这四个包确实都在npm run test:ci --workspaces通道内。此处不修,是因为它并不是看上去那样机械地复制一份 helper 就行。其一,没有共同的归属地:只有
sdk-typescript依赖core,channels/base完全没有 qwen 依赖,而本仓库也不存在根级共享 test-utils 的先例。为一个纯测试 helper 新增channels/base → core的依赖边是真实的耦合。其二,也是决定性的:对那两个 channels 包而言,先隔离预算几乎不会带来任何收益。这两个包都没有设置
testTimeout,因此跑在 vitest 的 5000 ms 默认值上、对着 1000 ms 的预算 —— 可用倍数最大约为 4 倍,而dingtalk自己的注释实测它所守护的二次代价为约 4.1 秒,机群自身的争抢因子又是约 5 倍。根本没有余量。#10915 正是创造余量的前置条件,它为这些包提供 60 秒的池上限;待其合入后,这些预算即可在后续 PR 中带上poolMultiplier。sdk-typescript的四处与此无关且简单 —— 四处都是脚手架性质的上界(注释写着「generous bound —— 只是确认定时器触发了」),直接跳过即可。关联 Issue
#10870 的后续,该站点由 @doudouOUC(S3)提出并由 @wenshao 在合并后确认。被推迟部分的前置条件:#10915。底层 flakiness 总 issue:#10490。