fix(autofix): budget the repair pass, and keep its timeouts out of the cap - #9745
fix(autofix): budget the repair pass, and keep its timeouts out of the cap#9745wenshao wants to merge 2 commits into
Conversation
…e cap Two defects with one cause. The same-run repair pass ran on an 18-minute budget under a 20-minute step, and every exhaustion it produced was counted into TIMEOUT_WINDOW_CAP as though the round itself had run out of time. The budget could not work. The pass has to re-run the verification the gate just finished before its own verdict counts, and that measured 6.6-10.6 minutes, leaving the model roughly 8 minutes to read the rejection, fix it and commit — on a repository where the primary pass averages 41 of its 120. Across five PRs sampled on 2026-08-22, twenty repair passes ran, twenty hit the wall at exactly 18.0 minutes, none succeeded. Raise it to 40 minutes under a 45-minute backstop; the four long steps plus the setup reserve then sum to 320, so the job cap moves to 325 — the largest value still under review-scan's PENDING_STALE_MIN, keeping the slack the old pair had. The verification gates keep their 60-minute caps; nothing was squeezed to make room. Counting those exhaustions was the idle mistake in a second form. The cap's remedy is to split the PR or raise the round budget, and neither applies: the primary pass finished and produced the commit the gate rejected, and the repair sub-budget is pinned independently of the round budget that remedy names. Over the fourteen days to 2026-08-21 this was 30 of 119 timeouts, and 30 of the 61 that were not idle — so once idle stopped counting, it was what kept parking PRs, taking #9394, #9576 and #9340 within hours. Exclude it from the cap and from the prompt-narrowing census, whose warning says the round finished nothing and is wrong here. A PR that keeps failing this way still terminates at CONSECUTIVE_FAILURE_CAP, exactly as an idle one does. Telling the classes apart needed a name, because a census pinned to a literal millisecond value breaks the moment anyone retunes it. The runner now opens its timeout detail with QWEN_TIMEOUT_LABEL, the repair step sets it, and a test pins that literal against the census needle. The size baseline moves with the file. Note that main was already 5545 bytes over its recorded 392111 with a 4096 allowance, so the ratchet was failing for every PR touching this workflow before this one; 2061 of the new number is this change.
|
|
|
Thanks for the PR! Template looks good ✓ — all required headings present, including a concrete reviewer test plan and a bilingual body. Problem: Observed, not theoretical. The description documents a measurement rather than a hypothesis: across 5 sampled PRs on 2026-08-22, 20 repair passes ran, all 20 hit the wall at exactly 18.0 minutes, and none succeeded. The arithmetic holds independently of the sample — the repair pass must re-run the same verification the gate just finished (6.6–10.6 min measured), leaving the model only ~8 minutes to read the rejection, fix, and commit on a repo where the primary pass averages 41 minutes. Over the 14 days to 2026-08-21 this class was 30 of the 61 non-idle timeouts, and it parked #9394, #9576 and #9340 within hours of the idle exclusion (af-073) landing. This is a real, reproduced failure mode. Direction: Aligned. This is the autofix workflow fixing its own repair budget and timeout census — squarely within the workflow's remit, and it mirrors the established af-073 idle-timeout exclusion rather than inventing a new mechanism. It touches no auth / sandbox model selection / telemetry / release / public-contract surface, so no direction escalation. Size: No core-module paths touched — the change is confined to Approach: Scope feels right — raise the repair sub-budget to something that can finish, give the runner a caller-supplied timeout label so the census can tell the classes apart, exclude repair exhaustions from both the cap and the prompt-narrowing warning, and raise the job cap (300→325) to fit the new step sum while staying under review-scan's pending-check staleness bound. One thing I spotted in the skim that looks like an unintended drive-by: the Risk: No elevated risk signals — none of the changed files match the revert-correlated high-risk paths. Moving on to code review. 🔍 中文说明感谢贡献! 模板完整 ✓ —— 所有必需小节齐全,包含具体的评审者验证计划和中文说明。 问题: 已观测到,而非理论推测。PR 描述给出的是测量数据而非假设:2026-08-22 对 5 个 PR 取样,20 次 repair pass 全部恰好在 18.0 分钟撞墙,无一成功。这个结论不依赖样本也成立——repair pass 必须先重跑一遍 gate 刚跑完的验证(实测 6.6–10.6 分钟),留给模型的只有约 8 分钟去读拒绝原因、修复并提交,而本仓库主 pass 平均要用 41 分钟。截至 2026-08-21 的 14 天里,这一类占 61 次非 idle 超时中的 30 次,并在 idle 排除(af-073)落地后数小时内停摆了 #9394、#9576 和 #9340。这是真实、可复现的失效模式。 方向: 对齐。这是 autofix workflow 修复自身的 repair 预算与超时统计——完全在其职责范围内,且沿用了 af-073 的 idle 超时排除机制而非另起炉灶。不触及 auth / sandbox 模型选择 / telemetry / release / 公开契约,无需方向升级。 规模: 未触及核心模块路径——改动仅限于 方案: 范围合理——把 repair 子预算提高到能跑完的数值、给 runner 一个调用方提供的超时标签以便统计区分类别、在累计上限与提示词收窄警告两处都排除 repair 耗尽、并把 job 上限(300→325)提高到能容纳新的步骤总和且仍低于 review-scan 的 pending-check 陈旧阈值。快速浏览时发现一处疑似顺手改动: 风险: 无升级风险信号——改动文件均未命中与 revert 相关的高风险路径。 进入代码审查。🔍 — Qwen Code · qwen3.8-max Reviewed at |
Code reviewIndependent baseline. From the title and motivation alone, my plan was exactly the shape this PR takes: raise the repair sub-budget to something that can actually finish (re-verification measures ~10 min, so the old 18 min could never work), give repair timeouts a distinguishable label so the census can separate them from primary-pass timeouts, exclude them from both the cumulative cap and the "finished anything" warning, raise the job cap to fit the new step sum, and pin the emitted label against the census needle in tests. The PR matches that proposal and does not over-engineer it — I did not find a simpler path it missed. Findings. No correctness, security, or regression blockers. The easy-to-get-wrong parts are all handled and test-pinned:
One thing to fix before merge (minor, non-functional): the Test evidence (the PR's own CI)Per the gate rules I do not build or run PR code — the evidence below is the PR's own CI on the reviewed commit, read through the API. The decisive check is Final CI results for
One row per check name (latest run); skipped checks omitted; failures sort first. / 每个检查名一行(取最新一次运行),省略 skipped,失败项排在最前。 The remaining conditional/orchestration checks (Integration Tests, tmux-testing, verify, publish-tmux, publish-verify, precheck-pr, resolve-pr, review-config, ack-review-request) are skipped for this event. There is no user-visible TUI surface in this change, so no live 中文说明代码审查独立基线。 只看标题和动机,我的方案与本 PR 完全同形:把 repair 子预算提高到真能跑完的数值(重跑验证实测约 10 分钟,旧的 18 分钟必然跑不完)、给 repair 超时加可区分的标签以便统计与主 pass 超时分离、在累计上限与"什么都没跑完"警告两处都排除、把 job 上限提高到容纳新的步骤总和、并用测试把输出标签与统计匹配串互相钉住。PR 与该方案一致且没有过度设计——我没有找到它遗漏的更简路径。 发现。 无正确性、安全或回归阻断项。容易出错的部分都已处理并被测试钉住:
合入前需修一处(轻微、非功能性): 测试证据(PR 自身的 CI)按门禁规则,我不构建或运行 PR 代码——以下证据来自对被审提交的 PR 自身 CI(经 API 读取)。决定性检查是 上方表格为被审提交在审查时刻的 CI 快照;其余条件/编排类检查(Integration Tests、tmux-testing、verify、publish-*、precheck-pr、resolve-pr、review-config、ack-review-request)在本事件下被跳过。本改动无用户可见的 TUI 界面,因此不适用 — Qwen Code · qwen3.8-max Reviewed at |
|
Confidence: 4/5 — clean, well-evidenced fix that matches what I would have proposed; the only blemish is a one-line comment pointer to revert. Stepping back: this is a measured failure, not a hypothesised one — 20 of 20 repair passes hit the 18.0-minute wall and none succeeded, and this class is what kept parking healthy PRs (#9394, #9576, #9340) once the idle exclusion landed. The fix is exactly the shape I would have proposed from the title alone: give the repair pass a budget it can actually finish (40 min under a 45-minute backstop, since re-verification alone measures 6.6–10.6 min), label its timeouts so the census can tell them from a primary-pass exhaustion, exclude them wherever the idle class is already excluded (both the cap and the prompt-narrowing warning), and raise the job cap to the new step sum while keeping the review-scan staleness slack. The escape hatch is preserved — a repair timeout pushes nothing and resets no consecutive-failure streak — so a PR that is genuinely stuck still terminates. The implementation is honest and maintainable: the label is validated and defaults to the neutral token so no other caller's output changes shape, the subtraction is provably non-negative, and the tests pin the emitted label against the census needle in both directions (plus five reported mutation runs) so a future retune cannot silently regress the class back into the cap. The af-148 design record keeps the rationale next to the code. The one thing to fix before merge is small and non-functional: the The decisive unit suite ( 中文说明置信度:4/5 —— 干净、证据充分的修复,与我本会提出的方案一致;唯一的瑕疵是一行需要还原的注释指针。 整体来看:这是一次测量出来的失效,而非假设——20 次 repair pass 全部撞在 18.0 分钟、无一成功,而在 idle 排除落地之后,正是这一类在持续停摆健康的 PR(#9394、#9576、#9340)。这个修复与我仅凭标题就会提出的方案完全同形:给 repair pass 一个真能跑完的预算(45 分钟兜底下的 40 分钟,因为仅重跑验证就实测 6.6–10.6 分钟)、给它的超时加标签以便统计能与主 pass 耗尽区分、在 idle 类已被排除的两处(累计上限与提示词收窄警告)同样排除它、并把 job 上限提到新的步骤总和同时保留 review-scan 的陈旧判定余量。逃生通道不变——repair 超时不推送、也不重置连续失败计数——真正卡住的 PR 仍会被终止。 实现诚实且易维护:标签经过校验并回退到中性词,其他调用方的输出形态不变;减法可证非负;测试把输出标签与统计匹配串双向互相钉住(另有五个变异运行),未来重新调参不会悄悄把这一类重新计入上限。af-148 设计档案把理由留在了代码旁边。 合入前需修的一处很小且非功能性: 决定性的单元测试( — Qwen Code · qwen3.8-max Reviewed at |
Code Coverage Summary
CLI Package - Full Text ReportCore Package - Full Text ReportFor detailed HTML reports, please see the 'coverage-reports-22.x-ubuntu-latest' artifact from the main CI run. |
|
@qwen-code /resolve |
|
Qwen Code attempted to resolve merge conflicts but the run did not complete successfully. Check the workflow run for full logs. |
Conflict: .size-baseline. #9747 recorded qwen-autofix.yml's shipped size, which is the drift this branch had absorbed into its own number. Take main's line and re-stamp it with this branch's size, so the recorded number is main's plus this change alone. Also repairs two defects this branch introduced, caught by workflow-size.test.js in CI: The af-148 renumber was applied with a global substitution and rewrote a PRE-EXISTING af-074 pointer at the top of the workflow along with the three new ones, orphaning that section. Restored. af-148 was appended to the design record without a contents-table entry, which the table/anchor equality check reads as a missing section.
|
@qwen-code /takeover |
|
🤝 Takeover engaged: the autofix loop now manages this PR — it will address new review feedback and resolve base conflicts until the label is removed or the round cap is reached. Remove the 中文说明🤝 已接管:autofix 循环现在管理此 PR —— 将持续处理新的评审反馈与 base 冲突,直到移除标签或达到轮次上限。移除 |
|
Thanks — the one finding is real, and it was already fixed before the review landed. No new commit is needed. The What else that substitution could have hit. Since the failure mode was "a global replace touched something it should not have", the interesting question is whether One more defect fixed in the same commit, not caught by the review: CI. The ❌ row for The deferred approval was withheld on the red CI for 中文说明多谢——这条 finding 是真的,但在评审落地之前就已经修好了,不需要新提交。 关于 那次替换还可能误伤什么。 既然失败模式是"全局替换碰到了不该碰的东西",真正值得问的是 同一提交还修了另一个缺陷, 评审未捕获: CI。 Stage 2 表格中 延迟审批是因 🤖 Reviewed and answered with Claude Code — Claude Opus 5 |
|
🤖 Reviewed the latest feedback — no changes needed. Why, point by point: · 已审阅最新反馈——无需改动。逐点说明原因如下: No action needed this roundThe only new feedback is an issue-level confirmation comment ([ic:5383212930]) that states the sole review finding was already fixed before the review landed, and that no new commit is needed. Every factual claim in it was verified against the current head (
Nothing in the comment requests a code change; its closing ask (a Verification
中文说明本轮无需改动唯一的新反馈是一条 Issue 级确认评论([ic:5383212930]),其中说明:那条评审 finding 在评审落地之前就已修复,不需要新提交。接受该说法前,已逐条对照当前 head(
评论中没有任何要求代码改动的内容;其结尾的请求(重新运行 验证
Base-conflict check · 基分支冲突检查: no conflict with main. · 与 main 无冲突。 🧠 Handled by Qwen Code · model/模型 |
|
Converting to draft — #9691 landed the budget half of this PR, and did it better. What #9691 supersedes. It raises the repair budget to 45 minutes (this PR: 40), the step backstop to 55 (this PR: 45), and the job cap to 330 (this PR: 325). The difference traces to one decision: What is left. The census half: labelling repair-pass exhaustions so they can be told apart from primary-pass ones, and excluding them from Why this is a draft rather than a rebase. The quantitative case for the exclusion was that repair timeouts were 30 of 119 timeouts, and 30 of the 61 that were not idle. That case rests on the 18-minute budget, which #9691 removed. If 45 minutes is enough, repair timeouts largely stop happening and this change adds a third census class, a new environment-variable contract in So the plan is to measure rather than argue. A few days of Two arguments survive either outcome, and they are why this is not closed outright: a repair timeout is mis-attributed regardless of how often it happens — it parks a healthy PR under a remedy that does not apply — and 45 minutes is a prediction, not a verified fix. 中文说明转为草稿 —— #9691 已经把本 PR 的预算部分做掉了,而且做得更好。 #9691 覆盖了什么。 它把 repair 预算提到 45 分钟(本 PR 为 40)、步骤兜底提到 55(本 PR 为 45)、job 上限提到 330(本 PR 为 325)。差异源于一个判断: 剩下的部分。 统计这一半:给 repair pass 的耗尽打上标签,使其可与主 pass 的耗尽区分,并将其从 为什么是草稿而不是直接 rebase。 支持这项排除的量化依据是:repair 超时占 119 次超时中的 30 次,占 61 次非 idle 超时中的 30 次。该依据建立在 18 分钟预算之上,而 #9691 已经移除了它。如果 45 分钟够用,repair 超时将基本不再发生,而本改动会为一个不再出现的失败,向一个正压着体积 ratchet 的 workflow 文件引入第三个统计类别、 因此计划是测量而非争论。几天内 有两条理由在任一结果下都成立,也正是本 PR 不被直接关闭的原因:repair 超时无论发生频率如何都是错误归因——它以一条并不适用的补救措施停摆了一个健康的 PR;以及 45 分钟能否跑完是预测,而非已验证的事实。 🤖 Written with Claude Code — Claude Opus 5 |
|
@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(在飞的一轮如有,将完成其有界工作)。重新打上 |
What this PR does
The same-run repair pass gets a budget it can actually finish in — 40 minutes under a 45-minute backstop, up from 18 under 20 — and its exhaustions stop counting toward the cumulative timeout cap. The four long steps plus the unbounded setup reserve now sum to 320 minutes, so the job cap moves from 300 to 325, the largest value that still sits under review-scan's pending-check staleness bound and preserves the same slack the old pair had. Nothing else was squeezed to make room: the two verification gates keep their 60-minute caps even though they measure a fraction of that, because that headroom is their safety margin rather than spare change.
Telling a repair exhaustion apart from a primary-pass one needed a name. The runner emitted a bare
timeout (Nms)for every caller, leaving the census nothing but the millisecond count to key on, and a census pinned to a literal budget value breaks the moment anyone retunes it. The runner now opens its timeout detail with a caller-supplied label — validated, lowercase-dashed, defaulting to the neutral word so every other caller is unaffected — the repair step sets it, and a test pins that literal against the census needle so a typo in either cannot silently return the class to the cap. The exclusion is applied in both places that count timeouts: the cap itself, and the prompt-narrowing warning, whose text tells the agent the round finished nothing, which is false here.Why it's needed
The 18-minute budget could not work, independently of any measurement. The repair pass has to re-run the same verification the gate just finished before its own verdict counts, and that verification measured 6.6 to 10.6 minutes across the sampled runs. What is left is roughly eight minutes for the model to read the rejection, make a fix and land a commit — on a repository where the primary pass averages 41 minutes of its 120. Across five PRs sampled on 2026-08-22, twenty repair passes ran, twenty hit the wall at exactly 18.0 minutes, and none succeeded. That sample is drawn from runs already known to contain a repair timeout, so the rate is indicative rather than fleet-wide, though one of the five was not selected for it and behaved identically.
Counting those exhaustions into the cap was the idle-timeout mistake in a second form. The cap exists to stop a PR too big to finish a round, and its remedy says to split the PR or raise the round budget together with its step backstop. Neither applies: the primary pass finished and produced the commit the gate then rejected, so the round was never too big for its budget, and the repair sub-budget is pinned independently of the round budget that remedy names. Over the fourteen days to 2026-08-21 this class was 30 of 119 timeouts, and 30 of the 61 that were not idle — so once the idle exclusion landed, this was what kept parking healthy PRs, taking #9394, #9576 and #9340 within hours of it.
The escape hatch is unchanged and is what makes the exclusion safe. A repair timeout pushes nothing and matches none of the consecutive breaker's streak-reset phrases, so a PR that keeps failing this way still terminates. What no longer terminates is a PR that is making progress and occasionally loses a round to a sub-budget nobody would have thought to raise.
The reasoning is recorded in the design record as
af-148.Reviewer Test Plan
How to verify
Run
npx vitest run scripts/tests/qwen-autofix-workflow.test.js. The behaviours worth reading sit in the circuit-breaker replay, which extracts the real block out of the workflow and runs it against synthesised comment histories: repair timeouts interleaved with pushes never terminate however many the window holds; a run of consecutive ones still terminates at the consecutive cap under its own headline; budget timeouts alone still trip the cap and report the budget-only count while naming the repair rounds as excluded; one repair round holds open a window that would otherwise have been capped; and a window holding one idle and one repair round counts them separately rather than merging the two classes.The step-budget invariants are asserted from the workflow rather than from literals — the sum of the long steps against the job cap, the job cap against the pending-check staleness bound, and each census needle against the token the runner actually emits.
To confirm the tests are load-bearing, five mutations were run against them: dropping the repair count from the subtraction, dropping the current round's increment, typoing the label in the workflow so the emitter and census disagree, reverting the budget to its old value, and making the runner ignore the label. Each turns the suite red beyond its baseline; restoring returns it to baseline.
Note that
review verification gate: baseline A/B on deterministic rejection > locks the runner file-command backing files against env plantsfails in this environment and fails identically onmain— it asserts that a chmod lock blocks a write, which does not hold when the suite runs as root. It is unrelated to this change.Evidence (Before & After)
Step timings from one real round on #9576 before this change, which is the shape the PR removes: the primary pass finished in 58.7 minutes of its 120, the gate rejected the commit in 10.6, the repair pass then burned its full 18 and pushed nothing — and the round was reported as a time-budget exhaustion against a PR that had 61 minutes of its round budget left unused.
Tested on
Environment (optional)
Unit tests,
npx prettier --check,npx eslint --max-warnings 0on the changed test file, andbash .github/scripts/check-workflow-size.sh.Risk & Scope
needs-humansources the same measurement surfaced: automatic re-arm after a transient stop, and the conflict-resolution failures.mainwas already 5545 bytes over its recorded 392111 against a 4096 allowance, so the ratchet was failing for every PR that touched this file before this one; 2061 bytes of the new number come from this change and the rest is that pre-existing drift.Linked Issues
None.
中文说明
这个 PR 做了什么
同轮 repair pass 拿到了一个真能跑完的预算——45 分钟兜底下的 40 分钟,此前是 20 分钟兜底下的 18 分钟——并且它的耗尽不再计入累计超时上限。四个长步骤加上无界的准备预留现在合计 320 分钟,因此 job 上限从 300 调到 325,这是仍然低于 review-scan 的 pending-check 陈旧判定阈值、并保住原有余量的最大值。没有为此挤压其他任何东西:两个 verification gate 保留各自的 60 分钟上限,尽管实测只用掉其中一小部分——那份余量是它们的安全边际,不是可以挪用的零头。
要把 repair 的耗尽和主 pass 的耗尽区分开,需要一个名字。此前 runner 对所有调用方都只输出裸的
timeout (Nms),census 只能靠毫秒数来判别,而把 census 钉在一个具体预算值上,任何人重新调参时都会失效。现在 runner 用调用方提供的标签作为超时描述的开头(经过校验、小写连字符、默认回退到中性词,因此其他调用方不受影响),repair 步骤设置它,并有测试把这个字面量与 census 的匹配串互相钉住,使得任一处的拼写错误都不会悄悄让这一类重新计入上限。两处统计超时的地方都做了排除:上限本身,以及提示词收窄的警告——后者的文案说该轮"什么都没跑完",在这里是错的。为什么需要它
18 分钟的预算跑不完,这一点与任何测量无关。repair pass 必须在自己的结论生效之前,重跑一遍 gate 刚刚跑完的那套验证,而这套验证在取样的 run 中实测为 6.6 到 10.6 分钟。剩下的大约八分钟,要让模型读完拒绝原因、做出修改并提交——而在这个仓库里,主 pass 平均要用掉 120 分钟中的 41 分钟。2026-08-22 对五个 PR 取样:20 次 repair pass 运行,20 次都恰好撞在 18.0 分钟,无一成功。该样本取自已知含有 repair 超时的 run,因此这个比例是指示性的而非全队测量,不过其中一个 PR 并非因此被选中,表现却完全一致。
把这些耗尽计入上限,是 idle 超时那个错误的第二种形态。这条上限的存在是为了拦住大到跑不完一轮的 PR,其补救措施写的是拆分 PR,或者同时提高轮次预算与其步骤兜底。两者都不适用:主 pass 已经跑完并产出了随后被 gate 拒绝的那个提交,所以这一轮从来就没有超出自己的预算;而 repair 子预算是独立于补救措施所指的轮次预算钉死的。截至 2026-08-21 的十四天里,这一类占 119 次超时中的 30 次,占 61 次非 idle 超时中的 30 次——因此在 idle 排除落地之后,正是它在继续停摆健康的 PR,并在落地后数小时内拿下了 #9394、#9576 和 #9340。
安全网没有变化,它正是这项排除得以成立的原因。repair 超时不推送任何东西,也不匹配连续失败熔断器的任何一个重置短语,所以一个持续以这种方式失败的 PR 仍会被终止。不再被终止的,是那些正在推进、只是偶尔把一轮丢给某个没人会想到去提高的子预算的 PR。
相关推理已记录在设计档案的
af-148条目中。评审者验证计划
如何验证
执行
npx vitest run scripts/tests/qwen-autofix-workflow.test.js。值得一读的行为都在熔断回放里,它会把真实代码块从 workflow 中抽出,针对合成的评论历史运行:与推送交替出现的 repair 超时,无论窗口攒了多少次都不会终止;连续出现时仍会在连续失败上限处终止,并使用它自己的标题;预算超时单独达标时仍会触发上限,报告的是仅含预算的计数,同时点明 repair 轮次已被排除;一次 repair 就足以让一个本该被封顶的窗口继续开着;窗口中同时含有一次 idle 和一次 repair 时,两类分别计数而不会被合并。步骤预算的不变量全部从 workflow 中推导断言,而非写死常量——长步骤之和对 job 上限、job 上限对 pending-check 陈旧阈值、以及每个 census 匹配串对 runner 实际输出的标签。
为确认这些测试确实起作用,针对它们跑了五个变异:把 repair 计数从减法中去掉、去掉当前轮的自增、在 workflow 里把标签拼错使输出方与 census 不一致、把预算改回旧值、以及让 runner 忽略该标签。每一个都会让测试红出基线;恢复后回到基线。
需要说明的是,
review verification gate: baseline A/B on deterministic rejection > locks the runner file-command backing files against env plants在本环境下失败,且在main上以同样方式失败——它断言 chmod 锁能阻止写入,而当测试套件以 root 运行时这并不成立。与本次改动无关。证据(前后对比)
改动前 #9576 上一轮真实的步骤耗时,正是本 PR 要消除的形态:主 pass 用掉 120 分钟中的 58.7 分钟后跑完,gate 用 10.6 分钟拒绝了该提交,repair pass 随后烧完自己的 18 分钟且什么都没推送——而这一轮被报告为时间预算耗尽,尽管该 PR 的轮次预算还剩 61 分钟没用。
已测试平台
运行环境(可选)
单元测试、
npx prettier --check、对改动测试文件的npx eslint --max-warnings 0,以及bash .github/scripts/check-workflow-size.sh。风险与范围
needs-human来源:瞬时停机后的自动重新武装,以及冲突解决失败。main此前就已超出其记录值 392111 达 5545 字节,而允许量是 4096,因此在本 PR 之前,任何改动该文件的 PR 都会被这道 ratchet 拦下;新数值中有 2061 字节来自本次改动,其余是既有的漂移。关联 Issue
无。