fix(autofix): salvage race-lost pushes by merging the moved head and retrying - #8042
Conversation
|
Thanks for the PR! Template looks good ✓ (substance covers all required sections) Problem: observed bug with concrete evidence — two occurrences on 2026-07-29 alone (#7983 at 56 min, #7985 at 43 min), each discarding a full verified agent run. The per-PR concurrency group only serialises this repo's workflows and cannot prevent external pushes. Clearly real. Direction: aligned — this is a reliability fix for the autofix CI infrastructure, directly within scope. No CHANGELOG reference needed for internal CI tooling. Size: not applicable (no core paths touched — Approach: the scope feels right. Fetch → merge → retry bounded at 3, with merge (not rebase) to preserve the agent's conflict-resolution merge commits, clean abort on genuine conflict, and disclosure in the round report. The Risk: no elevated risk signals (no high-risk paths matched). Moving on to code review. 🔍 中文说明感谢贡献! 模板完整 ✓(内容覆盖所有必需章节) 问题:已观测到的 bug,有具体证据——仅 2026-07-29 一天就发生两次(#7983 运行 56 分钟、#7985 运行 43 分钟),每次整轮已验证的 agent 运行被丢弃。per-PR 并发组只能串行化本仓库 workflow,挡不住外部推送。问题真实存在。 方向:对齐——这是 autofix CI 基础设施的可靠性修复,完全在范围内。 规模:不适用(未触及核心路径——仅 方案:范围合理。fetch → merge → 重试(上限 3 次),用 merge 而非 rebase 以保留 agent 解冲突产生的 merge commit,真实冲突时干净 abort,报告中披露。 风险:无升级风险信号。 进入代码审查 🔍 — Qwen Code · qwen3.8-max-preview Reviewed at |
Code reviewIndependent proposal: I would wrap the push in a bounded retry loop — on rejection, fetch the moved head, merge it locally (preserving history), and retry since the merge result descends from the remote head. On genuine conflict, abort and fall through to the existing failure path. Disclose in the report when a mid-run merge happened. Comparison with the diff: the PR matches this approach exactly, and adds two refinements I'd have wanted: (1) the No correctness bugs, security holes, or regressions found. The loop is properly bounded, every failure path exits with an annotated error, and the merge abort is defensive ( No findings. Testing
CI is green on the primary platform. Windows/macOS tests are skipped (path-based filtering — this PR only touches CI workflow YAML and its test file, no platform-specific code). No failures. This is a CI-infrastructure change (workflow YAML + its pin test) with no user-visible runtime behavior — tmux real-scenario testing: N/A. 中文说明代码审查独立方案:在 push 外包一个有界重试循环——被拒后 fetch 移动的 head,本地 merge(保留历史),重试(merge 结果是远端 head 的后代,即 fast-forward)。真实冲突则 abort 进入现有失败路径。报告中披露运行期间的合并。 与 diff 对比:PR 完全匹配此方案,并增加了两个改进:(1) 未发现正确性 bug、安全漏洞或回归。循环有界,每个失败路径都有带注解的 error exit,merge abort 是防御性的( 无发现。 测试CI 在主要平台上通过。Windows/macOS 测试被跳过(基于路径过滤——本 PR 仅触及 CI workflow YAML 及其测试文件)。无失败。 这是 CI 基础设施变更,无用户可见运行时行为——tmux 真实场景测试:N/A。 — Qwen Code · qwen3.8-max-preview Reviewed at |
|
Confidence: 5/5 — clean across every stage; a textbook minimal fix for a real, observed, costly race condition. This is exactly the kind of PR that's easy to review and easy to maintain in six months. The problem is concrete (two wasted hour-long runs in one day), the fix is the minimum that solves it (bounded merge-and-retry, no new abstractions), and the test pins are unusually thorough — they catch structural mutations, not just string presence. The merge-vs-rebase rationale is sound and documented in both the code comment and the PR body. The disclosure mechanism is honest without being noisy. Nothing to cut, nothing missing, nothing that makes me hesitate. 中文说明置信度:5/5 — 每个阶段都干净;一个教科书式的最小修复,解决真实、已观测到、代价高昂的竞态条件。 问题具体(一天浪费两轮各约一小时的运行),修复是解决问题的最小集(有界 merge-and-retry,无新抽象),测试 pin 异常全面——捕获结构变异而非仅字符串存在性。merge vs rebase 的理由合理且有文档。披露机制诚实而不嘈杂。 无需删减,无遗漏,无犹豫。 — Qwen Code · qwen3.8-max-preview 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. |
fa157bb to
435fd6c
Compare
|
Please do not rebase or force-push to an active PR as it invalidates existing review comments. Note for future reference, the bots always squash all changes into a single commit automatically as part of the integration. 中文请勿对活跃的 PR 执行 rebase 或 force-push,因为这会使已有的评审评论失效。另外,供日后参考:作为集成流程的一部分,机器人始终会自动将所有改动压缩(squash)为单个提交。 |
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-preview via Qwen Code /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. Remove the 中文说明🤝 已接管:autofix 循环现在管理此 PR —— 将持续处理新的评审反馈与 base 冲突,直到移除标签或达到轮次上限。移除 |
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-preview via Qwen Code /review
|
🤖 Addressed the latest review feedback (round 1/100). What changed, and what I pushed back on: · 已处理最新评审反馈(第 1/100 轮)。改动内容与我反驳保留之处如下: Round summaryAddressed two new automated-reviewer suggestions that pin surviving mutations in the salvage test. Three earlier suggestions were already resolved in 902c7ac and re-verified as still holding. Feedback disposition
Changes
Conflict notesNo conflict ( Verification
中文说明本轮总结处理了自动化审查器提出的两个新建议,用于 pin 住抢救测试中仍可存活的突变。此前三个建议已在 902c7ac 中解决,本轮重新验证仍然有效。 反馈处置
变更
冲突说明无冲突( 验证
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/模型 |
|
🔀 Base updated: red check(s) [review-pr] pass on current main — merged current main via update-branch; CI will re-run. 中文说明🔀 已更新 base:红色检查 [review-pr] 在当前 main 上通过 —— 已通过 update-branch 合入当前 main,CI 将重新运行。 |
Local verification — real race, real git remoteVerdict: merge-ready. No blockers. The change does what it says, the failure modes it claims are the failure modes it has, and its stated design rationale reproduces under test. Verified at MethodI did not read the loop and reason about it — I ran it. The push block was extracted verbatim from The remote is a real git-over-HTTP server ( The bug reproduces, and the fix fixes itOn Behaviour matrixEverything the PR description claims holds, including the parts that are easy to get wrong:
Security note, since this PR creates a new public artifact: the merge commit message records the URL it merged from, and in CI that URL carries Are the new pins load-bearing, and is "merge, not rebase" right?10 of 10 mutations caught by the single new pin test — break, merge→rebase, clean abort, unconditional flag, unbounded loop, merge identity, Text pins passing isn't the same as the guards mattering at runtime, so I mutated the extracted block and re-ran the live harness: dropping the The merge-not-rebase rationale reproduces. Given a branch where the agent had already resolved a base conflict with a merge commit — exactly what its conflict-resolution rounds produce — Gates
Observations (none blocking)
CI
中文说明本地验证 —— 真实竞态、真实 git 远端结论:可以合并。 无阻塞项。改动的行为与描述一致,声称的失败模式确实就是它的失败模式,其设计理由在实验中也复现了。 验证提交: 方法我没有靠读代码推理,而是真的把它跑起来。用 远端是真实的 git-over-HTTP 服务器( Bug 复现了,修复也确实修好了在 行为矩阵PR 描述中的每一条都成立,包括那些容易做错的部分:
安全性说明(本 PR 引入了新的公开产物): merge commit 消息会记录合并来源 URL,而 CI 中该 URL 携带 新增 pin 是否承重?"merge 而非 rebase" 是否正确?10 / 10 变异全部被捕获,全部由那一个新 pin 测试捕获:break、merge→rebase、干净 abort、无条件置标志、无界循环、merge 身份、 文本 pin 通过不等于守卫在运行时起作用,于是我变异提取出的代码块并重跑实测环境:去掉 merge 而非 rebase 的理由复现了。 在 agent 此前已用 merge commit 解决过 base 冲突的分支上(这正是其解冲突轮产生的形态), 门禁
观察项(均不阻塞)
CI
|
|
🤖 Reviewed the latest feedback — no changes needed. Why, point by point: · 已审阅最新反馈——无需改动。逐点说明原因如下: No changes needed this roundThank you for the thorough verification — great to see the race, the fix, and every guard confirmed against a real git-over-HTTP server with 10/10 mutations caught. Observation 1 —
|
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-preview via Qwen Code /review
doudouOUC
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.7-max via Qwen Code /review
doudouOUC
left a comment
There was a problem hiding this comment.
Reviewed at c3cef46. The salvage path holds up on every axis I checked: retry is bounded (for push_attempt in 1 2 3, hard exit 1 on the third rejection), the conflict arm does git merge --abort || true + ::error + exit 1 — neither side is overwritten and there is no force-push anywhere in the new path (the existing no-force tests still pin git push --no-verify and reject any --force/+refspec variant); fork PRs are handled by routing both the fetch and the push through the same PUSH_URL (fork repo via allow-edits, same-repo otherwise); merge identity uses the established AUTOFIX_BOT name/email convention; and PUSH_RACE_MERGED only flips when HEAD actually advanced, feeding an honest disclosure that this round's verification predates the merge. The new test block asserts each of these specifically (loop bound, break-on-success, abort-on-conflict, no-rebase, disclosure wording), so removing any leg fails CI. Ran the changed test file locally at this HEAD: the one failure was 'classifies permanent API failures…' — a pre-existing spawn-heavy test untouched by this diff that hit the 30s suite timeout under full-file load and passes standalone (40.7s); the salvage tests themselves passed 102/103, and CI is green. No findings.
|
@qwen-code /resolve |
…retrying The review-address push is one-shot: when anything pushes to the PR head during the agent's ~50-minute window, the final push dies 'fetch first' and the entire verified agent run is discarded. The per-PR head-write concurrency group cannot prevent this — it serialises this repo's workflows, not the PR author or the fork side. Observed twice in one day (#7983 after a 56-minute run, #7985 after 43 minutes). On rejection, fetch the moved head, merge it into the local line, and retry (bounded at 3 attempts). Merge rather than rebase: the agent's own conflict-resolution rounds create merge commits, and a rebase would flatten them and can silently re-introduce the conflicts they resolved. The merge result descends from the remote head, so the retried push is a fast-forward and rewrites nothing. A genuine content conflict aborts the merge and falls through to the existing failure path unchanged. When a salvage merge happened, the round report discloses that the round's verification predates the merge so mid-run commits get re-checked by a human.
- Gate the PUSH_RACE_MERGED disclosure on HEAD actually advancing: a
transient push failure (upload timeout, 503) on an unmoved branch
no-ops the merge ('Already up to date') and must not tell the
reviewer to re-check mid-run commits that never existed.
- Annotate the salvage fetch failure with ::error:: like the two
adjacent failure paths, so a deleted fork branch or network error
does not kill the step with an unannotated exit 128 under bash -e.
- Re-pin the same-repo push URL construction in tests: it lost its old
'origin "${BRANCH}"' pin in this rework, leaving a ${REPO}→${HEAD_REPO}
mutation (malformed remote in the same-repo case) unkillable.
|
@qwen-code /triage |
qwen-code-ci-bot
left a comment
There was a problem hiding this comment.
Reviewed — no blockers. Suggestions are inline.
— qwen3.8-max-preview via Qwen Code /review
qwen-code-ci-bot
left a comment
There was a problem hiding this comment.
LGTM, looks ready to ship. ✅
doudouOUC
left a comment
There was a problem hiding this comment.
Re-reviewed at 3273c9f (previous approve was at c3cef46). The workflow side of the rework is strictly better: the fetch failure is now ::error::-annotated instead of dying as an unannotated exit 128 under bash -e, and PUSH_RACE_MERGED is gated on HEAD actually advancing past PRE_MERGE_HEAD, so a transient push failure on an unmoved branch (merge no-ops "Already up to date") no longer tells the reviewer to re-check commits that never existed. Ran the changed test file locally at this HEAD: 105/105 passed. CI green.
What keeps this from a re-approve: the rework dropped two mutation-killing assertions that were present at c3cef46, and the two open Suggestion threads still stand at this HEAD. Details inline. The dropped pins are the same failure class the fix commit itself fixed for the same-repo PUSH_URL pin — the rework losing a pin nobody notices — so it's worth sweeping once rather than one pin per round.
|
🤖 Addressed the latest review feedback (round 2/100). What changed, and what I pushed back on: · 已处理最新评审反馈(第 2/100 轮)。改动内容与我反驳保留之处如下: Address review summary — PR #8042 round 3Feedback dispositionrc:3679350702 — [Suggestion] Give-up guard not structurally pinned to
|
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-preview via Qwen Code /review
|
🤖 Addressed the latest review feedback (round 3/100). What changed, and what I pushed back on: · 已处理最新评审反馈(第 3/100 轮)。改动内容与我反驳保留之处如下: Round summaryFeedback addressed
Changes
Conflict notesNo conflict ( Verification
中文说明本轮总结已处理的反馈
变更内容
冲突说明无冲突( 验证
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.
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-preview via Qwen Code /review
|
🤖 Addressed the latest review feedback (round 4/100). What changed, and what I pushed back on: · 已处理最新评审反馈(第 4/100 轮)。改动内容与我反驳保留之处如下: Autofix review round summary — PR #8042Feedback triageOne inline suggestion from the automated reviewer this round; no failed checks,
ChangesIn the
Added a concise "why" comment to each, matching the existing give-up pin's style. Re-verified the mutations are now killed: temporarily deleting either Conflict notesNone — Verification
中文说明Autofix 审查轮次总结 — PR #8042反馈分类本轮来自自动审查器的一条行内建议;无失败检查,无 base 冲突(
变更在
为每处添加了一条简明的「为什么」注释,与既有 give-up pin 的风格一致。未改动生产代码; 重新验证变异现已被消除:临时删除 冲突说明无 — 验证
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.
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-preview via Qwen Code /review
…pture-order mutations (#8042)
doudouOUC
left a comment
There was a problem hiding this comment.
Re-reviewed at d47870c. The delta since 3273c9f is test-only and closes out everything I raised: both dropped pins are restored (success-path break, conditional disclosure structure), and the give-up guard, fetch-failure, and merge-conflict paths each got structural pins connecting message → exit 1, so the == 3 → == 4 mutation and the silent-fallthrough mutations are now killed. The workflow logic itself is unchanged since my previous review of it (bounded 3-attempt loop, abort-on-conflict, no force-push, PRE_MERGE_HEAD-gated disclosure) and all earlier threads are resolved. Ran the changed test file locally at this HEAD: 105/105 passed. CI green.
The two remaining open bot suggestions (position-pinning PUSH_RACE_MERGED='false' before the loop, and PRE_MERGE_HEAD capture before the merge) are the same test-hardening class, probe-confirmed, and come with ready-to-apply suggestion blocks — worth taking since they're one-line applies, but they pin test mutation-resistance, not workflow correctness, so I'm not holding the approve on them. This PR is at its fifth review round; per the house convention, remaining Suggestions beyond these should go to a follow-up rather than another round here.
|
🤖 Addressed the latest review feedback (round 5/100). What changed, and what I pushed back on: · 已处理最新评审反馈(第 5/100 轮)。改动内容与我反驳保留之处如下: Round summaryBoth inline suggestions from the automated reviewer were implemented — each replaced a bare Feedback points
Conflict notesNo conflict ( Verification
中文说明本轮总结自动审查器的两条行内建议均已实现——每条都将裸 反馈要点
冲突说明无冲突( 验证
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.
Reviewed — no blockers. Suggestions are inline.
— qwen3.8-max-preview via Qwen Code /review
| echo "::error::push rejected ${push_attempt} times; giving up" | ||
| exit 1 | ||
| fi | ||
| echo "⚠️ push rejected (attempt ${push_attempt}) — branch moved during the run; merging the new head and retrying" |
There was a problem hiding this comment.
[Suggestion] This log line asserts "branch moved during the run" as established fact before the fetch determines whether it moved — but the code's own comment a few lines below documents that a push can fail transiently (upload timeout, 503) with the branch unmoved. — Failure scenario: three consecutive transient push failures with the branch genuinely unmoved → the step prints two false "branch moved during the run" lines, then exit 1 before the report section, so the run log (the sole diagnostic artifact on that path) points the oncall toward branch movement / the concurrency group / the PR author's pushes, away from the real cause (a GitHub availability blip). The reviewer-facing PUSH_RACE_MERGED disclosure is already correctly gated on HEAD advancing; this log line just doesn't apply that same distinction. Concrete cost: misdirected incident diagnosis on the one path where the log is the only artifact.
| echo "⚠️ push rejected (attempt ${push_attempt}) — branch moved during the run; merging the new head and retrying" | |
| echo "⚠️ push rejected (attempt ${push_attempt}) — fetching the current head to check whether the branch moved" |
— qwen3.8-max-preview via Qwen Code /review
Local runtime verification — LGTM ✅I verified this by running the shipped Method: extract So the step's own Two arms, differing only in this PR's hunk: 1. The core claim reproduces, and so does the bug11 scenarios × 2 arms.
The BEFORE failure is verbatim what the PR description reports: …and in that arm no round-complete comment is posted at all — the run is silently discarded, exactly the waste the PR is fixing. 2. Two behaviours that are better than the description claims
3. Neither side is overwrittenThe agent's fix is the first parent (its line is preserved), the mid-run commit is the second, both trees are present, the merge is authored/committed as 4. The disclosure is conditional and correctPresent in 5. The new pins have teeth — and the review rounds earned their placeI mutated the shipped workflow shell 18 ways and ran the PR's own
So #8042's later test-only commits closed real holes, not cosmetic ones. Two of those mutants are worth naming, because at runtime they don't just misbehave — they fake success:
Each of those is killed by the suite at this head, and each flips an observable in my harness — so neither the tests nor the runtime scenarios are vacuous. 6. Repo gates
Notes — neither blocks merge
Verdict: behaviour matches the description on every path I could construct, the failure paths degrade to exactly today's behaviour, and the test suite kills every mutation I could think of. Good to merge. Reproduce./run-matrix.sh # 11 scenarios × {BEFORE, HEAD}, real bare-repo remotes
python3 mutate.py # 18 mutants of the shipped YAML → PR's own test suite
./run-arm.sh m06rebase race-clean # mutated step bodies, to check the harness itself bitesInterposition is one 中文版本 · Chinese version本地运行时验证 —— 建议合并 ✅我没有只读 YAML,而是把 方法:用 于是步骤自己的 两个 arm 只差本 PR 的这一个 hunk: 1. 核心结论可复现,问题本身也可复现11 个场景 × 2 个 arm。
BEFORE 的失败与 PR 描述完全一致: 而且该 arm 完全不会发出本轮完成评论——整轮运行被静默丢弃,正是本 PR 要解决的浪费。 2. 有两处行为比描述里说的更好
3. 双方历史都没有被覆盖agent 的修复是第一父(其提交线被保留),运行期间的提交是第二父,两边内容都在,合并提交的身份是 4. 披露是有条件的,且条件正确
5. 新增的 pin 有牙——并且几轮 review 提交都不白给我对实际发布的 workflow shell 做了 18 种变异,每次都跑 PR 自带的
也就是说 #8042 后续这些纯测试提交补的是真实漏洞。其中两个变异值得单独点出来,因为它们在运行时不只是行为异常,而是伪造成功:
这些在当前 head 都被测试杀掉,同时每一个都会让我 harness 里的可观测量翻转——所以测试和运行时场景都不是空转。 6. 仓库门禁
备注 —— 都不阻塞合并
结论:我能构造的每条路径上,行为都与描述一致;失败路径退化成与现状完全相同的行为;我能想到的每个变异都被测试杀掉。建议合并。 Harness: real local bare-repo remotes + verbatim step bodies + |
|
🤖 Reviewed the latest feedback — no changes needed. Why, point by point: · 已审阅最新反馈——无需改动。逐点说明原因如下: Autofix review round — no action takenNo actionable feedback this round.
Critical-only mode is active because this PR has completed five change-producing No commit was created and the branch is unchanged. 中文说明Autofix 审查轮次 —— 未采取任何操作本轮没有需要处理的反馈。
由于本 PR 已完成五个产生改动的审查轮次,目前处于仅处理 Critical 的模式。 未创建任何提交,分支保持不变。 Deferred non-Critical feedbackCritical-only mode is active after 5 change-producing rounds. Any items listed below stay open for human follow-up; do not modify code, resolve threads, or reply on their behalf.
中文说明完成 5 个产生改动的轮次后,进入仅处理 Critical 的模式。以上内容保持开放,留待人工跟进;不要为其修改代码、解决线程或代为回复。 Base-conflict check · 基分支冲突检查: no conflict with main. · 与 main 无冲突。 🧠 Handled by Qwen Code · model/模型 |
doudouOUC
left a comment
There was a problem hiding this comment.
Re-reviewed at cfe5f54. The delta since d47870c is a single test-only commit that applies both remaining structural pins exactly as suggested: PRE_MERGE_HEAD capture is now position-pinned immediately before the merge command (killing the capture-after-merge reorder that silently disabled the disclosure), and PUSH_RACE_MERGED='false' is pinned by value and position before the loop (killing both the value-flip and the reset-inside-loop mutations). Verified the diff line by line; the workflow itself is unchanged since 3273c9f. Ran the changed test file locally at this HEAD: 105/105 passed. CI green.
The one open suggestion (rewording the attempt-log line so "branch moved" isn't asserted before the fetch confirms it) is a log-wording improvement on a failure path — legitimate, one line, but diagnostic-text only; not holding the approve on it. This PR is past five review rounds — anything further should go to a follow-up.
|
@qwen-code /triage |
qwen-code-ci-bot
left a comment
There was a problem hiding this comment.
LGTM, looks ready to ship. ✅
|
Released in v0.21.2. |







Problem
The
review-addresspush is one-shot. When anything pushes to the PR head branch during the agent's ~50-minute run window — the PR author, a maintainer, or anything on the fork side — the finalgit pushdies withfetch first, and the entire verified agent run is discarded.The per-PR
qwen-pr-head-write-*concurrency group cannot prevent this: it serialises writers inside this repository's workflows only.Observed twice on 2026-07-29 alone:
review run— headless review with a machine-readable verdict #7983 — push rejected after a 56-minute agent runBoth runs produced verified fixes that were thrown away, and each burned an ~hour-long runner slot for nothing.
Change
On push rejection, the report step now:
git merge --no-edit FETCH_HEAD),Bounded at 3 attempts, then gives up into the existing failure path.
Why merge and not rebase: the agent's own conflict-resolution rounds create merge commits (
git mergeis one of its allowed commands), and a rebase would flatten them and can silently re-introduce the conflicts they resolved. The merge rewrites no pushed history on either side.If the mid-run commits genuinely conflict with the fix, the merge aborts (
git merge --abort) and the job falls through to the existing failure path — exactly today's behavior.When a salvage merge happened, the round report adds a⚠️ note: the round's verification ran before the merge, so commits that landed mid-run deserve a human re-check.
Both push sites (same-repo and fork/allow-edits) go through the same salvage loop; the fork push preflight in
prepareis unchanged.Tests
salvages a race-lost push by merging the moved head instead of discarding the run— loop bounds, fetch/merge form, no-rebase, explicit merge identity, clean abort, report disclosure.qwen-autofix-workflow.test.js: 103/103 pass; workflow YAML parses.中文说明
问题
review-address的推送是一次性的:agent 运行的约 50 分钟窗口内,只要有人(PR 作者、维护者或 fork 侧)向 head 分支推送,最终git push就会以fetch first被拒,整轮已验证的 agent 运行被丢弃。per-PR 并发组只能串行化本仓库 workflow 内部的写者,挡不住外部推送。仅 2026-07-29 一天就发生两次:#7983(56 分钟运行)、#7985(43 分钟运行),产出全部作废。
改动
推送被拒时:fetch 移动后的 head →
git merge --no-edit FETCH_HEAD合入本地 → 重试推送(merge 结果是远端 head 的后代,重试即 fast-forward)。最多 3 次,之后进入原失败路径。用 merge 而非 rebase:agent 解冲突轮会产生 merge commit(
git merge在其允许命令中),rebase 会将其打平并可能静默重引入已解决的冲突;merge 不改写任何已推送历史。真实内容冲突则git merge --abort,行为与现状完全一致。发生过抢救合并时,本轮报告会加⚠️ 说明:验证发生在合并之前,运行期间落地的提交需要人工复查。
测试
新增 pin 测试(重试上限、fetch/merge 形式、禁 rebase、显式身份、干净 abort、报告披露);更新两处旧推送字面量 pin;
qwen-autofix-workflow.test.js103/103 通过,YAML 解析正常。