fix(autofix): give the repair pass a budget it can finish in - #9691
Conversation
The repair attempt ran on a hardcoded 18-minute agent budget while the primary attempt gets 120 minutes from a configurable default. Raise the repair budget to 45 minutes and carry the step and job caps that bound it. The repair attempt is handed strictly less to work with than the primary one: a deterministic rejection is an opaque check failure, not the structured review feedback the primary attempt receives, so it must first re-derive which change caused the rejection before it can amend anything. Giving that 15% of the primary budget inverted the difficulty and the allowance. Measured on four takeover PRs over nine rounds on 2026-08-21: the primary attempt reported `Autofix agent completed address-review successfully.` in 9 of 9 rounds, and the repair attempt hit `timeout (1080000ms)` in 9 of 9. Every one of those rounds discarded work the primary attempt had already finished — on QwenLM#9340 a completed `origin/main` conflict resolution across three files with two mutation probes and `vitest run src/commands/review/` green at 97 files / 4335 tests. Three such rounds tripped TIMEOUT_WINDOW_CAP and parked the PR at its round cap with `autofix/needs-human`. The rejections themselves were a mix — a flaky unrelated test (QwenLM#9648), a genuine defect in the PR, and a scope violation — so this is not a substitute for fixing any one of them. It is the step they all funnel through: whatever the gate rejects on, the repair attempt has to be able to finish before the round can push. Carried bounds, each preserving its documented margin: - repair step cap 20m → 55m (budget + the same 10-minute margin the primary attempt keeps, so the internal kill path still writes `agent-timeout` before the step cap fires) - review-address job cap 300m → 330m (the four long steps now sum to 305m plus the 25m setup/report reserve) - PENDING_STALE_MIN 330 → 360 (its 30-minute margin over the job cap, so a live review-address run is never aged out mid-flight) 45 minutes is deliberately a fraction of the primary budget: a repair that cannot land in 45m is a handoff, not a longer retry. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VgTjRF91xANQh6SY9YGyCf
|
@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,首轮处理将由下一次定时扫描执行(通常几分钟内)。移除 |
qwen-code-ci-bot
left a comment
There was a problem hiding this comment.
@qqqys the change itself reads fine, but the PR body is missing two required sections from the PR template: ## Risk & Scope and ## Linked Issues (only ### Environment is marked optional). The Chinese <details> translation also only covers the first two sections — the template asks for a paragraph-by-paragraph translation of the full body.
Most of the content is already there in prose — the "45m is a handoff ceiling, not a longer retry" reasoning is exactly the risk/scope discussion, and #9648 / #9649 are the linked references — so this should be a quick fill-in rather than new work. Once the two sections are added and the translation is completed, re-run with @qwen-code /triage and the review picks up from here.
中文说明
改动本身看起来没问题,但 PR 正文缺少 PR 模板 中的两个必填章节:## Risk & Scope 和 ## Linked Issues(只有 ### Environment 标注为可选)。中文 <details> 翻译也只覆盖了前两节——模板要求逐段对应翻译全文。
相关内容其实已经在正文里了——"45 分钟是移交上限而非更长重试"的说法正是风险/范围讨论,#9648 / #9649 就是关联引用——所以这应该只是快速补齐,而不是额外工作。补上这两个章节并完成翻译后,用 @qwen-code /triage 重新触发,评审会从当前位置继续。
— Qwen Code · qwen3.8-max
|
@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: 48 passed · 0 failed · 48 total Flakiness gate: 中文 — 判定:✅ 通过 · 可合入(agent 判定)沙箱验证在隔离、无凭证的容器中执行了该 PR 的代码(与 base 构建 A/B 对照、无 mock harness 断言、定向门禁)。仅作为评审证据,不构成评审、批准或 CI 检查。 脚本断言:48 通过 · 0 失败 · 48 总计 抖动门: Verification reportPR #9691 verification — fix(autofix): give the repair pass a budget it can finish inVerdict: 中文摘要
Central claim and A/BCentral claim: the repair attempt's agent budget rises 18m→45m at the one place the timer is armed (
5/5 mutants killed, each on the intended assertion; M3 is the load-bearing cell for the PR's "derives the arithmetic rather than pinning it" claim — no string pin exists for the job cap, and the derived sum invariant ( Wire-oracle on the changed surface (
Reviewer Test Plan walk-through: all three greps hit exactly once ( FindingsF1 (nit, non-blocking) — stale comment in F2 (nit, non-blocking) — design doc still prices the slot at the old cap. Neither finding changes any executed behavior; both are prose the PR's own comment-hygiene standard would want carried. Not covered
MethodologyEnvironment: Flakiness gate logEvidence imagesHarness scripts and raw logs are in the workflow run artifacts (7-day retention). — Qwen Code · sandboxed verification |
|
Re-run on the new head: Problem: observed, not theoretical. The nine-round table with run links was spot-checked against the actual job log on the previous head (run 32493036626: primary attempt reports success, repair attempt dies with Direction: aligned. The repo's own autofix machinery; the change stops every deterministic rejection from discarding a round the primary attempt already completed. No auth/sandbox/model/telemetry/public-contract surface involved. Size: not applicable — no core package paths. Now three files (+28/−17): the workflow YAML (+20/−9), its contract suite (+6/−6), and the verification runner script (+2/−2, comments only). Approach: still the minimal coupled set — raising the repair budget from 18m to 45m forces the step backstop (20m → 55m), the job cap (300m → 330m), and Risk: no elevated risk signals. Moving on to code review. 🔍 中文说明在新 head 上重跑: 问题: 已观测到,而非理论性问题。带 run 链接的九轮对照表已在上一 head 上抽查过真实 job 日志(run 32493036626:主轮报告成功,修复轮以 方向: 对齐。仓库自身的 autofix 机制;改动让每一次确定性拒绝不再丢弃主轮已完成的整轮成果。不涉及认证/沙箱/模型/遥测/公共契约面。 规模: 不适用——未触及核心包路径。现为三个文件(+28/−17):workflow YAML(+20/−9)、其契约测试套件(+6/−6)、以及验证运行脚本(+2/−2,仅注释)。 方案: 仍是最小联动集合——修复预算从 18 分钟提到 45 分钟,连带迫使步骤兜底上限(20m → 55m)、job 上限(300m → 330m)与 风险: 无升级风险信号。 进入代码审查。🔍 — Qwen Code · qwen3.8-max Reviewed at |
Code reviewRe-derived the arithmetic at the new head rather than taking the table on faith. The four long steps in The second commit is prose-only — verified hunk by hunk: +7/−7, all of it comments. It sweeps three of the four stale sibling references the previous pass named (the review-scan concurrency rationale, the PAT-bearing-job comment inside Non-blocking remainder: the design doc's worst-case arithmetic still reads "The 300-minute job cap puts the worst case at 5 runner-hours per slot (100 across the fleet at 20)" — at the new cap that is 5.5 runner-hours per slot (110 across the fleet). Also visible nearby but pre-existing on Testing evidenceUnattended CI run — no local execution of the PR's code; the evidence below is the PR's own CI on the reviewed commit, fetched via API. Everything completed and nothing red: the contract suite this PR edits runs inside the ubuntu test job (
One row per check name (latest run); skipped checks omitted; failures sort first. / 每个检查名一行(取最新一次运行),省略 skipped,失败项排在最前。 Real-scenario testing: N/A — CI machinery with no user-visible surface. 中文说明代码审查没有直接采信正文的表格,而是在新 head 上重新推导了算术: 第二个提交是纯行文改动——逐块核实:+7/−7,全部为注释。它清理了上一轮点名的四处过期同级引用中的三处(review-scan 并发推理、 非阻塞遗留:设计文档的最坏情况算术仍写着 "The 300-minute job cap puts the worst case at 5 runner-hours per slot (100 across the fleet at 20)"——按新上限应为每槽位 5.5 runner-hours(fleet 合计 110)。另有一处相邻但 测试证据无人值守的 CI 运行——不在本地执行 PR 的代码;以下证据来自通过 API 获取的、该提交自身的 CI。全部完成且无红色:本 PR 修改的契约测试套件在 ubuntu 测试 job 内运行( CI 表格(检查名与结论)见英文部分两标记之间的区域。 真实场景测试:N/A——CI 机制,无用户可见面。 — Qwen Code · qwen3.8-max Reviewed at |
|
Confidence: 4/5 — clean across every stage; the only remainder is the design doc's stale worst-case line named above, which is prose, not a pin. Stepping back: the proposal I formed from the problem statement before reading the diff — raise the repair budget, then carry the three bounds the contract suite couples to it — is exactly what this PR does, and the follow-up commit did what the previous pass asked without touching a single functional line. The evidence base remains stronger than usual: the failure mode was verified in the actual job logs, not just in the PR's table. The 45-minute figure is framed honestly as a handoff ceiling rather than a completion promise — a round that still times out at 45m escalates to a human by design, so the tradeoff risks a slower queue at worst, never correctness, and the budget stays hardcoded rather than becoming an operator knob. What is left is one stale worst-case sentence in the design doc (5.5 runner-hours per slot at the new cap, not 5) and a pre-existing comment mismatch in the issue-autofix job this PR never touched — neither worth holding the merge for. CI is complete and green on the reviewed commit — including the contract suite that pins exactly these numbers — so approval posts now, pinned to it. 中文说明置信度:4/5 —— 各阶段审查都干净;唯一的遗留是上文点名的设计文档过期最坏情况一行,属于行文而非测试钉住的数值。 退一步看:在读 diff 之前,我仅从问题描述形成的方案——提高修复预算,再连带抬高契约测试与之耦合的三个上限——与本 PR 的做法完全一致;跟进提交完成了上一轮的要求,且没有触碰任何功能性代码行。证据基础依然高于一般水平:失败模式在真实 job 日志里得到验证,而不只是正文的表格。45 分钟的取值被诚实地定位为移交上限而非完成承诺——45 分钟仍超时的轮次按设计移交人工,因此这个权衡最坏只是队列变慢,不涉正确性;预算保持硬编码,没有变成运维旋钮。剩下的只有设计文档里一句过期的最坏情况描述(按新上限应为每槽位 5.5 runner-hours,而非 5),以及 issue-autofix job 中一处本 PR 从未触碰、main 上早已存在的注释失配——两者都不值得为此扣住合并。 CI 已在被审查的提交上全部完成且为绿色——包括恰好钉住这些数值的契约测试套件——因此现在发布批准,并钉在该提交上。 — Qwen Code · qwen3.8-max Reviewed at |
|
Triage re-run completed with a fresh approval. The head moved from head 从 |
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-ci-bot
left a comment
There was a problem hiding this comment.
Reviewed — no blockers. Suggestions are inline.
Not linted (tool limitation, not a blocker): the executable-script lint — .github/workflows/qwen-autofix.yml: actionlint embedded-shell source mapping is not yet supported — not linted.
中文说明
已审查——无阻断问题。 建议见行内评论。
未检查(工具限制,非阻断):the executable-script lint — .github/workflows/qwen-autofix.yml: actionlint embedded-shell source mapping is not yet supported — not linted。
— qwen3.8-max via Qwen Code /review (v0.21.15)
| # primary attempt (120m) had already succeeded, and the round's | ||
| # work was discarded. Still a fraction of the primary budget: a | ||
| # repair that cannot land in 45m is a handoff, not a longer retry. | ||
| QWEN_TIMEOUT_MS: '2700000' |
There was a problem hiding this comment.
[Suggestion] This change raises four linked bounds (repair budget 18m→45m, repair step cap 20m→55m, review-address job cap 300m→330m, PENDING_STALE_MIN 330→360) and updates the rationale comments next to each changed constant, but ten sibling prose sites quoting the same bounds still carry the old values:
qwen-autofix.yml:2176— "behind a 300-minute address round" (now 330)qwen-autofix.yml:2779— "the 330-minute horizon here" (the staleness horizon is now 360)qwen-autofix.yml:3891— "a PAT-bearing 300-minute job" (now 330)qwen-autofix.md:1263(af-039) — "The 300-minute job cap puts the worst case at 5 runner-hours per slot (100 across the fleet at 20)" (now 330 minutes, 5.5 runner-hours, 110)qwen-autofix.md:1499-1512(af-050) — the worst-case table still readsRepair 20 … worst case 280 => job timeout 300(nowRepair 55, worst case 315, job timeout 330)run-autofix-review-verification.sh:122and:1050— present-tense "the 18-minute repair budget/pass" (now 45m)run-agent.mjs:29-31— cites "the review workflow's 18-minute repair pass" as the example of a leg whose absolute budget is shorter than the 20-minute idle window; at 45m the repair leg now sits above that windowqwen-autofix-workflow.test.js:4147and:4197— "the 330-minute HAS_PENDING_CHECKS gate" / "the 330-minute horizon" (now 360)
The trap this sets: the next editor of any of these bounds (the fourth such change per the comments' own history) computes margins from numbers 30 minutes off — the af-050 table implies 20 minutes of headroom above worst case when the real headroom is 15 (330−315), and the stale "330-minute horizon" at yml:2779 now coincidentally equals the new job cap while still naming the staleness bound (360), so a maintainer "re-aligning" the two can break the strictly-greater PENDING_STALE_MIN > job cap invariant the contract test pins. We verified the idle-window crossing by running run-agent.mjs under both timer orderings: with the new ordering a wedged sandbox dies at the idle tick (idle-timeout (no output for 2000ms — the sandbox likely hung at startup)), where the old ordering hit the absolute budget (timeout (2000ms)). Prose drift only — runtime behavior is unchanged while the contract tests recompute from the YAML — so carry the bump through the ten sites: 300→330 at yml:2176/3891, 330→360 at yml:2779 and test:4147/4197, af-039 → "330-minute … 5.5 runner-hours per slot (110 across the fleet at 20)", af-050 → Repair 55, worst case 315 => job timeout 330, script:122/1050 → "45-minute", and reword run-agent.mjs:29-31 for the new ordering (e.g. "the repair pass (45m) now sits above this window, so a wedged repair sandbox trips the idle watchdog at ~20m before its absolute budget fires"). Leave the historical mentions at script:14/347 and yml:897's pre-existing "300-minute" inside issue-autofix (cap 180, untouched).
中文说明
本次改动抬高了四个相互关联的上限(修复轮预算 18m→45m、修复步骤上限 20m→55m、review-address job 上限 300m→330m、PENDING_STALE_MIN 330→360),并更新了每个被改常量旁边的理由注释,但引用这些上限的十处兄弟文本位置仍保留旧值:
qwen-autofix.yml:2176—— "behind a 300-minute address round"(现在是 330)qwen-autofix.yml:2779—— "the 330-minute horizon here"(过期界限现在是 360)qwen-autofix.yml:3891—— "a PAT-bearing 300-minute job"(现在是 330)qwen-autofix.md:1263(af-039)—— "The 300-minute job cap puts the worst case at 5 runner-hours per slot (100 across the fleet at 20)"(现在是 330 分钟、5.5 runner-hours、110)qwen-autofix.md:1499-1512(af-050)—— 最坏情况表仍写作Repair 20 … worst case 280 => job timeout 300(现在是Repair 55、最坏 315、job 上限 330)run-autofix-review-verification.sh:122与:1050—— 现在时的 "the 18-minute repair budget/pass"(现在是 45m)run-agent.mjs:29-31—— 以 "the review workflow's 18-minute repair pass" 作为"绝对预算短于 20 分钟空闲窗口"的示例;45m 之后修复轮已高于该窗口qwen-autofix-workflow.test.js:4147与:4197—— "the 330-minute HAS_PENDING_CHECKS gate" / "the 330-minute horizon"(现在是 360)
由此埋下的隐患:下一次调整这些上限的人(按注释自己的记载这已是第四次此类改动)会基于偏差 30 分钟的数字计算余量——af-050 表暗示最坏情况之上还有 20 分钟余量,实际只有 15 分钟(330−315);而 yml:2779 处过期的 "330-minute horizon" 恰好与新 job 上限数值相同、但它命名的其实是过期界限(360),若有人把两者"对齐",就会破坏契约测试所锁定的严格大于关系 PENDING_STALE_MIN > job cap。我们已在两种定时器顺序下实际运行 run-agent.mjs 验证了空闲窗口交叉:新顺序下卡死的沙箱在空闲节拍即被 idle-timeout 杀死(idle-timeout (no output for 2000ms — the sandbox likely hung at startup)),旧顺序下则是绝对预算先触发(timeout (2000ms))。这只是文本漂移——契约测试从 YAML 重新推导全部不变量,运行时行为不变——因此把这十个位置一并更新即可:yml:2176/3891 改 300→330,yml:2779 与 test:4147/4197 改 330→360,af-039 改为 "330-minute … 5.5 runner-hours per slot (110 across the fleet at 20)",af-050 改为 Repair 55、worst case 315 => job timeout 330,script:122/1050 改为 "45-minute",并把 run-agent.mjs:29-31 改写为新顺序(例如 "the repair pass (45m) now sits above this window, so a wedged repair sandbox trips the idle watchdog at ~20m before its absolute budget fires")。script:14/347 的历史事件提及、以及 issue-autofix 中本就存在的 yml:897 "300-minute"(其上限为 180,未改动)保持不动。
— qwen3.8-max via Qwen Code /review (v0.21.15)
There was a problem hiding this comment.
Seven of the ten sites are carried in 1450e2c60a — yml:2176/3891 300→330, yml:2779 330→360, script:122/1050 18-minute→45-minute, test:4147/4197 330→360 — with the historical mentions at script:14/347 (and their paired retelling at test:10689) and yml:897 left untouched as directed.
The remaining three sites are deferred to the follow-up queue (deferred-findings.json) rather than implemented in this round: qwen-autofix.md:1263 (af-039) and :1499-1512 (af-050 table) classify as ci-workflows, and run-agent.mjs:29-31 as agent-skills, under the deterministic sensitive-area gate — classes this PR's own diff never touches, so a round expanding into them is rejected outright; review feedback alone cannot authorize that expansion. The deferred entries carry the exact replacement text so the sweep stays mechanical: af-039 → "330-minute … 5.5 runner-hours per slot (110 across the fleet at 20)"; af-050 → Repair 55, worst case 315 => job timeout 330; run-agent.mjs → reword the parenthetical for the idle-window-first ordering the verification harness proved (e.g. "the primary attempt's 120m budget, and the repair pass's 45m, both exceed this window, so a silent sandbox dies at the idle limit with its own wording"). Leaving this thread open until that follow-up lands.
十个位置中的七处已在 1450e2c60a 中一并更新——yml:2176/3891 改 300→330,yml:2779 改 330→360,script:122/1050 改 18-minute→45-minute,test:4147/4197 改 330→360——并按指示保持 script:14/347 的历史事件提及(及 test:10689 的配套转述)与 yml:897 不动。
其余三处延期至后续队列(deferred-findings.json),不在本轮实现:qwen-autofix.md:1263(af-039)与 :1499-1512(af-050 表)在确定性敏感区域门禁下归入 ci-workflows 类,run-agent.mjs:29-31 归入 agent-skills 类——本 PR 自身 diff 从未触碰这两个类,扩张进去的轮次会被直接拒绝;仅凭评审反馈不能授权这种扩张。延期条目已携带确切的替换文本,保持清扫的机械性:af-039 → "330-minute … 5.5 runner-hours per slot (110 across the fleet at 20)";af-050 → Repair 55、worst case 315 => job timeout 330;run-agent.mjs → 按验证 harness 所证明的"空闲窗口先触发"顺序改写括注(例如 "the primary attempt's 120m budget, and the repair pass's 45m, both exceed this window, so a silent sandbox dies at the idle limit with its own wording")。在后续清扫落地前,本线程保持打开。
|
🤖 Addressed the latest review feedback (round 1/100). What changed, and what I pushed back on: · 已处理最新评审反馈(第 1/100 轮)。改动内容与我反驳保留之处如下: Autofix address-review round — PR #9691One commit this round: Feedback points and decisions[rc:3832839901] Suggestion — ten sibling prose sites still quote the old boundsVerified real — every one of the ten sites was re-read against the code and does carry the old value. Partially implemented, partially deferred (thread left open with a reply). Implemented this round — 7 sites inside this PR's gate-measured footprint (the sensitive-area gate classifies
Left untouched exactly as the finding directs: the historical incident mentions at Deferred to the follow-up queue (recorded in [rv:4996018879] CHANGES_REQUESTED (triage stage 1a) — PR body missing
|
qwen-code-ci-bot
left a comment
There was a problem hiding this comment.
Not reviewed: the executable-script lint — .github/scripts/run-autofix-review-verification.sh: shellcheck is not installed.
Not linted (tool limitation, not a blocker): the executable-script lint — .github/workflows/qwen-autofix.yml: actionlint embedded-shell source mapping is not yet supported — not linted.
中文说明
未审查:the executable-script lint — .github/scripts/run-autofix-review-verification.sh: shellcheck is not installed。
未检查(工具限制,非阻断):the executable-script lint — .github/workflows/qwen-autofix.yml: actionlint embedded-shell source mapping is not yet supported — not linted。
— qwen3.8-max via Qwen Code /review (v0.21.15)
|
🤖 Reviewed the latest feedback — no changes needed. Why, point by point: · 已审阅最新反馈——无需改动。逐点说明原因如下: Autofix review round — no action (PR #9691)This round's feedback contains no actionable findings, so no code changes were
The branch remains at its previous head ( 中文说明Autofix 评审轮次 — 无操作(PR #9691)本轮反馈中没有任何可处理的意见,因此未修改任何代码,也没有提交任何内容。
分支保持在先前的 HEAD( Base-conflict check · 基分支冲突检查: no conflict with main. · 与 main 无冲突。 🧠 Handled by Qwen Code · model/模型 |
|
@qwen-code /triage |
|
Sandboxed verification: ❌ not passed — findings reported (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: 72 passed · 3 failed · 75 total Flakiness gate: 中文 — 判定:❌ 不通过 · 报告了发现(agent 判定)沙箱验证在隔离、无凭证的容器中执行了该 PR 的代码(与 base 构建 A/B 对照、无 mock harness 断言、定向门禁)。仅作为评审证据,不构成评审、批准或 CI 检查。 脚本断言:72 通过 · 3 失败 · 75 总计 抖动门: Verification reportPR #9691 verification — fix(autofix): give the repair pass a budget it can finish inVerdict: 中文摘要
Scope
Central claim — A/B tableValues extracted with a real YAML parser (
Both arms are internally consistent — the base held 5m of unused slack (295 ≤ 300) which the bump consumes exactly (330 = 330, slack 0m). The 30m margin of Budget passthrough ( Vacuity / mutation matrix (
The two tests that pass in V2/V3 are the derive-don't-pin invariant tests ( Targeted gates (all liveness-proven): contract suite 215/215 on head; FindingsF1 — F2 — F3 — Census ( Not covered
MethodologyEnvironment: Flakiness gate logEvidence imagesHarness scripts and raw logs are in the workflow run artifacts (7-day retention). — Qwen Code · sandboxed verification |
qwen-code-ci-bot
left a comment
There was a problem hiding this comment.
LGTM, looks ready to ship. ✅
|
🤖 Reviewed the latest feedback — no changes needed. Why, point by point: · 已审阅最新反馈——无需改动。逐点说明原因如下: Autofix review round — no changes neededReviewed everything newer than the last evaluation (2026-08-21T20:17:39Z) on this PR:
No code was changed this round and nothing was committed. The PR stays at 中文说明Autofix 评审轮次 —— 无需改动已审阅本 PR 上次评估(2026-08-21T20:17:39Z)之后的全部新内容:
本轮未改动任何代码,也未提交任何内容。在正在进行的验证完成之前,PR 保持在 Base-conflict check · 基分支冲突检查: no conflict with main. · 与 main 无冲突。 🧠 Handled by Qwen Code · model/模型 |
|
🤖 AutoFix ran out of time before finishing (timeout (1080000ms)) (attempt 2/100) — it will retry on the next scan.
See the Qwen Autofix agent step logs for model/tool output. 中文说明🤖 AutoFix 在完成前耗尽了时间(timeout (1080000ms))(第 2/100 次尝试)—— 将在下次扫描时重试。 Run log: https://github.com/QwenLM/qwen-code/actions/runs/32585859828 🧠 Handled by Qwen Code · model/模型 |
…dget # Conflicts: # .github/workflows/qwen-autofix.yml
…wenLM#9691) Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
|
🤖 Addressed the latest review feedback (round 3/100). What changed, and what I pushed back on: · 已处理最新评审反馈(第 3/100 轮)。改动内容与我反驳保留之处如下: Address-review summary — PR #9691 (same-run verification repair)Feedback triageThe workflow-prepared feedback contained no actionable findings: the
ChangesReverted
|
qwen-code-ci-bot
left a comment
There was a problem hiding this comment.
No issues found. LGTM! ✅
Not linted (tool limitation, not a blocker): the executable-script lint — .github/workflows/qwen-autofix.yml: actionlint embedded-shell source mapping is not yet supported — not linted.
中文说明
未发现问题。LGTM!✅
未检查(工具限制,非阻断):the executable-script lint — .github/workflows/qwen-autofix.yml: actionlint embedded-shell source mapping is not yet supported — not linted。
— qwen3.8-max via Qwen Code /review (v0.22.0)
|
Released in v0.22.2. |








What this PR does
Raises the repair attempt's agent budget from 18 minutes to 45, and carries the two bounds that contain it: the repair step cap (20m → 55m), the
review-addressjob cap (300m → 330m), andPENDING_STALE_MIN(330 → 360). Each carried bound keeps the margin its own comment documents.Why it's needed
The repair attempt runs on a hardcoded
QWEN_TIMEOUT_MS: '1080000'while the primary attempt gets${{ vars.QWEN_AUTOFIX_TIMEOUT_MS || 7200000 }}— 120 minutes, configurable. That is 15% of the primary allowance for the harder half of the job: a deterministic rejection is an opaque check failure, not the structured review feedback the primary attempt is handed, so the repair attempt must first re-derive which change caused the rejection before it can amend anything.Measured across four takeover PRs over nine rounds on 2026-08-21, the split is total: the primary attempt reported
Autofix agent completed address-review successfully.in 9 of 9 rounds, and the repair attempt hittimeout (1080000ms)in 9 of 9.AuthDialog.test.tsx:141(flake)AuthDialog.test.tsx:155(flake)AuthDialog.test.tsx:141(flake)AuthDialog.test.tsx(flake)AuthDialog.test.tsx(flake)src/ipc/uds-inbox.test.ts(real defect)mustTranslateKeys.test.ts(real defect)AuthDialog.test.tsx(flake)Every one of those rounds discarded work the primary attempt had already finished. On #9340 that was a completed
origin/mainconflict resolution across three files, two mutation probes, andnpx vitest run src/commands/review/green at 97 files / 4335 tests — thrown away because an auth-dialog TUI test unrelated to that PR flaked. Three such rounds trippedTIMEOUT_WINDOW_CAPand parked #9340 at its round cap withautofix/needs-human.The rejections were a mix — a flaky unrelated test, two genuine defects, one scope violation — so this does not replace fixing any of them (#9648 / #9649 covers the flake, and the gate was right to reject the other three). It is the step they all funnel through: whatever the gate rejects on, the repair attempt has to be able to finish before the round can push anything.
45 minutes is deliberately a fraction of the primary budget, not parity — a repair that cannot land in 45m is a handoff, not a longer retry.
Reviewer Test Plan
How to verify
The invariants that constrain these numbers, all asserted by
bounds every long step so the round fits under the job timeout:sum(4 long step caps) + 25m reserve <= job cap→130 + 60 + 55 + 60 + 25 = 330 <= 330job cap <= 360→330PENDING_STALE_MIN > job cap→360 > 330repair step cap - repair budget >= 1→55 - 45 = 10Raising the repair budget past 45m is what forces the job cap past 330, so the ceiling here is the job cap's own 360 limit, not the budget.
Evidence (Before & After)
N/A (CI machinery). Contract suite: 214 passed, 1 failure —
locks the runner file-command backing files against env plants— which reproduces identically on unmodifiedupstream/mainwhen the suite runs as uid 0, and is untouched by this PR.Tested on
Environment (optional)
N/A — workflow YAML and its contract suite only; no local runtime involved.
Risk & Scope
review-addressmatrix is the only place different PRs compete for slots, so the worst case is a slower queue, not a stuck one — and the round cap,CONSECUTIVE_FAILURE_CAPandTIMEOUT_WINDOW_CAPall still bound how many such rounds a PR gets. The budget itself is the smaller half of that tradeoff: a repair attempt that used to die at 18m now costs up to 45m of agent time when it fails, but the rounds it converts from "discard everything" to "push" were already paying 60–137m of runner wall-clock each.qwen-autofix.ymland their contract test derives the arithmetic rather than pinning it.Linked Issues
Refs #9648 and #9649 — the AuthDialog flake behind four of the nine rounds cited above. This PR is complementary, not a substitute: #9649 removes one rejection cause, this removes the reason a rejection costs the whole round.
中文说明
这个 PR 做了什么
把修复轮(repair attempt)的 agent 预算从 18 分钟提高到 45 分钟,并同步抬高约束它的两个上限:修复步骤上限(20m → 55m)、
review-addressjob 上限(300m → 330m)、以及PENDING_STALE_MIN(330 → 360)。每一个连带改动都保持了其自身注释所记载的余量。为什么需要
修复轮跑在硬编码的
QWEN_TIMEOUT_MS: '1080000'上,而主轮拿到的是可配置的 120 分钟默认值。这等于把主轮 15% 的预算给了更难的那一半工作:确定性拒绝是一段不透明的检查失败输出,而不是主轮拿到的结构化评审反馈,因此修复轮必须先自行推导出是哪个改动导致了拒绝,才谈得上修改。2026-08-21 在四个 takeover PR 的九轮中实测,分化是彻底的:主轮 9/9 报
Autofix agent completed address-review successfully.,修复轮 9/9 报timeout (1080000ms)。对照表见英文正文,每行附 run 链接、闸门拒绝对象与修复轮结果。这九轮全部丢弃了主轮已经完成的成果。在 #9340 上,被丢弃的是三个文件的
origin/main冲突解决、两个变异探针,以及npx vitest run src/commands/review/97 文件 4335 测试通过——起因只是一个与该 PR 无关的认证对话框 TUI 测试 flake 了。三轮之后触发TIMEOUT_WINDOW_CAP,#9340 被顶到轮次上限并打上autofix/needs-human。这些拒绝的成因是混合的——一个无关 flake、两个真实缺陷、一次范围越界——所以本 PR 不替代对它们各自的修复(flake 由 #9648 / #9649 覆盖,另外三次闸门拒绝是对的)。它修的是这些情况共同流经的那一步:无论闸门因何拒绝,修复轮必须能跑完,本轮才可能推送任何东西。
45 分钟是刻意取的、远低于主轮的值,而非对等:45 分钟内落不了地的修复,应当移交人工,而不是给更长的重试。
评审者验证方案
如何验证
英文正文中的命令可直接核对预算本身与三个连带上限,并运行契约测试套件。
约束这些数字的不变量,全部由
bounds every long step so the round fits under the job timeout断言:四个长步骤上限之和 + 25m 预留 ≤ job 上限→130 + 60 + 55 + 60 + 25 = 330 ≤ 330job 上限 ≤ 360→330PENDING_STALE_MIN > job 上限→360 > 330修复步骤上限 − 修复预算 ≥ 1→55 − 45 = 10把修复预算提到 45m 以上就会迫使 job 上限突破 330,因此这里的天花板是 job 上限自身的 360m 限制,而不是预算。
证据(前后对比)
N/A(CI 机制类改动)。契约测试套件:214 通过,1 个失败——
locks the runner file-command backing files against env plants——该失败在未修改的upstream/main上以 uid 0 运行时同样复现,与本 PR 无关。测试环境
macOS N/A、Windows N/A、Linux ✅。
运行环境(可选)
N/A —— 仅涉及 workflow YAML 及其契约测试,不涉及本地运行时。
风险与范围
review-address矩阵是不同 PR 之间唯一竞争槽位的地方,因此最坏情况是队列变慢,而不是卡死——而且轮次上限、CONSECUTIVE_FAILURE_CAP与TIMEOUT_WINDOW_CAP仍然限制一个 PR 能得到多少这样的轮次。预算本身是这个权衡中较小的一半:过去在 18m 死掉的修复轮,失败时现在最多消耗 45m 的 agent 时间,但那些被它从"全部丢弃"转为"成功推送"的轮次,本来每轮就已经在付出 60~137 分钟的 runner 墙钟时间。qwen-autofix.yml内部值,且其契约测试是推导算术关系而非钉死数值。关联 Issue
关联 #9648 与 #9649 —— 上述九轮中有四轮源于该 AuthDialog flake。本 PR 与之互补而非替代:#9649 消除的是其中一种拒绝成因,本 PR 消除的是"一次拒绝就要赔上整轮"的原因。