Skip to content

feat(autofix): auto-update a PR red only from a stale, since-fixed base - #7554

Merged
wenshao merged 12 commits into
mainfrom
ci/autofix-update-stale-base
Jul 23, 2026
Merged

feat(autofix): auto-update a PR red only from a stale, since-fixed base#7554
wenshao merged 12 commits into
mainfrom
ci/autofix-update-stale-base

Conversation

@wenshao

@wenshao wenshao commented Jul 23, 2026

Copy link
Copy Markdown
Collaborator

What this PR does

Teaches the autofix scan to automatically unstick a PR that is red only because it merged a main that was broken at the time and has since been fixed — by merging current main in (GitHub's "Update branch"), gated on one safety condition.

Why it's needed

This happened twice today alone:

In both cases main self-healed within the hour, and the fix was the same manual step: merge current main into the PR and let CI re-run. That is exactly what GitHub's "Update branch" does. This automates it.

How

Once per scan, the scan fetches main's head and the set of check names currently passing on it. For each candidate PR, it computes the checks that are failing on the PR but passing on main by the same name. If that set is non-empty and the PR is behind main (compare status behind/diverged), it calls PUT /pulls/{n}/update-branch and skips the PR this scan (the merge re-runs CI).

The single safety gate is "the same failing check passes on current main." That one condition proves both halves at once:

  1. The red is base-inherited — green on main means it is not the PR's own bug.
  2. main is healthy on that check right now — so merging main in cannot import a fresh breakage.

Without that gate, auto-updating would churn genuinely-broken PRs and could pull a new main regression into a healthy one. With it, the action is safe by construction.

Deliberate properties:

  • Merge, not rebaseupdate-branch merges; no force-push, no dismissed history, consistent with the review-in-progress conventions.
  • Self-limiting — after the update the PR contains main's head, so it is no longer behind and the next scan will not re-update. No marker needed.
  • Fail-safe — if main's check set can't be fetched it is empty, so nothing matches and nothing is updated. A merge conflict on update is logged (base-update-failed) and the PR is left for a human.
  • Runs before the feedback logic — a stuck-on-stale-base PR often has no new feedback at all (it just sits red); that is precisely how fix(autofix): retry a skipped-Prepare instead of stranding the PR terminal #7490 was stranded, so the check must not be gated behind "has new feedback."
  • The stale-base selector carries the same review-address carve-out as the other check selectors, so it never acts on the loop's own run status.

Reviewer Test Plan

How to verify

  1. npx vitest run scripts/tests/qwen-autofix-workflow.test.js — 94/94, three runs. The new test replays the real extracted decision block under bash with a stubbed gh (compare + update-branch), over six cases:

    PR checks on main compare
    Test FAIL Test green behind update + skip
    Test FAIL Test red behind no update (PR's own bug)
    Test FAIL Test green ahead no update (not behind)
    Lint FAIL Lint green diverged update + skip
    Test OK behind no update (no red)
    Test FAIL Test green, update fails behind attempted, logged, skip
  2. Mutation-verified: removing the green-on-main gate (would churn a genuinely-broken PR) turns it red; removing the behind check (would no-op-update a current PR) turns it red.

  3. Static: js-yaml parses; all 37 run: blocks pass bash -n; actionlint 1.7.12 clean; prettier clean.

  4. Post-merge smoke: after a transient main breakage that a batch of PRs merged, the next scan should log 🔀 #N: … merged current main via update-branch for the affected PRs and they should recover once main is green — instead of a manual /retry per PR.

Evidence (Before & After)

BEFORE  main breaks transiently -> PRs merge it -> red on an unrelated check
        -> a human notices, /retry or merges main by hand, per PR

AFTER   scan sees: check X fails here, X passes on current main, PR behind main
        -> update-branch (merge) -> CI re-runs -> recovers, no human step

Tested on

OS Status
🍏 macOS ✅ tested
🪟 Windows N/A
🐧 Linux ⚠️ CI

Risk & Scope

  • Main tradeoff: an update-branch merge re-runs CI (~40 min) and, under dismiss_stale_reviews, dismisses existing approvals. That is the accepted cost of unsticking; it only fires when a check is confirmed base-inherited, which is rare, so it is not a churn source.
  • The green-on-main gate has a small TOCTOU window: main could break between the check and the merge. The window is seconds, and the result is a merge (recoverable), not a force-push.
  • Forks: update-branch needs allow-edits; without it the API returns an error and the PR is logged as base-update-failed rather than updated. Non-fatal.
  • Not in scope: this does not fix the underlying main breakage (a separate base-branch problem); it only stops the loop from leaving healthy PRs stranded on it. It also does not retry a check that is red on both the PR and main — that is the PR's own failure and stays for the agent/human.
  • Breaking changes / migration notes: none.

Linked Issues

Motivated by two main breakages today (web-shell TS, agent-registry test) that stranded healthy PRs including #7490. Part of the autofix-reliability line: #7438, #7482, #7490.

中文说明

本 PR 做了什么

让 autofix 扫描自动解救一个仅仅因为合并了当时坏、现已修复的 main 而变红的 PR —— 通过合入当前 main(GitHub 的 "Update branch"),并以一个安全条件设门。

为什么需要

仅今天就发生两次:main 上的 web-shell TS 错误让受信任 base 构建在整个扫描批次里失败、终态搁置六个健康 PR;agent.test.ts 的 fork/registry 测试在 main 上坏了约 1 小时,#7490 合了那个坏快照、在一个它从未触碰的测试上变红。两次 main 都在一小时内自愈,修复都是同一手动步骤:合入当前 main、让 CI 重跑 —— 正是 "Update branch" 做的事。本 PR 把它自动化。

怎么做

每次扫描取一次 main 的 head 与其上当前通过的检查名集合。对每个候选 PR,算出在 PR 上失败、但在 main 上同名通过的检查。若该集合非空且 PR 落后于 main(compare 状态 behind/diverged),则调 PUT /pulls/{n}/update-branch 并本轮跳过该 PR(合并会重跑 CI)。

唯一的安全门是"同一失败检查在当前 main 上通过",这一条同时证明两半:(1) 红是 base 继承的(main 上绿 = 不是 PR 自己的 bug);(2) main 此刻在这个检查上健康(合入不会引入新故障)。没有这个门,自动更新会搅扰真正坏掉的 PR,还可能把 main 的新回归拉进健康 PR;有了它,该动作由构造保证安全。

刻意的性质:merge 而非 rebase(不 force-push、不作废历史);自限(更新后 PR 已含 main head、不再落后,下次扫描不重复,无需 marker);失败安全(取不到 main 检查集合则为空,不匹配即不更新;合并冲突记为 base-update-failed 交人);在反馈逻辑之前运行(卡在旧 base 的 PR 常常根本没有新反馈,#7490 正是如此);stale-base 选择器带与其它检查选择器相同的 review-address carve-out,绝不作用于循环自己的运行状态。

评审验证

  1. npx vitest run scripts/tests/qwen-autofix-workflow.test.js —— 94/94,连跑三次。新测试用桩 gh(compare + update-branch)在 bash 下回放真实提取的决策块,覆盖六种情形(见上方英文表格)。
  2. 变异验证:去掉 green-on-main 门(会搅扰真坏的 PR)变红;去掉 behind 判断(会对已是最新的 PR 空更新)变红。
  3. 静态:YAML 可解析;37 个 run: 块过 bash -n;actionlint 1.7.12 clean;prettier clean。
  4. 合并后冒烟:一次瞬时 main 故障被一批 PR 合入后,下一次扫描应对受影响 PR 打印 🔀 #N … merged current main via update-branch,并在 main 变绿后自行恢复,而无需逐个 /retry

风险与范围

  • 主要权衡:update-branch 会重跑 CI(约 40 分钟),并在 dismiss_stale_reviews 下作废已有批准。这是解卡的既定代价;它只在检查被确诊为 base 继承时触发,较罕见,不会成为搅扰源。
  • green-on-main 门有一个很小的 TOCTOU 窗口:main 可能在检查与合并之间变坏。窗口是秒级,且结果是可恢复的 merge 而非 force-push。
  • fork:update-branch 需 allow-edits;没有则 API 报错、PR 记为 base-update-failed 而非被更新。非致命。
  • 不在范围内:本 PR 不修 main 的底层故障(另一个 base 分支问题),只阻止循环把健康 PR 留在上面搁置;也不重试在 PR 与 main 上红的检查 —— 那是 PR 自己的失败,留给 agent/人。
  • 破坏性变更:无。

关联 Issue

由今天两次 main 故障(web-shell TS、agent-registry 测试)促成,它们搁置了包括 #7490 在内的健康 PR。属 autofix 可靠性主线:#7438#7482#7490

A PR can be red purely because it merged a main that was broken then and
is fixed now — observed twice today: a web-shell TS break and an
agent-registry test, each stranding healthy PRs on a failure with nothing
to do with them. The recovery was manual: merge current main and let CI
re-run. The scan now does that automatically via GitHub's update-branch
(a merge, never a rebase, so no force-push and no dismissed history).

The single safety gate is that the SAME failing check is passing on
current main. That one condition proves both halves at once: the red is
base-inherited (green on main = not the PR's own bug) AND main is healthy
on that check right now (so the merge cannot import a fresh breakage). It
acts only when the PR is also BEHIND main (compare status behind/diverged)
— otherwise the update is a no-op and the red is not stale-base after all.

Self-limiting: after the update the PR contains main's head, so it is no
longer behind and the next scan will not re-update. A failed update (merge
conflict) is logged and the PR is left for a human. Runs before the
feedback logic because a stuck-on-stale-base PR often has no new feedback
at all — it just sits red — which is exactly what stranded #7490.
@wenshao

wenshao commented Jul 23, 2026

Copy link
Copy Markdown
Collaborator Author

@qwen-code /takeover

@qwen-code-dev-bot qwen-code-dev-bot added the autofix/takeover Summon the autofix loop to manage this PR (remove to release; needs triage+) label Jul 23, 2026
@qwen-code-dev-bot

Copy link
Copy Markdown
Collaborator

🤝 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/takeover label (or comment @qwen-code /takeover stop) to release.

中文说明

🤝 已接管:autofix 循环现在管理此 PR —— 将持续处理新的评审反馈与 base 冲突,直到移除标签或达到轮次上限。移除 autofix/takeover 标签(或评论 @qwen-code /takeover stop)即可释放。

@qwen-code-ci-bot

Copy link
Copy Markdown
Collaborator

Thanks for the PR!

Template looks good ✓

Problem: observed, not theoretical. Two concrete incidents today — a web-shell TS break and an agent-registry test failure on main — stranded healthy PRs (including #7490 at round 11) on checks they never touched. The manual fix was the same both times: merge current main and let CI re-run. This automates that step.

Direction: aligned. This is autofix-reliability infrastructure — it stops the scan loop from leaving healthy PRs terminally red after a transient main breakage self-heals. Part of the same line as #7438, #7482, #7490. No public contract, auth, or sandbox surface touched.

Size: not applicable — no core paths. 149 additions across 2 files (workflow YAML + test).

Approach: the scope feels right. One safety gate ("the same failing check passes on current main") proves both halves at once — the red is base-inherited AND main is healthy on that check right now. The merge-not-rebase choice, the self-limiting property (after update the PR is no longer behind), and the fail-safe (empty green set → no match → no update) are all deliberate and well-reasoned. No unrelated changes, no scope creep.

Moving on to code review. 🔍

中文说明

感谢贡献!

模板完整 ✓

问题:已观测到的实际问题,非理论性加固。今天发生了两次具体事件——main 上的 web-shell TS 错误和 agent-registry 测试失败——导致包括 #7490(第 11 轮)在内的健康 PR 在它们从未触碰的检查上终态搁置。两次的手动修复都是同一步骤:合入当前 main 让 CI 重跑。本 PR 将该步骤自动化。

方向:对齐。这是 autofix 可靠性基础设施——阻止扫描循环在 main 瞬时故障自愈后仍将健康 PR 留在终态红色。与 #7438#7482#7490 属同一主线。未触及公共契约、认证或沙箱。

规模:不适用——未触及核心路径。149 行新增,2 个文件(workflow YAML + 测试)。

方案:范围合理。一个安全门("同一失败检查在当前 main 上通过")同时证明两半——红是 base 继承的,且 main 此刻在该检查上健康。merge 而非 rebase 的选择、自限性质(更新后 PR 不再落后)、失败安全(空绿色集合 → 不匹配 → 不更新)都是刻意设计且合理。无无关改动,无范围蔓延。

进入代码审查 🔍

Qwen Code · qwen3.8-max-preview

Reviewed at b7666f080c6c89df26b3fe2c633ed7b0fbb32fad · re-run with @qwen-code /triage

@gwinthis

Copy link
Copy Markdown
Collaborator

Review & Local Verification Report

代码审查

设计评价:精准的安全门控自动化。 本 PR 解决了"健康 PR 因合并了当时已损坏的 main 而变红"的问题——自动合并当前 main 并重跑 CI。

安全门控(核心设计):

仅当 PR 上失败的 check 在当前 main 上以相同名称通过时才触发 update-branch。

这一个条件同时证明了:

  1. 红色是 base 继承的(不是 PR 自身的 bug)
  2. main 当前在该 check 上是健康的(merge 不会引入新损坏)

实现细节:

  • 每次扫描获取一次 main HEAD 的 green checks(MAIN_GREEN_CHECKS
  • STALE_BASE_REDS:PR 上失败但 main 上通过的 check 名称交集
  • compare API 确认 PR 确实 behind/diverged(避免 no-op 422)
  • update-branch 失败时(merge conflict)留给人类处理
  • 排除 Qwen Autofix 自身的 workflow(除 review-address)

测试: 从 workflow YAML 中提取 bash 块,用 mock gh 二进制验证 4 个场景(正常更新、main 不绿则不触发、已包含 main 则跳过、update-branch 失败)。

结论

LGTM。 单一安全门控(check 在 main 上绿)简洁有力,避免了过度工程化的多条件判断。注释解释了 why#7490 的真实案例)。

@qwen-code-ci-bot

Copy link
Copy Markdown
Collaborator

Code Review

Independent proposal: given the problem (PRs go red because they merged a broken main that has since been fixed), I would: (1) once per scan, fetch main's head and the set of check names currently passing on it; (2) for each candidate PR, compute checks failing on the PR but passing on main by the same name; (3) if that set is non-empty and the PR is behind main, call PUT /pulls/{n}/update-branch and skip the PR this scan; (4) handle failures gracefully.

Comparison with the diff: the PR's approach matches this proposal exactly. No simpler path missed.

Findings — no critical blockers:

  • Safety gate is sound. The single condition ("the same failing check passes on current main") proves both halves at once: the red is base-inherited (not the PR's own bug) AND main is healthy on that check right now. The jq filter correctly excludes the autofix workflow's own checks (same review-address carve-out as the other selectors).
  • Compare API usage is correct. compare/${MAIN_HEAD}...${PR_HEAD_OID} with status behind/diverged correctly identifies PRs that don't contain main's head. ahead correctly skips (the PR already has it).
  • Fail-safe by construction. If main's check set can't be fetched, MAIN_GREEN_CHECKS is [], nothing matches, nothing is updated. A merge conflict on update is logged (base-update-failed) and the PR is left for a human.
  • Self-limiting. After the update the PR contains main's head, so it's no longer behind and the next scan won't re-update. No marker needed.
  • Test coverage is thorough. The test extracts the actual decision block from the YAML via regex and runs it under bash with a stubbed gh, covering all six decision paths. The FELL_THROUGH sentinel correctly distinguishes "update triggered + continue" from "fell through to normal scan."
  • No AGENTS.md violations. No over-abstraction, no duplication, no unrelated changes. The 149 additions are all directly necessary for the stated goal.

Real-Scenario Testing

Ran the extracted decision block from the PR's workflow YAML under bash with a stubbed gh (compare + update-branch), covering all six decision paths. Also ran the full unit test suite (93/93 pass), YAML validation (parses cleanly), and bash -n on all 37 run: blocks (0 failures).

══════════════════════════════════════════════════════════
  Stale-base auto-update: real-scenario terminal test
  Extracted from PR #7554 workflow YAML, run under bash
══════════════════════════════════════════════════════════

📋 Extracted decision block (2029 chars):
──────────────────────────────────────────────────────────
            STALE_BASE_REDS="$(jq -c -n \
              --argjson checks "${CHECKS_JSON}" --argjson green "${MAIN_GREEN_CHECKS}" '
              [ $checks[]
                | select((.conclusion // .state // "") | IN("FAILURE", "FAILED", "ERROR", "TIMED_OUT", "ACTION_REQUIRED"))
                | select(((.workflowName // "") != "Qwen Autofix") or (((.name // "") | startswith("review-address"))))
  ... (25 lines total)
──────────────────────────────────────────────────────────

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
▶ Scenario: Base-inherited red (the bug this PR fixes)
  PR checks:    [{"name":"Test / unit","conclusion":"FAILURE"}]
  Main green:   ["Test / unit","Lint"]
  Compare:      behind
  Update OK:    true

  Result: 🔀 Update triggered (PR skipped this scan)
  🔀 #7490: red check(s) [Test / unit] pass on current main abc123def but fail here on a stale base — merged main in via update-branch; CI will re-run
    📊 fleet_row: 7490 → base-updated (stale-base red [Test / unit] — merged current main, CI re-running)

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
▶ Scenario: PR's own bug (check red on main too) — must NOT update
  PR checks:    [{"name":"Test / unit","conclusion":"FAILURE"}]
  Main green:   ["Lint"]
  Compare:      behind
  Update OK:    true

  Result: ⏭️  No update (fell through to normal scan)

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
▶ Scenario: PR already contains main (ahead) — must NOT update
  PR checks:    [{"name":"Test / unit","conclusion":"FAILURE"}]
  Main green:   ["Test / unit"]
  Compare:      ahead
  Update OK:    true

  Result: ⏭️  No update (fell through to normal scan)

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
▶ Scenario: Diverged from main — should update
  PR checks:    [{"name":"Lint","conclusion":"FAILURE"}]
  Main green:   ["Lint","Test / unit"]
  Compare:      diverged
  Update OK:    true

  Result: 🔀 Update triggered (PR skipped this scan)
  🔀 #7490: red check(s) [Lint] pass on current main abc123def but fail here on a stale base — merged main in via update-branch; CI will re-run
    📊 fleet_row: 7490 → base-updated (stale-base red [Lint] — merged current main, CI re-running)

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
▶ Scenario: All checks passing — nothing to do
  PR checks:    [{"name":"Test / unit","conclusion":"SUCCESS"}]
  Main green:   ["Test / unit"]
  Compare:      behind
  Update OK:    true

  Result: ⏭️  No update (fell through to normal scan)

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
▶ Scenario: Update-branch fails (merge conflict) — logged, skipped
  PR checks:    [{"name":"Test / unit","conclusion":"FAILURE"}]
  Main green:   ["Test / unit"]
  Compare:      behind
  Update OK:    false

  Result: 🔀 Update triggered (PR skipped this scan)
  ⚠️ #7490: wanted to update the stale base (red [Test / unit] green on main) but update-branch failed (likely a merge conflict) — leaving for a human
    📊 fleet_row: 7490 → base-update-failed (stale-base red [Test / unit] but update-branch failed (conflict?))

══════════════════════════════════════════════════════════
  All 6 scenarios complete
══════════════════════════════════════════════════════════

Unit tests: 93/93 pass · YAML: parses cleanly · bash -n: 37/37 run: blocks, 0 failures

中文说明

代码审查

独立方案: 给定问题(PR 因合入当时已坏、现已修复的 main 而变红),我的方案是:(1) 每次扫描取一次 main 的 head 与其上当前通过的检查名集合;(2) 对每个候选 PR,算出在 PR 上失败但在 main 上同名通过的检查;(3) 若该集合非空且 PR 落后于 main,调 update-branch 并本轮跳过;(4) 优雅处理失败。

与 diff 对比: PR 的方案与此完全一致。未发现更简路径。

审查结论——无关键阻塞项:

  • 安全门可靠。 单一条件("同一失败检查在当前 main 上通过")同时证明两半:红是 base 继承的(非 PR 自身 bug),且 main 此刻在该检查上健康。jq 过滤器正确排除了 autofix 工作流自身的检查(与其它选择器相同的 review-address carve-out)。
  • Compare API 用法正确。 compare/${MAIN_HEAD}...${PR_HEAD_OID}behind/diverged 状态正确识别不含 main head 的 PR。ahead 正确跳过。
  • 构造上失败安全。 取不到 main 检查集合时为 [],不匹配即不更新。合并冲突记为 base-update-failed 交人处理。
  • 自限。 更新后 PR 已含 main head,不再落后,下次扫描不重复。无需 marker。
  • 测试覆盖充分。 测试通过正则从 YAML 中提取实际决策块,在 bash 下用桩 gh 运行,覆盖全部六条决策路径。FELL_THROUGH 哨兵正确区分"触发更新 + continue"与"落入正常扫描"。
  • 无 AGENTS.md 违规。 无过度抽象、无重复、无无关改动。149 行新增全部直接服务于既定目标。

真实场景测试

从 PR 的 workflow YAML 中提取决策块,在 bash 下用桩 gh(compare + update-branch)运行,覆盖全部六条决策路径。同时运行完整单元测试套件(93/93 通过)、YAML 验证(解析正常)、以及对全部 37 个 run: 块的 bash -n 检查(0 失败)。

单元测试:93/93 通过 · YAML:解析正常 · bash -n37/37 个 run: 块,0 失败

Qwen Code · qwen3.8-max-preview

Reviewed at b7666f080c6c89df26b3fe2c633ed7b0fbb32fad · re-run with @qwen-code /triage

@qwen-code-ci-bot

Copy link
Copy Markdown
Collaborator

Confidence: 5/5 — clean across every stage; the problem is real, the safety gate is provably correct, and the implementation is exactly as simple as it can be.

This is the kind of PR that makes the autofix loop meaningfully more reliable. The problem was observed twice in a single day — healthy PRs stranded on a main breakage that self-healed within the hour, requiring the same manual fix each time. The solution automates that fix with a single, well-reasoned safety gate: only merge main in when the specific failing check is confirmed green on current main. That one condition proves both halves (the red is base-inherited, and main is healthy on it right now), which is about as tight as a safety argument gets for this kind of automation.

The implementation is minimal — 149 lines across 2 files, no abstractions, no config, no new dependencies. The self-limiting property (after the update the PR is no longer behind, so the next scan skips it) means no marker or state tracking is needed. The fail-safe (empty green set → no match → no update) means an API hiccup can't cause spurious merges. The test extracts the actual decision block from the YAML and runs it under bash, which is the right way to test embedded shell logic — it catches drift between the test and the real code.

Going back to my independent proposal: the PR matches it exactly. I didn't find a simpler path, and I don't think one exists. Every line in the diff earns its place.

中文说明

置信度:5/5 —— 每个阶段都干净;问题真实存在,安全门可证明正确,实现已是最简。

这个 PR 让 autofix 循环的可靠性有了实质性提升。问题在一天内被观测到两次——健康 PR 搁置在已自愈的 main 故障上,每次都需要相同的手动修复。该方案用一个合理的安全门将这个修复自动化:仅当特定失败检查被确认在当前 main 上为绿时才合入 main。这一个条件同时证明两半(红是 base 继承的,且 main 此刻在该检查上健康),对于这类自动化来说,这几乎是最严密的安全论证。

实现极简——149 行,2 个文件,无抽象、无配置、无新依赖。自限性质(更新后 PR 不再落后,下次扫描跳过)意味着不需要 marker 或状态跟踪。失败安全(空绿色集合 → 不匹配 → 不更新)意味着 API 故障不会导致错误合并。测试从 YAML 中提取实际决策块并在 bash 下运行,这是测试嵌入式 shell 逻辑的正确方式——能捕获测试与真实代码之间的漂移。

回到我的独立方案:PR 与之完全一致。未发现更简路径,也不认为存在。diff 中每一行都有其存在价值。

Qwen Code · qwen3.8-max-preview

Reviewed at b7666f080c6c89df26b3fe2c633ed7b0fbb32fad · re-run with @qwen-code /triage

@qwen-code-ci-bot qwen-code-ci-bot left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, looks ready to ship. ✅

@github-actions

github-actions Bot commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

Code Coverage Summary

Package Lines Statements Functions Branches
CLI 82.63% 82.63% 88.78% 82.3%
Core 87.04% 87.04% 88.45% 86.15%
CLI Package - Full Text Report
-------------------|---------|----------|---------|---------|-------------------
File               | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
-------------------|---------|----------|---------|---------|-------------------
All files          |   82.63 |     82.3 |   88.78 |   82.63 |                   
 src               |   84.12 |    80.67 |   88.88 |   84.12 |                   
  cli.ts           |   94.54 |    84.07 |     100 |   94.54 | ...86-487,497-498 
  gemini.tsx       |   73.89 |    76.49 |    82.6 |   73.89 | ...1183-1187,1308 
  ...ractiveCli.ts |   85.02 |    80.82 |   86.84 |   85.02 | ...2363,2369,2421 
  ...liCommands.ts |   88.34 |     83.6 |      90 |   88.34 | ...63,480,514,635 
  ...ActiveAuth.ts |     100 |     87.5 |     100 |     100 | 66-80             
 ...cp-integration |   68.02 |    70.81 |   88.79 |   68.02 |                   
  acpAgent.ts      |   67.63 |    70.62 |   88.79 |   67.63 | ...18,10623-10625 
  authMethods.ts   |      92 |       60 |     100 |      92 | 33-34             
  errorCodes.ts    |       0 |        0 |       0 |       0 | 1-22              
  ...ion-skills.ts |     100 |    88.23 |     100 |     100 | 17,32             
  generation.ts    |    97.1 |    81.25 |     100 |    97.1 | 109,112           
  ...DirContext.ts |     100 |      100 |     100 |     100 |                   
 ...ration/service |   97.04 |    95.71 |   93.33 |   97.04 |                   
  filesystem.ts    |   97.04 |    95.71 |   93.33 |   97.04 | ...21-122,238-239 
 ...ration/session |    91.4 |    85.27 |   95.86 |    91.4 |                   
  Session.ts       |   90.93 |    83.91 |   95.05 |   90.93 | ...8196,8223-8227 
  ...entTracker.ts |   91.87 |    89.18 |   88.88 |   91.87 | ...33,197,280-289 
  ...stop-guard.ts |     100 |    97.05 |     100 |     100 | 37,127,247        
  ...eplay-page.ts |   92.27 |    88.09 |     100 |   92.27 | ...83,108-118,121 
  ...y-replayer.ts |    98.5 |    95.38 |     100 |    98.5 | 229-231           
  index.ts         |       0 |        0 |       0 |       0 | 1-40              
  ...ssionUtils.ts |   89.76 |    86.76 |     100 |   89.76 | ...54-270,326-328 
  tasksSnapshot.ts |   94.26 |     87.5 |     100 |   94.26 | 65-71             
  ...on-tracker.ts |     100 |      100 |     100 |     100 |                   
  types.ts         |     100 |      100 |     100 |     100 |                   
 ...ssion/emitters |   95.68 |     93.7 |   96.66 |   95.68 |                   
  ...ageEmitter.ts |   95.34 |    94.11 |     100 |   95.34 | 52-59             
  PlanEmitter.ts   |     100 |    83.33 |     100 |     100 | 59                
  base-emitter.ts  |   78.26 |       75 |     100 |   78.26 | 23-24,26-28       
  index.ts         |       0 |        0 |       0 |       0 | 1-10              
  ...ll-emitter.ts |   99.17 |    97.43 |     100 |   99.17 | 352-353           
 ...ession/rewrite |    91.8 |    89.13 |   94.44 |    91.8 |                   
  LlmRewriter.ts   |    82.4 |     86.2 |     100 |    82.4 | ...,88-89,166-170 
  ...Middleware.ts |   96.96 |    88.09 |     100 |   96.96 | 144,152-154       
  TurnBuffer.ts    |     100 |      100 |     100 |     100 |                   
  config.ts        |     100 |      100 |     100 |     100 |                   
  index.ts         |     100 |      100 |     100 |     100 |                   
  types.ts         |       0 |        0 |       0 |       0 | 1                 
 src/commands      |   88.74 |    73.18 |   64.51 |   88.74 |                   
  auth.ts          |     100 |    83.33 |     100 |     100 | 11,14             
  channel.ts       |   55.55 |      100 |       0 |   55.55 | 18-22,30-40       
  extensions.tsx   |   96.77 |      100 |      50 |   96.77 | 39                
  hooks.tsx        |   66.66 |      100 |       0 |   66.66 | 20-24             
  mcp.ts           |   95.45 |      100 |      50 |   95.45 | 31                
  review.ts        |   97.77 |      100 |      50 |   97.77 | 56                
  serve.ts         |   86.44 |     67.3 |     100 |   86.44 | ...08-611,625-629 
  sessions.ts      |     100 |      100 |      50 |     100 |                   
  update.ts        |   98.13 |    94.44 |   66.66 |   98.13 | 82-83             
 ...mmands/channel |    86.7 |    87.24 |   90.11 |    86.7 |                   
  channel-cwd.ts   |     100 |      100 |     100 |     100 |                   
  ...l-registry.ts |   79.31 |    84.61 |      80 |   79.31 | 35-38,47-50,61-64 
  ...entry-path.ts |      75 |       50 |     100 |      75 | 8-9               
  config-utils.ts  |   95.85 |    96.32 |     100 |   95.85 | ...08-213,271-274 
  configure.ts     |    14.7 |      100 |       0 |    14.7 | 18-21,23-84       
  daemon-worker.ts |   94.69 |    85.77 |   97.61 |   94.69 | ...90-991,995-996 
  ...classifier.ts |   98.49 |    96.51 |     100 |   98.49 | 115-116,161       
  ...tact-store.ts |   93.51 |    87.65 |     100 |   93.51 | ...71,288-289,337 
  pairing.ts       |   72.85 |      100 |      50 |   72.85 | 22-28,57-68       
  pidfile.ts       |   95.55 |       90 |     100 |   95.55 | ...50-251,315-316 
  proxy.ts         |     100 |      100 |     100 |     100 |                   
  reload.ts        |    77.5 |    86.95 |      75 |    77.5 | 72-84,93-97       
  runtime.ts       |   81.22 |    87.27 |     100 |   81.22 | ...65-169,229-231 
  set.ts           |   75.72 |    85.71 |      50 |   75.72 | 65-83,111-116     
  start.ts         |   75.68 |    75.28 |   66.66 |   75.68 | ...56,562-565,577 
  ...ure-format.ts |   93.65 |    82.45 |     100 |   93.65 | ...42,48-49,74-75 
  status.ts        |   78.57 |    59.25 |   66.66 |   78.57 | ...36-137,150-161 
  stop.ts          |   57.83 |    82.35 |      50 |   57.83 | ...3,74-76,85-111 
 ...nds/extensions |   88.82 |    87.64 |   87.09 |   88.82 |                   
  consent.ts       |   72.53 |       90 |   42.85 |   72.53 | ...86-142,157-163 
  disable.ts       |     100 |       90 |     100 |     100 | 30                
  enable.ts        |     100 |    91.66 |     100 |     100 | 38                
  install.ts       |   82.95 |    81.57 |      75 |   82.95 | ...96-199,202-211 
  link.ts          |     100 |      100 |     100 |     100 |                   
  list.ts          |     100 |     87.5 |     100 |     100 | 18                
  new.ts           |     100 |      100 |     100 |     100 |                   
  settings.ts      |   99.15 |      100 |   83.33 |   99.15 | 151               
  sources.ts       |   93.42 |    87.09 |   92.85 |   93.42 | ...4-66,96-98,167 
  uninstall.ts     |   74.57 |       40 |   66.66 |   74.57 | 45-47,60-67,70-73 
  update.ts        |   96.71 |    97.05 |     100 |   96.71 | 114-118           
  utils.ts         |      75 |    53.84 |     100 |      75 | ...27-131,133-137 
 ...les/mcp-server |       0 |        0 |       0 |       0 |                   
  example.ts       |       0 |        0 |       0 |       0 | 1-60              
 ...amples/starter |       0 |        0 |       0 |       0 |                   
  example.ts       |       0 |        0 |       0 |       0 | 1-64              
 src/commands/mcp  |   90.17 |    84.39 |   83.33 |   90.17 |                   
  add.ts           |    99.3 |    96.07 |     100 |    99.3 | 154-155           
  approve.ts       |   76.19 |     87.5 |   66.66 |   76.19 | ...,89-99,114-124 
  list.ts          |   92.59 |    83.87 |      80 |   92.59 | ...62-164,180-181 
  reconnect.ts     |   78.85 |    66.66 |   85.71 |   78.85 | 42-55,169-191     
  remove.ts        |     100 |       80 |     100 |     100 | 21-25             
 ...ommands/review |   79.87 |    86.45 |   80.15 |   79.87 |                   
  agent-prompt.ts  |   90.85 |    92.78 |      96 |   90.85 | ...1256,1710-1779 
  capture-local.ts |   72.16 |     90.9 |      75 |   72.16 | 101-105,152-174   
  ...k-coverage.ts |   48.38 |    14.28 |   66.66 |   48.38 | ...21-226,239-249 
  cleanup.ts       |   64.28 |    45.45 |      50 |   64.28 | ...33-138,140-141 
  ...ose-review.ts |   95.42 |    92.13 |   91.66 |   95.42 | ...1099,1127-1143 
  fetch-pr.ts      |   24.78 |      100 |    12.5 |   24.78 | ...27-326,367-369 
  load-rules.ts    |   26.41 |      100 |   16.66 |   26.41 | ...41-153,155-156 
  parse-args.ts    |   99.25 |       96 |     100 |   99.25 | 341,413           
  plan-diff.ts     |    67.9 |      100 |   66.66 |    67.9 | 121-148           
  pr-context.ts    |   84.02 |    76.37 |   91.66 |   84.02 | ...22-903,932-934 
  presubmit.ts     |   74.32 |       82 |   85.71 |   74.32 | ...46-347,399-429 
  ...ve-anchors.ts |   77.02 |    88.46 |      75 |   77.02 | ...70-175,187-204 
  submit.ts        |   74.44 |    80.82 |      80 |   74.44 | ...48-584,586-587 
  test-efficacy.ts |   80.68 |    69.41 |    92.3 |   80.68 | ...93-594,602-622 
 ...nds/review/lib |   95.46 |    92.66 |   94.81 |   95.46 |                   
  agent-briefs.ts  |   98.68 |      100 |       0 |   98.68 | 493-494           
  anchors.ts       |     100 |    94.79 |     100 |     100 | ...33,169,178,225 
  coverage.ts      |   95.37 |    94.08 |   95.45 |   95.37 | ...98,335,429-446 
  diff-flags.ts    |     100 |        0 |     100 |     100 | 63                
  diff-plan.ts     |   98.73 |    92.93 |     100 |   98.73 | ...41,264,290-291 
  gh.ts            |   85.27 |     87.5 |   69.23 |   85.27 | ...01,238-239,266 
  git.ts           |   97.64 |    95.65 |     100 |   97.64 | 180-181           
  heavy.ts         |     100 |      100 |     100 |     100 |                   
  inline-counts.ts |     100 |      100 |     100 |     100 |                   
  local-diff.ts    |    84.4 |    88.46 |     100 |    84.4 | ...63-473,475-483 
  merge-base.ts    |     100 |      100 |     100 |     100 |                   
  path-rules.ts    |     100 |      100 |     100 |     100 |                   
  paths.ts         |    92.3 |    83.33 |   83.33 |    92.3 | 76-77             
  prompt-record.ts |   94.73 |    88.23 |     100 |   94.73 | ...28,151-152,156 
  report.ts        |   92.13 |    86.66 |     100 |   92.13 | 170-171,173-177   
  roster.ts        |     100 |    92.85 |     100 |     100 | 104,118,163       
  shell-quote.ts   |     100 |      100 |     100 |     100 |                   
  transcripts.ts   |   96.27 |    93.25 |     100 |   96.27 | ...83,269-270,294 
  workspaces.ts    |   97.76 |     91.3 |     100 |   97.76 | 186-187,212-213   
 ...mands/sessions |   91.56 |    86.95 |   83.33 |   91.56 |                   
  common.ts        |     100 |      100 |     100 |     100 |                   
  list.ts          |   90.96 |    86.66 |   81.81 |   90.96 | 208-219,221-222   
 src/config        |   94.49 |    88.58 |   95.48 |   94.49 |                   
  auth.ts          |   89.35 |    83.56 |     100 |   89.35 | ...97-298,314-315 
  ...eMcpImport.ts |   87.91 |    81.52 |     100 |   87.91 | ...63-371,453-454 
  config.ts        |   88.29 |    88.03 |   84.84 |   88.29 | ...2375,2377-2385 
  ...heme-names.ts |     100 |      100 |     100 |     100 |                   
  environment.ts   |   94.18 |     89.4 |   94.73 |   94.18 | ...22-626,642-643 
  ...le-watcher.ts |   90.86 |    83.65 |   95.83 |   90.86 | ...23-325,370,418 
  ...resh-state.ts |   90.57 |    97.29 |   93.75 |   90.57 | 137-142,146-152   
  ...ime-reload.ts |     100 |    69.69 |     100 |     100 | ...12-113,122-123 
  hot-reload.ts    |     100 |    89.74 |     100 |     100 | 47,160,220        
  keyBindings.ts   |   97.24 |       50 |     100 |   97.24 | 221-224           
  ...ngsAdapter.ts |     100 |    94.11 |     100 |     100 | 64                
  ...ig-watcher.ts |   95.17 |    83.05 |     100 |   95.17 | ...78,200,292-293 
  ...er-secrets.ts |   98.97 |    96.96 |     100 |   98.97 | 85                
  mcpApprovals.ts  |   96.55 |    95.65 |     100 |   96.55 | 223-224,229-231   
  mcpJson.ts       |     100 |      100 |     100 |     100 |                   
  mcpServers.ts    |   92.85 |     87.5 |     100 |   92.85 | 46-47             
  ...idersScope.ts |      95 |    94.73 |     100 |      95 | 11-12             
  ...abledTools.ts |     100 |      100 |     100 |     100 |                   
  ...comparison.ts |     100 |      100 |     100 |     100 |                   
  ...n-settings.ts |   99.15 |    93.75 |     100 |   99.15 | 63                
  sandboxConfig.ts |   61.64 |    71.87 |   66.66 |   61.64 | ...54-68,73,77-89 
  ...ings-cache.ts |   96.52 |    93.93 |     100 |   96.52 | 90-91,201-202     
  settings.ts      |    90.6 |    91.84 |   89.65 |    90.6 | ...61,963,965-966 
  ...ingsSchema.ts |     100 |      100 |     100 |     100 |                   
  ...ngsWatcher.ts |   95.54 |    88.34 |     100 |   95.54 | ...28,277-278,293 
  ...d-env-keys.ts |     100 |      100 |     100 |     100 |                   
  ...paths-lite.ts |   89.47 |       88 |     100 |   89.47 | 43-44,53-54,56-57 
  ...tedFolders.ts |   94.46 |    95.68 |     100 |   94.46 | ...53-354,390-401 
 ...nfig/migration |   95.23 |    77.77 |   83.33 |   95.23 |                   
  index.ts         |   95.65 |     87.5 |     100 |   95.65 | 117-118           
  scheduler.ts     |   96.55 |    77.77 |     100 |   96.55 | 19-20             
  types.ts         |       0 |        0 |       0 |       0 | 1                 
 ...ation/versions |   94.91 |      100 |     100 |   94.91 |                   
  ...-v2-shared.ts |     100 |      100 |     100 |     100 |                   
  v1-to-v2.ts      |   81.75 |      100 |     100 |   81.75 | ...28-229,231-247 
  v2-to-v3.ts      |     100 |      100 |     100 |     100 |                   
  v3-to-v4.ts      |     100 |      100 |     100 |     100 |                   
  v5-to-v4.ts      |      96 |      100 |     100 |      96 | 94-95,99          
 src/core          |     100 |      100 |     100 |     100 |                   
  auth.ts          |     100 |      100 |     100 |     100 |                   
  initializer.ts   |     100 |      100 |     100 |     100 |                   
  theme.ts         |     100 |      100 |     100 |     100 |                   
 src/dualOutput    |    71.8 |    70.31 |   66.66 |    71.8 |                   
  ...tputBridge.ts |   71.95 |    70.96 |   68.42 |   71.95 | ...08-409,417-420 
  ...utContext.tsx |     100 |      100 |     100 |     100 |                   
  index.ts         |       0 |        0 |       0 |       0 | 1-8               
 src/export        |       0 |        0 |       0 |       0 |                   
  index.ts         |       0 |        0 |       0 |       0 | 1-7               
 src/generated     |     100 |      100 |     100 |     100 |                   
  git-commit.ts    |     100 |      100 |     100 |     100 |                   
 src/i18n          |   85.83 |    81.92 |   89.65 |   85.83 |                   
  index.ts         |   73.45 |    77.77 |      90 |   73.45 | ...70-271,294-299 
  languages.ts     |   93.07 |     92.3 |   85.71 |   93.07 | ...35,164-169,184 
  ...nslateKeys.ts |     100 |      100 |     100 |     100 |                   
  ...lationDict.ts |   93.33 |    66.66 |     100 |   93.33 | 15                
 src/i18n/locales  |     100 |      100 |     100 |     100 |                   
  ca.js            |     100 |      100 |     100 |     100 |                   
  de.js            |     100 |      100 |     100 |     100 |                   
  en.js            |     100 |      100 |     100 |     100 |                   
  fr.js            |     100 |      100 |     100 |     100 |                   
  ja.js            |     100 |      100 |     100 |     100 |                   
  pt.js            |     100 |      100 |     100 |     100 |                   
  ru.js            |     100 |      100 |     100 |     100 |                   
  zh-TW.js         |     100 |      100 |     100 |     100 |                   
  zh.js            |     100 |      100 |     100 |     100 |                   
 ...nonInteractive |      80 |    76.31 |   81.35 |      80 |                   
  session.ts       |   84.08 |    75.27 |   93.61 |   84.08 | ...1007,1016-1026 
  types.ts         |    42.5 |      100 |   33.33 |    42.5 | ...24-625,628-629 
 ...active/control |   76.11 |    89.09 |      80 |   76.11 |                   
  ...rolContext.ts |    6.45 |        0 |       0 |    6.45 | 56-95             
  ...Dispatcher.ts |   91.79 |    92.45 |   88.88 |   91.79 | ...49-367,387,390 
  ...rolService.ts |     7.4 |        0 |       0 |     7.4 | 46-185            
 ...ol/controllers |   39.72 |    62.93 |   47.22 |   39.72 |                   
  ...Controller.ts |   39.49 |      100 |      80 |   39.49 | 88-92,127-210     
  ...Controller.ts |       0 |        0 |       0 |       0 | 1-56              
  ...Controller.ts |   49.11 |    62.96 |   54.54 |   49.11 | ...63-568,570-575 
  ...Controller.ts |   14.06 |      100 |       0 |   14.06 | ...82-117,130-133 
  ...Controller.ts |    37.8 |       60 |   46.66 |    37.8 | ...40-652,661-690 
 .../control/types |       0 |        0 |       0 |       0 |                   
  serviceAPIs.ts   |       0 |        0 |       0 |       0 | 1                 
 ...Interactive/io |   98.14 |    94.38 |   95.23 |   98.14 |                   
  ...putAdapter.ts |   98.09 |    93.62 |   98.07 |   98.09 | ...1319,1422-1423 
  ...putAdapter.ts |      96 |    91.66 |   85.71 |      96 | 51-52             
  ...nputReader.ts |     100 |    94.73 |     100 |     100 | 67                
  ...putAdapter.ts |   98.38 |      100 |   90.47 |   98.38 | 84-85,125-126     
  index.ts         |     100 |      100 |     100 |     100 |                   
 src/patches       |       0 |        0 |       0 |       0 |                   
  is-in-ci.ts      |       0 |        0 |       0 |       0 | 1-17              
 src/remoteInput   |   87.31 |    75.32 |   88.23 |   87.31 |                   
  ...utContext.tsx |     100 |      100 |     100 |     100 |                   
  ...putWatcher.ts |   88.01 |       76 |   93.33 |   88.01 | ...49-350,361-364 
  index.ts         |       0 |        0 |       0 |       0 | 1-8               
 src/serve         |   87.86 |    83.92 |   90.95 |   87.86 |                   
  ...tp-enabled.ts |     100 |      100 |     100 |     100 |                   
  ...ion-bridge.ts |     100 |      100 |     100 |     100 |                   
  auth.ts          |    93.4 |    92.95 |     100 |    93.4 | ...19-320,323-325 
  ...em-adapter.ts |     100 |      100 |     100 |     100 |                   
  capabilities.ts  |     100 |    97.77 |     100 |     100 | 603               
  ...cp-command.ts |     100 |      100 |     100 |     100 |                   
  ...-selection.ts |     100 |      100 |     100 |     100 |                   
  ...ings-store.ts |   85.85 |    91.78 |   95.83 |   85.85 | ...94-206,366-369 
  ...ebhook-ipc.ts |    98.5 |    86.66 |     100 |    98.5 | 47                
  ...iagnostics.ts |     100 |      100 |     100 |     100 |                   
  ...worker-env.ts |     100 |      100 |     100 |     100 |                   
  ...rker-group.ts |   90.97 |    85.34 |     100 |   90.97 | ...80-684,690-694 
  ...er-manager.ts |   95.12 |    88.82 |   94.28 |   95.12 | ...68,492,503-505 
  ...tartup-ipc.ts |   97.72 |    96.66 |     100 |   97.72 | 82-83             
  ...supervisor.ts |   96.57 |     86.9 |   96.49 |   96.57 | ...1026,1134-1138 
  ...e-grouping.ts |     100 |    94.11 |     100 |     100 | 69,132            
  ...ub-session.ts |   92.04 |    77.77 |     100 |   92.04 | ...36-445,470,508 
  daemon-logger.ts |    82.2 |    77.31 |   91.76 |    82.2 | ...1720,1747-1753 
  ...trics-ring.ts |     100 |      100 |     100 |     100 |                   
  ...s-provider.ts |   68.04 |    52.77 |     100 |   68.04 | ...44-249,282-290 
  daemon-status.ts |   98.37 |    90.06 |     100 |   98.37 | ...1037,1039-1040 
  debug-mode.ts    |     100 |      100 |     100 |     100 |                   
  demo.ts          |     100 |      100 |     100 |     100 |                   
  env-snapshot.ts  |    91.3 |       80 |     100 |    91.3 | ...24-127,205-212 
  ...-scheduler.ts |   87.34 |    83.87 |     100 |   87.34 | 33-36,48-50,79-81 
  ...-path-argv.ts |     100 |      100 |     100 |     100 |                   
  ...h-settings.ts |   94.39 |    88.75 |     100 |   94.39 | ...22,700,716,726 
  fast-path.ts     |    91.3 |    81.98 |   95.45 |    91.3 | ...65-474,540-541 
  ...ration-sse.ts |   42.55 |    33.33 |     100 |   42.55 | 23-24,30,33-56    
  health-query.ts  |     100 |      100 |     100 |     100 |                   
  index.ts         |       0 |        0 |       0 |       0 | 1-143             
  ...e-observer.ts |   89.89 |    83.24 |      96 |   89.89 | ...11-512,541-543 
  ...back-binds.ts |     100 |    88.88 |     100 |     100 | 32                
  ...-workspace.ts |    90.9 |    85.71 |     100 |    90.9 | ...27-128,139-140 
  ...iders-edit.ts |     100 |    82.14 |     100 |     100 | 58-60,65,81       
  ...sion-audit.ts |     100 |      100 |   93.33 |     100 |                   
  rate-limit.ts    |   92.77 |    88.42 |     100 |   92.77 | ...93-295,307-309 
  ...qwen-serve.ts |   84.76 |     80.7 |   72.68 |   84.76 | ...5593,5598-5599 
  ...tup-errors.ts |     100 |      100 |     100 |     100 |                   
  ...-keepalive.ts |   96.03 |    90.72 |     100 |   96.03 | ...36,498-500,540 
  ...-lifecycle.ts |     100 |      100 |     100 |     100 |                   
  server.ts        |   95.62 |    93.09 |   78.94 |   95.62 | ...1784,1804-1807 
  ...on-helpers.ts |     100 |      100 |     100 |     100 |                   
  ...t-event-id.ts |     100 |    95.23 |     100 |     100 | 12                
  ...-admission.ts |   98.71 |    89.65 |     100 |   98.71 | 68                
  types.ts         |     100 |      100 |     100 |     100 |                   
  ...erver-name.ts |     100 |      100 |     100 |     100 |                   
  ...ion-limits.ts |     100 |      100 |     100 |     100 |                   
  ...t-sessions.ts |   93.34 |    76.57 |     100 |   93.34 | ...17,820,833-835 
  ...l-resolver.ts |   90.32 |    66.66 |     100 |   90.32 | 16,45-46          
  ...ell-static.ts |   91.07 |    86.66 |     100 |   91.07 | ...79-182,216-219 
  ...ace-agents.ts |   64.79 |    71.33 |   91.66 |   64.79 | ...2125,2135-2145 
  ...generation.ts |    95.4 |    82.35 |   66.66 |    95.4 | 55-56,78,92       
  ...-git-state.ts |     100 |       90 |    87.5 |     100 | 61,121            
  ...ace-inputs.ts |     100 |      100 |     100 |     100 |                   
  ...-constants.ts |     100 |      100 |     100 |     100 |                   
  ...-summaries.ts |   86.66 |       50 |     100 |   86.66 | 11,19             
  ...ace-memory.ts |   82.19 |    75.28 |     100 |   82.19 | ...82-489,549-556 
  ...ers-status.ts |   98.52 |       79 |     100 |   98.52 | 94,122,162,165    
  ...tion-store.ts |   89.63 |    88.27 |   92.59 |   89.63 | ...91-400,411-414 
  ...e-registry.ts |   91.26 |     90.8 |     100 |   91.26 | ...93-294,300-301 
  ...ber-errors.ts |     100 |    95.32 |     100 |     100 | 53,93-94,172,192  
  ...e-remember.ts |   97.94 |    94.33 |     100 |   97.94 | ...00,304-309,350 
  ...te-runtime.ts |   93.14 |    87.71 |     100 |   93.14 | ...-88,92,145-150 
  ...management.ts |   71.84 |    71.67 |      96 |   71.84 | ...65-866,873-877 
  ...ls-mapping.ts |     100 |      100 |     100 |     100 |                   
  ...lls-status.ts |     100 |    94.73 |     100 |     100 | 109               
 ...serve/acp-http |   75.83 |     78.3 |   93.85 |   75.83 |                   
  ...r-registry.ts |     100 |    95.45 |     100 |     100 | 191               
  client-mcp-ws.ts |   54.85 |    58.62 |   72.72 |   54.85 | ...99-300,304-305 
  ...n-registry.ts |   98.19 |    88.55 |     100 |   98.19 | 1015,1037-1048    
  dispatch.ts      |   69.34 |    74.79 |     100 |   69.34 | ...4525,4573-4579 
  index.ts         |   82.04 |    78.69 |   89.58 |   82.04 | ...2197,2228-2230 
  json-rpc.ts      |     100 |    96.96 |     100 |     100 | 92                
  safe-ws-send.ts  |   52.94 |    71.42 |     100 |   52.94 | 33-42,47-55       
  sse-stream.ts    |   93.96 |    88.57 |   84.61 |   93.96 | ...57-159,161-163 
  ...ort-stream.ts |       0 |        0 |       0 |       0 | 1                 
  ws-stream.ts     |   91.86 |       80 |     100 |   91.86 | 45,50,96,100-103  
 src/serve/auth    |   86.86 |     79.7 |   93.87 |   86.86 |                   
  device-flow.ts   |   96.35 |    80.57 |   97.61 |   96.35 | ...1358,1453,1519 
  ...w-provider.ts |   44.24 |    74.07 |   71.42 |   44.24 | ...23-284,297,301 
 ...rve/cdp-tunnel |   85.73 |    73.17 |    97.5 |   85.73 |                   
  ...r-emulator.ts |   88.57 |    63.63 |     100 |   88.57 | ...72-175,194-195 
  ...verse-link.ts |      88 |    76.19 |     100 |      88 | ...28-329,420-423 
  ...l-registry.ts |     100 |      100 |     100 |     100 |                   
  cdp-ws.ts        |   76.28 |    61.29 |    87.5 |   76.28 | ...13-217,223-228 
 ...nel/acceptance |       0 |        0 |       0 |       0 |                   
  ...mcp-smoke.mjs |       0 |        0 |       0 |       0 | 1-119             
  ...cceptance.mjs |       0 |        0 |       0 |       0 | 1-473             
  real-tab.mjs     |       0 |        0 |       0 |       0 | 1-218             
 src/serve/fs      |   85.68 |    80.06 |     100 |   85.68 |                   
  audit.ts         |     100 |    96.15 |     100 |     100 | 204               
  errors.ts        |     100 |      100 |     100 |     100 |                   
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...x-registry.ts |     100 |      100 |     100 |     100 |                   
  paths.ts         |   77.64 |     73.6 |     100 |   77.64 | ...65,594-598,611 
  policy.ts        |   90.32 |    89.18 |     100 |   90.32 | 142-150           
  ...ile-system.ts |   85.19 |     78.6 |     100 |   85.19 | ...2094,2104-2105 
 src/serve/routes  |   85.39 |    79.74 |   95.91 |   85.39 |                   
  a2ui-action.ts   |   99.49 |    94.52 |    87.5 |   99.49 | 250               
  capabilities.ts  |     100 |      100 |     100 |     100 |                   
  ...l-webhooks.ts |   93.56 |    84.09 |     100 |   93.56 | ...42,292,332,334 
  daemon-status.ts |   85.45 |    83.33 |     100 |   85.45 | 98-105            
  goals.ts         |    98.8 |    88.46 |     100 |    98.8 | 134               
  health-demo.ts   |   94.17 |    83.33 |     100 |   94.17 | 62-66,143         
  permission.ts    |     100 |     92.3 |     100 |     100 | 50,98             
  ...uled-tasks.ts |    84.2 |    83.18 |     100 |    84.2 | ...55-863,980-981 
  ...on-runtime.ts |     100 |     87.5 |     100 |     100 | 43,79             
  session.ts       |   86.24 |    81.78 |   94.82 |   86.24 | ...3824,3826-3827 
  sse-events.ts    |   84.45 |     87.5 |   77.77 |   84.45 | ...36,453-456,485 
  usage-stats.ts   |     100 |    95.65 |     100 |     100 | 116               
  ...space-auth.ts |    83.7 |       75 |     100 |    83.7 | ...23,328,340-344 
  ...el-control.ts |   86.26 |    78.94 |     100 |   86.26 | ...17-318,339-347 
  ...d-contacts.ts |     100 |      100 |     100 |     100 |                   
  ...controller.ts |    82.1 |    77.17 |      90 |    82.1 | ...1000,1006,1009 
  ...extensions.ts |   87.44 |    72.76 |   95.74 |   87.44 | ...1788,1830-1831 
  ...-file-read.ts |   92.32 |       80 |     100 |   92.32 | ...94-595,598-599 
  ...file-write.ts |   84.44 |    64.13 |     100 |   84.44 | ...73-275,355-357 
  ...e-git-diff.ts |   94.11 |    91.89 |     100 |   94.11 | ...54-155,201-206 
  ...ce-git-log.ts |     100 |    92.68 |     100 |     100 | 51,76,182         
  workspace-git.ts |   62.19 |    83.33 |     100 |   62.19 | 71-81,87-107      
  ...-lifecycle.ts |   96.85 |       75 |     100 |   96.85 | 130-131,161-162   
  ...management.ts |   87.43 |    85.13 |     100 |   87.43 | ...1441,1461-1466 
  ...cp-control.ts |   71.29 |       67 |     100 |   71.29 | ...67-573,582-583 
  ...ace-models.ts |   95.87 |    92.42 |     100 |   95.87 | 38-39,136-141     
  ...ermissions.ts |   74.66 |    69.23 |     100 |   74.66 | ...25-233,254-271 
  ...e-settings.ts |   72.81 |     69.9 |     100 |   72.81 | ...85-589,594-604 
  ...tup-github.ts |   77.58 |    70.27 |   84.21 |   77.58 | ...88,310,354-355 
  ...ace-skills.ts |   69.87 |    78.12 |     100 |   69.87 | ...59-284,290-324 
  ...ace-status.ts |   75.41 |    63.51 |     100 |   75.41 | ...35-336,360-361 
  ...pace-tools.ts |   74.82 |    69.23 |     100 |   74.82 | ...41-146,175-176 
  ...pace-trust.ts |   76.08 |       50 |   66.66 |   76.08 | ...01-206,214-215 
  ...pace-voice.ts |   91.45 |    82.35 |     100 |   91.45 | ...21-624,627-629 
 src/serve/server  |   90.53 |    89.41 |      95 |   90.53 |                   
  access-log.ts    |   98.68 |     97.1 |     100 |   98.68 | 115,186           
  ...er-helpers.ts |   63.82 |    77.96 |   81.81 |   63.82 | ...16,330,332-347 
  ...w-registry.ts |    98.8 |    86.95 |     100 |    98.8 | 107               
  ...r-handlers.ts |   97.14 |    71.42 |     100 |   97.14 | 16                
  ...r-response.ts |    85.4 |    76.16 |     100 |    85.4 | ...91,708,771-780 
  fs-factory.ts    |     100 |    92.59 |     100 |     100 | 33,41,100,156     
  ...t-deadline.ts |     100 |      100 |     100 |     100 |                   
  ...iter-setup.ts |      65 |    73.33 |   33.33 |      65 | 30-35,38-43,47-48 
  ...st-helpers.ts |   95.11 |    95.09 |     100 |   95.11 | ...65-167,422-427 
  self-origin.ts   |   76.19 |       80 |     100 |   76.19 | 45-54             
  ...e-features.ts |    94.3 |       92 |     100 |    94.3 | 159-165           
  ...on-archive.ts |   89.61 |    90.56 |   88.23 |   89.61 | ...36-441,513-523 
  ...ion-export.ts |     100 |    94.44 |     100 |     100 | 64                
  session-list.ts  |   93.55 |    91.01 |     100 |   93.55 | ...79,681-687,827 
  telemetry.ts     |   98.72 |    97.39 |     100 |   98.72 | ...26-628,769-771 
 src/serve/voice   |   85.15 |     93.1 |   90.47 |   85.15 |                   
  ...ice-config.ts |   96.77 |       30 |     100 |   96.77 | 85-86             
  voice-ws.ts      |   77.97 |    96.39 |   83.33 |   77.97 | ...55,470,508-510 
  ...oordinator.ts |     100 |    98.11 |     100 |     100 | 171               
 ...kspace-service |   89.53 |     83.4 |   89.47 |   89.53 |                   
  index.ts         |   89.05 |     82.9 |   87.87 |   89.05 | ...1158-1162,1165 
  types.ts         |     100 |      100 |     100 |     100 |                   
 src/services      |   91.96 |    88.41 |   97.81 |   91.96 |                   
  ...mandLoader.ts |     100 |    88.88 |     100 |     100 | 104-117           
  ...killLoader.ts |   97.14 |    87.87 |     100 |   97.14 | 140,151-152       
  ...andService.ts |   98.73 |      100 |     100 |   98.73 | 107               
  ...mandLoader.ts |   86.83 |    83.87 |     100 |   86.83 | ...30-335,340-345 
  ...omptLoader.ts |   77.36 |    85.52 |   83.33 |   77.36 | ...43,168,210-211 
  ...mandLoader.ts |   97.36 |    92.68 |     100 |   97.36 | 153,160-161       
  ...nd-factory.ts |   91.42 |    91.66 |     100 |   91.42 | 128,137-144       
  ...ation-tool.ts |     100 |    95.45 |     100 |     100 | 125               
  ...ndMetadata.ts |   98.23 |    96.72 |     100 |   98.23 | 83,87             
  commandUtils.ts  |      96 |     90.9 |     100 |      96 | 48                
  ...and-parser.ts |   90.69 |    85.71 |     100 |   90.69 | 63-66             
  ...ionService.ts |     100 |      100 |     100 |     100 |                   
  prompt-stash.ts  |   96.66 |    93.75 |     100 |   96.66 | 34-35             
  ...tree-lease.ts |   88.29 |    86.11 |     100 |   88.29 | ...91-196,229-230 
  ...low-loader.ts |     100 |    96.15 |     100 |     100 | 88                
  setup-github.ts  |    90.5 |    81.81 |     100 |    90.5 | ...37-438,445-446 
  ...-args-file.ts |   93.54 |    90.47 |    87.5 |   93.54 | 201-203,217-223   
  types.ts         |     100 |      100 |     100 |     100 |                   
  ...e-keyterms.ts |   98.64 |    95.83 |     100 |   98.64 | 116,142-143       
  voice-model.ts   |     100 |      100 |     100 |     100 |                   
  voice-service.ts |   88.14 |    87.69 |     100 |   88.14 | ...80,287,352-357 
  ...e-settings.ts |     100 |    95.45 |     100 |     100 | 19                
  ...ranscriber.ts |   90.46 |    82.11 |      96 |   90.46 | ...66-668,671-673 
 ...ght/generators |   88.86 |    85.78 |   96.29 |   88.86 |                   
  DataProcessor.ts |   88.23 |    85.71 |      95 |   88.23 | ...1348,1352-1359 
  ...tGenerator.ts |   98.21 |    85.71 |     100 |   98.21 | 46                
  ...teRenderer.ts |     100 |      100 |     100 |     100 |                   
 .../insight/types |       0 |       50 |      50 |       0 |                   
  ...sightTypes.ts |       0 |        0 |       0 |       0 |                   
  ...sightTypes.ts |       0 |        0 |       0 |       0 | 1                 
 ...mpt-processors |   97.27 |    94.04 |     100 |   97.27 |                   
  ...tProcessor.ts |     100 |      100 |     100 |     100 |                   
  ...eProcessor.ts |   94.52 |    84.21 |     100 |   94.52 | 46-47,93-94       
  ...tionParser.ts |     100 |      100 |     100 |     100 |                   
  ...lProcessor.ts |   97.41 |    95.65 |     100 |   97.41 | 95-98             
  types.ts         |     100 |      100 |     100 |     100 |                   
 src/services/tips |   97.27 |    84.61 |     100 |   97.27 |                   
  index.ts         |     100 |      100 |     100 |     100 |                   
  tipHistory.ts    |   92.59 |       70 |     100 |   92.59 | ...24,146,153,162 
  tipRegistry.ts   |     100 |      100 |     100 |     100 |                   
  tipScheduler.ts  |     100 |    91.66 |     100 |     100 | 55                
 src/startup       |   88.99 |    83.47 |    90.9 |   88.99 |                   
  ...p-prefetch.ts |   98.09 |    94.23 |    87.5 |   98.09 | 50,209,225-226    
  ...reeStartup.ts |   80.53 |     74.6 |     100 |   80.53 | ...94,403,409-412 
 src/test-utils    |   94.04 |    83.33 |      80 |   94.04 |                   
  ...omMatchers.ts |   69.69 |       50 |      50 |   69.69 | 32-35,37-39,45-47 
  ...andContext.ts |     100 |      100 |     100 |     100 |                   
  render.tsx       |     100 |      100 |     100 |     100 |                   
 src/ui            |   71.01 |    73.07 |   66.66 |   71.01 |                   
  App.tsx          |   33.33 |       75 |   33.33 |   33.33 | 32-86             
  AppContainer.tsx |   72.24 |     70.1 |   66.66 |   72.24 | ...4026,4030-4034 
  ...tionNudge.tsx |    9.58 |      100 |       0 |    9.58 | 24-94             
  ...ackDialog.tsx |   29.23 |      100 |       0 |   29.23 | 25-75             
  ...tionNudge.tsx |    7.69 |      100 |       0 |    7.69 | 25-103            
  colors.ts        |      60 |      100 |   35.29 |      60 | ...52,54-55,60-61 
  constants.ts     |     100 |      100 |     100 |     100 |                   
  keyMatchers.ts   |   95.91 |    97.14 |     100 |   95.91 | 25-26             
  ...tic-colors.ts |     100 |      100 |     100 |     100 |                   
  ...ractiveUI.tsx |   62.73 |    47.22 |   66.66 |   62.73 | ...95-296,313-318 
  ...inePresets.ts |   96.27 |    83.87 |     100 |   96.27 | ...97,402,410-412 
  textConstants.ts |     100 |      100 |     100 |     100 |                   
  types.ts         |     100 |      100 |     100 |     100 |                   
 src/ui/auth       |   58.45 |    66.18 |   51.06 |   58.45 |                   
  AuthDialog.tsx   |   59.01 |     42.1 |   16.66 |   59.01 | ...25,332-354,358 
  ...nProgress.tsx |       0 |        0 |       0 |       0 | 1-64              
  ...etupSteps.tsx |   60.03 |    70.73 |   57.69 |   60.03 | ...87,791,800,803 
  useAuth.ts       |    94.6 |    73.52 |     100 |    94.6 | ...21-222,241-247 
  ...rSetupFlow.ts |   43.18 |    33.33 |      50 |   43.18 | ...78-399,416-459 
 src/ui/commands   |   80.75 |    83.26 |   88.83 |   80.75 |                   
  aboutCommand.ts  |     100 |      100 |     100 |     100 |                   
  agentsCommand.ts |   83.78 |      100 |      60 |   83.78 | 30-32,42-44       
  ...odeCommand.ts |    93.1 |    95.23 |     100 |    93.1 | 77-82             
  arenaCommand.ts  |   62.81 |    58.73 |   65.21 |   62.81 | ...90-595,680-688 
  authCommand.ts   |     100 |      100 |     100 |     100 |                   
  branchCommand.ts |     100 |      100 |     100 |     100 |                   
  btwCommand.ts    |   94.32 |    77.41 |     100 |   94.32 | 35-36,114-119     
  bugCommand.ts    |     100 |    77.77 |     100 |     100 | 27,61             
  cdCommand.ts     |    92.1 |     84.9 |     100 |    92.1 | ...4-69,94-99,178 
  clearCommand.ts  |    80.9 |    70.83 |     100 |    80.9 | ...24-125,133-142 
  ...essCommand.ts |   67.95 |    55.88 |      75 |   67.95 | ...86-187,201-204 
  ...astCommand.ts |   84.17 |       75 |     100 |   84.17 | ...,91-97,125-130 
  ...ig-command.ts |   93.12 |    88.42 |     100 |   93.12 | ...07-315,321-323 
  ...extCommand.ts |   67.81 |    69.69 |   84.61 |   67.81 | ...59-592,603-604 
  copyCommand.ts   |   98.49 |    95.78 |     100 |   98.49 | ...80,280,321,327 
  deleteCommand.ts |     100 |      100 |     100 |     100 |                   
  diffCommand.ts   |     100 |    87.87 |     100 |     100 | ...63,231-232,245 
  ...ryCommand.tsx |   81.64 |    87.67 |    90.9 |   81.64 | ...73-278,325-332 
  docsCommand.ts   |     100 |     90.9 |     100 |     100 | 25                
  doctorCommand.ts |   65.37 |    81.88 |   94.11 |   65.37 | ...85-535,538-672 
  dreamCommand.ts  |   85.45 |    88.88 |     100 |   85.45 | 58-65             
  editorCommand.ts |     100 |      100 |     100 |     100 |                   
  ...rt-command.ts |   82.97 |    78.57 |     100 |   82.97 | 47-52,67-70,91-96 
  exportCommand.ts |   98.25 |    91.02 |     100 |   98.25 | ...81,198-199,364 
  ...onsCommand.ts |   52.31 |    56.25 |   69.23 |   52.31 | ...09,277-329,390 
  forgetCommand.ts |     100 |       90 |     100 |     100 | 59                
  forkCommand.ts   |     100 |    94.11 |     100 |     100 | 96,147            
  goalCommand.ts   |   91.13 |    83.72 |      90 |   91.13 | ...81-184,196-199 
  helpCommand.ts   |     100 |      100 |     100 |     100 |                   
  ...oryCommand.ts |     100 |      100 |     100 |     100 |                   
  hooksCommand.ts  |   81.13 |    65.71 |   85.71 |   81.13 | ...,86-93,131-132 
  ideCommand.ts    |   60.75 |    64.28 |   41.17 |   60.75 | ...05-306,310-324 
  ...figCommand.ts |   52.83 |    81.25 |      70 |   52.83 | ...74-319,321-330 
  initCommand.ts   |   91.86 |       80 |     100 |   91.86 | 48,83-88          
  ...ghtCommand.ts |   77.87 |    71.42 |     100 |   77.87 | ...44-245,250-272 
  ...ageCommand.ts |   93.45 |    89.06 |     100 |   93.45 | ...68-169,196-206 
  learn-command.ts |     100 |      100 |     100 |     100 |                   
  lspCommand.ts    |     100 |    86.95 |     100 |     100 | 31,101-102        
  mcpCommand.ts    |     100 |      100 |     100 |     100 |                   
  memoryCommand.ts |     100 |      100 |     100 |     100 |                   
  modelCommand.ts  |    81.1 |     89.5 |   88.23 |    81.1 | ...80-793,827-832 
  ...onsCommand.ts |     100 |      100 |     100 |     100 |                   
  planCommand.ts   |   78.82 |    76.92 |     100 |   78.82 | 30-35,51-56,68-73 
  quitCommand.ts   |     100 |      100 |     100 |     100 |                   
  recapCommand.ts  |   21.81 |      100 |      50 |   21.81 | 24-73             
  ...ns-command.ts |   98.83 |    81.81 |     100 |   98.83 | 100               
  ...berCommand.ts |     100 |     87.5 |     100 |     100 | 46                
  renameCommand.ts |   89.06 |    88.37 |     100 |   89.06 | ...72-176,202-209 
  ...oreCommand.ts |    90.9 |    86.04 |     100 |    90.9 | ...41-146,176-177 
  resumeCommand.ts |     100 |      100 |     100 |     100 |                   
  rewindCommand.ts |   81.25 |      100 |      50 |   81.25 | 20-22             
  ...ngsCommand.ts |     100 |      100 |     100 |     100 |                   
  ...hubCommand.ts |   89.47 |       75 |      80 |   89.47 | 54-59             
  skillsCommand.ts |   78.82 |    81.81 |     100 |   78.82 | 37-52,78,97       
  statsCommand.ts  |    90.6 |    77.95 |     100 |    90.6 | ...91-694,785-792 
  ...ineCommand.ts |     100 |      100 |     100 |     100 |                   
  ...aryCommand.ts |    6.43 |      100 |      50 |    6.43 | 31-330            
  tasksCommand.ts  |   77.22 |    72.13 |     100 |   77.22 | ...46-150,172-177 
  ...tupCommand.ts |     100 |      100 |     100 |     100 |                   
  themeCommand.ts  |     100 |      100 |     100 |     100 |                   
  toolsCommand.ts  |     100 |      100 |     100 |     100 |                   
  trustCommand.ts  |     100 |      100 |     100 |     100 |                   
  types.ts         |     100 |      100 |     100 |     100 |                   
  ...te-command.ts |     100 |    94.11 |     100 |     100 | 74,148            
  vimCommand.ts    |   54.54 |      100 |      50 |   54.54 | 19-29             
  voice-command.ts |   93.57 |       88 |     100 |   93.57 | 35,97-102         
  ...owsCommand.ts |   91.82 |    78.87 |   66.66 |   91.82 | ...59-160,169-174 
 src/ui/components |   69.54 |    78.21 |   76.11 |   69.54 |                   
  AboutBox.tsx     |     100 |      100 |     100 |     100 |                   
  ...ateScreen.tsx |   97.29 |     87.5 |   66.66 |   97.29 | 49                
  AnsiOutput.tsx   |   65.57 |      100 |      50 |   65.57 | 69-90             
  ApiKeyInput.tsx  |       0 |        0 |       0 |       0 | 1-97              
  AppHeader.tsx    |    88.7 |       75 |     100 |    88.7 | 36,38-43,45       
  ...odeDialog.tsx |   87.24 |    72.22 |   33.33 |   87.24 | ...85,233-238,245 
  AsciiArt.ts      |     100 |      100 |     100 |     100 |                   
  ...Indicator.tsx |   95.65 |    66.66 |     100 |   95.65 | 27,52             
  ...TextInput.tsx |   86.72 |    86.66 |     100 |   86.72 | ...00-302,355-359 
  Composer.tsx     |   94.49 |    66.66 |     100 |   94.49 | ...-72,84,139,153 
  ...entPrompt.tsx |     100 |      100 |     100 |     100 |                   
  ...ryDisplay.tsx |   75.89 |    62.06 |     100 |   75.89 | ...,88,93-108,113 
  ...geDisplay.tsx |   68.42 |    57.14 |     100 |   68.42 | 16-17,31-32,42-50 
  CronPill.tsx     |     100 |    93.75 |     100 |     100 | 18                
  ...ification.tsx |      84 |       60 |     100 |      84 | 23-24,40-42       
  ...gProfiler.tsx |       0 |        0 |       0 |       0 | 1-36              
  ...ogManager.tsx |       0 |        0 |       0 |       0 | 1-596             
  DiffDialog.tsx   |    53.5 |     37.5 |   69.23 |    53.5 | ...32-737,747-760 
  ...ngsDialog.tsx |       0 |        0 |       0 |       0 | 1-195             
  EffortDialog.tsx |   97.36 |      100 |     100 |   97.36 | 55-56             
  ExitWarning.tsx  |     100 |      100 |     100 |     100 |                   
  ...hProgress.tsx |    87.8 |    33.33 |     100 |    87.8 | 28-31,56          
  ...ustDialog.tsx |     100 |      100 |     100 |     100 |                   
  Footer.tsx       |   78.71 |     62.5 |     100 |   78.71 | ...28-233,251-255 
  ...ngSpinner.tsx |   68.42 |    85.71 |      50 |   68.42 | 35-52,73,80-81    
  GoalPill.tsx     |   83.33 |    76.92 |     100 |   83.33 | 24-30             
  Header.tsx       |   98.65 |    94.73 |     100 |   98.65 | 173,175           
  Help.tsx         |   98.33 |       90 |     100 |   98.33 | ...25,382,448-449 
  ...emDisplay.tsx |   78.22 |    64.28 |     100 |   78.22 | ...94,497,500-506 
  ...ngeDialog.tsx |     100 |      100 |     100 |     100 |                   
  InputPrompt.tsx  |   82.25 |    79.81 |      80 |   82.25 | ...2161,2187,2247 
  ...Shortcuts.tsx |   20.65 |      100 |       0 |   20.65 | ...7,50-52,68-126 
  ...Indicator.tsx |   98.18 |    97.82 |     100 |   98.18 | 161-162           
  ...firmation.tsx |   91.42 |      100 |      50 |   91.42 | 26-31             
  MainContent.tsx  |   95.54 |    93.84 |      50 |   95.54 | ...93,436-440,443 
  MemoryDialog.tsx |   86.59 |    80.15 |     100 |   86.59 | ...34-435,485,553 
  ...geDisplay.tsx |       0 |        0 |       0 |       0 | 1-41              
  ModelDialog.tsx  |   86.41 |       73 |     100 |   86.41 | ...74,876,881-897 
  ...tsDisplay.tsx |     100 |    97.22 |     100 |     100 | 270               
  ...fications.tsx |       0 |        0 |       0 |       0 | 1-56              
  ...onsDialog.tsx |       0 |        0 |       0 |       0 | 1-1004            
  ...ryDisplay.tsx |     100 |      100 |     100 |     100 |                   
  ...icePrompt.tsx |   92.64 |    85.71 |     100 |   92.64 | 102-106,134-139   
  PrepareLabel.tsx |   91.66 |    77.27 |     100 |   91.66 | 73-75,77-79,110   
  ...atePrompt.tsx |       0 |        0 |       0 |       0 | 1-134             
  ...geDisplay.tsx |     100 |      100 |     100 |     100 |                   
  ...ngDisplay.tsx |       0 |        0 |       0 |       0 | 1-39              
  ...hProgress.tsx |   85.25 |    88.46 |     100 |   85.25 | 121-147           
  ...dSelector.tsx |   92.79 |    82.65 |     100 |   92.79 | ...19-323,354-370 
  ...ionPicker.tsx |   83.66 |    72.13 |     100 |   83.66 | ...96,402,444-466 
  ...onPreview.tsx |   93.58 |    83.78 |     100 |   93.58 | ...,70-71,195-197 
  ...ryDisplay.tsx |     100 |      100 |     100 |     100 |                   
  ...putPrompt.tsx |   72.56 |       80 |      40 |   72.56 | ...06-109,114-117 
  ...tedDialog.tsx |     100 |      100 |     100 |     100 |                   
  ...ngsDialog.tsx |   71.47 |    73.89 |   69.23 |   71.47 | ...1243,1249-1250 
  ...ionDialog.tsx |    92.3 |    96.15 |   33.33 |    92.3 | 60-63,68-75,164   
  ...putPrompt.tsx |    15.9 |      100 |       0 |    15.9 | 20-63             
  ...Indicator.tsx |   57.14 |      100 |       0 |   57.14 | 12-15             
  ...MoreLines.tsx |       0 |        0 |       0 |       0 | 1-40              
  ...iewDialog.tsx |   97.77 |    87.67 |     100 |   97.77 | ...97,305-307,324 
  ...tsDisplay.tsx |   95.86 |       75 |     100 |   95.86 | 67-71             
  ...ionPicker.tsx |       0 |        0 |       0 |       0 | 1-172             
  ...tivityTab.tsx |    3.94 |      100 |       0 |    3.94 | 27-275            
  StatsDialog.tsx  |    8.64 |      100 |       0 |    8.64 | ...76-111,130-322 
  StatsDisplay.tsx |     100 |      100 |     100 |     100 |                   
  ...ciencyTab.tsx |    78.9 |    56.52 |     100 |    78.9 | ...26,213,262-288 
  ...atmapView.tsx |    8.98 |      100 |       0 |    8.98 | 20-107            
  ...essionTab.tsx |    5.46 |      100 |       0 |    5.46 | 24-215            
  ...ineDialog.tsx |    93.5 |    85.18 |     100 |    93.5 | ...05,267,287-289 
  ...yTodoList.tsx |   96.33 |    88.23 |     100 |   96.33 | 137-140           
  ...nsDisplay.tsx |   92.95 |       85 |     100 |   92.95 | ...79,182,209-211 
  ThemeDialog.tsx  |   89.95 |    46.15 |      75 |   89.95 | ...71-173,243-245 
  Tips.tsx         |   93.54 |       75 |     100 |   93.54 | 39-40             
  TodoDisplay.tsx  |     100 |      100 |     100 |     100 |                   
  ...tsDisplay.tsx |     100 |     87.5 |     100 |     100 | 31-32             
  ...criptView.tsx |   98.27 |    84.21 |     100 |   98.27 | 45,53             
  TrustDialog.tsx  |     100 |    81.81 |     100 |     100 | 71-86             
  ...ification.tsx |   36.36 |      100 |       0 |   36.36 | 15-22             
  ...Indicator.tsx |    92.5 |     87.5 |     100 |    92.5 | 50-53             
  ...ackDialog.tsx |       0 |        0 |       0 |       0 | 1-134             
  ...xitDialog.tsx |   80.36 |    43.47 |      60 |   80.36 | ...24-238,248-251 
  ...odeVisuals.ts |   97.22 |    85.71 |     100 |   97.22 | 25                
  ...s-helpers.tsx |   66.25 |    81.25 |      50 |   66.25 | 25-32,46-53,62-72 
 ...nts/agent-view |   53.72 |    70.87 |   42.85 |   53.72 |                   
  ...atContent.tsx |    9.09 |      100 |       0 |    9.09 | 54-275,281-283    
  ...tChatView.tsx |   21.05 |      100 |       0 |   21.05 | 21-39             
  ...tComposer.tsx |   64.78 |    29.41 |   33.33 |   64.78 | ...51,269,277-279 
  AgentFooter.tsx  |   15.38 |      100 |       0 |   15.38 | 28-65             
  AgentHeader.tsx  |   15.38 |      100 |       0 |   15.38 | 27-64             
  AgentTabBar.tsx  |    87.9 |    63.88 |     100 |    87.9 | ...88,110-118,136 
  ...oryAdapter.ts |     100 |    91.83 |     100 |     100 | 103,109-110,138   
  index.ts         |       0 |        0 |       0 |       0 | 1-12              
 ...mponents/arena |   42.38 |    68.69 |   73.68 |   42.38 |                   
  ArenaCards.tsx   |   73.06 |    71.79 |   85.71 |   73.06 | ...83-185,321-326 
  ...ectDialog.tsx |   83.48 |    69.86 |   88.88 |   83.48 | ...88-392,409-410 
  ...artDialog.tsx |       0 |        0 |       0 |       0 | 1-164             
  ...tusDialog.tsx |       0 |        0 |       0 |       0 | 1-288             
  ...topDialog.tsx |       0 |        0 |       0 |       0 | 1-213             
 ...ackground-view |    82.2 |    81.36 |    90.9 |    82.2 |                   
  ...sksDialog.tsx |   77.53 |     76.9 |   80.76 |   77.53 | ...1781,1803-1809 
  ...TasksPill.tsx |   67.03 |     86.2 |     100 |   67.03 | ...02-122,130-138 
  ...gentPanel.tsx |   97.08 |    86.31 |     100 |   97.08 | 132,442-446,520   
  agent-forest.ts  |    99.2 |    93.93 |     100 |    99.2 | 256               
  ...Visibility.ts |     100 |      100 |     100 |     100 |                   
  ...e-overlay.tsx |    88.2 |    76.47 |     100 |    88.2 | ...36-138,140-142 
 ...nts/extensions |   84.32 |    76.78 |   83.33 |   84.32 |                   
  ...gerDialog.tsx |   82.15 |    76.08 |     100 |   82.15 | ...91-198,258,260 
  TabBar.tsx       |   97.29 |    88.88 |     100 |   97.29 | 33                
  index.ts         |       0 |        0 |       0 |       0 | 1-12              
  types.ts         |     100 |      100 |     100 |     100 |                   
 ...tensions/steps |   46.26 |       85 |   58.82 |   46.26 |                   
  ...ctionStep.tsx |   95.12 |    92.85 |   85.71 |   95.12 | 84-86,89          
  ...etailStep.tsx |       0 |        0 |       0 |       0 | 1-145             
  ...nListStep.tsx |   75.26 |    88.37 |   66.66 |   75.26 | ...53,174,203-209 
  ...electStep.tsx |       0 |        0 |       0 |       0 | 1-83              
  ...nfirmStep.tsx |   16.32 |      100 |       0 |   16.32 | 28-74             
  index.ts         |       0 |        0 |       0 |       0 | 1-11              
 ...xtensions/tabs |   71.86 |    68.14 |   70.83 |   71.86 |                   
  DiscoverTab.tsx  |   68.22 |    67.66 |   55.55 |   68.22 | ...93,656-660,664 
  InstalledTab.tsx |   75.45 |    67.28 |   83.33 |   75.45 | ...76,781-782,819 
  SourcesTab.tsx   |   71.52 |    70.47 |   77.77 |   71.52 | ...27,546,618-630 
 ...tensions/views |   50.97 |    52.38 |   20.83 |   50.97 |                   
  ...tionsView.tsx |   73.75 |    56.36 |   66.66 |   73.75 | ...30,353,369-374 
  ...tionsView.tsx |   43.45 |    44.82 |    6.66 |   43.45 | ...98-405,408-420 
  ...etailView.tsx |    9.56 |      100 |       0 |    9.56 | 40-67,70-158      
 ...mponents/hooks |   86.99 |    81.37 |   91.89 |   86.99 |                   
  ...rListBody.tsx |   95.29 |    85.18 |     100 |   95.29 | 95-98             
  ...etailStep.tsx |   75.32 |    71.42 |      60 |   75.32 | ...56-169,173-186 
  ...etailStep.tsx |     100 |      100 |     100 |     100 |                   
  ...rListStep.tsx |     100 |      100 |     100 |     100 |                   
  ...entHeader.tsx |     100 |    85.71 |     100 |     100 | 47                
  ...rListStep.tsx |     100 |      100 |     100 |     100 |                   
  ...etailStep.tsx |     100 |      100 |     100 |     100 |                   
  ...abledStep.tsx |     100 |      100 |     100 |     100 |                   
  ...sListStep.tsx |     100 |      100 |     100 |     100 |                   
  ...entDialog.tsx |   72.29 |    70.49 |     100 |   72.29 | ...51,563-568,572 
  constants.ts     |     100 |      100 |     100 |     100 |                   
  index.ts         |       0 |        0 |       0 |       0 | 1-13              
  ...erGrouping.ts |     100 |      100 |     100 |     100 |                   
  sourceLabels.ts  |     100 |      100 |     100 |     100 |                   
  types.ts         |     100 |      100 |     100 |     100 |                   
 ...components/mcp |   40.04 |    61.53 |   70.58 |   40.04 |                   
  ...ealthPill.tsx |   68.42 |    85.71 |     100 |   68.42 | 40-46             
  ...entDialog.tsx |   32.09 |    26.19 |      40 |   32.09 | ...12,914,927-933 
  ...valDialog.tsx |   15.06 |      100 |       0 |   15.06 | 40-109            
  constants.ts     |     100 |      100 |     100 |     100 |                   
  index.ts         |       0 |        0 |       0 |       0 | 1-35              
  types.ts         |     100 |      100 |     100 |     100 |                   
  utils.ts         |      97 |       95 |     100 |      97 | 24,113-114        
 ...ents/mcp/steps |    53.9 |    73.51 |   57.14 |    53.9 |                   
  ...icateStep.tsx |    5.65 |      100 |       0 |    5.65 | 40-66,69-308      
  ...electStep.tsx |   10.95 |      100 |       0 |   10.95 | 16-88             
  ...etailStep.tsx |     100 |      100 |     100 |     100 |                   
  ...eListStep.tsx |   99.09 |    97.36 |     100 |   99.09 | 71                
  ...etailStep.tsx |   62.83 |       60 |   33.33 |   62.83 | ...87-296,307-332 
  ...rListStep.tsx |   88.46 |    81.25 |     100 |   88.46 | ...63,169,174-179 
  ...etailStep.tsx |    10.3 |      100 |       0 |    10.3 | ...1,67-79,82-140 
  ToolListStep.tsx |   69.29 |       50 |     100 |   69.29 | ...23,126,135-144 
 ...nents/messages |   89.88 |    85.98 |   86.86 |   89.88 |                   
  ...ionDialog.tsx |   89.23 |    84.27 |   81.81 |   89.23 | ...75,593,611-613 
  BtwMessage.tsx   |     100 |      100 |     100 |     100 |                   
  ...upDisplay.tsx |     100 |    94.79 |     100 |     100 | 38,42,44,290,366  
  ...onMessage.tsx |   91.93 |    82.35 |     100 |   91.93 | 57-59,61,63       
  ...nMessages.tsx |    96.7 |    97.77 |   91.66 |    96.7 | 222-232           
  DiffRenderer.tsx |   93.17 |    86.02 |     100 |   93.17 | ...07,235-236,302 
  ...tsDisplay.tsx |   97.08 |    77.77 |     100 |   97.08 | 95,97,106         
  ...usMessage.tsx |   76.31 |     42.1 |   66.66 |   76.31 | ...99,101,124,155 
  ...tsDisplay.tsx |    95.5 |    88.31 |     100 |    95.5 | ...39,141,174-179 
  ...ssMessage.tsx |    12.5 |      100 |       0 |    12.5 | 18-59             
  ...edMessage.tsx |   16.66 |      100 |       0 |   16.66 | 22-38             
  ...sMessages.tsx |   58.65 |       50 |    37.5 |   58.65 | ...20-125,146-158 
  ...ryMessage.tsx |   14.28 |      100 |       0 |   14.28 | 23-62             
  ...onMessage.tsx |   89.75 |     79.1 |     100 |   89.75 | ...33-635,642-644 
  ...upMessage.tsx |   98.32 |    95.16 |     100 |   98.32 | 183-186,413       
  ToolMessage.tsx  |   92.43 |    84.77 |   93.33 |   92.43 | ...56-961,988-990 
 ...ponents/shared |   85.73 |    82.05 |   94.05 |   85.73 |                   
  ...ctionList.tsx |     100 |      100 |      75 |     100 |                   
  ...tonSelect.tsx |     100 |      100 |     100 |     100 |                   
  EnumSelector.tsx |     100 |    96.42 |     100 |     100 | 58                
  ...rBoundary.tsx |     100 |      100 |     100 |     100 |                   
  MaxSizedBox.tsx  |   84.71 |    86.86 |      90 |   84.71 | ...67-568,685-686 
  MultiSelect.tsx  |   93.58 |       75 |     100 |   93.58 | ...43,199-201,211 
  ...tonSelect.tsx |     100 |      100 |     100 |     100 |                   
  ...ontroller.tsx |     100 |    83.33 |     100 |     100 | 73,93-95          
  ...eSelector.tsx |     100 |       60 |     100 |     100 | 40-45             
  ...lableList.tsx |   81.48 |    84.84 |     100 |   81.48 | 46-66,73-76       
  StaticRender.tsx |   72.72 |      100 |     100 |   72.72 | 31-33             
  TextInput.tsx    |    80.8 |    67.24 |      80 |    80.8 | ...36-240,252-258 
  ...ontroller.tsx |     100 |    81.81 |     100 |     100 | 59-62             
  ...apsedTime.tsx |     100 |      100 |     100 |     100 |                   
  ...Indicator.tsx |     100 |      100 |     100 |     100 |                   
  ...lizedList.tsx |   88.51 |    85.11 |   81.81 |   88.51 | ...51-779,792,887 
  text-buffer.ts   |   85.94 |    81.73 |   97.91 |   85.94 | ...2651,2749-2750 
  ...er-actions.ts |   73.93 |    67.22 |     100 |   73.93 | ...32-733,934-936 
 ...ponents/skills |       0 |        0 |       0 |       0 |                   
  ...gerDialog.tsx |       0 |        0 |       0 |       0 | 1-678             
 ...ents/subagents |       0 |        0 |       0 |       0 |                   
  constants.ts     |       0 |        0 |       0 |       0 | 1-71              
  index.ts         |       0 |        0 |       0 |       0 | 1-11              
  reducers.tsx     |       0 |        0 |       0 |       0 | 1-190             
  types.ts         |       0 |        0 |       0 |       0 | 1-125             
  utils.ts         |       0 |        0 |       0 |       0 | 1-102             
 ...bagents/create |       0 |        0 |       0 |       0 |                   
  ...ionWizard.tsx |       0 |        0 |       0 |       0 | 1-299             
  ...rSelector.tsx |       0 |        0 |       0 |       0 | 1-85              
  ...onSummary.tsx |       0 |        0 |       0 |       0 | 1-331             
  ...tionInput.tsx |       0 |        0 |       0 |       0 | 1-177             
  ...dSelector.tsx |       0 |        0 |       0 |       0 | 1-63              
  ...nSelector.tsx |       0 |        0 |       0 |       0 | 1-58              
  ...EntryStep.tsx |       0 |        0 |       0 |       0 | 1-78              
  ToolSelector.tsx |       0 |        0 |       0 |       0 | 1-253             
 ...bagents/manage |   14.04 |    53.19 |    37.5 |   14.04 |                   
  ...ctionStep.tsx |       0 |        0 |       0 |       0 | 1-103             
  ...eleteStep.tsx |       0 |        0 |       0 |       0 | 1-62              
  ...tEditStep.tsx |       0 |        0 |       0 |       0 | 1-124             
  ...ctionStep.tsx |   35.42 |    59.52 |     100 |   35.42 | ...20-432,437-439 
  ...iewerStep.tsx |       0 |        0 |       0 |       0 | 1-73              
  ...gerDialog.tsx |       0 |        0 |       0 |       0 | 1-341             
 ...mponents/views |   69.81 |    72.64 |   61.11 |   69.81 |                   
  ContextUsage.tsx |   70.88 |    63.88 |      80 |   70.88 | ...20-426,463-557 
  DoctorReport.tsx |     9.8 |      100 |       0 |     9.8 | 25-54,57-131      
  ...sionsList.tsx |   88.05 |       75 |     100 |   88.05 | 70-77             
  McpStatus.tsx    |   92.01 |     73.8 |     100 |   92.01 | ...36,175-177,262 
  SkillsList.tsx   |   20.51 |      100 |       0 |   20.51 | 17-20,27-57       
  ToolsList.tsx    |     100 |      100 |     100 |     100 |                   
 src/ui/contexts   |    82.3 |    80.15 |   84.37 |    82.3 |                   
  ...ewContext.tsx |   64.83 |    88.88 |      50 |   64.83 | ...16-219,225-235 
  AppContext.tsx   |      80 |       50 |     100 |      80 | 19-20             
  ...ewContext.tsx |   92.45 |    62.79 |      50 |   92.45 | ...69-270,272-276 
  ...igContext.tsx |   81.81 |       50 |     100 |   81.81 | 15-16             
  ...ssContext.tsx |   83.43 |    84.58 |     100 |   83.43 | ...1313,1321-1323 
  ...owContext.tsx |   91.07 |    81.81 |     100 |   91.07 | 47-48,60-62       
  ...deContext.tsx |     100 |      100 |      50 |     100 |                   
  ...onContext.tsx |   78.68 |    73.77 |   91.66 |   78.68 | ...86-389,398-401 
  ...gsContext.tsx |     100 |      100 |     100 |     100 |                   
  ...usContext.tsx |     100 |      100 |     100 |     100 |                   
  ...ngContext.tsx |   71.42 |       50 |     100 |   71.42 | 17-20             
  ...utContext.tsx |   85.71 |      100 |   66.66 |   85.71 | 13-14             
  ...edContext.tsx |     100 |      100 |      50 |     100 |                   
  ...nsContext.tsx |   88.88 |       50 |     100 |   88.88 | 150-151           
  ...teContext.tsx |   86.66 |       50 |     100 |   86.66 | 233-234           
  ...deContext.tsx |      80 |     87.5 |      75 |      80 | ...11-112,118-120 
 src/ui/daemon     |   88.35 |    73.51 |   95.45 |   88.35 |                   
  ...ui-adapter.ts |   88.35 |    73.51 |   95.45 |   88.35 | ...74,792-793,879 
 src/ui/editors    |       0 |        0 |       0 |       0 |                   
  ...ngsManager.ts |       0 |        0 |       0 |       0 | 1-67              
 src/ui/hooks      |   84.29 |    82.13 |   89.06 |   84.29 |                   
  ...dProcessor.ts |   81.73 |    81.69 |     100 |   81.73 | ...41-742,748-753 
  ...ention-ref.ts |   97.67 |       84 |     100 |   97.67 | 65                
  keyToAnsi.ts     |    3.92 |      100 |       0 |    3.92 | 19-77             
  ...esourceRef.ts |     100 |      100 |     100 |     100 |                   
  ...dProcessor.ts |   94.62 |    73.58 |     100 |   94.62 | ...86-287,292-293 
  ...dProcessor.ts |   85.14 |    66.27 |   81.81 |   85.14 | ...1400,1421-1425 
  ...rt-command.ts |     100 |      100 |     100 |     100 |                   
  ...sced-flush.ts |     100 |      100 |     100 |     100 |                   
  ...oice-input.ts |   92.36 |    81.95 |   66.66 |   92.36 | ...00,502-503,658 
  ...ke-repaint.ts |     100 |      100 |     100 |     100 |                   
  ...amingState.ts |   12.22 |      100 |       0 |   12.22 | 54-157            
  ...agerDialog.ts |   88.23 |      100 |     100 |   88.23 | 20,24             
  ...dScrollbar.ts |     100 |      100 |     100 |     100 |                   
  ...ationFrame.ts |      42 |       75 |     100 |      42 | 42-44,53-59,62-87 
  ...odeCommand.ts |   58.82 |      100 |     100 |   58.82 | 28,33-48          
  ...enaCommand.ts |      85 |      100 |     100 |      85 | 23-24,29          
  ...aInProcess.ts |   27.92 |       80 |      25 |   27.92 | ...69-170,173-175 
  ...Completion.ts |   89.83 |    88.97 |     100 |   89.83 | ...49-456,496-505 
  ...ifications.ts |   87.82 |    96.77 |     100 |   87.82 | 138-152           
  ...tIndicator.ts |   88.28 |    81.08 |     100 |   88.28 | ...66,175,179-187 
  ...waySummary.ts |   96.22 |    69.69 |     100 |   96.22 | 125-127,169       
  ...ndTaskView.ts |   94.73 |    76.59 |     100 |   94.73 | 162-166,255,261   
  ...chedScroll.ts |     100 |      100 |     100 |     100 |                   
  ...ketedPaste.ts |    23.8 |      100 |       0 |    23.8 | 19-37             
  ...nchCommand.ts |   94.85 |    80.76 |     100 |   94.85 | ...54,229,292-295 
  ...ompletion.tsx |   96.75 |    81.81 |     100 |   96.75 | ...78-279,289-290 
  ...dMigration.ts |    92.1 |    88.88 |     100 |    92.1 | 42-44             
  useCompletion.ts |   94.11 |    89.65 |     100 |   94.11 | ...32-133,137-138 
  ...nitMessage.ts |     100 |      100 |     100 |     100 |                   
  ...extualTips.ts |   78.26 |       50 |     100 |   78.26 | ...2,75-79,96-104 
  ...eteCommand.ts |   78.53 |    88.57 |     100 |   78.53 | ...96-104,112-113 
  ...ialogClose.ts |   36.11 |       10 |     100 |   36.11 | ...89-195,202-207 
  useDiffData.ts   |       0 |        0 |       0 |       0 | 1-87              
  ...oublePress.ts |   53.12 |       75 |     100 |   53.12 | 33-35,41-54       
  ...orSettings.ts |     100 |      100 |     100 |     100 |                   
  ...Completion.ts |   99.12 |     97.7 |     100 |   99.12 | 182-183           
  ...ionUpdates.ts |   93.72 |    92.98 |     100 |   93.72 | ...87-291,314-320 
  ...agerDialog.ts |   88.88 |      100 |     100 |   88.88 | 21,25             
  ...backDialog.ts |    63.9 |    76.47 |   66.66 |    63.9 | ...66-168,190-191 
  useFocus.ts      |     100 |      100 |     100 |     100 |                   
  ...olderTrust.ts |     100 |      100 |     100 |     100 |                   
  ...ggestions.tsx |   96.47 |    78.94 |     100 |   96.47 | 121,155-156       
  ...miniStream.ts |   85.04 |    80.81 |   96.15 |   85.04 | ...3878,4040-4048 
  ...BranchName.ts |     100 |    91.66 |     100 |     100 | 30                
  ...oryManager.ts |   98.01 |    98.36 |     100 |   98.01 | 139-142           
  ...ooksDialog.ts |    87.5 |      100 |     100 |    87.5 | 19,23             
  ...stListener.ts |     100 |      100 |     100 |     100 |                   
  ...nAuthError.ts |   76.19 |       50 |     100 |   76.19 | 39-40,43-45       
  ...putHistory.ts |   92.59 |    85.71 |     100 |   92.59 | 63-64,72,94-96    
  ...storyStore.ts |     100 |    94.11 |     100 |     100 | 69                
  useKeypress.ts   |     100 |      100 |     100 |     100 |                   
  ...rdProtocol.ts |   36.36 |      100 |       0 |   36.36 | 24-31             
  ...unchEditor.ts |    9.67 |      100 |       0 |    9.67 | 11-32,39-90       
  ...gIndicator.ts |     100 |    96.66 |     100 |     100 | 109               
  useLogger.ts     |      16 |      100 |       0 |      16 | 15-45             
  useMCPHealth.ts  |   63.15 |       80 |      50 |   63.15 | 42-52,64-67       
  ...cpApproval.ts |   93.12 |    86.11 |     100 |   93.12 | ...24-127,139-140 
  useMcpDialog.ts  |    87.5 |      100 |     100 |    87.5 | 19,23             
  ...moryDialog.ts |    87.5 |      100 |     100 |    87.5 | 19,23             
  ...oryMonitor.ts |   83.14 |    78.57 |     100 |   83.14 | 54-63,74-79       
  ...ssageQueue.ts |     100 |    96.77 |     100 |     100 | 75                
  ...delCommand.ts |     100 |    92.85 |     100 |     100 | 48                
  ...ouseEvents.ts |   94.31 |    97.43 |   83.33 |   94.31 | 76-80             
  ...raseCycler.ts |   84.74 |    76.47 |     100 |   84.74 | ...49,52-53,69-71 
  ...rredEditor.ts |   58.33 |    22.22 |     100 |   58.33 | 23-27,29-33       
  ...derUpdates.ts |    87.4 |    78.78 |     100 |    87.4 | ...71,321-333,381 
  useQwenAuth.ts   |     100 |      100 |     100 |     100 |                   
  ...lScheduler.ts |   91.16 |     90.9 |     100 |   91.16 | ...35-338,453-463 
  ...oryCommand.ts |       0 |        0 |       0 |       0 | 1-7               
  ...tleRepaint.ts |     100 |      100 |     100 |     100 |                   
  ...umeCommand.ts |   94.67 |    74.28 |     100 |   94.67 | ...19,174,233-238 
  ...ompletion.tsx |   90.67 |    83.33 |     100 |   90.67 | ...02,105,138-141 
  ...ectionList.ts |   97.12 |    96.19 |     100 |   97.12 | ...92-193,247-250 
  ...sionPicker.ts |   92.87 |    90.35 |     100 |   92.87 | ...99-501,503-505 
  ...earchInput.ts |     100 |    97.29 |     100 |     100 | 82                
  ...ngsCommand.ts |   18.75 |      100 |       0 |   18.75 | 10-25             
  ...ellHistory.ts |   93.28 |    80.95 |     100 |   93.28 | ...96,153-154,164 
  ...oryCommand.ts |       0 |        0 |       0 |       0 | 1-73              
  ...agerDialog.ts |   88.23 |      100 |     100 |   88.23 | 20,24             
  ...Completion.ts |   82.85 |    85.13 |   94.73 |   82.85 | ...78-680,688-724 
  ...tateAndRef.ts |     100 |      100 |     100 |     100 |                   
  ...tatsDialog.ts |     100 |      100 |     100 |     100 |                   
  useStatusLine.ts |   97.13 |    93.33 |     100 |   97.13 | ...78-382,478-485 
  ...eateDialog.ts |   88.23 |      100 |     100 |   88.23 | 14,18             
  ...mInProcess.ts |   27.35 |       80 |      25 |   27.35 | ...82-183,186-188 
  ...tification.ts |     100 |     87.5 |     100 |     100 | 50                
  ...alProgress.ts |   53.06 |       50 |   66.66 |   53.06 | ...53,61-68,79-85 
  ...rminalSize.ts |     100 |      100 |     100 |     100 |                   
  ...emeCommand.ts |   67.01 |    29.41 |     100 |   67.01 | ...10-111,115-116 
  useTimer.ts      |   97.59 |    94.73 |     100 |   97.59 | 17-18             
  ...lMigration.ts |       0 |        0 |       0 |       0 |                   
  ...rustModify.ts |     100 |      100 |     100 |     100 |                   
  useTurnDiffs.ts  |   95.12 |    78.57 |     100 |   95.12 | 133-134,156-157   
  ...elcomeBack.ts |   87.36 |     90.9 |     100 |   87.36 | ...,94-96,114-115 
  ...reeSession.ts |   93.75 |       70 |     100 |   93.75 | 47-48,72          
  vim.ts           |      74 |    67.56 |   69.23 |      74 | ...1854-1861,1869 
 src/ui/layouts    |    91.2 |    89.47 |     100 |    91.2 |                   
  ...AppLayout.tsx |    90.9 |     87.5 |     100 |    90.9 | 60-62,110-115,151 
  ...AppLayout.tsx |   91.66 |    92.85 |     100 |   91.66 | 75-80             
 src/ui/models     |   80.24 |    79.16 |   71.42 |   80.24 |                   
  ...ableModels.ts |   80.24 |    79.16 |   71.42 |   80.24 | ...,61-71,123-125 
 ...noninteractive |     100 |      100 |    6.66 |     100 |                   
  ...eractiveUi.ts |     100 |      100 |    6.66 |     100 |                   
 src/ui/selection  |   86.47 |    79.88 |   96.66 |   86.47 |                   
  screen-buffer.ts |   94.73 |    64.28 |     100 |   94.73 | 51-52             
  ...ion-coords.ts |     100 |      100 |     100 |     100 |                   
  ...ction-span.ts |   92.72 |       90 |     100 |   92.72 | 37-38,67-68       
  ...tion-state.ts |   85.71 |      100 |   88.88 |   85.71 | 51-58             
  ...ction-text.ts |   92.85 |    92.45 |     100 |   92.85 | 30-34,114-115     
  ...selection.tsx |   80.31 |    59.64 |     100 |   80.31 | ...13-314,330-331 
 src/ui/state      |      95 |    81.81 |     100 |      95 |                   
  extensions.ts    |      95 |    81.81 |     100 |      95 | 69-70,89          
 src/ui/themes     |    98.5 |    73.17 |     100 |    98.5 |                   
  ansi-light.ts    |     100 |      100 |     100 |     100 |                   
  ansi.ts          |     100 |      100 |     100 |     100 |                   
  atom-one-dark.ts |     100 |      100 |     100 |     100 |                   
  ayu-light.ts     |     100 |      100 |     100 |     100 |                   
  ayu.ts           |     100 |      100 |     100 |     100 |                   
  color-utils.ts   |   99.23 |    97.05 |     100 |   99.23 | 277-278           
  default-light.ts |     100 |      100 |     100 |     100 |                   
  default.ts       |     100 |      100 |     100 |     100 |                   
  ...inal-theme.ts |   88.59 |    85.96 |     100 |   88.59 | ...57-261,266-270 
  dracula.ts       |     100 |      100 |     100 |     100 |                   
  github-dark.ts   |     100 |      100 |     100 |     100 |                   
  github-light.ts  |     100 |      100 |     100 |     100 |                   
  googlecode.ts    |     100 |      100 |     100 |     100 |                   
  no-color.ts      |     100 |      100 |     100 |     100 |                   
  qwen-dark.ts     |     100 |      100 |     100 |     100 |                   
  qwen-light.ts    |     100 |      100 |     100 |     100 |                   
  ...tic-tokens.ts |     100 |      100 |     100 |     100 |                   
  ...-of-purple.ts |     100 |      100 |     100 |     100 |                   
  theme-manager.ts |   88.68 |    84.52 |     100 |   88.68 | ...83-392,397-398 
  theme.ts         |     100 |    38.02 |     100 |     100 | ...34-449,457-461 
  xcode.ts         |     100 |      100 |     100 |     100 |                   
 src/ui/utils      |   86.01 |    84.91 |   94.67 |   86.01 |                   
  ...Colorizer.tsx |   80.31 |    85.41 |     100 |   80.31 | ...00-201,313-339 
  ...nRenderer.tsx |   68.83 |    70.14 |      50 |   68.83 | ...52-254,274-293 
  ...wnDisplay.tsx |   92.85 |    93.46 |     100 |   92.85 | ...,953,1000-1018 
  ...idDiagram.tsx |   87.79 |    95.34 |     100 |   87.79 | 156-179           
  ...eRenderer.tsx |   92.68 |    82.35 |   95.23 |   92.68 | ...34-737,790-795 
  ...odeDisplay.ts |   94.28 |    85.71 |     100 |   94.28 | 23,40             
  asciiCharts.ts   |   96.77 |    87.62 |     100 |   96.77 | 173-180,281       
  ...dWorkUtils.ts |     100 |      100 |     100 |     100 |                   
  ...boardUtils.ts |   52.52 |    73.25 |   91.66 |   52.52 | ...23,626-635,638 
  commandUtils.ts  |    96.1 |    88.77 |     100 |    96.1 | ...73,175-176,320 
  computeStats.ts  |     100 |      100 |     100 |     100 |                   
  customBanner.ts  |   90.68 |    91.22 |     100 |   90.68 | ...13,324-327,334 
  displayUtils.ts  |   90.38 |    73.91 |     100 |   90.38 | 23,25,29,31,33    
  formatters.ts    |    95.4 |    98.43 |     100 |    95.4 | 123-126           
  gradientUtils.ts |     100 |      100 |     100 |     100 |                   
  highlight.ts     |     100 |      100 |     100 |     100 |                   
  ...gap-notice.ts |     100 |      100 |     100 |     100 |                   
  ...oryMapping.ts |     100 |       95 |     100 |     100 | 44,103            
  historyUtils.ts  |    95.4 |    95.08 |     100 |    95.4 | 96-99             
  input-mouse.ts   |     100 |    85.71 |     100 |     100 | 48,93             
  isNarrowWidth.ts |     100 |      100 |     100 |     100 |                   
  ...olDetector.ts |   69.47 |       75 |   66.66 |   69.47 | ...24-129,157-158 
  latexRenderer.ts |   94.95 |     73.8 |     100 |   94.95 | ...76-178,184-187 
  layoutUtils.ts   |     100 |      100 |     100 |     100 |                   
  list-mouse.ts    |     100 |      100 |     100 |     100 |                   
  ...ightLoader.ts |     100 |       95 |     100 |     100 | 81                
  ...nUtilities.ts |   98.72 |    94.59 |     100 |   98.72 | 145-146           
  ...t-position.ts |     100 |     87.5 |     100 |     100 | 85                
  ...geRenderer.ts |   86.23 |    69.06 |   95.12 |   86.23 | ...1284,1324-1330 
  ...alRenderer.ts |   86.69 |     71.9 |     100 |   86.69 | ...1476,1513-1519 
  ...lsBySource.ts |     100 |    95.23 |     100 |     100 | 84                
  mouse.ts         |   92.85 |    73.77 |     100 |   92.85 | ...38,145,149-152 
  osc8.ts          |   94.84 |    88.74 |     100 |   94.84 | ...57,442,446-447 
  ...red-height.ts |   96.85 |    95.45 |     100 |   96.85 | 71-73,201-203     
  ...mConstants.ts |     100 |      100 |     100 |     100 |                   
  restoreGoal.ts   |     100 |      100 |     100 |     100 |                   
  ...storyUtils.ts |   71.02 |    78.86 |   93.75 |   71.02 | ...03-525,655-656 
  ...ickerUtils.ts |     100 |      100 |     100 |     100 |                   
  ...evel-label.ts |   77.77 |    66.66 |     100 |   77.77 | 18,22-24          
  ...are-cursor.ts |   89.47 |    85.71 |     100 |   89.47 | 39-44             
  ...ataService.ts |   93.17 |     79.1 |     100 |   93.17 | ...14,227,254-256 
  suggestions.ts   |     100 |      100 |     100 |     100 |                   
  ...izedOutput.ts |   94.94 |      100 |   88.88 |   94.94 | 112-117           
  ...wOptimizer.ts |     100 |    96.77 |     100 |     100 | 69                
  terminalSetup.ts |    4.37 |      100 |       0 |    4.37 | 44-393            
  textUtils.ts     |   95.97 |    93.22 |   94.44 |   95.97 | ...21-322,482-483 
  ...background.ts |     100 |      100 |     100 |     100 |                   
  todoSnapshot.ts  |   89.65 |       92 |     100 |   89.65 | ...83-184,217-218 
  ...isplay-map.ts |     100 |      100 |     100 |     100 |                   
  updateCheck.ts   |     100 |    92.75 |     100 |     100 | 227-239,331       
  ...ow-keyword.ts |     100 |      100 |     100 |     100 |                   
 ...i/utils/export |      75 |    59.89 |   94.59 |      75 |                   
  collect.ts       |   71.21 |    65.81 |      96 |   71.21 | ...88-631,653-654 
  index.ts         |     100 |      100 |     100 |     100 |                   
  normalize.ts     |   80.42 |    50.68 |     100 |   80.42 | ...59-364,376-378 
  types.ts         |       0 |        0 |       0 |       0 | 1                 
  utils.ts         |     100 |      100 |     100 |     100 |                   
 ...ort/formatters |   52.92 |    47.22 |   71.42 |   52.92 |                   
  html.ts          |   84.61 |       50 |     100 |   84.61 | ...53,57-58,62-63 
  json.ts          |     100 |      100 |     100 |     100 |                   
  jsonl.ts         |   82.45 |     37.5 |     100 |   82.45 | ...48,50-51,65-66 
  markdown.ts      |   36.32 |    47.05 |      50 |   36.32 | ...16-219,233-295 
 src/ui/voice      |   80.94 |    72.69 |   80.55 |   80.94 |                   
  ...d-recorder.ts |     6.2 |      100 |       0 |     6.2 | ...33-159,162-163 
  ...o-recorder.ts |   84.61 |    93.33 |   57.14 |   84.61 | ...16-117,131-136 
  ...me-session.ts |   89.72 |    65.33 |   93.75 |   89.72 | ...99,305,316-319 
  sox-recorder.ts  |    92.7 |    71.87 |     100 |    92.7 | ...34-135,153-154 
  ...ailability.ts |     100 |      100 |     100 |     100 |                   
  ...e-keyterms.ts |     100 |      100 |     100 |     100 |                   
  voice-model.ts   |     100 |      100 |     100 |     100 |                   
  ...e-recorder.ts |   88.29 |    67.74 |   81.81 |   88.29 | ...,98-99,112,115 
  voice-refine.ts  |     100 |    93.33 |     100 |     100 | 92                
  ...ream-retry.ts |   86.79 |    68.42 |     100 |   86.79 | 16-18,48-49,59-60 
  ...am-session.ts |   88.02 |    66.66 |   84.61 |   88.02 | ...26,343-345,363 
  ...ranscriber.ts |     100 |      100 |     100 |     100 |                   
 src/utils         |   80.64 |    86.85 |   92.27 |   80.64 |                   
  ...p-profiler.ts |   98.39 |    90.56 |     100 |   98.39 | 141,185,235       
  acpModelUtils.ts |    97.3 |    95.09 |     100 |    97.3 | ...04-205,209-210 
  apiPreconnect.ts |   96.74 |    94.59 |     100 |   96.74 | 167-170           
  ...ol-call-id.ts |   84.61 |       60 |     100 |   84.61 | 26-27,37-38       
  ...ng-failure.ts |     100 |       95 |     100 |     100 | 72                
  checks.ts        |   33.33 |      100 |       0 |   33.33 | 23-28             
  ...-api-error.ts |     100 |    96.42 |     100 |     100 | 14                
  cleanup.ts       |   84.05 |    94.11 |      80 |   84.05 | 80,111-121        
  commands.ts      |   96.96 |    97.95 |     100 |   96.96 | 123-125           
  commentJson.ts   |   91.37 |    94.87 |     100 |   91.37 | 67-76             
  ...Calculator.ts |     100 |      100 |     100 |     100 |                   
  cpuProfiler.ts   |   70.73 |    73.23 |   88.88 |   70.73 | ...27,430-431,438 
  deepMerge.ts     |     100 |       90 |     100 |     100 | 41-43,49          
  ...ScopeUtils.ts |   97.56 |    88.88 |     100 |   97.56 | 67                
  doctorChecks.ts  |   70.31 |    74.57 |     100 |   70.31 | ...95-301,325-341 
  ...putCapture.ts |   90.65 |    86.17 |     100 |   90.65 | ...72,370,372-373 
  ...arResolver.ts |   97.14 |    96.55 |     100 |   97.14 | 125-126           
  errors.ts        |   97.56 |    94.64 |     100 |   97.56 | 69-70,304-305     
  events.ts        |     100 |      100 |     100 |     100 |                   
  ...on-mention.ts |   88.48 |     82.6 |     100 |   88.48 | ...56-160,164-168 
  gitUtils.ts      |   92.85 |    86.66 |     100 |   92.85 | ...13-116,164-167 
  ...AutoUpdate.ts |    93.1 |       94 |      90 |    93.1 | 103,108,179-190   
  ...tyWarnings.ts |     100 |      100 |     100 |     100 |                   
  ...lationInfo.ts |   92.39 |    92.23 |     100 |   92.39 | ...52,369-370,415 
  languageUtils.ts |   98.88 |    97.05 |     100 |   98.88 | 184-185           
  load-undici.ts   |     100 |      100 |     100 |     100 |                   
  ...npm-update.ts |   85.55 |       74 |     100 |   85.55 | ...39-240,268-278 
  math.ts          |       0 |        0 |       0 |       0 | 1-15              
  ...er-mention.ts |     100 |    66.66 |     100 |     100 | 14,30,44-46       
  ...iagnostics.ts |   94.57 |    83.01 |   88.88 |   94.57 | ...05,311,315-317 
  ...serMessage.ts |     100 |      100 |     100 |     100 |                   
  ...onfigUtils.ts |   94.25 |    91.17 |     100 |   94.25 | ...30,436,439-443 
  ...iveHelpers.ts |   95.13 |    91.79 |     100 |   95.13 | ...53-454,552,565 
  osc.ts           |    97.5 |      100 |   88.88 |    97.5 | 195-196           
  package.ts       |   88.88 |    85.71 |     100 |   88.88 | 31-32             
  ...uggestions.ts |   74.38 |    69.56 |     100 |   74.38 | ...92-103,105-116 
  processUtils.ts  |    92.3 |       80 |     100 |    92.3 | 45-46             
  readStdin.ts     |   93.67 |    94.11 |   85.71 |   93.67 | 79-83             
  relaunch.ts      |   95.87 |    89.28 |     100 |   95.87 | 103-105,131       
  resolvePath.ts   |     100 |      100 |     100 |     100 |                   
  runBudget.ts     |   99.35 |    96.77 |     100 |   99.35 | 119               
  sandbox-path.ts  |     100 |      100 |     100 |     100 |                   
  sandbox.ts       |   45.67 |    56.93 |   76.92 |   45.67 | ...1034,1046-1069 
  ...xImageName.ts |     100 |    77.77 |     100 |     100 | 10,18             
  sandboxMounts.ts |     100 |      100 |     100 |     100 |                   
  sessionPaths.ts  |   90.84 |    90.56 |     100 |   90.84 | ...81-182,185-186 
  settingsUtils.ts |   82.35 |    89.57 |      90 |   82.35 | ...25-743,750-758 
  spawnWrapper.ts  |     100 |      100 |     100 |     100 |                   
  ...ate-verify.ts |     100 |      100 |     100 |     100 |                   
  ...one-update.ts |   39.81 |    77.44 |   62.16 |   39.81 | ...1193,1196-1215 
  ...upProfiler.ts |   98.47 |    94.66 |     100 |   98.47 | 132-133,308       
  ...upWarnings.ts |     100 |      100 |     100 |     100 |                   
  stdioHelpers.ts  |     100 |     87.5 |     100 |     100 | 23                
  systemInfo.ts    |   95.12 |    90.27 |     100 |   95.12 | ...54-255,260-264 
  ...InfoFields.ts |    87.5 |    65.85 |     100 |    87.5 | ...24-125,146-147 
  ...alSequence.ts |     100 |    97.61 |     100 |     100 | 60                
  ...iffPreview.ts |   76.47 |       25 |     100 |   76.47 | 13,17,23-24       
  ...e-relaunch.ts |   89.61 |    86.66 |      50 |   89.61 | 56-61,83-84       
  ...entEmitter.ts |     100 |      100 |     100 |     100 |                   
  ...ansionHook.ts |     100 |      100 |     100 |     100 |                   
  ...upWarnings.ts |   87.75 |       75 |     100 |   87.75 | 47-48,53-54,57-58 
  version.ts       |     100 |    66.66 |     100 |     100 | 11                
  ...ingHandler.ts |     100 |      100 |     100 |     100 |                   
  windowTitle.ts   |   95.45 |    93.33 |     100 |   95.45 | 54-55             
  ...WithBackup.ts |   65.04 |    77.77 |     100 |   65.04 | 97,112,133-172    
 ...s/housekeeping |   91.63 |    91.02 |      95 |   91.63 |                   
  cleanup.ts       |   95.77 |    95.83 |     100 |   95.77 | 70-72             
  ...eractionAt.ts |     100 |      100 |     100 |     100 |                   
  scheduler.ts     |   91.91 |    90.47 |    87.5 |   91.91 | 58-62,73,131-135  
  throttledOnce.ts |   86.66 |     86.2 |     100 |   86.66 | ...99,105,137-138 
-------------------|---------|----------|---------|---------|-------------------
Core Package - Full Text Report
-------------------|---------|----------|---------|---------|-------------------
File               | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
-------------------|---------|----------|---------|---------|-------------------
All files          |   87.04 |    86.15 |   88.45 |   87.04 |                   
 src               |     100 |      100 |     100 |     100 |                   
  index.ts         |     100 |      100 |     100 |     100 |                   
 src/__mocks__/fs  |       0 |        0 |       0 |       0 |                   
  promises.ts      |       0 |        0 |       0 |       0 | 1-48              
 src/agents        |   89.97 |    83.82 |   94.02 |   89.97 |                   
  ...transcript.ts |   88.15 |    84.61 |     100 |   88.15 | ...99,607,613-617 
  ...ent-resume.ts |   84.53 |    76.01 |   78.26 |   84.53 | ...1674-1678,1681 
  ...ound-tasks.ts |   96.14 |     90.1 |   98.76 |   96.14 | ...1728,1748-1751 
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...ent-result.ts |    96.8 |    92.68 |     100 |    96.8 | 106,129-131       
  ...n-registry.ts |   95.65 |    89.28 |     100 |   95.65 | ...12-413,485-489 
  ...w-snapshot.ts |   91.86 |       75 |     100 |   91.86 | ...54,178,185-187 
 src/agents/arena  |   76.27 |    67.71 |   78.94 |   76.27 |                   
  ...gentClient.ts |   79.47 |    88.88 |   81.81 |   79.47 | ...68-183,189-204 
  ArenaManager.ts  |   75.05 |    64.51 |   78.57 |   75.05 | ...1876,1882-1883 
  arena-events.ts  |   64.44 |      100 |      50 |   64.44 | ...71-175,178-183 
  diff-summary.ts  |    87.5 |    72.34 |     100 |    87.5 | ...32-133,137-138 
  index.ts         |     100 |      100 |     100 |     100 |                   
  types.ts         |     100 |      100 |     100 |     100 |                   
 ...gents/backends |   78.02 |    85.19 |   76.28 |   78.02 |                   
  ITermBackend.ts  |   97.97 |    93.93 |     100 |   97.97 | ...78-180,255,307 
  ...essBackend.ts |    90.8 |    85.24 |   93.33 |    90.8 | ...64,666,668-669 
  TmuxBackend.ts   |    90.7 |    76.55 |   97.36 |    90.7 | ...87,697,743-747 
  detect.ts        |   31.25 |      100 |       0 |   31.25 | 34-88             
  index.ts         |     100 |      100 |     100 |     100 |                   
  iterm-it2.ts     |     100 |     92.1 |     100 |     100 | 37-38,106         
  tmux-commands.ts |    6.64 |      100 |    3.03 |    6.64 | ...93-363,386-503 
  types.ts         |     100 |      100 |     100 |     100 |                   
 ...agents/runtime |   89.22 |     86.2 |   86.86 |   89.22 |                   
  agent-context.ts |     100 |      100 |     100 |     100 |                   
  agent-core.ts    |    81.3 |    76.49 |    74.5 |    81.3 | ...2137,2164-2211 
  agent-events.ts  |     100 |      100 |     100 |     100 |                   
  ...t-headless.ts |   93.49 |    88.09 |   83.33 |   93.49 | ...96-497,500-501 
  ...nteractive.ts |   81.01 |    82.35 |   76.66 |   81.01 | ...33,535-538,541 
  ...statistics.ts |   98.29 |    82.55 |     100 |   98.29 | 141,165,206,239   
  agent-types.ts   |     100 |      100 |     100 |     100 |                   
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...ool-policy.ts |   98.34 |      100 |    92.3 |   98.34 | 81-82             
  ...low-budget.ts |     100 |      100 |     100 |     100 |                   
  ...ow-journal.ts |   91.76 |    75.86 |     100 |   91.76 | ...38-139,179-181 
  ...chestrator.ts |   91.79 |    87.79 |   82.35 |   91.79 | ...1774,1823-1826 
  ...ow-prompts.ts |     100 |      100 |     100 |     100 |                   
  ...ow-sandbox.ts |   96.87 |    94.51 |     100 |   96.87 | ...24-325,330-331 
  ...flow-saved.ts |   96.51 |    94.36 |     100 |   96.51 | 134-135,234-237   
  ...flow-stall.ts |    97.9 |    83.33 |     100 |    97.9 | 138-139,236       
 src/agents/tasks  |     100 |      100 |     100 |     100 |                   
  types.ts         |     100 |      100 |     100 |     100 |                   
 src/agents/team   |   81.83 |    84.09 |    87.4 |   81.83 |                   
  TeamManager.ts   |   72.04 |     79.6 |   78.84 |   72.04 | ...1629,1652-1653 
  identity.ts      |     100 |      100 |     100 |     100 |                   
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...sionBridge.ts |     100 |      100 |     100 |     100 |                   
  mailbox.ts       |   94.76 |    86.36 |   92.85 |   94.76 | 86-87,348-354     
  ...ptAddendum.ts |     100 |      100 |     100 |     100 |                   
  tasks.ts         |   88.85 |    82.56 |   96.29 |   88.85 | ...-990,1034-1035 
  team-events.ts   |   60.52 |      100 |      50 |   60.52 | ...40-144,151-155 
  teamHelpers.ts   |   92.02 |    94.91 |   95.23 |   92.02 | ...31-332,368-378 
  types.ts         |     100 |      100 |     100 |     100 |                   
 ...eam/test-utils |   94.39 |    94.26 |   98.21 |   94.39 |                   
  ...on-harness.ts |   96.49 |    84.21 |     100 |   96.49 | 128-129,141-142   
  fake-agent.ts    |   98.49 |    95.08 |     100 |   98.49 | 201-203           
  fake-backend.ts  |   86.46 |    97.61 |   95.83 |   86.46 | 124-146           
 src/config        |   83.46 |    86.65 |   72.34 |   83.46 |                   
  approval-mode.ts |     100 |      100 |     100 |     100 |                   
  ...xtDefaults.ts |     100 |      100 |     100 |     100 |                   
  config.ts        |   82.57 |    86.26 |   70.14 |   82.57 | ...7197,7201-7202 
  constants.ts     |     100 |      100 |     100 |     100 |                   
  models.ts        |     100 |      100 |     100 |     100 |                   
  storage.ts       |   94.11 |    91.95 |      88 |   94.11 | ...25-426,429-430 
 ...nfirmation-bus |   98.27 |    97.14 |     100 |   98.27 |                   
  message-bus.ts   |   98.14 |    97.05 |     100 |   98.14 | 42-43             
  types.ts         |     100 |      100 |     100 |     100 |                   
 src/core          |    91.5 |     87.9 |   92.65 |    91.5 |                   
  baseLlmClient.ts |   88.28 |    82.48 |   81.81 |   88.28 | ...47,660,666-668 
  client.ts        |   91.07 |    86.46 |   90.27 |   91.07 | ...3202,3298-3299 
  ...tGenerator.ts |   85.81 |     85.5 |   80.95 |   85.81 | ...23-424,469-475 
  ...lScheduler.ts |   89.98 |    86.14 |   95.83 |   89.98 | ...5346,5374-5385 
  geminiChat.ts    |   91.83 |    89.27 |   95.69 |   91.83 | ...4075,4123-4124 
  geminiRequest.ts |     100 |      100 |     100 |     100 |                   
  genai-compat.ts  |     100 |      100 |     100 |     100 |                   
  ...MediaLimit.ts |     100 |    95.83 |     100 |     100 | 96                
  ...htProtocol.ts |    9.09 |      100 |       0 |    9.09 | ...9,62-66,69-110 
  ...ream-error.ts |     100 |      100 |     100 |     100 |                   
  logger.ts        |   87.41 |    87.02 |     100 |   87.41 | ...64-568,614-628 
  ...lay-buffer.ts |     100 |      100 |     100 |     100 |                   
  ...dispatcher.ts |     100 |      100 |     100 |     100 |                   
  ...tyDefaults.ts |     100 |      100 |     100 |     100 |                   
  ...olExecutor.ts |   93.33 |    83.33 |      50 |   93.33 | 46-47             
  ...on-helpers.ts |   93.49 |    78.57 |     100 |   93.49 | ...10-211,228-229 
  ...issionFlow.ts |   98.97 |    96.96 |     100 |   98.97 | 107               
  ...try-policy.ts |     100 |      100 |     100 |     100 |                   
  ...ell-policy.ts |   95.19 |    89.47 |     100 |   95.19 | ...44-245,290-291 
  prompts.ts       |   93.31 |    91.34 |   81.25 |   93.31 | ...1109,1312-1313 
  ...ing-effort.ts |     100 |      100 |     100 |     100 |                   
  ...n-recovery.ts |   95.13 |       80 |     100 |   95.13 | ...06-107,142-144 
  ...t-profiler.ts |   96.89 |    80.88 |   88.23 |   96.89 | ...10,117-118,123 
  ...port-retry.ts |     100 |      100 |     100 |     100 |                   
  tokenLimits.ts   |     100 |     92.1 |     100 |     100 | 87,122-123        
  ...reparation.ts |     100 |      100 |     100 |     100 |                   
  ...allIdUtils.ts |   98.41 |    93.02 |     100 |   98.41 | 36,45             
  ...okTriggers.ts |   99.45 |    92.43 |     100 |   99.45 | 182,193           
  ...terruption.ts |     100 |     92.3 |     100 |     100 | 86,104            
  turn.ts          |   98.49 |    91.17 |     100 |   98.49 | ...94,622-623,669 
 ...ntentGenerator |   96.15 |    87.11 |   95.38 |   96.15 |                   
  ...tGenerator.ts |   97.05 |    86.94 |   94.44 |   97.05 | ...1309,1338,1349 
  converter.ts     |   96.04 |    87.15 |     100 |   96.04 | ...,931,1086-1088 
  index.ts         |       0 |        0 |       0 |       0 | 1-21              
  usage.ts         |     100 |      100 |     100 |     100 |                   
 ...ntentGenerator |   89.93 |    71.83 |   93.33 |   89.93 |                   
  ...tGenerator.ts |    88.3 |    71.21 |   92.85 |    88.3 | ...19-325,343-344 
  index.ts         |     100 |       80 |     100 |     100 | 50                
 ...ntentGenerator |   95.16 |    86.79 |    92.5 |   95.16 |                   
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...tGenerator.ts |   95.07 |    85.81 |    92.1 |   95.07 | ...1203-1204,1232 
  ...tDetection.ts |     100 |      100 |     100 |     100 |                   
 ...ntentGenerator |   91.52 |    90.02 |   95.09 |   91.52 |                   
  constants.ts     |     100 |      100 |     100 |     100 |                   
  converter.ts     |   91.03 |    89.12 |   96.87 |   91.03 | ...1909,2078-2093 
  errorHandler.ts  |     100 |      100 |     100 |     100 |                   
  index.ts         |   60.31 |       75 |      50 |   60.31 | ...71,74-78,90-94 
  ...tGenerator.ts |    66.4 |    70.58 |   88.88 |    66.4 | ...51-157,168-169 
  pipeline.ts      |   96.76 |    90.53 |     100 |   96.76 | ...1052,1060,1128 
  ...ureContext.ts |     100 |      100 |     100 |     100 |                   
  ...ingOptions.ts |       0 |        0 |       0 |       0 | 1                 
  ...CallParser.ts |    92.2 |     92.4 |     100 |    92.2 | ...15-516,536-539 
  ...kingParser.ts |     100 |    96.87 |     100 |     100 | 42                
  types.ts         |       0 |        0 |       0 |       0 | 1                 
 ...rator/provider |   96.49 |    89.61 |   96.55 |   96.49 |                   
  dashscope.ts     |   97.48 |    91.91 |      95 |   97.48 | ...85-386,528-529 
  deepseek.ts      |   94.91 |    89.36 |     100 |   94.91 | ...31-132,145-146 
  default.ts       |    97.5 |    96.55 |   88.88 |    97.5 | 123-124,198       
  index.ts         |     100 |      100 |     100 |     100 |                   
  mimo.ts          |   94.11 |    66.66 |     100 |   94.11 | 29,52-53          
  minimax.ts       |     100 |      100 |     100 |     100 |                   
  mistral.ts       |   96.07 |    73.33 |     100 |   96.07 | 32-33             
  modelscope.ts    |     100 |      100 |     100 |     100 |                   
  types.ts         |       0 |        0 |       0 |       0 |                   
  utils.ts         |     100 |      100 |     100 |     100 |                   
  zai.ts           |   92.13 |    82.14 |     100 |   92.13 | ...,39-40,135-137 
 src/extension     |   86.08 |    82.95 |   92.19 |   86.08 |                   
  ...ive-safety.ts |     100 |      100 |     100 |     100 |                   
  ...-converter.ts |   78.32 |    71.83 |     100 |   78.32 | ...1122,1168-1169 
  corruptFile.ts   |     100 |       50 |     100 |     100 | 40-45             
  ...-converter.ts |   80.39 |     87.5 |     100 |   80.39 | 50-59             
  ...me-refresh.ts |     100 |      100 |     100 |     100 |                   
  ...sion-store.ts |   90.69 |    85.42 |   97.82 |   90.69 | ...1189-1195,1239 
  ...ionManager.ts |   80.56 |    77.97 |   80.23 |   80.56 | ...2577,2599-2600 
  ...references.ts |     100 |     90.9 |     100 |     100 | ...05,129,197,200 
  ...onSettings.ts |    92.3 |     94.4 |     100 |    92.3 | ...98-501,570-571 
  ...-converter.ts |    75.9 |    84.61 |   85.71 |    75.9 | ...98,202,214-248 
  github.ts        |   88.55 |    82.13 |     100 |   88.55 | ...58,948-949,959 
  http-client.ts   |   84.61 |       80 |     100 |   84.61 | 20-21             
  i18n.ts          |   78.26 |       96 |      50 |   78.26 | 104-110,116-123   
  index.ts         |     100 |      100 |     100 |     100 |                   
  marketplace.ts   |   88.39 |    83.11 |     100 |   88.39 | ...08,494,507-508 
  ...ork-policy.ts |   89.72 |       90 |     100 |   89.72 | ...36,148-154,156 
  npm.ts           |   89.02 |    81.81 |     100 |   89.02 | ...86-688,695-700 
  override.ts      |   94.11 |    93.33 |     100 |   94.11 | 63-64,81-82       
  redaction.ts     |     100 |      100 |     100 |     100 |                   
  settings.ts      |   66.26 |      100 |      50 |   66.26 | 81-107,141-146    
  ...ceRegistry.ts |   94.01 |    83.14 |     100 |   94.01 | ...38-344,365-366 
  storage.ts       |     100 |      100 |     100 |     100 |                   
  ...ableSchema.ts |     100 |      100 |     100 |     100 |                   
  variables.ts     |   88.95 |    83.78 |     100 |   88.95 | ...32-235,238-241 
  ...extraction.ts |   85.77 |    80.61 |   89.47 |   85.77 | ...02-205,260-261 
 src/followup      |   77.38 |    79.84 |    90.9 |   77.38 |                   
  followupState.ts |   98.44 |    95.74 |     100 |   98.44 | 236-237           
  index.ts         |     100 |      100 |     100 |     100 |                   
  overlayFs.ts     |   96.29 |    88.88 |     100 |   96.29 | 78,108,122        
  speculation.ts   |   65.26 |    62.63 |   71.42 |   65.26 | ...17-618,625-626 
  ...onToolGate.ts |     100 |    96.55 |     100 |     100 | 97                
  ...nGenerator.ts |   72.03 |    81.15 |   83.33 |   72.03 | ...68-219,331-333 
 src/generated     |       0 |        0 |       0 |       0 |                   
  git-commit.ts    |       0 |        0 |       0 |       0 | 1-10              
 src/goals         |      95 |    88.94 |   95.83 |      95 |                   
  ...eGoalStore.ts |   87.61 |    88.88 |   86.66 |   87.61 | ...85-188,196-204 
  goalHook.ts      |   96.91 |    92.42 |     100 |   96.91 | 115-120,221-222   
  goalJudge.ts     |   95.84 |    87.09 |     100 |   95.84 | ...55-356,448-449 
  index.ts         |     100 |      100 |     100 |     100 |                   
 src/hooks         |   87.41 |    85.72 |   88.38 |   87.41 |                   
  ...okRegistry.ts |   86.48 |    77.08 |     100 |   86.48 | ...41-344,362-369 
  ...bortSignal.ts |     100 |      100 |     100 |     100 |                   
  context-usage.ts |     100 |      100 |     100 |     100 |                   
  ...terpolator.ts |   96.66 |    93.33 |     100 |   96.66 | 66-67             
  ...HookRunner.ts |   96.68 |    87.23 |     100 |   96.68 | 110-112,231-233   
  ...Aggregator.ts |   96.57 |    91.48 |     100 |   96.57 | ...20-321,402,404 
  ...entHandler.ts |   95.43 |     83.5 |   94.59 |   95.43 | ...1010-1011,1021 
  hookPlanner.ts   |    87.5 |    85.36 |   86.66 |    87.5 | ...21-225,232-243 
  hookRegistry.ts  |   92.53 |    85.43 |     100 |   92.53 | ...39,458,462,466 
  hookRunner.ts    |   62.42 |    72.04 |   66.66 |   62.42 | ...64-765,774-775 
  hookSystem.ts    |    87.5 |      100 |   70.21 |    87.5 | ...43-744,750-751 
  ...HookRunner.ts |   75.51 |     61.9 |      80 |   75.51 | ...05-406,424-425 
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...edCallback.ts |     100 |      100 |     100 |     100 |                   
  ...HookRunner.ts |   94.19 |    84.37 |   81.81 |   94.19 | ...76-384,458-459 
  ...SkillHooks.ts |   78.75 |       75 |   66.66 |   78.75 | 62-66,137-152     
  ...oksManager.ts |   94.87 |    88.88 |     100 |   94.87 | ...84,325,327-329 
  ssrfGuard.ts     |   77.22 |    85.36 |     100 |   77.22 | ...57,261-267,273 
  stopHookCap.ts   |     100 |      100 |     100 |     100 |                   
  trustedHooks.ts  |      90 |    52.63 |     100 |      90 | ...53,66-67,97-98 
  types.ts         |   94.24 |    96.09 |   88.88 |   94.24 | ...42-543,628-632 
  urlValidator.ts  |     100 |      100 |     100 |     100 |                   
 src/ide           |   76.98 |    85.03 |   79.03 |   76.98 |                   
  constants.ts     |     100 |      100 |     100 |     100 |                   
  detect-ide.ts    |     100 |      100 |     100 |     100 |                   
  ide-client.ts    |   69.16 |    84.65 |   68.29 |   69.16 | ...1068,1097-1105 
  ide-installer.ts |   89.06 |    79.31 |     100 |   89.06 | ...36,143-147,160 
  ideContext.ts    |     100 |      100 |     100 |     100 |                   
  process-utils.ts |   84.84 |    71.79 |     100 |   84.84 | ...37,151,193-194 
  types.ts         |     100 |      100 |     100 |     100 |                   
 src/lsp           |   58.96 |    70.57 |   66.14 |   58.96 |                   
  ...nfigLoader.ts |   80.55 |       72 |   95.45 |   80.55 | ...02-504,508-514 
  ...ionFactory.ts |   42.81 |    73.07 |      50 |   42.81 | ...76-427,433-450 
  ...Normalizer.ts |   23.09 |    13.72 |   30.43 |   23.09 | ...04-905,909-924 
  ...verManager.ts |   75.73 |     80.1 |   79.66 |   75.73 | ...1346,1352-1382 
  ...eLspClient.ts |   32.78 |       80 |   16.66 |   32.78 | ...89-293,299-300 
  ...LspService.ts |      60 |    73.36 |   78.26 |      60 | ...1575,1635-1645 
  configHash.ts    |     100 |      100 |     100 |     100 |                   
  constants.ts     |     100 |      100 |     100 |     100 |                   
  types.ts         |     100 |      100 |     100 |     100 |                   
 src/mcp           |   82.39 |    77.81 |   78.33 |   82.39 |                   
  configHash.ts    |     100 |      100 |     100 |     100 |                   
  constants.ts     |     100 |      100 |     100 |     100 |                   
  ...h-provider.ts |   86.95 |      100 |   33.33 |   86.95 | ...,93,97,101-102 
  ...h-provider.ts |   79.52 |    58.06 |     100 |   79.52 | ...33-940,947-949 
  ...en-storage.ts |   98.78 |    97.95 |     100 |   98.78 | 106-107           
  oauth-utils.ts   |   73.61 |    85.48 |    92.3 |   73.61 | ...46-366,392-421 
  ...n-provider.ts |   89.83 |       96 |   45.45 |   89.83 | ...43,147,151-152 
 .../token-storage |   82.12 |    88.19 |   89.28 |   82.12 |                   
  ...en-storage.ts |     100 |      100 |     100 |     100 |                   
  ...en-storage.ts |   87.08 |    87.03 |   95.23 |   87.08 | ...00-201,214-215 
  ...en-storage.ts |     100 |      100 |     100 |     100 |                   
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...en-storage.ts |   68.14 |    82.35 |   64.28 |   68.14 | ...81-295,298-314 
  types.ts         |     100 |      100 |     100 |     100 |                   
 src/memory        |   86.88 |    82.63 |   90.06 |   86.88 |                   
  ...y-document.ts |   89.52 |    84.61 |     100 |   89.52 | ...24-325,329-330 
  ...nel-memory.ts |   97.11 |    95.72 |   96.29 |   97.11 | ...85-287,361-362 
  const.ts         |   94.28 |     92.3 |     100 |   94.28 | 66-67             
  dream.ts         |    64.6 |    72.22 |      50 |    64.6 | ...04-109,124-165 
  ...entPlanner.ts |     100 |    81.81 |     100 |     100 | 126,136           
  entries.ts       |   75.59 |    84.84 |   83.33 |   75.59 | ...56-157,172-180 
  extract.ts       |   91.48 |    75.75 |     100 |   91.48 | ...99,118-121,189 
  ...entPlanner.ts |   91.51 |    76.19 |     100 |   91.51 | ...04,113-116,290 
  ...ionPlanner.ts |       0 |        0 |       0 |       0 | 1                 
  forget.ts        |   81.83 |       75 |   83.33 |   81.83 | ...51,474,478-507 
  indexer.ts       |   94.14 |       84 |     100 |   94.14 | ...32-233,334,337 
  ...kill-agent.ts |     100 |      100 |     100 |     100 |                   
  manager.ts       |   78.44 |    82.29 |   77.77 |   78.44 | ...1482,1495-1497 
  ...ent-config.ts |   82.27 |    77.92 |   83.33 |   82.27 | ...66,285,292-298 
  memoryAge.ts     |   90.47 |       80 |     100 |   90.47 | 50-51             
  paths.ts         |   94.73 |    95.94 |     100 |   94.73 | ...35-336,357-358 
  ...ing-skills.ts |     100 |       72 |     100 |     100 | 31-35,73-78,97    
  prompt.ts        |   96.96 |    85.71 |     100 |   96.96 | ...22,225,560-561 
  recall.ts        |   82.06 |       75 |    90.9 |   82.06 | ...59-364,395-406 
  refresh.ts       |   89.85 |    82.92 |     100 |   89.85 | ...54-155,162-163 
  ...ceSelector.ts |    93.1 |    81.81 |     100 |    93.1 | ...25,127-128,136 
  remember.ts      |   98.89 |    89.79 |     100 |   98.89 | 50,70             
  scan.ts          |   93.12 |    77.41 |     100 |   93.12 | ...08-109,154,157 
  ...et-scanner.ts |     100 |      100 |     100 |     100 |                   
  ...entPlanner.ts |   71.68 |    65.51 |   68.75 |   71.68 | ...90-394,397,403 
  status.ts        |   10.52 |      100 |       0 |   10.52 | 41-98             
  store.ts         |   93.33 |    81.25 |     100 |   93.33 | ...,94-95,119-120 
  ...git-status.ts |     100 |     87.5 |     100 |     100 | 30                
  ...cret-guard.ts |     100 |      100 |     100 |     100 |                   
  ...emory-sync.ts |   94.24 |    82.85 |     100 |   94.24 | ...34-236,246-247 
  types.ts         |     100 |      100 |     100 |     100 |                   
  ...ontextFile.ts |   79.38 |    81.03 |   81.81 |   79.38 | ...58-272,286-291 
 src/mocks         |       0 |        0 |       0 |       0 |                   
  msw.ts           |       0 |        0 |       0 |       0 | 1-9               
 src/models        |   92.43 |    88.36 |   91.13 |   92.43 |                   
  constants.ts     |     100 |      100 |     100 |     100 |                   
  ...tor-config.ts |   97.69 |    91.11 |     100 |   97.69 | 150,156,166       
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...nfigErrors.ts |   74.22 |       44 |   84.61 |   74.22 | ...,67-74,106-117 
  ...igResolver.ts |   98.71 |    93.33 |     100 |   98.71 | 166,328,334       
  modelRegistry.ts |     100 |    98.13 |     100 |     100 | 177,259           
  modelsConfig.ts  |   89.23 |    86.49 |   88.09 |   89.23 | ...1393,1422-1423 
  types.ts         |     100 |      100 |     100 |     100 |                   
 src/output        |     100 |      100 |     100 |     100 |                   
  ...-formatter.ts |     100 |      100 |     100 |     100 |                   
  types.ts         |     100 |      100 |     100 |     100 |                   
 src/permissions   |   83.54 |       91 |   70.71 |   83.54 |                   
  autoMode.ts      |   97.64 |    93.13 |     100 |   97.64 | ...78-585,631,708 
  ...transcript.ts |      98 |    84.61 |     100 |      98 | 200-201           
  classifier.ts    |      94 |    94.54 |     100 |      94 | 158-165,389-393   
  ...erousRules.ts |     100 |    89.36 |     100 |     100 | 110,133,147,175   
  ...alTracking.ts |     100 |      100 |     100 |     100 |                   
  ...e-commands.ts |   86.77 |     73.8 |     100 |   86.77 | 131-141,210-214   
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...on-manager.ts |   86.53 |    89.57 |      80 |   86.53 | ...1095,1201-1205 
  rule-parser.ts   |   94.14 |    91.89 |     100 |   94.14 | ...1335,1369-1371 
  ...-semantics.ts |   70.36 |    91.02 |   46.66 |   70.36 | ...2237,2300-2303 
  types.ts         |     100 |      100 |     100 |     100 |                   
 ...sifier-prompts |   99.04 |    95.23 |     100 |   99.04 |                   
  system-prompt.ts |   99.04 |    95.23 |     100 |   99.04 | 220               
 src/prompts       |   83.63 |      100 |    87.5 |   83.63 |                   
  mcp-prompts.ts   |   18.18 |      100 |       0 |   18.18 | 11-19             
  ...t-registry.ts |     100 |      100 |     100 |     100 |                   
 src/providers     |   83.68 |    78.87 |   81.25 |   83.68 |                   
  all-providers.ts |     100 |      100 |     100 |     100 |                   
  index.ts         |     100 |      100 |     100 |     100 |                   
  install.ts       |   93.11 |     84.5 |     100 |   93.11 | ...56-257,330-331 
  ...der-config.ts |   75.78 |    74.41 |   78.26 |   75.78 | ...72-473,501-502 
  types.ts         |       0 |        0 |       0 |       0 | 1                 
 ...viders/presets |   97.82 |    91.66 |   63.63 |   97.82 |                   
  ...oding-plan.ts |   87.34 |      100 |       0 |   87.34 | 82-84,87-89,91-94 
  ...a-standard.ts |     100 |      100 |     100 |     100 |                   
  ...token-plan.ts |     100 |      100 |     100 |     100 |                   
  ...m-provider.ts |   97.05 |    81.25 |      75 |   97.05 | 118-119           
  deepseek.ts      |     100 |      100 |     100 |     100 |                   
  grok.ts          |     100 |      100 |     100 |     100 |                   
  idealab.ts       |     100 |      100 |     100 |     100 |                   
  minimax.ts       |     100 |      100 |     100 |     100 |                   
  modelscope.ts    |     100 |      100 |     100 |     100 |                   
  openrouter.ts    |     100 |      100 |     100 |     100 |                   
  requesty.ts      |     100 |      100 |     100 |     100 |                   
  zai.ts           |     100 |      100 |     100 |     100 |                   
 src/qwen          |    85.3 |    78.57 |   95.89 |    85.3 |                   
  ...tGenerator.ts |   98.64 |    98.18 |     100 |   98.64 | 105-106           
  qwenOAuth2.ts    |   82.55 |    73.24 |   90.62 |   82.55 | ...1183-1199,1229 
  ...kenManager.ts |   85.36 |    76.61 |     100 |   85.36 | ...52-757,778-783 
 src/resources     |     100 |      100 |     100 |     100 |                   
  ...e-registry.ts |     100 |      100 |     100 |     100 |                   
 src/services      |   89.52 |    84.99 |   96.29 |   89.52 |                   
  ...ionTrailer.ts |     100 |      100 |     100 |     100 |                   
  ...llRegistry.ts |   97.35 |    85.34 |     100 |   97.35 | ...94,117,417-418 
  ...ionService.ts |   96.71 |    95.79 |     100 |   96.71 | ...83,699,832-840 
  ...ingService.ts |   87.48 |    81.45 |   89.83 |   87.48 | ...1840,1867-1868 
  ...ttribution.ts |   91.73 |    87.71 |      90 |   91.73 | ...80-685,826-827 
  ...utSlimming.ts |    97.2 |       94 |     100 |    97.2 | ...39-340,378-381 
  cronScheduler.ts |   94.29 |    91.06 |   97.91 |   94.29 | ...1274,1673-1674 
  cronTasksFile.ts |   95.71 |    91.01 |     100 |   95.71 | ...93,318-319,437 
  cronTasksLock.ts |   94.44 |    89.47 |     100 |   94.44 | ...02-103,132-133 
  ...eryService.ts |   96.22 |    93.54 |      90 |   96.22 | 121,155-156,161   
  ...oryService.ts |   88.17 |    79.02 |    92.3 |   88.17 | ...1303,1344-1347 
  fileReadCache.ts |     100 |      100 |     100 |     100 |                   
  ...temService.ts |   92.07 |    85.93 |    90.9 |   92.07 | ...09,211,323-330 
  ...ratedFiles.ts |      96 |    88.23 |     100 |      96 | 119-120,146-147   
  gitInit.ts       |     100 |      100 |     100 |     100 |                   
  ...reeService.ts |   74.05 |       69 |   95.74 |   74.05 | ...2170,2198-2199 
  ...references.ts |   98.39 |    88.76 |     100 |   98.39 | 154-155,215-216   
  ...ionService.ts |   98.22 |    97.32 |     100 |   98.22 | ...63-664,711-712 
  ...ticsDumper.ts |   98.37 |    95.23 |     100 |   98.37 | 185-186           
  ...ureMonitor.ts |   95.82 |    90.52 |   97.05 |   95.82 | ...60,861,875-877 
  ...orRegistry.ts |   97.27 |    91.22 |     100 |   97.27 | ...50-451,606-607 
  ...ttachments.ts |   97.74 |     90.8 |     100 |   97.74 | 298-308,646       
  ...ersistence.ts |   90.95 |    78.75 |     100 |   90.95 | ...78,963-964,992 
  ...on-service.ts |   94.49 |    92.26 |   97.14 |   94.49 | ...98-600,656-664 
  ...ipt-reader.ts |   94.49 |    89.16 |   97.95 |   94.49 | ...1038,1049-1050 
  ...est-helper.ts |       0 |        0 |       0 |       0 | 1-65              
  ...iter-lease.ts |   76.81 |    73.71 |    92.1 |   76.81 | ...15-816,820-827 
  sessionRecap.ts  |   67.56 |    43.47 |     100 |   67.56 | ...60,178,180-183 
  ...ionService.ts |   88.73 |     83.5 |    97.1 |   88.73 | ...2401,2471-2491 
  sessionTitle.ts  |   94.19 |    73.21 |     100 |   94.19 | ...43-246,277-278 
  ...ionService.ts |   84.21 |    78.16 |   97.14 |   84.21 | ...2452,2458-2463 
  ...pInhibitor.ts |   97.42 |    92.68 |     100 |   97.42 | ...30,169,369-370 
  ...Estimation.ts |     100 |    86.66 |     100 |     100 | 96-97             
  ...ageService.ts |   97.76 |    91.59 |   93.75 |   97.76 | ...61-262,366,567 
  ...UseSummary.ts |   94.63 |    88.46 |     100 |   94.63 | ...62-164,214-215 
  ...rd-service.ts |     100 |    88.37 |     100 |     100 | ...29,145-146,241 
  ...oryService.ts |   90.72 |    84.07 |     100 |   90.72 | ...06-509,561-562 
  ...reeCleanup.ts |   14.56 |      100 |   33.33 |   14.56 | 58-185            
  ...ionService.ts |   87.98 |    86.95 |     100 |   87.98 | ...38-439,455-456 
 ...icrocompaction |   99.41 |    96.03 |     100 |   99.41 |                   
  microcompact.ts  |   99.41 |    96.03 |     100 |   99.41 | 244-245,677       
 ...s/visionBridge |    98.6 |    94.08 |     100 |    98.6 |                   
  ...capability.ts |     100 |      100 |     100 |     100 |                   
  ...part-utils.ts |     100 |      100 |     100 |     100 |                   
  ...-constants.ts |     100 |      100 |     100 |     100 |                   
  ...ge-service.ts |   98.31 |    92.59 |     100 |   98.31 | ...21,645,658-659 
 src/skills        |   88.37 |    87.22 |   90.16 |   88.37 |                   
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...activation.ts |     100 |    93.33 |     100 |     100 | 93,112            
  skill-load.ts    |   94.84 |     87.5 |     100 |   94.84 | ...03,223,235-237 
  skill-manager.ts |   83.78 |    82.63 |   82.35 |   83.78 | ...1218,1225-1229 
  skill-paths.ts   |   89.65 |    86.95 |     100 |   89.65 | ...11-112,117-118 
  symlinkScope.ts  |     100 |      100 |     100 |     100 |                   
  types.ts         |   97.91 |       98 |     100 |   97.91 | 277-278           
 ...ataviz/scripts |   80.06 |    95.23 |   88.23 |   80.06 |                   
  ...te_palette.js |   80.06 |    95.23 |   88.23 |   80.06 | 261-296,306-328   
 ...s/bundled/loop |   97.48 |    95.77 |     100 |   97.48 |                   
  ...omous-loop.ts |     100 |      100 |     100 |     100 |                   
  ...-task-file.ts |   94.85 |     92.4 |     100 |   94.85 | ...56,367,375-376 
  ...k-resolver.ts |     100 |      100 |     100 |     100 |                   
 src/subagents     |   87.28 |    88.63 |   96.42 |   87.28 |                   
  ...ter-schema.ts |     100 |    98.07 |     100 |     100 | 99                
  ...tin-agents.ts |     100 |      100 |     100 |     100 |                   
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...nt-manager.ts |   83.55 |    85.01 |   94.59 |   83.55 | ...1501,1578-1579 
  types.ts         |     100 |      100 |     100 |     100 |                   
  validation.ts    |   92.46 |    95.18 |     100 |   92.46 | 47-52,63-68,71-76 
 src/telemetry     |   81.28 |    88.39 |   83.17 |   81.28 |                   
  ...ty-tracker.ts |     100 |      100 |     100 |     100 |                   
  config.ts        |     100 |      100 |     100 |     100 |                   
  constants.ts     |     100 |      100 |     100 |     100 |                   
  ...on-metrics.ts |   99.07 |    80.95 |     100 |   99.07 | 183,197           
  ...on-tracing.ts |   76.31 |    74.62 |   73.68 |   76.31 | ...80,387-389,405 
  ...attributes.ts |   97.47 |    93.15 |     100 |   97.47 | 39-44             
  ...ag-metrics.ts |     100 |    77.77 |     100 |     100 | 21,40             
  ...t-loop-lag.ts |     100 |    90.47 |     100 |     100 | 49,76             
  ...-exporters.ts |   65.78 |    83.33 |   55.55 |   65.78 | ...04-105,108-109 
  ...i-provider.ts |     100 |       99 |     100 |     100 | 99                
  gen-ai-usage.ts  |     100 |      100 |     100 |     100 |                   
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...t.circular.ts |       0 |        0 |       0 |       0 | 1-111             
  ...-processor.ts |   99.09 |    95.61 |      95 |   99.09 | 141,365-366       
  ...t.circular.ts |       0 |        0 |       0 |       0 | 1-128             
  loggers.ts       |   55.35 |    71.56 |   63.46 |   55.35 | ...1350,1367-1387 
  metrics.ts       |   78.44 |    79.62 |   79.66 |   78.44 | ...1079,1082-1093 
  otlp-urls.ts     |     100 |      100 |     100 |     100 |                   
  ...attributes.ts |     100 |      100 |     100 |     100 |                   
  ...ime-config.ts |       0 |        0 |       0 |       0 | 1                 
  sanitize.ts      |      80 |    83.33 |     100 |      80 | 35-36,41-42       
  ...rters-grpc.ts |     100 |      100 |     100 |     100 |                   
  ...rters-http.ts |     100 |      100 |     100 |     100 |                   
  sdk-impl.ts      |   91.06 |    87.15 |   68.75 |   91.06 | ...32,478-479,495 
  sdk.ts           |   79.22 |    89.18 |   63.63 |   79.22 | ...57-161,199-221 
  ...on-context.ts |     100 |      100 |     100 |     100 |                   
  ...on-tracing.ts |    90.3 |    89.15 |   96.66 |    90.3 | ...1602,1633-1636 
  ...etry-utils.ts |     100 |      100 |     100 |     100 |                   
  ...l-decision.ts |     100 |      100 |     100 |     100 |                   
  trace-context.ts |     100 |      100 |     100 |     100 |                   
  ...e-id-utils.ts |     100 |      100 |     100 |     100 |                   
  tracer.ts        |   98.56 |    88.63 |     100 |   98.56 | 52,101            
  types.ts         |      82 |    86.95 |   85.71 |      82 | ...1328,1332-1339 
  uiTelemetry.ts   |   93.07 |    92.59 |   83.33 |   93.07 | ...62,290,410-411 
 ...ry/qwen-logger |   73.62 |    81.08 |   69.49 |   73.62 |                   
  event-types.ts   |       0 |        0 |       0 |       0 |                   
  qwen-logger.ts   |   73.62 |     80.9 |   68.96 |   73.62 | ...1095,1133-1134 
 src/test-utils    |      94 |    98.24 |   78.94 |      94 |                   
  config.ts        |     100 |      100 |     100 |     100 |                   
  ...st-helpers.ts |   94.11 |       90 |     100 |   94.11 | 69-70             
  index.ts         |     100 |      100 |     100 |     100 |                   
  mock-tool.ts     |   92.57 |      100 |   75.75 |   92.57 | ...63,227-228,241 
  ...aceContext.ts |     100 |      100 |     100 |     100 |                   
 src/tools         |   85.42 |    84.36 |   87.97 |   85.42 |                   
  ...erQuestion.ts |   89.71 |    80.76 |   91.66 |   89.71 | ...66-367,374-375 
  ...-registrar.ts |    77.7 |    66.66 |   66.66 |    77.7 | ...72-277,292-294 
  ...ub-session.ts |   89.67 |     91.3 |   81.81 |   89.67 | ...03-304,315-322 
  cron-create.ts   |   90.64 |    92.85 |   72.72 |   90.64 | ...,73-74,223-231 
  cron-delete.ts   |   97.56 |      100 |   83.33 |   97.56 | 31-32             
  cron-list.ts     |   98.23 |    95.34 |    87.5 |   98.23 | 57-58             
  diffOptions.ts   |     100 |      100 |     100 |     100 |                   
  edit.ts          |    82.7 |    86.77 |   81.25 |    82.7 | ...43-744,863-913 
  ...r-worktree.ts |   83.14 |    67.56 |    87.5 |   83.14 | ...84-187,278-279 
  enterPlanMode.ts |      85 |     82.6 |    87.5 |      85 | ...28-133,161-175 
  exit-worktree.ts |   83.29 |    83.65 |   94.44 |   83.29 | ...14-515,537-538 
  exitPlanMode.ts  |   94.04 |    82.53 |     100 |   94.04 | ...92,311,342-344 
  glob.ts          |   96.33 |     88.5 |     100 |   96.33 | ...24-225,373,376 
  grep.ts          |   83.21 |    86.66 |   80.95 |   83.21 | ...65-666,716-717 
  ...adTracking.ts |     100 |      100 |     100 |     100 |                   
  list-agents.ts   |   94.02 |    82.35 |   83.33 |   94.02 | 31-32,47-48       
  loop-wakeup.ts   |   99.24 |    92.85 |     100 |   99.24 | 44                
  ls.ts            |   96.74 |    90.27 |     100 |   96.74 | 176-181,212,216   
  lsp.ts           |   72.71 |     59.5 |   90.32 |   72.71 | ...1212,1214-1215 
  ...nt-manager.ts |   81.63 |       79 |   85.41 |   81.63 | ...3221,3223-3224 
  mcp-client.ts    |   79.58 |    84.81 |   88.88 |   79.58 | ...2186,2190-2193 
  ...ry-timeout.ts |     100 |      100 |     100 |     100 |                   
  mcp-errors.ts    |     100 |      100 |     100 |     100 |                   
  ...pool-entry.ts |   77.56 |    84.11 |   77.14 |   77.56 | ...1291,1299-1300 
  ...ool-events.ts |       8 |        0 |       0 |       8 | 132-158           
  mcp-pool-key.ts  |   97.46 |    93.93 |     100 |   97.46 | 175-176           
  ...ce-content.ts |   96.55 |    91.17 |     100 |   96.55 | 80-82             
  mcp-retry.ts     |   97.67 |    95.65 |     100 |   97.67 | 131-132           
  mcp-status.ts    |     100 |      100 |     100 |     100 |                   
  mcp-tool.ts      |   95.43 |    93.89 |     100 |   95.43 | ...79-780,830-831 
  ...sport-pool.ts |   83.49 |    80.15 |   84.61 |   83.49 | ...1409,1416-1420 
  ...ace-budget.ts |   87.27 |     82.6 |     100 |   87.27 | ...00-305,340-345 
  memory-config.ts |     100 |      100 |     100 |     100 |                   
  ...iable-tool.ts |     100 |    84.61 |     100 |     100 | 101,108           
  monitor.ts       |   91.74 |    84.28 |   88.46 |   91.74 | ...93,606,804-809 
  notebook-edit.ts |   85.55 |    77.39 |   81.25 |   85.55 | ...86-902,948-949 
  ...escendants.ts |   36.17 |    64.51 |   55.55 |   36.17 | ...46-310,385-390 
  ...nforcement.ts |   82.57 |    89.74 |     100 |   82.57 | 174-185,234-247   
  read-file.ts     |   95.64 |    88.88 |   86.66 |   95.64 | ...74,489,561-562 
  ...p-resource.ts |   96.85 |      100 |   91.66 |   96.85 | 92-96             
  ...d-artifact.ts |    90.9 |    86.71 |    87.5 |    90.9 | ...13-414,428-440 
  ripGrep.ts       |    95.9 |     88.4 |   94.73 |    95.9 | ...61-662,668-669 
  ...-transport.ts |   71.42 |    55.55 |   71.42 |   71.42 | ...36-137,143-144 
  send-message.ts  |    81.2 |    89.74 |    62.5 |    81.2 | ...80-286,369-377 
  ...n-mcp-view.ts |   93.57 |     92.3 |      90 |   93.57 | 122-130           
  shell.ts         |   78.45 |    83.42 |   91.75 |   78.45 | ...4960,5023-5024 
  skill-utils.ts   |     100 |      100 |     100 |     100 |                   
  skill.ts         |   91.06 |    93.33 |   89.47 |   91.06 | ...71,475,520-542 
  ...eticOutput.ts |   95.12 |      100 |      80 |   95.12 | 87-88             
  task-create.ts   |    94.4 |    93.33 |   81.81 |    94.4 | 45-49,63-64,95    
  task-list.ts     |   73.38 |    77.77 |   83.33 |   73.38 | ...02,105,109-116 
  task-stop.ts     |   93.14 |    96.15 |   85.71 |   93.14 | 39-40,54-64       
  task-update.ts   |   82.89 |    83.92 |    92.3 |   82.89 | ...14-422,454-465 
  team-create.ts   |   97.22 |    85.71 |   83.33 |   97.22 | 48-49,129-130     
  team-delete.ts   |   86.74 |    83.33 |   83.33 |   86.74 | 37-38,42-48,72-73 
  ...n-approval.ts |   92.14 |    96.77 |   77.77 |   92.14 | 38-39,42-43,93-99 
  todoWrite.ts     |   93.92 |    83.13 |   92.85 |   93.92 | ...86-391,413-414 
  tool-error.ts    |     100 |      100 |     100 |     100 |                   
  tool-names.ts    |     100 |      100 |     100 |     100 |                   
  tool-registry.ts |   77.13 |    76.47 |   82.22 |   77.13 | ...23-924,932-933 
  tool-search.ts   |   96.19 |    89.72 |   93.33 |   96.19 | ...09,259-264,426 
  tools.ts         |   92.74 |    91.52 |    91.3 |   92.74 | ...63-564,580-586 
  ...reapproved.ts |   99.27 |    94.11 |     100 |   99.27 | 170               
  web-fetch.ts     |   96.05 |    90.54 |   96.77 |   96.05 | ...85-786,800-801 
  web-search.ts    |   90.53 |    83.57 |      80 |   90.53 | ...1007,1065-1068 
  write-file.ts    |   85.66 |    85.04 |   85.71 |   85.66 | ...53-756,793-828 
 src/tools/agent   |   85.04 |    85.02 |   86.66 |   85.04 |                   
  agent.ts         |   84.87 |    84.77 |   86.17 |   84.87 | ...4082,4104-4114 
  fork-subagent.ts |   88.32 |       90 |    90.9 |   88.32 | ...05-123,200-201 
 ...tools/artifact |   95.78 |    92.51 |   88.63 |   95.78 |                   
  artifact-tool.ts |   91.46 |    88.46 |   71.42 |   91.46 | ...13-314,322-325 
  ...-publisher.ts |     100 |    85.71 |     100 |     100 | 32                
  ...-publisher.ts |   96.74 |    97.72 |    87.5 |   96.74 | 29-30,156-157     
  html.ts          |     100 |    96.77 |     100 |     100 | 122               
  ...-publisher.ts |     100 |       80 |     100 |     100 | 30                
  oss-publisher.ts |    98.1 |    91.48 |     100 |    98.1 | 43-45             
  publisher.ts     |     100 |      100 |     100 |     100 |                   
 ...s/computer-use |   90.21 |    82.17 |   78.08 |   90.21 |                   
  bootstrap.ts     |   59.42 |    80.95 |   41.66 |   59.42 | ...35-339,341-345 
  client.ts        |   80.11 |       90 |   77.77 |   80.11 | ...97,242-243,274 
  constants.ts     |     100 |    94.73 |     100 |     100 | 129,256           
  downloader.ts    |   65.29 |    52.77 |   58.33 |   65.29 | ...99-300,316-355 
  index.ts         |     100 |      100 |     100 |     100 |                   
  install-state.ts |   94.44 |    72.72 |     100 |   94.44 | 44-45             
  ...n-detector.ts |     100 |     87.5 |     100 |     100 | 50                
  schemas.ts       |     100 |      100 |     100 |     100 |                   
  tool.ts          |    96.3 |    85.71 |     100 |    96.3 | 75-76,184,252-258 
 ...tools/workflow |   87.46 |    79.41 |   85.71 |   87.46 |                   
  workflow.ts      |   87.46 |    79.41 |   85.71 |   87.46 | ...51-652,664-667 
 src/utils         |   92.53 |    89.69 |   96.58 |   92.53 |                   
  LruCache.ts      |     100 |      100 |     100 |     100 |                   
  ...Controller.ts |     100 |      100 |     100 |     100 |                   
  ...ssageQueue.ts |     100 |      100 |     100 |     100 |                   
  ...cFileWrite.ts |   94.76 |     93.3 |     100 |   94.76 | ...30-531,634-638 
  bareMode.ts      |   81.81 |      100 |      50 |   81.81 | 18-19             
  ...ry-content.ts |   98.45 |    95.45 |     100 |   98.45 | 132-133,159-160   
  browser.ts       |   86.84 |    78.94 |     100 |   86.84 | 34,36-37,65-66    
  btwUtils.ts      |   13.95 |      100 |       0 |   13.95 | 17-31,34-55       
  bundlePaths.ts   |     100 |      100 |     100 |     100 |                   
  ...on-context.ts |     100 |      100 |     100 |     100 |                   
  ...ncyLimiter.ts |   94.64 |    95.23 |     100 |   94.64 | 64-66             
  ...igResolver.ts |     100 |      100 |     100 |     100 |                   
  ...engthError.ts |   91.11 |    89.47 |     100 |   91.11 | ...46-147,154-155 
  ...n-branches.ts |   95.81 |    93.95 |      95 |   95.81 | ...91-492,504-517 
  ...tion-chain.ts |     100 |      100 |     100 |     100 |                   
  cronDisplay.ts   |     100 |    91.66 |     100 |     100 | 15,43,57          
  cronParser.ts    |   95.34 |    93.33 |     100 |   95.34 | 41-42,47-48,70-71 
  debugLogger.ts   |   96.66 |    96.61 |   88.88 |   96.66 | 192-196           
  editHelper.ts    |   93.63 |     83.9 |     100 |   93.63 | ...27-428,462-463 
  editor.ts        |   97.65 |    95.45 |     100 |   97.65 | ...35-336,338-339 
  env.ts           |     100 |      100 |     100 |     100 |                   
  ...arResolver.ts |   94.28 |    88.88 |     100 |   94.28 | 28-29,125-126     
  ...entContext.ts |   96.63 |    90.06 |   96.66 |   96.63 | ...42,444-445,512 
  errorParsing.ts  |     100 |      100 |     100 |     100 |                   
  ...rReporting.ts |   95.65 |    93.33 |     100 |   95.65 | 37-38             
  errors.ts        |   82.23 |    92.85 |    61.9 |   82.23 | ...56-372,376-382 
  fetch.ts         |   90.68 |    82.51 |     100 |   90.68 | ...72,483-484,503 
  fileUtils.ts     |   95.33 |       92 |   96.15 |   95.33 | ...1747,1772-1773 
  forkedAgent.ts   |   92.45 |    82.35 |   93.75 |   92.45 | ...34,642,647-654 
  formatters.ts    |   81.81 |       75 |     100 |   81.81 | 15-16             
  ...eUtilities.ts |    92.4 |    86.95 |     100 |    92.4 | ...52-158,168-169 
  ...rStructure.ts |   94.36 |    94.28 |     100 |   94.36 | ...17-120,331-336 
  getPty.ts        |   31.57 |       50 |     100 |   31.57 | 26-38             
  gitDiff.ts       |   95.12 |    81.03 |     100 |   95.12 | ...1073,1390-1391 
  gitDirect.ts     |   98.46 |    90.17 |     100 |   98.46 | 148,268,352       
  ...noreParser.ts |   94.59 |    92.59 |     100 |   94.59 | ...05-106,140-141 
  gitUtils.ts      |      75 |    88.88 |   83.33 |      75 | ...,78-79,103-154 
  iconvHelper.ts   |     100 |      100 |     100 |     100 |                   
  ...rePatterns.ts |     100 |      100 |     100 |     100 |                   
  ...ionManager.ts |     100 |     90.9 |     100 |     100 | 27                
  ...lPromptIds.ts |     100 |      100 |     100 |     100 |                   
  ...on-context.ts |     100 |      100 |     100 |     100 |                   
  jsonl-utils.ts   |   95.27 |     93.1 |     100 |   95.27 | ...16-317,356-359 
  ...-detection.ts |     100 |      100 |     100 |     100 |                   
  ...iagnostics.ts |    96.4 |     94.2 |     100 |    96.4 | ...66,293-294,376 
  ...yDiscovery.ts |    92.4 |    89.01 |     100 |    92.4 | ...28,331,522-525 
  ...tProcessor.ts |   93.77 |    89.15 |     100 |   93.77 | ...13-319,406-407 
  ...Inspectors.ts |     100 |      100 |     100 |     100 |                   
  modelId.ts       |   98.96 |    98.21 |     100 |   98.96 | 153               
  ...kerChecker.ts |    90.9 |    91.66 |     100 |    90.9 | 73-79             
  notebook.ts      |   94.57 |    89.91 |   95.83 |   94.57 | ...21,333,385-387 
  openaiLogger.ts  |   91.66 |    89.74 |     100 |   91.66 | ...26-228,251-256 
  partUtils.ts     |     100 |    98.61 |     100 |     100 | 206               
  pathReader.ts    |   97.77 |       90 |     100 |   97.77 | 93,121            
  paths.ts         |   93.95 |    92.79 |     100 |   93.95 | ...78-479,481-483 
  pdf.ts           |   92.17 |    85.81 |     100 |   92.17 | ...64-565,606-611 
  projectPath.ts   |     100 |      100 |     100 |     100 |                   
  projectRoot.ts   |   71.73 |    78.57 |     100 |   71.73 | 54-66             
  ...ectSummary.ts |   89.62 |    72.41 |     100 |   89.62 | ...40-145,196-199 
  ...tIdContext.ts |     100 |      100 |     100 |     100 |                   
  proxyUtils.ts    |     100 |      100 |     100 |     100 |                   
  ...rDetection.ts |   59.15 |    76.92 |     100 |   59.15 | ...5,89-90,96-101 
  ...noreParser.ts |   92.63 |    91.37 |     100 |   92.63 | ...72-173,192-193 
  rateLimit.ts     |   93.75 |    89.62 |     100 |   93.75 | ...13,218-219,262 
  ...text-range.ts |   97.73 |    93.24 |     100 |   97.73 | 85-86,107,262-263 
  readManyFiles.ts |   96.29 |     87.5 |     100 |   96.29 | 225,275,286-290   
  retry.ts         |   95.93 |    92.23 |     100 |   95.93 | ...33,524-525,543 
  retryContext.ts  |     100 |      100 |     100 |     100 |                   
  ...sification.ts |   97.65 |    96.96 |     100 |   97.65 | ...00,250-251,277 
  retryPolicy.ts   |   97.72 |    90.56 |     100 |   97.72 | 130-131           
  ripgrepUtils.ts  |   50.94 |    85.71 |      70 |   50.94 | ...54-255,268-346 
  ...sDiscovery.ts |   97.46 |    93.05 |     100 |   97.46 | ...04,182-183,202 
  ...iagnostics.ts |   83.08 |     67.5 |   92.59 |   83.08 | ...23,543-544,550 
  ...tchOptions.ts |   83.59 |    86.25 |      96 |   83.59 | ...08,633,662-671 
  ...odelPrefix.ts |     100 |      100 |     100 |     100 |                   
  runtimeStatus.ts |    97.5 |       90 |     100 |    97.5 | 162-163           
  safe-mode.ts     |     100 |      100 |     100 |     100 |                   
  safeJsonParse.ts |     100 |      100 |     100 |     100 |                   
  ...nStringify.ts |     100 |      100 |     100 |     100 |                   
  ...-child-env.ts |     100 |      100 |     100 |     100 |                   
  ...aConverter.ts |   94.77 |     94.2 |     100 |   94.77 | ...41-42,96,98-99 
  ...aValidator.ts |   92.09 |    83.65 |   90.47 |   92.09 | ...60,882-883,896 
  ...r-launcher.ts |   96.35 |    93.97 |   85.71 |   96.35 | ...35-336,347-348 
  sedEditParser.ts |   91.72 |    92.12 |     100 |   91.72 | ...36-539,615-616 
  ...nIdContext.ts |     100 |      100 |     100 |     100 |                   
  ...orageUtils.ts |   95.98 |     83.8 |     100 |   95.98 | ...70,386,466,485 
  ...-pager-env.ts |     100 |      100 |     100 |     100 |                   
  ...fety-rules.ts |     100 |     89.7 |     100 |     100 | ...01,304,309-311 
  shell-utils.ts   |   86.05 |    88.56 |     100 |   86.05 | ...2246,2253-2257 
  ...lAstParser.ts |   98.16 |    91.91 |     100 |   98.16 | ...1244-1246,1256 
  ...ContextEnv.ts |     100 |    90.47 |     100 |     100 | 46-48             
  ...nlyChecker.ts |   96.33 |    96.57 |     100 |   96.33 | ...83-284,292-293 
  sideQuery.ts     |   86.82 |    86.66 |     100 |   86.82 | ...79-185,187-193 
  ...pEventSink.ts |     100 |       80 |     100 |     100 | 61                
  ...tGenerator.ts |     100 |      100 |     100 |     100 |                   
  ...ameContext.ts |     100 |      100 |     100 |     100 |                   
  symlink.ts       |   77.77 |       50 |     100 |   77.77 | 44,54-59          
  ...emEncoding.ts |   96.36 |    91.17 |     100 |   96.36 | 59-60,124-125     
  terminalSafe.ts  |     100 |      100 |     100 |     100 |                   
  ...Serializer.ts |   98.72 |       90 |     100 |   98.72 | 42-43,134,201-203 
  testUtils.ts     |   53.33 |      100 |   33.33 |   53.33 | ...53,59-64,70-72 
  ...-constants.ts |     100 |      100 |     100 |     100 |                   
  textUtils.ts     |      65 |      100 |      75 |      65 | 56-75             
  thoughtUtils.ts  |     100 |    95.65 |     100 |     100 | 99                
  ...-converter.ts |   95.23 |    85.71 |     100 |   95.23 | 36-37             
  ...name-utils.ts |     100 |      100 |     100 |     100 |                   
  ...-finalizer.ts |   97.66 |    90.82 |     100 |   97.66 | 165-166,168-172   
  tool-utils.ts    |    95.2 |    93.61 |     100 |    95.2 | ...58-159,162-163 
  ...ultCleanup.ts |   54.62 |    30.76 |      75 |   54.62 | ...03-105,108-134 
  ...Compaction.ts |   96.11 |    96.33 |     100 |   96.11 | ...22-327,329-334 
  ...pt-records.ts |   85.78 |    83.63 |     100 |   85.78 | ...84-388,418-433 
  truncation.ts    |   90.44 |    88.99 |     100 |   90.44 | ...18-426,463-469 
  windowsPath.ts   |   89.47 |    79.31 |     100 |   89.47 | ...57-58,62,90-91 
  ...aceContext.ts |   95.81 |    89.39 |     100 |   95.81 | ...74-275,299-301 
  xml.ts           |    97.8 |    87.69 |     100 |    97.8 | 98-99             
  yaml-parser.ts   |   83.87 |    77.27 |     100 |   83.87 | ...31-234,239-240 
 ...ils/filesearch |   83.68 |    80.38 |   94.69 |   83.68 |                   
  crawlCache.ts    |     100 |      100 |     100 |     100 |                   
  crawler.ts       |   82.47 |    76.22 |      95 |   82.47 | ...1525,1559-1560 
  fileSearch.ts    |   93.78 |    87.67 |     100 |   93.78 | ...71-272,274-275 
  fzfWorker.ts     |       0 |        0 |       0 |       0 | 1-109             
  ...rkerHandle.ts |   84.05 |    75.43 |   89.47 |   84.05 | ...30-334,340-341 
  ignore.ts        |     100 |    97.36 |     100 |     100 | 187               
  result-cache.ts  |     100 |    93.75 |     100 |     100 | 49                
 ...uest-tokenizer |   69.76 |    75.47 |   85.29 |   69.76 |                   
  ...eTokenizer.ts |   65.72 |    74.02 |    92.3 |   65.72 | ...65-466,479-533 
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...tTokenizer.ts |   68.39 |    69.49 |    90.9 |   68.39 | ...24-325,327-328 
  ...ageFormats.ts |   76.92 |      100 |   33.33 |   76.92 | 46-49,56-57       
  textTokenizer.ts |     100 |      100 |     100 |     100 |                   
  types.ts         |       0 |        0 |       0 |       0 | 1                 
-------------------|---------|----------|---------|---------|-------------------

For detailed HTML reports, please see the 'coverage-reports-22.x-ubuntu-latest' artifact from the main CI run.

@qwen-code-dev-bot

Copy link
Copy Markdown
Collaborator

🤖 Reviewed the latest feedback — no changes needed. Why, point by point:

No changes made — the only new feedback is an LGTM review from @gwinthis with no actionable items.

The review confirms the design (single safety gate: a failing check must be green on current main) and implementation are sound, and explicitly concludes LGTM. There are no inline comments, no change requests, no failed checks, and no still-red checks to address.

中文说明

未做任何更改——唯一的新反馈是 @gwinthis 的 LGTM 审查,没有需要处理的事项。

该审查确认了设计(单一安全门控:失败的 check 必须在当前 main 上为绿色)和实现均合理,并明确给出 LGTM 结论。没有行内评论、没有变更请求、没有失败的 check、也没有持续红色的 check 需要处理。

Base-conflict check: no conflict with main.


🧠 Handled by Qwen Code · model/模型 qwen3.8-max-preview

@qwen-code-ci-bot qwen-code-ci-bot left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed — no blockers. Suggestions are inline.

— qwen3.7-max via Qwen Code /review

Comment thread .github/workflows/qwen-autofix.yml Outdated
@qwen-code-dev-bot

Copy link
Copy Markdown
Collaborator

🤖 Addressed the latest review feedback (round 1/100). What changed, and what I pushed back on:

Review feedback addressed

[rc:3635373023] || echo '[]' double-output under pipefailimplemented

Finding: Under GitHub Actions' default bash -eo pipefail, when gh api fails in the MAIN_GREEN_CHECKS pipeline, jq still emits [] on stdout, then || echo '[]' appends a second []. The resulting []\n[] is invalid JSON, which would cause the downstream --argjson green to fail and abort the entire scan step under set -e.

Fix: Moved the fallback assignment outside the command substitution:

-              | jq -c -s 'add // []' || echo '[]')"
+              | jq -c -s 'add // []')" || MAIN_GREEN_CHECKS='[]'

Now when the pipeline fails, the command substitution captures only jq's output, and the || MAIN_GREEN_CHECKS='[]' cleanly overwrites the variable with a valid fallback — no double output.

Conflict notes: No conflicts (--conflict false).

Verification

  • npm run build — passed
  • npm run typecheck — passed
  • npm run lint — passed
  • npx vitest run scripts/tests/qwen-autofix-workflow.test.js — 94 passed (94)
中文说明

已处理的评审反馈

[rc:3635373023] || echo '[]'pipefail 下产生双重输出 — 已实现

问题: 在 GitHub Actions 默认的 bash -eo pipefail 下,当 gh apiMAIN_GREEN_CHECKS 管道中失败时,jq 仍会在标准输出中输出 [],然后 || echo '[]' 会追加第二个 []。产生的 []\n[] 是无效的 JSON,会导致下游 --argjson green 失败,并在 set -e 下中止整个扫描步骤。

修复: 将回退赋值移到命令替换之外:

-              | jq -c -s 'add // []' || echo '[]')"
+              | jq -c -s 'add // []')" || MAIN_GREEN_CHECKS='[]'

现在当管道失败时,命令替换仅捕获 jq 的输出,|| MAIN_GREEN_CHECKS='[]' 会干净地用有效的回退值覆盖变量——不会产生双重输出。

冲突说明: 无冲突(--conflict false)。

验证

  • npm run build — 通过
  • npm run typecheck — 通过
  • npm run lint — 通过
  • npx vitest run scripts/tests/qwen-autofix-workflow.test.js — 94 通过(共 94 个)

Base-conflict check: no conflict with main.

Re-review when you have a moment. After round 100 this bot stops and leaves the PR for a human.


🧠 Handled by Qwen Code · model/模型 qwen3.8-max-preview

@qwen-code-ci-bot qwen-code-ci-bot left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed — no blockers. Suggestions are inline.

— qwen3.7-max via Qwen Code /review

Comment thread .github/workflows/qwen-autofix.yml Outdated
Comment thread scripts/tests/qwen-autofix-workflow.test.js
@qwen-code-dev-bot

Copy link
Copy Markdown
Collaborator

🤖 Addressed the latest review feedback (round 2/100). What changed, and what I pushed back on:

Autofix review feedback addressed

Both reviewer suggestions on PR #7554 were implemented. No conflict (--conflict false), so no merge was performed.

Feedback points

1. [rc:3635572375] Missing expected_head_sha compare-and-swap guard on update-branch — IMPLEMENTED

The stale-base path computed STALE_BASE_REDS against the PR head it had just read, but then called update-branch without pinning that head. If the PR author pushed new commits between the compare read and the update-branch call, GitHub would merge main into the new, unverified head. Added -f expected_head_sha="${PR_HEAD_OID}" to the update-branch call so GitHub rejects the update (compare-and-swap) when the head moved, matching the existing pattern in qwen-fleet-shepherd.yml. Also added a short comment explaining the race.

2. [rc:3635572378] Exclusion filter never exercised by the test helpers — IMPLEMENTED

The behavioral test helpers never set workflowName, so the Qwen Autofix exclusion in the STALE_BASE_REDS jq filter was never run at runtime — a logic inversion would have passed all existing cases. Added two cases to the stale-base test:

  • A Qwen Autofix check (not review-address) that fails on the PR and passes on main must NOT trigger update-branch (updated: false, continued: false).
  • A review-address check under the Qwen Autofix workflow IS eligible and still updates (updated: true, continued: true), covering the or branch of the filter.

Changes

  • .github/workflows/qwen-autofix.yml: added expected_head_sha compare-and-swap guard (plus a why-comment) to the stale-base update-branch call.
  • scripts/tests/qwen-autofix-workflow.test.js: added two cases exercising the Qwen Autofix exclusion filter and its review-address exception.

Conflict notes

None — no merge required.

Verification

  • npx vitest run scripts/tests/qwen-autofix-workflow.test.js — 94 passed (includes the modified stale-base test)
  • npx eslint scripts/tests/qwen-autofix-workflow.test.js — passed
  • npx prettier --check (both touched files) — passed (after --write on the test file)
  • npm run lint — passed
  • npm run build — passed
  • npm run typecheck — passed

No settings source changed, so no schema regeneration was needed. The change is workflow YAML plus its colocated unit test, exercised through the Vitest harness rather than the bundled CLI, so no integration run was required.

中文说明

已处理 Autofix 审查反馈

PR #7554 上审查者的两条建议均已实现。无冲突(--conflict false),因此未执行合并。

反馈要点

1. [rc:3635572375] update-branch 缺少 expected_head_sha 比较并交换(compare-and-swap)保护 — 已实现

stale-base 分支会针对刚读取到的 PR head 计算 STALE_BASE_REDS,但随后调用 update-branch 时并未锁定该 head。如果 PR 作者在 compare 读取与 update-branch 调用之间推送了新提交,GitHub 就会把 main 合并进那个未经验证的新 head。已为 update-branch 调用添加 -f expected_head_sha="${PR_HEAD_OID}",这样当 head 发生变动时 GitHub 会拒绝该更新(比较并交换),与 qwen-fleet-shepherd.yml 中已有的写法保持一致。同时添加了一条简短注释说明这一竞态。

2. [rc:3635572378] 排除过滤器从未被测试辅助函数覆盖 — 已实现

行为测试的辅助函数从未设置 workflowName,因此 STALE_BASE_REDS jq 过滤器中对 Qwen Autofix 的排除逻辑在运行时从未被执行——即便逻辑写反了,所有现有用例也都能通过。已为 stale-base 测试新增两个用例:

  • 一个 Qwen Autofix 检查(非 review-address)在 PR 上失败、在 main 上通过时,不应触发 update-branchupdated: false, continued: false)。
  • 一个位于 Qwen Autofix workflow 下的 review-address 检查属于合格情形,仍会更新(updated: true, continued: true),覆盖过滤器中的 or 分支。

改动

  • .github/workflows/qwen-autofix.yml:为 stale-base 的 update-branch 调用添加 expected_head_sha 比较并交换保护(以及一条说明原因的注释)。
  • scripts/tests/qwen-autofix-workflow.test.js:新增两个用例,覆盖 Qwen Autofix 排除过滤器及其 review-address 例外。

冲突说明

无 — 无需合并。

验证

  • npx vitest run scripts/tests/qwen-autofix-workflow.test.js — 94 个通过(包含修改后的 stale-base 测试)
  • npx eslint scripts/tests/qwen-autofix-workflow.test.js — 通过
  • npx prettier --check(两个改动文件)— 通过(对测试文件执行 --write 之后)
  • npm run lint — 通过
  • npm run build — 通过
  • npm run typecheck — 通过

未改动任何 settings 源文件,因此无需重新生成 schema。本次改动为 workflow YAML 及其同目录单元测试,通过 Vitest 测试框架而非打包后的 CLI 来验证,因此无需运行集成测试。

Base-conflict check: no conflict with main.

Re-review when you have a moment. After round 100 this bot stops and leaves the PR for a human.


🧠 Handled by Qwen Code · model/模型 qwen3.8-max-preview

@qwen-code-ci-bot qwen-code-ci-bot left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed — no blockers. Suggestions are inline.

— qwen3.7-max via Qwen Code /review

Comment thread scripts/tests/qwen-autofix-workflow.test.js Outdated
Comment thread scripts/tests/qwen-autofix-workflow.test.js Outdated
@qwen-code-dev-bot

Copy link
Copy Markdown
Collaborator

🤖 Addressed the latest review feedback (round 3/100). What changed, and what I pushed back on:

Address review summary

Feedback points

  1. [rc:3635752320] Suggestion — no test for MAIN_HEAD empty (scripts/tests/qwen-autofix-workflow.test.js:448)

    • Decision: Implemented.
    • Change: Added a mainHead parameter to the stale-base run helper (defaulting to 'mainhead999' so all existing calls are unchanged), wired it into the MAIN_HEAD env var, and added one assertion: mainHead: ''{ updated: false, continued: false }. This pins the -n "${MAIN_HEAD}" guard at the workflow's stale-base block — a future refactor removing that guard would now fail this test instead of silently allowing update-branch with a null compare baseline.
  2. [rc:3635752324] Suggestion — no test for CMP_STATUS empty (scripts/tests/qwen-autofix-workflow.test.js:482)

    • Decision: Implemented.
    • Change: Added one assertion: cmp: ''{ updated: false, continued: false }. This pins the == 'behind' || == 'diverged' check — a future change treating empty as "assume behind" (e.g. != 'ahead') would now fail this test instead of auto-merging main into PRs blindly.

Conflict notes

No conflicts (--conflict false).

Verification

  • npx vitest run scripts/tests/qwen-autofix-workflow.test.js — 94 passed (94)
  • npm run build — passed
  • npm run typecheck — passed
  • npm run lint — passed
中文说明

审查反馈处理总结

反馈要点

  1. [rc:3635752320] 建议 — 缺少 MAIN_HEAD 为空的测试用例(scripts/tests/qwen-autofix-workflow.test.js:448)

    • 决定: 已实现。
    • 变更: 在 stale-base 的 run 辅助函数中添加了 mainHead 参数(默认值为 'mainhead999',所有现有调用不受影响),将其传入 MAIN_HEAD 环境变量,并添加了一个断言:mainHead: ''{ updated: false, continued: false }。这固定了工作流 stale-base 代码块中 -n "${MAIN_HEAD}" 守卫的行为——如果未来重构移除了该守卫,此测试将会失败,而不是静默地允许在空比较基准下调用 update-branch
  2. [rc:3635752324] 建议 — 缺少 CMP_STATUS 为空的测试用例(scripts/tests/qwen-autofix-workflow.test.js:482)

    • 决定: 已实现。
    • 变更: 添加了一个断言:cmp: ''{ updated: false, continued: false }。这固定了 == 'behind' || == 'diverged' 检查的行为——如果未来将空值视为"假设落后"(例如改为 != 'ahead'),此测试将会失败,而不是盲目地将 main 自动合并到 PR 中。

冲突说明

无冲突(--conflict false)。

验证

  • npx vitest run scripts/tests/qwen-autofix-workflow.test.js — 94 个测试全部通过
  • npm run build — 通过
  • npm run typecheck — 通过
  • npm run lint — 通过

Base-conflict check: no conflict with main.

Re-review when you have a moment. After round 100 this bot stops and leaves the PR for a human.


🧠 Handled by Qwen Code · model/模型 qwen3.8-max-preview

Comment thread .github/workflows/qwen-autofix.yml Outdated
github-merge-queue Bot pushed a commit that referenced this pull request Jul 23, 2026
…7562)

* feat(autofix): auto-rerun a check that died on infrastructure, once

A failed check can be red because the machine died, not the code — a
self-hosted runner losing the server, the disk filling. #7490's E2E
failed with "runner lost communication with the server" and went green
on a rerun. The scan now reruns such a check's failed jobs automatically.

Detection is a conservative annotation whitelist (INFRA_FAILURE_SIGNATURES)
— only unambiguous machine failures, never a test-level timeout, which
could be a real regression. The one-shot guard is run_attempt, not a
marker: a run already retried to attempt 2 and still infra-failing is
persistent, so it is left for a human; after a rerun the attempt
increments, so the next scan will not rerun it. Every step is fail-safe
(any API error → no rerun), it runs only when the PR actually has a
failed check, and the gate carries the same review-address carve-out as
the other check selectors so the loop never reruns its own runs.

This is the transient-infra sibling of #7554 (stale-base): that merges
current main when a check is base-inherited; this reruns when a check
died on the runner. Neither touches a check that is a genuine failure.

Note: rerun-failed-jobs needs the PAT to hold `actions: write`.

* fix(autofix): use POSIX ERE groups in infra-failure regex, cover all signatures in tests (#7562)

* fix(autofix): also treat a git fetch/clone transport death as infra

#6506's checkout died mid-transfer — "fetch-pack: invalid index-pack
output" and "RPC failed; curl 92 ... CANCEL" — which then hung the job
into the 20m limit. That is infra, not the PR (it only touches a doc),
and a re-run made it green. But the infra-signature whitelist did not
cover it, so the auto-rerun did not fire and it waited on a human.

Add `invalid index-pack output` and `RPC failed` — the two canonical
git-transport-death phrases — to INFRA_FAILURE_SIGNATURES. A co-present
job-timeout line does not block the match (one matching line classifies
the run), and a BARE timeout with no transport signature is still left
alone, since it can be a real regression. Both new signatures are pinned
in the test's per-signature loop, plus a case on #6506's real composite
annotation and a bare-timeout-is-not-rerun guard.

* fix(autofix): paginate annotations and filter Autofix runs in infra-rerun loop (#7562)

---------

Co-authored-by: wenshao <wenshao@example.com>
Co-authored-by: Qwen Code Bot <qwen-code-bot@users.noreply.github.com>
Co-authored-by: qwen-code-ci-bot <qwen-code-ci-bot@users.noreply.github.com>
@qwen-code-dev-bot

Copy link
Copy Markdown
Collaborator

🤖 Addressed the latest review feedback (round 4/100). What changed, and what I pushed back on:

Review feedback addressed

[Critical] update-branch not guarded by DRY_RUN (rc:3636071250)

Decision: Implemented.

The update-branch PUT call — a write that merges main into the PR branch and retriggers CI — was the only write in the scan step not gated on DRY_RUN. A dry_run: true dispatch would still merge main into every eligible PR branch.

Fix: Added a DRY_RUN guard immediately after RED_NAMES is computed and before the gh api -X PUT call, matching the existing pattern used by the engage-ack comment (line 1947) and the cap-paused notice (line 2058): log a 🧪 DRY-RUN: message, record a fleet_row, and continue to the next PR.

Test: Added a dryRun parameter to the stale-base test harness (defaults to false, so all existing cases are unaffected) and a new assertion: with dryRun: true, the update-branch API is never called (updated: false) but the PR is still skipped via continue (continued: true).

No conflicts (--conflict false).

Verification

  • npm run build — passed
  • npm run typecheck — passed
  • npm run lint — passed
  • npx vitest run scripts/tests/qwen-autofix-workflow.test.js — 94 passed (including the new DRY_RUN case)
中文说明

已处理的评审反馈

[Critical] update-branch 未受 DRY_RUN 保护 (rc:3636071250)

决定: 已实现。

update-branch PUT 调用——一个会将 main 合并到 PR 分支并重新触发 CI 的写操作——是扫描步骤中唯一未受 DRY_RUN 门控的写操作。以 dry_run: true 派发工作流时,仍会将 main 合并到每个符合条件的 PR 分支中。

修复:RED_NAMES 计算之后、gh api -X PUT 调用之前,添加了 DRY_RUN 守卫,与现有的 engage-ack 评论(第 1947 行)和 cap-paused 通知(第 2058 行)所使用的模式一致:记录 🧪 DRY-RUN: 消息、写入 fleet_row,然后 continue 跳到下一个 PR。

测试: 在 stale-base 测试工具中添加了 dryRun 参数(默认为 false,因此所有现有用例不受影响),并新增了一个断言:当 dryRun: true 时,update-branch API 不会被调用(updated: false),但 PR 仍会通过 continue 被跳过(continued: true)。

无冲突(--conflict false)。

验证

  • npm run build — 通过
  • npm run typecheck — 通过
  • npm run lint — 通过
  • npx vitest run scripts/tests/qwen-autofix-workflow.test.js — 94 个测试通过(包括新增的 DRY_RUN 用例)

Base-conflict check: no conflict with main.

Re-review when you have a moment. After round 100 this bot stops and leaves the PR for a human.


🧠 Handled by Qwen Code · model/模型 qwen3.8-max-preview

@wenshao

wenshao commented Jul 23, 2026

Copy link
Copy Markdown
Collaborator Author

@qwen-code /resolve

chiga0 pushed a commit that referenced this pull request Jul 23, 2026
…7562)

* feat(autofix): auto-rerun a check that died on infrastructure, once

A failed check can be red because the machine died, not the code — a
self-hosted runner losing the server, the disk filling. #7490's E2E
failed with "runner lost communication with the server" and went green
on a rerun. The scan now reruns such a check's failed jobs automatically.

Detection is a conservative annotation whitelist (INFRA_FAILURE_SIGNATURES)
— only unambiguous machine failures, never a test-level timeout, which
could be a real regression. The one-shot guard is run_attempt, not a
marker: a run already retried to attempt 2 and still infra-failing is
persistent, so it is left for a human; after a rerun the attempt
increments, so the next scan will not rerun it. Every step is fail-safe
(any API error → no rerun), it runs only when the PR actually has a
failed check, and the gate carries the same review-address carve-out as
the other check selectors so the loop never reruns its own runs.

This is the transient-infra sibling of #7554 (stale-base): that merges
current main when a check is base-inherited; this reruns when a check
died on the runner. Neither touches a check that is a genuine failure.

Note: rerun-failed-jobs needs the PAT to hold `actions: write`.

* fix(autofix): use POSIX ERE groups in infra-failure regex, cover all signatures in tests (#7562)

* fix(autofix): also treat a git fetch/clone transport death as infra

#6506's checkout died mid-transfer — "fetch-pack: invalid index-pack
output" and "RPC failed; curl 92 ... CANCEL" — which then hung the job
into the 20m limit. That is infra, not the PR (it only touches a doc),
and a re-run made it green. But the infra-signature whitelist did not
cover it, so the auto-rerun did not fire and it waited on a human.

Add `invalid index-pack output` and `RPC failed` — the two canonical
git-transport-death phrases — to INFRA_FAILURE_SIGNATURES. A co-present
job-timeout line does not block the match (one matching line classifies
the run), and a BARE timeout with no transport signature is still left
alone, since it can be a real regression. Both new signatures are pinned
in the test's per-signature loop, plus a case on #6506's real composite
annotation and a bare-timeout-is-not-rerun guard.

* fix(autofix): paginate annotations and filter Autofix runs in infra-rerun loop (#7562)

---------

Co-authored-by: wenshao <wenshao@example.com>
Co-authored-by: Qwen Code Bot <qwen-code-bot@users.noreply.github.com>
Co-authored-by: qwen-code-ci-bot <qwen-code-ci-bot@users.noreply.github.com>

@qwen-code-ci-bot qwen-code-ci-bot left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed — no blockers. Suggestions are inline.

— qwen3.7-max via Qwen Code /review

Comment thread .github/workflows/qwen-autofix.yml
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
wenshao added a commit to chinesepowered/qwen-code that referenced this pull request Jul 23, 2026
…n fix (QwenLM#7595)

A fix that fails to build is not always the fix's fault. QwenLM#7471 stalled
when the agent's verification gate failed with "Cannot find module
'update-notifier'" — a dependency main removed in QwenLM#7515, still imported
on a branch 32 commits behind. The loop could not tell a stale-base build
failure from a genuine one, so it advanced past the feedback and asked a
human to take over.

In the gate-rejection branch, before the handoff, compare the checked-out
head with main; if it is behind or diverged, update-branch (a CAS on
REPORT_HEAD) merges main in and the round retries (sentinel ts keeps the
feedback live). It self-limits: after the update the PR is current, so a
next-round rejection is no longer "behind" and falls through to the human
handoff — a genuine fix failure costs at most one base-update. The round
is exempt from the consecutive-failure breaker (not the PR's fault), and
every API call is fail-safe.

This is the agent-gate sibling of QwenLM#7554, which only sees PR status checks,
never the gate's own build.

Co-authored-by: wenshao <wenshao@example.com>

@qwen-code-ci-bot qwen-code-ci-bot left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed — no blockers. Suggestions are inline. 1 Suggestion-level finding(s) could not be anchored to a changed line and were dropped; nothing further to act on here.

— qwen3.7-max via Qwen Code /review

Comment thread scripts/tests/qwen-autofix-workflow.test.js Outdated
@wenshao

wenshao commented Jul 23, 2026

Copy link
Copy Markdown
Collaborator Author

Review

The idea is right and the block is written in the file's idiom — merge not rebase, expected_head_sha as a CAS, fail-safe empty green set, the review-address carve-out, a DRY-RUN path. My concern is not the shape of the code; it is that the safety gate it hangs on has no data behind it in this repo, so the block cannot fire for the failures it was built for.


🔴 The green-on-main gate can never match the checks this targets

MAIN_GREEN_CHECKS (.github/workflows/qwen-autofix.yml:1743-1745) reads GET /repos/{repo}/commits/{MAIN_HEAD}/check-runs. The CI checks that go red from a bad base — Test (ubuntu-latest, Node 22.x), Lint, Build, Integration Tests, Post Coverage Comment, web-shell E2E Smokenever appear as check-runs on a main commit, because:

  • ci.yml has no push: trigger. That is deliberate and documented in its own header: every job is gated to pull_request / merge_group, on the premise that "the merge queue validates the merged tree before it lands."
  • That premise is currently stale. The last merge_group run in this repo was 2026-07-02, and the main ruleset has rules deletion, non_fast_forward, pull_request — no merge_queue rule. So nothing re-attaches those check names to a main SHA.

Measured against the live repo:

  • 25 most recent main commits → 0 check-runs named Test (…) / Lint / Build / Integration Tests / Post Coverage, even with ?filter=all.
  • The only CI-ish green names that do land on main are E2E Test (Linux) - sandbox:* (which does not run on PRs, so it can never be a PR-side red) and Publish web-shell visuals to the PR.
  • Running the exact production jq from :1852-1858 against real data: every currently-red open PR is red on Test (ubuntu-latest, Node 22.x) — the same check #7490 was stranded on — and STALE_BASE_REDS comes back [] for all of them.

A second, independent starvation: MAIN_HEAD is read fresh each scan, and the scan runs every ~10 min against a repo that merges often, so it usually points at a commit that is minutes old. Observed MAIN_GREEN_CHECKS lengths on live main heads during this review: 1 and 2.

Worth separating the two motivating incidents, because they need different fixes:

incident surfaces as reachable from this block?
web-shell TS break failing the trusted-base build the address job's own build — never in statusCheckRollup no — that is #7595's path
#7490, agent.test.ts red on a check it never touched Test (ubuntu-latest, Node 22.x) in principle yes, but the gate can't see it

So the one in-scope case is the one the gate is blind to. Meanwhile the already-merged sibling #7595 gates on behind-main alone with no green-on-main condition — the asymmetry is worth a deliberate decision rather than an accident of which signal happened to be available.

Directions, roughly in order of how much I'd trust them:

  1. Read the green set from where those names actually exist. GET /repos/{repo}/commits/{MAIN_HEAD}/pulls resolves main's head to the PR that landed it; that PR's statusCheckRollup carries the real ci.yml names, and they were green — that is precisely the claim "main was healthy on this check when the current head landed." Sample a few landed PRs before committing to it; the first one I probed had no Test entry either, so it needs its own verification.
  2. Give ci.yml a push:/scheduled run on main. That makes the signal exist and also re-establishes the post-merge validation its header assumes — but it's a separate change with its own cost.
  3. Drop the by-name gate here and align with feat(autofix): update a stale base when the gate rejects a behind-main fix #7595's predicate, accepting the weaker safety argument explicitly.

Whichever route: :1739-1746 currently has no test coverage — the new test injects MAIN_GREEN_CHECKS as an env var, so the derivation and its intersection with real check names are never exercised. A case that feeds an actual check-runs payload from this repo through that block would have caught this before review.


🟡 Non-blocking

  • base-update-failed retries forever (:1880-1885). There's no marker or backoff, so a merge-conflicted PR costs a compare call, an update-branch call, a ⚠️ line and a fleet row on every 10-minute scan, indefinitely. The "self-limiting, no marker needed" property in the description holds only on the success path; the failure path is the one that repeats.
  • Duplicate PR_HEAD_OID — assigned at :1859 and again at :1898. The second is now dead.
  • DEFAULT_BRANCH is a knob nothing sets (:1739). Grep finds exactly one occurrence, and candidate selection hardcodes --base main (:1662, :1665), so setting it would desync the two. Either wire it through or inline main.
  • One unguarded new command. STALE_BASE_REDS="$(jq …)" at :1852 is the only addition not wrapped in || … or an if. The job runs under defaults.run.shell: bash-eo pipefail, so a jq error aborts the whole scan for every remaining candidate. Reachability is low (both inputs are jq-produced), but every neighbouring call in this file is defensive.
  • Selector drift. The pending-check selector at :1946 applies the NON_BLOCKING_CHECKS carve-out; the new one at :1856 doesn't. Harmless today — NON_BLOCKING_CHECKS is ["review-pr"], already excluded by the workflowName test — but the two will drift the moment that list grows.
  • Ordering vs. HAS_PENDING_CHECKS. The block runs before the in-flight-checks gate, so an update can fire while the PR's own CI is still running and cancel a partially-complete run. Consistent with where the infra-rerun block sits, so I assume it's deliberate; a line of comment would keep it that way.
  • Test harness runs a different shell than production: bash -c 'set -uo pipefail' vs. bash --noprofile --norc -eo pipefail. -e is missing from the test, -u is missing from production. Matching production would make the point above self-evident.
  • The INFRA_SIGNATURES single-sourcing hunk is already on main via test(autofix): single-source the infra-signature list from the workflow #7565 with identical content — it'll merge clean, just noting it isn't new here.

✅ What holds up

  • expected_head_sha is the right instinct; it closes the read-then-write race properly.
  • The test is genuinely load-bearing, not decorative. I mutated three things independently — removed the green-on-main gate, made the compare status unconditional, dropped expected_head_sha — and each one turned it red; restored, 97/97 pass.
  • Merge-not-rebase, the fail-safe empty green set, and the review-address carve-out are all consistent with how the rest of this file reasons.

My call: the mechanism is sound, but I'd hold off merging until the green signal points at data that exists — otherwise this lands as a no-op that reads like a fix, and the next stranded PR still needs a human.

中文说明

评审

思路是对的,代码也符合本文件的既有风格 —— merge 而非 rebase、expected_head_sha 做 CAS、绿集取不到时 fail-safe、review-address carve-out、DRY-RUN 路径。我的顾虑不在代码形态,而在于:它所依赖的安全门,在本仓库里没有对应的数据,因此这段逻辑对它想解决的故障根本不会触发。


🔴 green-on-main 这个门永远匹配不到目标检查

MAIN_GREEN_CHECKS(.github/workflows/qwen-autofix.yml:1743-1745)读的是 GET /repos/{repo}/commits/{MAIN_HEAD}/check-runs。而真正会因为坏 base 变红的那些 CI 检查 —— Test (ubuntu-latest, Node 22.x)LintBuildIntegration TestsPost Coverage Commentweb-shell E2E Smoke —— 从来不会作为 check-run 出现在 main 的 commit 上,原因是:

  • ci.yml 没有 push: 触发器。这是刻意的,它自己的头部注释写明:所有 job 都只在 pull_request / merge_group 下运行,前提是"合并队列在落地前已校验合并后的树"。
  • 而这个前提目前已经失效。本仓库最后一次 merge_group 运行是 2026-07-02,main ruleset 的规则是 deletion, non_fast_forward, pull_request —— 没有 merge_queue 规则。所以没有任何东西再把那些检查名附着到 main 的 SHA 上。

对线上仓库的实测:

  • 最近 25 个 main commit → 0 个名为 Test (…) / Lint / Build / Integration Tests / Post Coverage 的 check-run,加 ?filter=all 也一样。
  • 唯一能落到 main 上的 CI 类绿名只有 E2E Test (Linux) - sandbox:*(它不在 PR 上跑,所以不可能成为 PR 侧的红)和 Publish web-shell visuals to the PR
  • :1852-1858 处的生产 jq 原样跑真实数据:当前所有变红的 open PR 都红在 Test (ubuntu-latest, Node 22.x) —— 正是 #7490 被搁置的那个检查 —— 而 STALE_BASE_REDS 全部返回 []

还有第二重独立的"饥饿":MAIN_HEAD 每次扫描现取,而扫描每 ~10 分钟一次、仓库合并频繁,所以它通常指向一个刚产生几分钟的 commit。本次评审期间在线上 main head 观察到的 MAIN_GREEN_CHECKS 长度是 12

两个促成本 PR 的事故值得分开看,它们需要不同的修法:

事故 表现形式 本段逻辑够得着吗?
web-shell TS 错误导致受信任 base 构建失败 address job 自己的构建 —— 从不进入 statusCheckRollup 不能 —— 那是 #7595 的路径
#7490,agent.test.ts 在从未触碰的检查上变红 Test (ubuntu-latest, Node 22.x) 原理上可以,但门看不见它

也就是说,唯一落在本 PR 范围内的场景,恰恰是这个门盲掉的那个。与此同时,已合并的姊妹 PR #7595 只以 behind-main 设门,完全没有 green-on-main 条件 —— 这种不对称应当是一次有意的决策,而不是"哪个信号刚好拿得到"的偶然结果。

几个方向,大致按我的信任程度排序:

  1. 从那些检查名真实存在的地方取绿集。GET /repos/{repo}/commits/{MAIN_HEAD}/pulls 能把 main 的 head 解析成落地它的那个 PR;该 PR 的 statusCheckRollup 带有真正的 ci.yml 检查名,且当时是绿的 —— 这恰好就是"当前 head 落地时 main 在这个检查上是健康的"这一论断。落定前请多抽样几个已落地 PR:我探的第一个也没有 Test 条目,所以这条路本身也需要验证。
  2. ci.yml 加上对 mainpush: 或定时运行。这样信号才存在,同时也重建了它头部注释所假设的合并后校验 —— 但这是另一个变更,有自己的代价。
  3. 去掉这里的按名设门,与 feat(autofix): update a stale base when the gate rejects a behind-main fix #7595 的判据对齐,并把更弱的安全论证明确写出来。

无论走哪条::1739-1746 目前没有任何测试覆盖 —— 新测试把 MAIN_GREEN_CHECKS 当环境变量注入,因此推导过程本身、以及它与真实检查名的交集,从未被执行过。一个把本仓库真实 check-runs 负载喂进这段逻辑的用例,本可以在评审之前就抓到这个问题。


🟡 非阻塞

  • base-update-failed 会永远重试(:1880-1885)。没有 marker 也没有退避,所以一个存在合并冲突的 PR 会在每次 10 分钟扫描里消耗一次 compare 调用、一次 update-branch 调用、一行 ⚠️ 和一行 fleet row,无限持续。描述里"自限、无需 marker"的性质只在成功路径成立;会重复的恰恰是失败路径。
  • PR_HEAD_OID 重复赋值 —— :1859:1898 各一次,后者已成死代码。
  • DEFAULT_BRANCH 是一个没人设置的旋钮(:1739)。全文件只此一处出现,而候选筛选硬编码了 --base main(:1662:1665),所以真去设置它反而会让两处不同步。要么接通,要么直接内联 main
  • 有一处新命令没有保护。 :1852STALE_BASE_REDS="$(jq …)" 是本次新增中唯一没有 || …if 包裹的。该 job 运行在 defaults.run.shell: bash-eo pipefail 之下,因此 jq 一旦出错会中止整个扫描、连带放弃所有剩余候选。可达性很低(两个输入都由 jq 产生),但本文件里相邻的调用无一不是防御式的。
  • 选择器漂移。 :1946 的 pending-check 选择器带 NON_BLOCKING_CHECKS carve-out,:1856 的新选择器没有。今天无害 —— NON_BLOCKING_CHECKS["review-pr"],已被 workflowName 判断排除 —— 但那个列表一旦增长,两者立刻分叉。
  • HAS_PENDING_CHECKS 的先后顺序。 本段跑在"检查在飞"这道闸之前,因此更新可能在 PR 自己的 CI 还在跑时触发、取消一次已完成过半的运行。这与 infra-rerun 块的位置一致,我姑且认为是刻意的;补一行注释可以让它保持刻意。
  • 测试外壳与生产不同:bash -c 'set -uo pipefail'bash --noprofile --norc -eo pipefail。测试少了 -e,生产少了 -u。与生产对齐后,上一条会变得不言自明。
  • INFRA_SIGNATURES 单一来源那一段已经通过 test(autofix): single-source the infra-signature list from the workflow #7565 落在 main 上且内容一致 —— 合并不会冲突,只是说明它在本 PR 里并非新增。

✅ 站得住的部分

  • expected_head_sha 是正确的直觉,干净地关掉了"先读后写"的竞态。
  • 测试是真正承重的,不是装饰。我独立做了三次变异 —— 去掉 green-on-main 门、让 compare 状态恒真、删掉 expected_head_sha —— 每一次都让它变红;还原后 97/97 全绿
  • merge 而非 rebase、绿集为空时 fail-safe、review-address carve-out,都与本文件其余部分的推理方式一致。

我的结论:机制本身是成立的,但在绿信号指向真实存在的数据之前,我倾向先不合 —— 否则它落地后看起来像修复,实则是空操作,下一个被搁置的 PR 依然要人工处理。


🤖 Generated with Claude Code — Claude Opus 4.8 (1M context)

@wenshao

wenshao commented Jul 23, 2026

Copy link
Copy Markdown
Collaborator Author

Code review — auto-update a PR red only from a stale, since-fixed base

Reviewed at head d8d0f21. The mechanism, the CAS via expected_head_sha, the fail-safe empty-set defaults, and the extract-the-real-block test harness are all well built. My one substantive concern is with the central safety claim, not the code that implements it.

What works well

  • expected_head_sha compare-and-swap on update-branch closes the read→write race on the PR head cleanly.
  • Fail-safe defaults: unreadable MAIN_HEAD/MAIN_GREEN_CHECKS/CMP_STATUS all collapse to "do nothing," and the -n "${MAIN_HEAD}" / -n "${PR_HEAD_OID}" guards are belt-and-suspenders on top.
  • Case discipline across two sources: main greens come from the REST check-runs API (lowercase success) and PR reds from the GraphQL rollup (uppercase FAILURE…). Each filter matches its own source's convention — easy to get wrong, correct here.
  • review-address carve-out matches the other selectors verbatim, and the test pins both directions (a Qwen Autofix Build is ineligible; a review-address check is eligible).
  • Test replays the real extracted block under bash with a stubbed gh, asserts the CAS payload, dry-run, empty-mainhead, empty-cmp; and the infra test now single-sources INFRA_FAILURE_SIGNATURES from the workflow (kills a drift class). Strong.

🔴 Primary concern — "green on current main" does not prove "base-inherited" (High)

The PR's load-bearing claim is:

green on main means it is not the PR's own bug

That implication does not hold. "Check X fails on the PR but passes on current main" is satisfied by two different situations:

  1. Base-inherited, since-fixed — the PR merged a broken main, main was fixed, X now passes on main. (the intended target — update-branch helps)
  2. The PR's own new bug — the PR's diff breaks X; main never had that change, so X is green on main. (update-branch does not help — the bug rides along in the merge)

Both present identically as red-on-PR / green-on-main. The gate cannot tell them apart, and case 2 is the normal state of any PR mid-iteration — which is exactly the population the scan targets (bot-authored PRs + takeover PRs, qwen-autofix.yml:1661-1685).

This is visible in the test itself. The first assertion —

run({ prChecks: [FAIL('Test')], mainGreen: ['Test'] })  // behind → { updated: true }

— is labeled "base-inherited red," but FAIL('Test') + Test green on main + behind is byte-for-byte the fingerprint of a PR that introduced its own failing Test. The gate fires on both; nothing downstream distinguishes them. The mutation test frames the alternative as "red on the PR AND on main," but that case is main currently broken, not "the PR's own bug" — so the model of what the gate rejects is inverted from what it actually rejects.

Why it bites, concretely — because the block runs before the feedback logic and continues on success (:1870, :1878), a false positive doesn't just cost one wasted merge:

  • A takeover/bot PR that is red on its own unfinished work and behind main (main moves constantly) → update-branch fires → continue skips the address/feedback logic (~:2038-2242) that would actually fix it.
  • Next scan: the PR is behind again (main advanced), still self-red, X still green on main → fires again → feedback skipped again. On a busy repo this is a livelock: the bot base-merges the PR every scan and never runs its fix loop — a regression from today's behavior, where the agent iterates on the red.
  • Each firing also re-runs full CI (~40 min) and, under dismiss_stale_reviews, dismisses the PR's approvals — repeatedly, on PRs whose only problem is their own in-progress diff.

So the "only fires when confirmed base-inherited, which is rare" framing is inverted: the rare case (base-inherited) is the intended target, but the common case (self-red + behind) satisfies the same gate.

The valuable half of the gate is real and worth keeping: excluding checks that are red on main too correctly avoids importing a live breakage. The gap is only the green-on-main branch conflating cases 1 and 2.

What would actually distinguish them — a signal that the failure is not attributable to the PR's own diff. Options, roughly in increasing cost:

  • Gate additionally on the PR head being a base-merge commit with no content delta since the last green (the failure appeared without a code push) — cheap-ish from commit metadata.
  • Require the same check to have been failing at the PR's merge-base with main (the main it currently contains) but passing on current main — i.e., prove the fix landed between what the PR has and what main has.
  • At minimum, only auto-update when the PR has no new feedback to address this scan, so the base-merge never preempts an actual fix round.

Green-on-main alone can't carry the "base-inherited" conclusion; one of these is needed to keep the automation from acting on ordinary broken PRs.

🟡 Secondary — ordering preempts the cheaper infra-rerun (Low)

For a behind PR whose infra-flaked check happens to be green on main, the stale-base block fires first and does a full base-merge instead of the targeted single-job rerun the infra block (:1889) would have done. Still recovers, just heavier (full CI + approval dismissal vs. one job). Worth a moment's thought on whether infra-rerun should run first.

Minor notes

  • Status-context coverage: MAIN_GREEN_CHECKS is check-runs only, and the red selector's (.name // .workflowName // "") yields "" for a legacy StatusContext (no .name), so it's filtered out. A PR red purely on a required commit status that's green on main is silently never auto-updated. Fail-closed, so safe — just noting the blind spot.
  • Redundant assignment: PR_HEAD_OID is set at :1859 and again at :1898. Harmless (same value), keeps the blocks independent; leave or drop as you like.

Verdict

Mechanically sound and well-tested. I'd hold on merge until the green-on-main gate is narrowed with a "not caused by the PR's own diff" signal — as written it will act on ordinary self-broken behind PRs, and because it runs before and continues past the feedback loop, it can stall the very fix cycle it sits in front of.

中文说明

机制实现(expected_head_sha 的 CAS、失败安全默认、抽取真实代码块回放的测试)都很扎实。核心疑虑在于安全论断本身

主要问题(High)——"在当前 main 上为绿"并不能证明"红是 base 继承的"。"检查 X 在 PR 上红、在当前 main 上绿"同时满足两种情况:(1) base 继承、且已在 main 上修复(目标场景,update-branch 有效);(2) PR 自己的新 bug——改动破坏了 X,而 main 从未有此改动,所以 X 在 main 上是绿的(update-branch 无效,bug 会随合并一起带过来)。两者表现完全相同,门无法区分,而情况 (2) 正是迭代中 PR 的常态,也正是扫描的目标群体(bot PR + takeover PR)。

测试第一条 FAIL('Test') + mainGreen:['Test'] + behind → updated:true 被标注为"base 继承",但它逐字就是"PR 自己引入了失败的 Test"的指纹。变异测试把对立面设为"PR 与 main 上都红",那其实是"main 当前坏了",并非"PR 自己的 bug"——判据方向反了。

为何有害:该块在反馈逻辑之前、成功即 continue。因此一个自己红且落后于 main(main 一直在前进)的 PR 会:触发 update-branch → 跳过本可修复它的 address/反馈逻辑 → 下一轮又落后、又自红、X 又在 main 绿 → 再次触发。繁忙仓库上这是活锁:bot 每轮都在合 main、却永不跑修复循环(相对现状是回退)。且每次都重跑约 40 分钟 CI,并在 dismiss_stale_reviews 下反复作废批准。所以"仅在确诊 base 继承时触发、较罕见"的表述是反的:罕见的才是目标场景,常见的(自红+落后)恰好满足同一道门。

门有价值的那一半应保留:排除"在 main 上也红"的检查,能正确避免引入实时故障。缺口只在 green-on-main 这一支混淆了两种子情况。需要一个"失败非源于 PR 自身改动"的信号(例如:PR head 是无内容增量的 base-merge 提交;或该检查在 PR 的 merge-base 上也红、仅在当前 main 上变绿;或至少只在本轮没有新反馈需处理时才更新)。

次要(Low):对一个落后 PR、其基础设施抖动的检查恰好在 main 上为绿时,stale-base 会先触发整轮 base-merge,而非 infra 块(:1889)本可做的单 job 重跑。

小注:MAIN_GREEN_CHECKS 仅取 check-runs,红选择器对 legacy StatusContext 产出 "" 被过滤,故纯 commit-status 红永不自动更新(失败安全,但是盲点);PR_HEAD_OID:1859:1898 各赋值一次(无害)。

结论:机制正确、测试充分,但建议在把 green-on-main 门收窄到带"非 PR 自身改动导致"的信号之前先不合入。

@wenshao wenshao left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed. 1 Suggestion-level finding(s) could not be anchored to a changed line and were dropped; nothing further to act on here.

— qwen3.8-max-preview via Qwen Code /review

@qwen-code-dev-bot

Copy link
Copy Markdown
Collaborator

🤖 Addressed the latest review feedback (round 6/100). What changed, and what I pushed back on: · 已处理最新评审反馈(第 6/100 轮)。改动内容与我反驳保留之处如下:

Review feedback addressed

All feedback points from @wenshao's two reviews have been addressed.

🔴 Critical #1 — the gate can never match the checks it was built for

Fixed. MAIN_GREEN_CHECKS is now sourced from the PR that produced main's head commit, not from main's squash commit directly. Since ci.yml has no push trigger, its check-runs never land on main's squash commits; resolving MAIN_HEAD → its PR via GET /repos/{repo}/commits/{sha}/pulls → reading check-runs from that PR's head SHA gives us the ci.yml job names (Test (…), web-shell E2E Smoke (…), etc.). Also added | unique to deduplicate.

🔴 Critical #2 — "green on main" does not prove the red is base-inherited

Fixed. Added the base dimension: the failing check must now satisfy TWO predicates — (1) green on current main, AND (2) NOT green at the merge-base commit the PR carries. The merge-base is extracted from the compare response (merge_base_commit.sha), resolved to its PR's head SHA the same way as main's head, and its non-success check names are intersected with the PR's failing checks. A PR-introduced regression (green at the merge-base, red on the PR) is now cleanly rejected.

🟠 High #1 — "self-limiting, no marker needed" doesn't hold

Fixed. Two guards now bound repetition:

  1. The block is moved after the round cap check, so a round-capped PR is never base-updated.
  2. A <!\-\- autofix-base-updated --> marker comment is posted after a successful update, and the block checks for a recent marker (within 2 hours) before updating again. The marker is added to BOT_COMMENT_FILTER so it is never counted as feedback.

🟠 High #2 — runs before the in-flight-checks gate

Fixed. The block is now positioned after both the HAS_PENDING_CHECKS gate and the round cap check, so it never fires while checks are still running.

🟡 Medium #1 — the review-address carve-out is inverted

Fixed. The stale-base selector now excludes ALL Qwen Autofix checks (!= "Qwen Autofix") with no review-address carve-out. This is strictly narrower than the old behavior and matches the description's intent.

🟡 Medium #2 — the failure branch can't tell you why

Fixed. The update-branch call now captures stderr into UPDATE_ERR (2>&1 >/dev/null) and includes it in the log message and fleet row, making 409/422/403 causes diagnosable.

Nits

  • PR_HEAD_OID computed twice: hoisted once after CHECKS_JSON, removed from both the stale-base and infra-rerun blocks.
  • MAIN_GREEN_CHECKS duplicates: | unique added.
  • DEFAULT_BRANCH never set: removed; uses main directly.
  • Test harness shell options: changed from set -uo pipefail to set -eo pipefail to match production (-e on, -u off).

Test coverage updates

  • All 11 existing cases updated for the two-predicate gate (base dimension).
  • New case: PR-introduced regression (green at merge-base) → no update.
  • New case: review-address check excluded (carve-out removed).
  • New case: repetition guard (recent marker → no update).
  • New case: marker posted on successful update.
  • Infra-rerun test updated for hoisted PR_HEAD_OID.
  • BOT_COMMENT_FILTER assertion updated for autofix-base-updated.
  • Check-selector guard assertion updated to accept both carve-out and full exclusion.

Verification

  • npm run build — passed
  • npm run typecheck — passed
  • npm run lint — passed
  • npx vitest run scripts/tests/qwen-autofix-workflow.test.js — 97 passed (97 total)
中文说明

已处理的评审反馈

@wenshao 两次评审中的所有反馈点均已处理。

🔴 Critical #1 — 门永远匹配不到目标检查

已修复。 MAIN_GREEN_CHECKS 现在取自产生 main head 提交的 PR,而非直接取自 main 的 squash 提交。由于 ci.yml 没有 push 触发器,其 check-run 永远不会出现在 main 的 squash 提交上;通过 GET /repos/{repo}/commits/{sha}/pullsMAIN_HEAD 解析到其 PR → 从该 PR 的 head SHA 读取 check-run,即可获得 ci.yml 的作业名(Test (…)web-shell E2E Smoke (…) 等)。同时添加了 | unique 去重。

🔴 Critical #2 — "main 上绿"不能证明红是 base 继承的

已修复。 添加了 base 维度:失败检查现在必须同时满足两个条件 —— (1) 在当前 main 上为绿,且 (2) 在 PR 所含的 merge-base 提交上不为绿。merge-base 从 compare 响应(merge_base_commit.sha)中提取,以与 main head 相同的方式解析到其 PR 的 head SHA,其非成功检查名与 PR 的失败检查取交集。PR 自身引入的回归(merge-base 上为绿、PR 上为红)现在被干净地拒绝。

🟠 High #1 — "自限、无需 marker"不成立

已修复。 现在有两重护栏限制重复触发:

  1. 块被移到轮次上限检查之后,因此已达上限的 PR 不会被 base-update。
  2. 成功更新后会发布 <!\-\- autofix-base-updated --> 标记评论,块在更新前检查是否有近期标记(2 小时内)。该标记已加入 BOT_COMMENT_FILTER,不会被计为反馈。

🟠 High #2 — 跑在 in-flight 检查门之前

已修复。 块现在位于 HAS_PENDING_CHECKS 门和轮次上限检查之后,不会在检查仍在运行时触发。

🟡 Medium #1review-address carve-out 与描述相反

已修复。 stale-base 选择器现在排除所有 Qwen Autofix 检查(!= "Qwen Autofix"),不再有 review-address 例外。这比旧行为更严格,符合描述意图。

🟡 Medium #2 — 失败分支吞掉了原因

已修复。 update-branch 调用现在将 stderr 捕获到 UPDATE_ERR2>&1 >/dev/null),并在日志和 fleet row 中包含错误信息,使 409/422/403 原因可诊断。

小项

  • PR_HEAD_OID 重复计算:提升到 CHECKS_JSON 之后一次性计算,从 stale-base 和 infra-rerun 块中移除。
  • MAIN_GREEN_CHECKS 重复:添加 | unique
  • DEFAULT_BRANCH 从未赋值:移除,直接使用 main
  • 测试 harness shell 选项:从 set -uo pipefail 改为 set -eo pipefail,与生产一致(-e 开、-u 关)。

测试覆盖更新

  • 所有 11 个现有用例已更新为双条件门(base 维度)。
  • 新增用例:PR 引入的回归(merge-base 上为绿)→ 不更新。
  • 新增用例:review-address 检查被排除(carve-out 已移除)。
  • 新增用例:重复触发护栏(近期标记 → 不更新)。
  • 新增用例:成功更新时发布标记。
  • infra-rerun 测试已更新以适应提升的 PR_HEAD_OID
  • BOT_COMMENT_FILTER 断言已更新以包含 autofix-base-updated
  • 检查选择器护栏断言已更新,接受 carve-out 和完全排除两种形式。

验证

  • npm run build — 通过
  • npm run typecheck — 通过
  • npm run lint — 通过
  • npx vitest run scripts/tests/qwen-autofix-workflow.test.js — 97 通过(共 97 个)

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/模型 qwen3.8-max-preview

@wenshao

wenshao commented Jul 23, 2026

Copy link
Copy Markdown
Collaborator Author

Code review — auto-update a PR red only from a stale, since-fixed base

Reviewed at head 6ff5d98. Verified locally in an isolated worktree: extracted-block test passes (auto-updates a PR red only from a stale base ✓, 4.9s), the two suite "failures" are pure 5s load-timeouts that pass at --testTimeout=30000 (9.5s / 8.1s), so the suite is effectively 97/97. CI green on the legs that run.

The craftsmanship here is high, and the prior-round concerns are genuinely resolved. My one substantive concern is new, and it lands on the last commit (add base dimension) — which is exactly the part no prior review covered: @wenshao's two reviews were at d8d0f21, before predicate 2 existed, and the triage 5/5 rated the predicate-1-only design.

What works well

  • expected_head_sha CAS on update-branch (:2166) closes the read→write race cleanly; the 2>&1 >/dev/null redirect order correctly captures stderr while discarding the 202 body.
  • Fail-safe defaults everywhere — unreadable MAIN_HEAD / MAIN_GREEN_CHECKS / CMP_STATUS / BASE_SHA all collapse to "do nothing." The empty-MAIN_HEAD and empty-CMP cases are pinned by tests.
  • Marker guard reads the right file. ic.json is refetched per-candidate at :1928 (load-bearing ordering, commented) before the block at :2112, so BASE_UPDATE_RECENT never reads a previous candidate's comments.
  • Self-limiting + marker + fall-through-on-failure together kill the livelock the earlier design had. Merge (not rebase), review-address/Qwen Autofix exclusion, DRY-RUN path — all correct.
  • The extract-the-real-block-and-replay-under-bash test is the right methodology, and it exercises both mutation directions plus CAS, DRY_RUN, and the fail-closed inputs.

🔴 Predicate 2 contradicts the definition of a stale-base breakage — the update can essentially never fire for the cases it targets

BASE_NOT_GREEN (:2133-2135) reads the merge-base's originating PR's head check-runs and keeps only the checks that were red there. Predicate 2 then requires the failing check to be in that set (:2144, ... and ($basered | index($n))).

But a stale-base breakage is, by construction, a break that pre-merge CI did not catch — otherwise the base PR would never have merged. This repo has no push trigger and a merge queue (ci.yml:6-9): the only check-runs that ever land on a PR's head SHA are its pull_request runs, and a merged PR was green on those (that's why it merged). So:

  • The commit at the PR's merge-base was produced by a PR whose head is green on the check that later broke main.
  • Predicate 2 requires that head to be red on it.

These two are mutually exclusive for any genuine stale-base red. Concretely for #7490 — the named motivating case, "went red on a test it never touched": its merge-base is the broken-main commit; that commit's originating PR passed the test at merge time (required check ⇒ green ⇒ merged); BASE_NOT_GREEN therefore does not contain it; predicate 2 fails; no update. The green-at-merge-base signal that predicate 2 reads is precisely the signature of a base-inherited red, yet the code treats it as proof of "the PR's own regression" and skips.

The result is fail-safe (it degrades to the manual status quo, never a wrong action), but the automation is effectively inert for its own motivating scenarios. The 13-case test can't catch this: it feeds baseNotGreen as a literal input, so it validates the decision logic given the array — never whether the array can actually be non-empty in production.

Recommendation — before relying on this, validate empirically: for #7490 (or any real stranded PR), fetch GET /commits/{merge_base_sha}/pulls.[0].head.sha/check-runs and confirm the stranding check is actually listed red there. I expect it will be green. If so, replace predicate 2 with a signal that survives the merge-queue model — the most faithful to intent is "the PR's own diff doesn't touch what the failing check exercises" (compare main...PR_HEAD file list vs the check's domain — literally the "a test it never touched" property). Alternatively, drop predicate 2 and lean on predicate 1 + behind + the marker guard + self-limiting: a predicate-1 false positive is now bounded to one recoverable merge per PR per 2h, which may be an acceptable trade for a gate that actually fires.


🟡 Minor

  • Predicate 1 has the same proxy substitution, in the safe direction. MAIN_GREEN_CHECKS (:1743) proves "main-HEAD's originating PR was green," not "main-HEAD is green." The merge queue validates main-HEAD for the required set, so this is sound for the checks that matter; it's only loose for checks outside the merge-queue gate. Worth a one-line note in the comment that the guarantee is "green in the merge queue," not "green on the commit."
  • Failed updates re-attempt every scan. The marker is posted only on success (:2169); a persistent update-branch failure (merge conflict / missing allow-edits) re-hits the API and emits a base-update-failed row every scan, since it falls through without a marker. Rare (gated behind predicate 2), but a short-lived failure marker would quiet it.
  • Legacy commit-status contexts are silently outside the feature. (.name // .workflowName // "") (:2143) yields "" for a StatusContext (its label is .context), so select(. != "") drops it. Fine if everything is Actions check-runs; a landmine if any required gate is a classic status.
  • CANCELLED asymmetry: the PR-side selector (:2141) omits CANCELLED, while BASE_NOT_GREEN (:2134) and N_FAILED_CHECKS (:2186) include it. Conservative, but worth a comment so it reads as intentional.
  • The marker's 120-min window isn't actually tested. date -u -d is GNU-only; on the macOS dev box it errors, cutoff becomes "", and created_at > "" is always true — so the hasMarker case passes for the wrong reason and an old marker is never exercised. Prod (Linux) is correct; a fixed-epoch fixture would close the gap.

Verdict

Mechanically clean, safe by construction, well-tested at the block level, and the prior livelock is gone. The blocker-for-usefulness (not for safety) is the 🔴: please confirm predicate 2 can actually be satisfied by a real stranded PR before merging — I believe it can't, which would make the feature a no-op for #7490-class incidents. Everything else is polish.

中文说明

在 head 6ff5d98 审查。已在隔离 worktree 本地验证:提取块测试通过(auto-updates a PR red only from a stale base ✓,4.9s);两个"失败"是纯 5s 负载超时,在 --testTimeout=30000 下通过(9.5s/8.1s),故实测 97/97。运行到的 CI 腿为绿。

代码工艺很高,上一轮的问题也确实修好了。我唯一的实质担忧是新的,且落在最后一个提交(add base dimension)——恰是此前评审没覆盖的部分:@wenshao 的两次评审在 d8d0f21(predicate 2 尚不存在),triage 的 5/5 评的是只有 predicate 1 的设计。

做得好的地方: expected_head_sha CAS(:2166,2>&1 >/dev/null 顺序正确);处处 fail-safe 默认;marker guard 读的是每候选在 :1928 重取的 ic.json(在 :2112 块之前,注释标注为 load-bearing);self-limiting + marker + 失败落回一起消除了旧设计的 livelock;提取真实块并在 bash 下回放的测试方法学正确。

🔴 predicate 2 与"陈旧 base 变红"的定义自相矛盾——它几乎永远不会为目标场景触发。BASE_NOT_GREEN(:2133-2135)读的是 merge-base 对应 PR 的 head check-runs变红的检查。但"陈旧 base 变红"按定义就是合并前 CI 没抓到的坏——否则那个 base PR 根本不会合入。本仓库push 触发且用合并队列(ci.yml:6-9),PR head SHA 上只有 pull_request 的 check-runs,而已合并的 PR 在那上面是绿的(所以才合入)。于是:merge-base 那个提交对应的 PR 在后来搞坏 main 的检查上是绿的,而 predicate 2 要求它是的——两者互斥。对 #7490("在一个它从未触碰的测试上变红")具体走一遍:merge-base 是坏掉的 main 提交,其对应 PR 合并时该测试是绿的 ⇒ BASE_NOT_GREEN 不含它 ⇒ predicate 2 失败 ⇒ 不更新。predicate 2 读到的"merge-base 处为绿"恰恰是 base 继承红的特征,代码却把它当成"PR 自身回归"的证据而跳过。结果是 fail-safe(退化为人工现状),但对它自己的动机场景实际是 no-op。13 个用例抓不到这点:baseNotGreen 是字面输入,只验证"给定数组后的决策",从不验证生产中该数组能否非空。

建议:合并前做实证——对 #7490(或任一真实被搁置的 PR),取 GET /commits/{merge_base_sha}/pulls.[0].head.sha/check-runs,确认搁置的那个检查在那里确实是红。我预计它是绿的。若是,请把 predicate 2 换成能在合并队列模型下成立的信号——最贴合意图的是"PR 自身 diff 没有触碰失败检查所覆盖的区域"(比较 main...PR_HEAD 的文件列表 vs 该检查的领域,正是"从未触碰的测试"这个性质);或者干脆去掉 predicate 2,依赖 predicate 1 + behind + marker guard + self-limiting——此时 predicate 1 的误报被限制在每 PR 每 2 小时一次可恢复的 merge。

🟡 次要: predicate 1 有同样的代理替换但方向安全(证的是"main-HEAD 对应 PR 曾绿",非"main-HEAD 现绿";合并队列对必需检查成立);失败的更新每次扫描都会重试(成功才发 marker);遗留的 commit-status context 因 (.name // .workflowName // "") 取到 "" 而被静默排除;CANCELLED 在 PR 侧选择器省略而 base 侧包含(建议加注释表明有意);marker 的 120 分钟窗口实际未被测试(date -d 为 GNU 专有,macOS 上 cutoff 变空,> "" 恒真)。

**结论:**机械上干净、构造上安全、块级测试充分、旧 livelock 已除。唯一"影响有用性(非安全)"的是 🔴:合并前请确认 predicate 2 能被真实搁置 PR 满足——我认为不能,若如此则该功能对 #7490 类事件是 no-op。其余皆为打磨。

@qwen-code-ci-bot qwen-code-ci-bot left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed — no blockers. Suggestions are inline. 1 Suggestion-level finding(s) could not be anchored to a changed line and were dropped; nothing further to act on here.

— qwen3.7-max via Qwen Code /review

Comment thread scripts/tests/qwen-autofix-workflow.test.js
@qwen-code-dev-bot

Copy link
Copy Markdown
Collaborator

🤖 Addressed the latest review feedback (round 7/100). What changed, and what I pushed back on: · 已处理最新评审反馈(第 7/100 轮)。改动内容与我反驳保留之处如下:

Review feedback addressed

🔴 Predicate 2 (BASE_NOT_GREEN) is self-contradictory — @wenshao (review at 6ff5d98)

Decision: IMPLEMENTED — dropped predicate 2 entirely.

The reviewer correctly identified that BASE_NOT_GREEN reads the merge-base's originating PR's head check-runs and requires the failing check to have been red there. But in this repo's merge-queue model, a merged PR was green on all required checks (that's why it merged). So BASE_NOT_GREEN can never contain the stranding check for a genuine stale-base red — the feature was a no-op for #7490-class incidents.

Changes:

  • Removed the entire BASE_SHABASE_PR_HEADBASE_NOT_GREEN resolution block (3 API calls per candidate eliminated)
  • Removed $basered | index($n) from the STALE_BASE_REDS jq filter
  • The gate is now: failing check is GREEN on current main + PR is behind/diverged
  • Updated comments to explicitly acknowledge the limitation (cannot distinguish base-inherited red from the PR's own regression) and document the safety bounds: recoverable merge, marker limits re-updates to once per 2h, CAS via expected_head_sha
  • Updated log messages and PR comment body (EN + ZH) to remove "red at base" / "failed at the base" claims
  • Updated test: removed baseNotGreen parameter and the "green at merge-base → no update" case; simplified the gh mock (removed commits*pulls* and check-runs stubs)

🟡 Unguarded STALE_BASE_REDS jq — @wenshao

Decision: IMPLEMENTED. Added || STALE_BASE_REDS='[]' so a jq error fails safe (empty set → no update) instead of aborting the entire scan under set -eo pipefail.

🟡 CANCELLED asymmetry — @wenshao

Decision: IMPLEMENTED. Added a comment noting that CANCELLED is deliberately omitted from the PR-side selector (a cancelled check is not evidence of a stale base).

🟡 Predicate 1 proxy substitution note — @wenshao

Decision: IMPLEMENTED. The once-per-scan comment now explains that the guarantee is "green in the merge queue" (via the originating PR's check-runs), not "green on the commit" directly.

rc:3638150088 — FAIL_STATE test for .state fallback

Decision: IMPLEMENTED. Added FAIL_STATE helper ({ name, state: 'FAILURE' }) and a test case verifying the .conclusion // .state // "" fallback matches a check reported with only state.

rc:3637738960 — Empty PR_HEAD_OID guard test

Decision: IMPLEMENTED (partially). Added a test case with prHeadOid: '' verifying the -n "${PR_HEAD_OID}" guard prevents any update-branch call. The once-per-scan fetch block (MAIN_HEAD/MAIN_GREEN_CHECKS derivation) is not unit-tested because it calls gh api against live GitHub; the test harness injects MAIN_GREEN_CHECKS as an env var by design, matching the block's contract.

Deferred items (with reasons)

  • Failed updates re-attempt every scan (@wenshao 🟡): The fall-through to feedback processing is the designed behavior — a failed update is a human problem, but the bot's review comments need not be deferred. The marker bounds the success path; adding a separate failure marker is a separate concern that would grow the diff.
  • Legacy commit-status contexts (@wenshao 🟡): Fail-safe by design — (.name // .workflowName // "") yields "" for a StatusContext, which select(. != "") drops. No change needed.
  • Marker 120-min window not tested with fixed epoch (@wenshao 🟡): Requires GNU date mocking or a different approach; the test already validates the marker logic with a current timestamp. Deferred to avoid diff growth.
  • Selector drift (NON_BLOCKING_CHECKS) (@wenshao 🟡): The stale-base selector excludes ALL Qwen Autofix checks (!= "Qwen Autofix"), which is strictly narrower than the NON_BLOCKING_CHECKS carve-out. Harmless today and by construction.
  • DEFAULT_BRANCH knob (@wenshao 🟡): Not in this PR's diff; the MAIN_HEAD fetch hardcodes main consistently with candidate selection.
  • Ordering vs HAS_PENDING_CHECKS (@wenshao 🟡): Already commented in the block ("Runs after the round cap and pending-checks gates but before the feedback logic").
  • Test harness shell mismatch (@wenshao 🟡): The stale-base test already uses set -eo pipefail matching production. The infra test's set -uo pipefail is pre-existing and outside this PR's scope.

Verification

  • npx vitest run scripts/tests/qwen-autofix-workflow.test.js --testTimeout=30000 — 97/97 passed
  • npm run lint — passed
  • npm run typecheck — passed
  • npm run build — timed out in this environment (changes are YAML + JS test only, not TypeScript source; build output from runner setup is unaffected)
中文说明

已处理的评审反馈

🔴 Predicate 2(BASE_NOT_GREEN)自相矛盾 — @wenshao6ff5d98 处的评审)

决定:已实施 —— 完全移除 predicate 2。

评审者正确指出 BASE_NOT_GREEN 读取 merge-base 对应 PR 的 head check-runs,并要求失败检查在其中为红。但在本仓库的合并队列模型下,已合并的 PR 在所有必需检查上都是绿的(正因如此才能合并)。因此对于真正的陈旧 base 红色,BASE_NOT_GREEN 永远不可能包含搁置检查 —— 该功能对 #7490 类事件实际是空操作。

变更:

  • 移除了整个 BASE_SHABASE_PR_HEADBASE_NOT_GREEN 解析块(每候选减少 3 次 API 调用)
  • STALE_BASE_REDS jq 过滤器中移除 $basered | index($n)
  • 门现在为:失败检查在当前 main 上为绿 + PR 落后/分叉
  • 更新注释,明确承认局限性(无法区分 base 继承红与 PR 自身回归),并记录安全边界:可恢复的合并、marker 限制每 2 小时最多一次重更新、expected_head_sha 的 CAS
  • 更新日志消息和 PR 评论正文(中英文),移除"在 base 上失败"的表述
  • 更新测试:移除 baseNotGreen 参数和"merge-base 处为绿 → 不更新"用例;简化 gh mock

🟡 未保护的 STALE_BASE_REDS jq — @wenshao

决定:已实施。 添加 || STALE_BASE_REDS='[]',使 jq 错误时安全失败(空集 → 不更新),而非在 set -eo pipefail 下中止整个扫描。

🟡 CANCELLED 不对称 — @wenshao

决定:已实施。 添加注释说明 PR 侧选择器故意省略 CANCELLED(取消的检查不是陈旧 base 的证据)。

🟡 Predicate 1 代理替换说明 — @wenshao

决定:已实施。 每次扫描的注释现在解释保证是"在合并队列中为绿"(通过对应 PR 的 check-runs),而非直接在"提交上为绿"。

rc:3638150088 — .state 回退的 FAIL_STATE 测试

决定:已实施。 添加 FAIL_STATE 辅助函数({ name, state: 'FAILURE' })和测试用例,验证 .conclusion // .state // "" 回退能匹配仅有 state 的检查。

rc:3637738960 — 空 PR_HEAD_OID 保护测试

决定:已实施(部分)。 添加 prHeadOid: '' 测试用例,验证 -n "${PR_HEAD_OID}" 保护阻止任何 update-branch 调用。每次扫描的获取块(MAIN_HEAD/MAIN_GREEN_CHECKS 推导)未做单元测试,因为它调用 gh api 访问实际 GitHub;测试外壳按设计注入 MAIN_GREEN_CHECKS 环境变量,匹配该块的契约。

延迟项(附原因)

  • 失败的更新每次扫描都重试@wenshao 🟡):落回反馈处理是设计行为 —— 失败的更新是人工问题,但 bot 的评审评论不应被无限推迟。Marker 限制成功路径;添加单独的失败 marker 是另一个关注点,会增加 diff。
  • 遗留 commit-status context@wenshao 🟡):设计上安全失败 —— (.name // .workflowName // "")StatusContext 产出 "",被 select(. != "") 丢弃。无需更改。
  • Marker 120 分钟窗口未用固定时间戳测试@wenshao 🟡):需要 GNU date mock 或不同方法;测试已用当前时间戳验证 marker 逻辑。为避免 diff 增长而延迟。
  • 选择器漂移(NON_BLOCKING_CHECKS)@wenshao 🟡):陈旧 base 选择器排除所有 Qwen Autofix 检查(!= "Qwen Autofix"),严格窄于 NON_BLOCKING_CHECKS 例外。当前无害且构造上如此。
  • DEFAULT_BRANCH 旋钮@wenshao 🟡):不在本 PR 的 diff 中;MAIN_HEAD 获取硬编码 main,与候选筛选一致。
  • 与 HAS_PENDING_CHECKS 的先后顺序@wenshao 🟡):块中已有注释("在轮次上限和待处理检查闸之后、反馈逻辑之前运行")。
  • 测试外壳 shell 不匹配@wenshao 🟡):陈旧 base 测试已使用 set -eo pipefail 匹配生产。infra 测试的 set -uo pipefail 是既有的,不在本 PR 范围内。

验证

  • npx vitest run scripts/tests/qwen-autofix-workflow.test.js --testTimeout=30000 — 97/97 通过
  • npm run lint — 通过
  • npm run typecheck — 通过
  • npm run build — 在此环境超时(变更仅涉及 YAML + JS 测试,非 TypeScript 源码;runner 初始构建输出不受影响)

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/模型 qwen3.8-max-preview

@wenshao

wenshao commented Jul 23, 2026

Copy link
Copy Markdown
Collaborator Author

Code review — feat(autofix): auto-update a PR red only from a stale, since-fixed base

Reviewed at 1cbb0eaa (diff vs merge-base c5dddb5e, 2 files, +413/−15). I extracted the real decision block and replayed it under bash -eo pipefail with a stubbed gh, ran the suite (97/97 green), A/B-mutated the guard invariant, and probed the live GitHub API to see what MAIN_GREEN_CHECKS actually resolves to on this repo.

What it does

Once per scan the loop resolves main's head → the PR that produced it → that PR's head SHA, and reads the set of check names that concluded success there (MAIN_GREEN_CHECKS). Per candidate PR, after the round-cap and pending-checks gates and before the feedback logic, it compares main...PR-head; if the PR is behind/diverged and some non-Qwen Autofix check is red on the PR but present in MAIN_GREEN_CHECKS, it PUT /pulls/{n}/update-branch (CAS'd on expected_head_sha), posts an <!-- autofix-base-updated --> marker, and skips the PR for this scan. A 2h marker window bounds repetition; a failed update falls through to feedback processing.

The shape is right: merge not rebase, CAS on the head, fail-safe empty sets everywhere, self-limiting via the ahead compare, marker-bounded repetition, Qwen Autofix fully excluded on the PR side (strictly narrower than the review-address carve-out the other selectors use), and the new marker added to BOT_COMMENT_FILTER so the bot's own comment never counts as feedback. The replay confirms all of that behaves as documented — including index-0 matching in $green | index($n), exact (not substring) name matching, and the .conclusion // .state fallback.


Critical

1. The marker — the only repetition guard for a mutating action — is written without the job's mandatory identity check, with every error silenced

.github/workflows/qwen-autofix.yml:2158

gh pr comment "${PR}" --repo "${REPO}" --body "$(printf '🔀 Base updated: … <!-- autofix-base-updated -->')" > /dev/null 2>&1 || true

Both other comment writes in review-scan gate on SCAN_BOT_ACTOR and log a ::warning:: when identity is wrong — the engage ack (:1984) and the cap notice (:2106), whose comment states the reason verbatim:

Convention: verify the PAT identity before ANY write. A rotated PAT would post under a foreign login the dedup (which counts AUTOFIX_BOT comments only) can never see — reposting the notice every scan.

The new dedup at :2139-2143 is the same shape (select((.user.login // "") == $ab)), so it inherits the same failure — but the consequence is worse than a duplicate comment.

Failure scenario. CI_DEV_BOT_PAT is rotated to an account other than AUTOFIX_BOT (or the gh pr comment simply 403s/rate-limits — || true swallows it either way, with no log line). BASE_UPDATE_RECENT is then permanently false. A PR red on a check that is green in MAIN_GREEN_CHECKS — which the block's own comment at :1736 admits includes the PR's own regression — gets update-branch'd, CI re-runs ~40 min (HAS_PENDING_CHECKS blocks meanwhile), comes back red, main has advanced (*/10 cron, main moves ~13 min) so the compare is diverged again, and it updates again. Every ~45 min, per PR, across the managed fleet — each cycle burning a full CI run and, under dismiss_stale_reviews, dismissing approvals. That is exactly the churn the marker exists to prevent, and it is silent.

Also worth noting: update-branch at :2155 is itself a write and runs before any identity verification, which the convention above forbids.

Suggested fix — reuse the already-memoized variable, and stop treating the marker post as best-effort:

if [[ -z "${SCAN_BOT_ACTOR:-}" ]]; then
  SCAN_BOT_ACTOR="$(gh api user --jq '.login' 2> /dev/null || echo 'unknown')"
fi
if [[ "${SCAN_BOT_ACTOR}" != "${AUTOFIX_BOT}" ]]; then
  echo "::warning::stale-base update skipped: PAT authenticates as '${SCAN_BOT_ACTOR}', expected ${AUTOFIX_BOT}"
elif UPDATE_ERR="$(gh api -X PUT … )"; then
  …
  gh pr comment … > /dev/null 2>&1 \
    || echo "::warning::#${PR}: base-updated marker post failed — the 2h repetition guard is not armed for this update"
fi

2. MAIN_GREEN_CHECKS measures the last-merged PR's pre-merge CI, not main's health — so the load-bearing safety claim does not hold in the scenario the PR was written for

.github/workflows/qwen-autofix.yml:1744-1754

The stated invariant (:1734-1736, and the PR body) is:

We do that automatically when the failing check is GREEN on current main — main is healthy on it right now, so the update cannot pull a NEW breakage in.

I ran the exact chain against this repo:

main head          4f7429a0b93d78f388aa6bc0ecaf1c83a78e2c90
  → /commits/{sha}/pulls    → #7576, head 28504e2cd…
  → /commits/28504e2cd…/check-runs, conclusion==success
  → ["Classify PR","Test (ubuntu-latest, Node 22.x)","authorize",
     "delay-automatic-review","delete-asset-branch","precheck-pr / precheck",
     "remove-suspicious-attachments","review-config","review-pr","route",
     "triage","web-shell E2E Smoke (ubuntu-latest, Node 22.x)"]

Those are pull_request check-runs on the PR branch head. They ran against PR ⊕ main-as-of-then — never against the tree that is on main now. And a PR cannot merge unless they are green, so this set contains the required checks essentially by construction.

The consequence is an inversion, not a weakening. main breaks here by semantic conflict — two PRs green apart, broken together — which is precisely the "web-shell TypeScript break" in the PR body. In that state the last-merged PR (the one that broke main) is green, MAIN_GREEN_CHECKS reports the broken check as green, the gate opens, and the loop merges a currently-broken main into every stranded healthy PR. The one condition the design says makes the action "safe by construction" is false exactly when it matters.

A merge queue would close this — but ci.yml's merge_group trigger last fired 2026-07-02 (gh run list --workflow ci.yml --event merge_group), so merged trees are not being validated today. That is also why main can break at all, which is consistent with the two incidents cited.

Two smaller consequences of sourcing from a single PR:

  • Coverage is a lottery. On fix(core,cli): isolate teammate leader turns from agent context #7576, Test (macos-latest, Node 22.x) and Test (windows-latest, Node 22.x) were SKIPPED, so they are absent from the green set — a PR stranded on macOS Test can never be unstuck, purely because of which PR merged last. Fail-safe, but non-deterministic.
  • The comment at :1741 says "ci.yml has no push trigger, so its check-runs never land on main's squash commits". Accurate (main's head carries only skipped/null runs — I checked), but ci.yml does have merge_group, and a re-enabled merge queue would give a green source that genuinely validated the merged tree. Worth a line, since it changes the right implementation.

I do not think this sinks the feature — the marker guard, the CAS, and merge-not-rebase keep the blast radius recoverable. But the comment and PR body should stop claiming the gate proves main is healthy, and it is worth corroborating the signal before acting, e.g. requiring the check to be green across the last N merged PRs, or cross-checking that the same check is not currently red on other open PRs (a broad red is what "main is broken" actually looks like).

3. The "every failed-check selector carries a guard" invariant was relaxed into a near-vacuous assertion — A/B proven

scripts/tests/qwen-autofix-workflow.test.js:305-312

const carveOutCount   = (reviewScanJob.match(/startswith\("review-address"\)/g) ?? []).length;
const fullExclusionCount = (reviewScanJob.match(/!= "Qwen Autofix"/g) ?? []).length;
expect(carveOutCount + fullExclusionCount).toBeGreaterThanOrEqual(scanCheckSelectors.length);

!= "Qwen Autofix" is a substring of the carve-out expression itself (((.workflowName // "") != "Qwen Autofix") or (… startswith("review-address"))), so every carve-out selector increments both counters. Measured on this file:

selectors = 5   carveOutCount = 4   fullExclusionCount = 5   sum = 9

Four units of slack. Mutation, at the same neutral anchor in review-scan in both trees:

tree injected selector result
base c5dddb5e select((.conclusion // .state // "") | IN("FAILURE")), no guard at all expected [ Array(4) ] to have a length of 5 but got 4
PR 1cbb0eaa identical injection 97/97 pass

Per AGENTS.md — "a test weakened in this diff so new behavior passes is Critical" — and the regression is real: a future selector that reads the loop's own runs as feedback about the PR now sails through the test written to stop it.

The relaxation is legitimately needed (the new selector genuinely uses a different guard); only the form is wrong. Either count exclusion-only selectors:

const exclusionOnly = (
  reviewScanJob.match(/!= "Qwen Autofix"\)\)?\s*\)/g) ?? []
).length;
expect(carveOutCount + exclusionOnly).toBe(scanCheckSelectors.length);

or, more robustly, assert per selector that its own text carries one guard or the other:

const guardless = reviewScanJob
  .split(/(?=IN\("(?:FAILURE|QUEUED)")/)
  .slice(1)
  .filter((seg) => {
    const sel = seg.slice(0, 400);
    return (
      !/startswith\("review-address"\)/.test(sel) &&
      !/!= "Qwen Autofix"/.test(sel)
    );
  });
expect(guardless).toHaveLength(0);

Suggestion

4. The compare call is unconditional and pulls the full payload — ~60 KB × 60 candidates × every 10 minutes

.github/workflows/qwen-autofix.yml:2121-2127

if [[ -n "${MAIN_HEAD}" && -n "${PR_HEAD_OID}" ]]; then
  CMP="$(gh api "repos/${REPO}/compare/${MAIN_HEAD}...${PR_HEAD_OID}" 2> /dev/null || echo '{}')"
  CMP_STATUS="$(jq -r '.status // ""' <<< "${CMP}")"
  if [[ … ]]; then
    STALE_BASE_REDS="$(jq -c -n …)"   # pure jq over data already in memory — free

STALE_BASE_REDS costs nothing (it reads CHECKS_JSON and MAIN_GREEN_CHECKS, both already local) and is the far more selective predicate, yet the expensive network call runs first, for every candidate, including PRs with zero red checks. My replay confirms the compare fires even when the block is a guaranteed no-op. And with no --jq, the whole diff document lands in a shell variable — measured 60 785 bytes for this PR's own compare. With MAX_CANDIDATE_INSPECTIONS: '60' and a */10 cron, that is up to ~60 extra API calls and ~3.6 MB per scan, ~8 600 calls/day.

An earlier revision on this branch (edae6b74) had both right — if [[ "${STALE_BASE_REDS}" != '[]' && -n "${MAIN_HEAD}" && … ]] with --jq '.status'. Restoring that shape is a pure win and does not change behavior.

5. The rescue sits after the round-cap continue, so the most-stranded PRs are excluded

.github/workflows/qwen-autofix.yml:2067-2111 (round cap, continue) precedes the block at :2113. With MAX_ROUNDS: '10', a PR at or past its cap never reaches the stale-base check — but the PR body's own motivation is "stranded six healthy PRs (one at round 11)". The round cap exists to bound agent cycles; update-branch costs zero agent cycles and is exactly the mechanical unstick a capped-and-stranded PR needs. Moving the block above the round-cap gate (still below pending-checks) would cover the motivating case. If the current order is deliberate, the comment at :2117 should say why, since it currently reads as incidental.


Nice to have

  • :2140date -u -d '120 minutes ago' forks a subshell per candidate PR inside the loop. It is loop-invariant; hoist it next to PENDING_CUTOFF (:1726), which is already hoisted with exactly this reasoning ("invariant across candidate PRs, computed once").
  • :2132 — external commit statuses are silently excluded: a StatusContext in statusCheckRollup exposes .context, not .name, so .name // .workflowName // "" yields "" and select(. != "") drops it (confirmed by replay). Conservative and probably intended, but the comment at :2125 only calls out the CANCELLED omission — one more line would save the next reader the trace.
  • The PR body says 94/94; the branch is now at 97/97 after the later commits.

Security

Nothing exploitable found. RED_NAMES derives from check names (attacker-influenceable via a fork's workflow file) but only ever expands inside double quotes and reaches the comment body as a printf %s argument, so there is no injection path — worst case is cosmetic Markdown in a bot comment. expected_head_sha correctly prevents merging into a head the loop never inspected. Fork PRs without allow-edits land in the base-update-failed path, as documented.

中文摘要

1cbb0eaa 上审阅(对比 merge-base c5dddb5e)。我抽取真实决策块在 bash -eo pipefail 下用桩 gh 回放、跑了测试(97/97 通过)、对守卫不变量做了 A/B 变异验证,并调用真实 GitHub API 验证 MAIN_GREEN_CHECKS 在本仓库实际解析出什么。

整体设计方向正确:merge 而非 rebase、CAS 锁 head、各处失败安全、ahead 自限、marker 限制重复、PR 侧完全排除 Qwen Autofix、新 marker 已加入 BOT_COMMENT_FILTER。回放确认这些行为都与注释一致。

Critical 1(:2158:marker 是这个「会改仓库」的动作唯一的重复护栏,却没有走本 job 强制的 SCAN_BOT_ACTOR 身份校验,并且用 > /dev/null 2>&1 || true 吞掉了所有错误。同 job 的另外两处评论写入(:1984 引擎 ack、:2106 上限提示)都做了身份校验并在失败时 ::warning::,其注释明确写了原因。一旦 PAT 轮换(或评论 POST 只是限流失败),去重永远为 false:每约 45 分钟就会对同一个 PR 再做一次 update-branch(CI 重跑约 40 分钟 → main 前进 → compare 再次 diverged),在整个托管队列上反复烧 CI 并作废 approval,而且无任何日志。另外 :2155update-branch 本身也是写操作,却在任何身份校验之前执行。

Critical 2(:1744-1754MAIN_GREEN_CHECKS 量的不是 main 的健康度,而是「最后一个已合并 PR 的合并前 CI」。实测链路:main head 4f7429a0b → PR #7576 → head 28504e2cdpull_request check-runs。这些跑的是 PR ⊕ 当时的 main,且 PR 只有绿了才能合,所以这个集合几乎必然包含必需检查。而 main 恰恰是被语义冲突打破的(两个 PR 各自绿、合在一起坏 —— 正是 PR 描述里的 web-shell TS 事故):此时最后合并的那个 PR 是绿的,门会打开,循环于是把当前已坏的 main 合进所有健康 PR。「合入不会引入新故障」这一条恰好在最需要它的时候不成立。merge queue 本可堵住,但 ci.ymlmerge_group 最近一次触发是 2026-07-02。另外绿集合还是「抽签」:#7576 上 macOS/Windows 的 Test 是 SKIPPED,因此卡在 macOS Test 的 PR 永远救不回来。建议弱化注释与 PR 描述里的安全性断言,并加一个佐证信号(例如要求最近 N 个已合并 PR 都绿,或核对该检查是否同时红在其它 open PR 上)。

Critical 3(测试 :305-312!= "Qwen Autofix" 是 carve-out 表达式的子串,所以每个 carve-out 选择器会被两个计数器各记一次。实测 selectors=5、carveOut=4、fullExclusion=5、和=9 —— 有 4 个单位的松弛。变异验证:在同一中性锚点注入一个完全没有守卫的失败检查选择器,base 树报错 expected length 5 but got 4,PR 树 97/97 全绿。按 AGENTS.md「本 diff 中为让新行为通过而削弱的测试属于 Critical」。修法见上方英文代码块(按选择器逐个断言,或只统计「仅有全排除」的选择器并用 toBe)。

Suggestion 4(:2121-2127:compare 调用无条件先行且未加 --jq,把整份 diff 文档读进 shell 变量(本 PR 实测 60 785 字节)。而 STALE_BASE_REDS 是纯 jq、零成本且选择性强得多,应先算并短路。按 MAX_CANDIDATE_INSPECTIONS: '60'*/10 cron 计,每次扫描多约 60 次 API、约 3.6 MB。本分支早期版本(edae6b74)两点都是对的,建议恢复。

Suggestion 5(:2067-2111:2113:该逻辑位于 round-cap 的 continue 之后,MAX_ROUNDS: '10',因此达到上限的 PR 永远进不来 —— 但 PR 描述的动机正是「六个健康 PR(其中一个在第 11 轮)」。round cap 限的是 agent 轮次,而 update-branch 不消耗 agent 轮次。建议上移到 round-cap 之前(仍在 pending-checks 之后);若顺序是刻意的,请在 :2117 注释里写明理由。

Nice to have:2140date 是循环不变量,应像 PENDING_CUTOFF:1726)那样提到循环外;:2132 会静默排除外部 commit status(StatusContext.context 而非 .name),:2125 注释只提了 CANCELLED,值得补一句;PR 描述写的 94/94,当前分支已是 97/97。

安全:未发现可利用问题。RED_NAMES 只在双引号内展开、且以 printf %s 参数进入评论正文,无注入路径;expected_head_sha 正确阻止了对未审查 head 的合并。

@qwen-code-ci-bot qwen-code-ci-bot left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed — no blockers. Suggestions are inline.

— qwen3.7-max via Qwen Code /review

Comment thread .github/workflows/qwen-autofix.yml Outdated
Comment thread .github/workflows/qwen-autofix.yml
…rrect the green-checks safety claim, per-selector guard test, gate the compare call (#7554)
@qwen-code-dev-bot

Copy link
Copy Markdown
Collaborator

🤖 Addressed the latest review feedback (round 8/100). What changed, and what I pushed back on: · 已处理最新评审反馈(第 8/100 轮)。改动内容与我反驳保留之处如下:

Autofix review response — PR #7554

Addressed all three Critical findings, both inline Suggestions (and the
overlapping Suggestion 4), and the cheap nice-to-haves. One Suggestion
(round-cap ordering) is deferred with a recorded reason for a maintainer
decision. No conflict (--conflict false), so no merge was performed.

Critical

  • C1 — marker/update-branch written without the mandatory identity check
    (fixed).
    The stale-base block now verifies the PAT identity before ANY
    write, reusing the memoized SCAN_BOT_ACTOR exactly like the engage-ack and
    cap-notice writes: if the PAT authenticates as anyone other than
    AUTOFIX_BOT, the update-branch PUT and its marker are skipped with a
    ::warning:: (and a base-update-skipped fleet row) instead of writing under
    a foreign login the dedup can never see. The marker post is no longer
    silently swallowed — a failed post now logs a ::warning:: stating the 2h
    repetition guard is not armed, so the dedup gap is visible. Added a
    wrong-identity test case (skips the update, falls through to feedback).
  • C2 — MAIN_GREEN_CHECKS is a proxy, not proof main is healthy (comment
    corrected; design enhancement deferred).
    Rewrote the rationale comment and
    the per-PR gate comment. They no longer claim "the update cannot pull a NEW
    breakage in." The signal is now documented as a necessary-but-NOT-sufficient
    proxy sourced from the last-merged PR's pre-merge check-runs (which ran
    against that PR ⊕ main-as-of-then, never the tree now on main), with the
    semantic-conflict failure mode (two PRs green apart, broken together — the
    gate reads green while main is actually broken), the SKIPPED-platform matrix
    lottery, the recoverable-not-zero blast radius, and the note that ci.yml
    does have a merge_group trigger so a re-enabled merge queue would give a
    genuinely-validated green source. Deferred: corroborating the signal
    (green across the last N merged PRs, or cross-checking the check isn't broadly
    red on other open PRs). Reason: that is a larger behavioral/API-cost change
    warranting its own design decision; the review itself notes it does not sink
    the feature and the merge-not-rebase + CAS + marker keep the blast radius
    recoverable. The PR body's safety wording should be softened to match the
    corrected comment (the body is maintained by the workflow, not editable here).
  • C3 — the "every selector carries a guard" test was vacuous (fixed).
    Replaced the global-count assertion with a per-selector one: split
    reviewScanJob at each IN("FAILURE|QUEUED" anchor and assert each
    selector's own text (first 400 chars) carries the review-address carve-out or
    the full Qwen Autofix exclusion. Verified by A/B mutation — injecting a
    guardless failed-check selector now yields 1 guardless (test fails), whereas
    the old carveOutCount + fullExclusionCount >= selectors passed (4+5=9 ≥ 6)
    because != "Qwen Autofix" is a substring of the carve-out expression.

Suggestions

  • S4 / inline rc:3638579376 — unconditional full compare call (fixed).
    STALE_BASE_REDS (pure jq over data already in memory — free, and far more
    selective) is now computed FIRST and gates the compare round-trip, so green
    PRs and PRs whose red check is also red on main make no compare call at all.
    The compare also uses --jq '.status', so the ~60KB diff document is never
    pulled into a shell variable. This subsumes the inline suggestion.
  • inline rc:3638579394 — MAIN_GREEN_CHECKS population untested (fixed).
    Added a test that extracts the population block and runs it end-to-end against
    a stubbed gh: resolves main's head → the PR that produced it → that PR's
    check-runs, then concatenates pages and uniques them. Covers multi-page
    aggregation, single-page dedup, and all three failure paths (commits/main,
    /pulls, check-runs) failing safe to []. The success-only --jq predicate is
    pinned by a text assertion since the stub cannot execute it.
  • S5 — rescue sits after the round-cap continue (deferred). The reviewer
    is right that a capped-and-stranded PR (the round-11 motivation) never reaches
    the rescue, and that update-branch costs zero agent cycles. Deferred with
    reason:
    moving the block above the round-cap gate is a fleet-wide behavioral
    change to a mutating bot action, and the review framed it as an open question
    ("if the order is deliberate, the comment should say why"). This is a
    maintainer judgment call best made deliberately rather than slipped into a
    review round; flagging it here so it is not dropped.

Nice-to-have

  • :2140 (fixed) — the 2h marker cutoff is now hoisted as BASE_UPDATE_CUTOFF
    next to PENDING_CUTOFF (loop-invariant, computed once per scan).
  • :2132 (fixed) — added a comment noting external commit statuses are
    conservatively excluded (a StatusContext exposes .context, not
    .name/.workflowName, so it yields "" and is dropped).
  • PR body test count — the body says 94/94; the suite is now 98/98.

Verification

  • npx vitest run scripts/tests/qwen-autofix-workflow.test.js98 passed
    (was 97; +1 new test block for the MAIN_GREEN_CHECKS population; the
    wrong-identity case is an added assertion in the existing stale-base test).
  • A/B mutation check (standalone node) — current tree: 5 selectors / 0 guardless
    (passes); with an injected guardless selector: 6 selectors / 1 guardless
    (fails). Confirms C3 fix is meaningful.
  • npm run lint — passed.
  • npm run typecheck — passed.
  • npm run build — passed.
  • YAML parse of .github/workflows/qwen-autofix.yml (js-yaml) — passed.
中文说明

Autofix 评审回应 — PR #7554

已处理全部三个 Critical、两条 inline Suggestion(以及与之重叠的 Suggestion 4)和成本较低的 nice-to-have。其中一条 Suggestion(round-cap 顺序)附带理由推迟,留待维护者决定。无冲突(--conflict false),因此未执行 merge。

Critical

  • C1 — marker / update-branch 写入缺少强制身份校验(已修复)。 stale-base 代码块现在在任何写入之前先校验 PAT 身份,完全复用已 memoize 的 SCAN_BOT_ACTOR,与 engage-ack 和 cap-notice 两处写入一致:若 PAT 认证身份不是 AUTOFIX_BOT,则跳过 update-branch PUT 及其 marker,并打印一条 ::warning::(同时记一行 base-update-skipped fleet row),而不是以一个 dedup 永远看不到的外部登录身份去写。marker 发送不再被静默吞掉 —— 发送失败现在会打印一条 ::warning::,说明 2 小时重复护栏尚未武装,使 dedup 缺口可见。新增了一个「身份错误」测试用例(跳过更新、落到 feedback 处理)。
  • C2 — MAIN_GREEN_CHECKS 是代理信号,并非 main 健康的证明(已修正注释;设计增强推迟)。 重写了理由注释和每个 PR 的门控注释,不再声称「更新不会引入新故障」。该信号现在被如实描述为「必要但不充分」的代理:它取自最后一个已合并 PR 的合并前 check-runs(跑的是该 PR ⊕ 当时的 main,而非现在 main 上的树),并写明:语义冲突这一失效场景(两个 PR 各自绿、合在一起坏 —— 此时门读作绿,而 main 实际已坏)、SKIPPED 平台 job 导致的「抽签」覆盖、可恢复但非零的爆炸半径,以及 ci.yml 确实merge_group 触发器、重启 merge queue 即可得到一个真正经验证的绿源。推迟:对信号做佐证(要求最近 N 个已合并 PR 都绿,或核对该检查是否同时大面积红在其它 open PR 上)。理由:这是一项更大的行为 / API 成本变更,应单独立项设计;评审本身也指出它不足以否掉本功能,且 merge 而非 rebase + CAS + marker 使爆炸半径可恢复。PR 描述里的安全性措辞应与修正后的注释保持一致(描述由 workflow 维护,此处无法编辑)。
  • C3 — 「每个选择器都带守卫」的测试形同虚设(已修复)。 将「全局计数」断言替换为「逐选择器」断言:在每个 IN("FAILURE|QUEUED" 锚点处切分 reviewScanJob,断言每个选择器自身文本(前 400 字符)带有 review-address carve-out 或完整的 Qwen Autofix 排除。已用 A/B 变异验证 —— 注入一个无守卫的失败检查选择器现在会得到 1 个无守卫(测试失败),而旧的 carveOutCount + fullExclusionCount >= selectors 会通过(4+5=9 ≥ 6),因为 != "Qwen Autofix" 是 carve-out 表达式的子串。

Suggestions

  • S4 / inline rc:3638579376 — 无条件的整份 compare 调用(已修复)。 现在先计算 STALE_BASE_REDS(纯 jq、基于已在内存中的数据 —— 零成本且选择性强得多),由它来门控 compare 网络调用:绿色 PR、以及红检查在 main 上同样红的 PR,完全不会发起 compare。compare 也改用 --jq '.status',因此约 60KB 的 diff 文档永远不会被读进 shell 变量。这已涵盖该 inline 建议。
  • inline rc:3638579394 — MAIN_GREEN_CHECKS 的填充逻辑未被测试(已修复)。 新增测试:抽取填充代码块,用桩 gh 端到端运行 —— 解析 main 的 head → 产生它的 PR → 该 PR 的 check-runs,然后跨页拼接并去重。覆盖多页聚合、单页去重,以及三条失败路径(commits/main、/pulls、check-runs)都失败安全地得到 []。success-only 的 --jq 谓词用文本断言固定下来(因为桩无法执行它)。
  • S5 — 救援逻辑位于 round-cap 的 continue 之后(推迟)。 评审说得对:达到上限且卡住的 PR(第 11 轮这一动机)永远进不到救援逻辑,而 update-branch 不消耗任何 agent 轮次。附理由推迟: 把该代码块上移到 round-cap 门之前,是对一个会改仓库的 bot 动作的全fleet行为变更,且评审本身将其框定为开放问题(「若顺序是刻意的,注释应写明原因」)。这应由维护者审慎决定,而非夹带进一次评审回合;在此明确标出以免被遗漏。

Nice-to-have

  • :2140(已修复) — 2 小时 marker 截止时间现在作为 BASE_UPDATE_CUTOFF 提到 PENDING_CUTOFF 旁边(循环不变量,每次扫描只算一次)。
  • :2132(已修复) — 增加注释说明外部 commit status 被保守排除(StatusContext 暴露的是 .context 而非 .name/.workflowName,因此得到 "" 并被丢弃)。
  • PR 描述里的测试数 — 描述写的是 94/94;当前测试套件已是 98/98

验证

  • npx vitest run scripts/tests/qwen-autofix-workflow.test.js98 通过(原为 97;新增 1 个 MAIN_GREEN_CHECKS 填充测试块;「身份错误」用例是既有 stale-base 测试中新增的一条断言)。
  • A/B 变异检查(独立 node 脚本)— 当前树:5 个选择器 / 0 个无守卫(通过);注入一个无守卫选择器后:6 个选择器 / 1 个无守卫(失败)。确认 C3 修复确有实效。
  • npm run lint — 通过。
  • npm run typecheck — 通过。
  • npm run build — 通过。
  • .github/workflows/qwen-autofix.yml 的 YAML 解析(js-yaml)— 通过。

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/模型 qwen3.8-max-preview

@wenshao

wenshao commented Jul 23, 2026

Copy link
Copy Markdown
Collaborator Author

Review — round 3 (head d8a9f43)

Re-review after the two changes since my round-2 note: predicate 2 was dropped (my round-2 finding — it was self-defeating under a merge-queue repo with no push trigger) and the gate was reworked (green-checks now sourced from the last-merged PR's pre-merge check-runs, plus a PAT-identity gate before the write). Net: this is meaningfully better. The core control flow now reads clean, and — verified by executing the extracted block under bash with a stubbed gh — the round-1 livelock is genuinely fixed.

What the change does

Once per scan it resolves main's head → the PR that produced it → that PR's green check-run names (MAIN_GREEN_CHECKS). Per candidate PR: if a check fails on the PR but its name is in that set, and the PR is behind/diverged, it PUT /pulls/{n}/update-branch (a merge, CAS-guarded by expected_head_sha), posts a marker, and skips the PR this scan. A 2h marker + PAT-identity check + DRY_RUN + fall-through-on-failure round it out.

Credit where due (verified)

  • Livelock resolved. With a real cutoff, a 1h-old marker blocks re-update; a 3h-old marker lets it fire again → bounded to once/2h/PR, then it falls through to feedback. Executed, confirmed.
  • Honest downgrade of the safety claim in the code comment to "necessary-but-NOT-sufficient signal — NOT proof main is healthy," with the semantic-conflict hole documented. Good.
  • CAS via expected_head_sha; identity-gate before every write (matches the engage-ack/cap-notice convention, SCAN_BOT_ACTOR memoized); compute the free jq selector before the compare round-trip; fall-through on failed update so feedback isn't deferred forever. The per-selector carve-out test is a real improvement over the old vacuous count assertion.

1. [Medium — efficacy/accuracy, not a blocker] The gate still fires on a PR's own bug — the description's "rare / not a churn source" overstates selectivity

The gate — fails-on-PR ∧ same-name-green-on-main ∧ behind — is satisfied by two populations: (a) the target (base-inherited, since-fixed) and (b) a PR whose own diff breaks check X (main never had that diff → green on X). Case (b) is the normal state of an actively-iterating takeover PR, and nothing here distinguishes it.

I executed the extracted PR block on the (b) fingerprint — Test FAILURE on PR, MAIN_GREEN_CHECKS=["Test"], behind, no marker:

api repos/o/r/compare/mainhead999...prhead123 --jq .status
api user --jq .login
api -X PUT repos/o/r/pulls/1/update-branch -f expected_head_sha=prhead123   ← fires
pr comment 1 ... <!-- autofix-base-updated -->
→ CONTINUED (feedback SKIPPED this scan)

This is byte-for-byte a self-introduced Test failure, yet it update-branches and skips the fix cycle. It's now bounded (once/2h — good, that's the livelock fix), but "bounded churn" ≠ the PR body's:

it only fires when a check is confirmed base-inherited, which is rare, so it is not a churn source.

For a long-lived takeover PR (cap 100) that's red-on-its-own-bug and drifts behind main, the cost recurs every ~2h: one skipped fix scan + a ~40-min CI re-run + (under dismiss_stale_reviews) an approval dismissal. That's real, if bounded.

I recognize a cheap clean distinguisher is genuinely hard here (predicate 2 was the attempt, and it was rightly dropped), so bounding-with-a-marker is a defensible call. Minimum ask: correct the description to say bounded-churn, not zero-churn. Optional: gate on "no new actionable feedback this scan" — which is the feature's own stated rationale ("a stuck-on-stale-base PR often has no NEW feedback at all") and would scope it toward the genuine target.

2. [Low — test coverage] The 2h repetition window is unexercised

BASE_UPDATE_CUTOFF is hoisted above the loop and is never set in the vitest env, so in-test it expands to "" and select(.created_at > "") is true for any non-empty timestamp. Executed proof — same block, marker 3h old:

cutoff = 2h-ago (production-like)  → UPDATED   (window correctly expired)
cutoff = ''      (as in the suite) → no-update (any-age marker blocks)

So the hasMarker case passes for the wrong reason: it proves "a marker exists," not "the marker is within 2h." A regression that dropped > $cutoff would stay green. Pass BASE_UPDATE_CUTOFF into the harness and assert a >2h marker does not block. (Production uses GNU date on the runner, so the live logic is correct — this is purely a coverage gap.)

3. [Low — ordering] The round-cap gate precedes stale-base

The ROUND >= EFF_MAX_ROUNDS → continue at ~L2131 runs before the stale-base block, so a PR that reached its cap while stranded red-on-stale-base — the exact "terminally stranded" case this PR targets — is never auto-updated. Narrow in practice (a purely-stranded PR rarely burns rounds, and takeover cap is 100), but a base-merge isn't an agent fix round; consider whether it should run before the cap.

4. [Nit] autofix-base-updated filter asymmetry is harmless

It's added to the scan-site BOT_COMMENT_FILTER but not the 3 address-site regex filters (unlike autofix-rearm, which is in all 4). Harmless — all 4 sites also select(.user.login != AUTOFIX_BOT) and the marker is bot-authored, so it's excluded everywhere regardless; the BOT_COMMENT_FILTER addition is effectively redundant. Only noting it because the inconsistency with the autofix-rearm precedent could bite if the marker were ever posted under a different identity.

5. [Nit] .[0] from /commits/{sha}/pulls

MAIN_PR_HEAD takes the first associated PR. Fine for a squash/merge commit (single PR) and fail-safe to [] on a direct push, but the array order isn't API-guaranteed — worth a one-line note.


Verdict: not blocking. The mechanism is safe-by-construction (recoverable merges, CAS, identity-gated, bounded), and the livelock is fixed. The substantive ask is to align the description with the bounded-churn reality (#1); #2 is a quick test fix; #3#5 are minor.

中文说明

第 3 轮评审(head d8a9f43)。 自我上轮以来的两处改动——去掉了 predicate 2(我上轮指出:在无 push 触发、合并队列的仓库里它自相矛盾),并重做了门控(green-checks 现从最后合并 PR 的合并前 check-runs 取,写操作前加 PAT 身份校验)——总体是实质改进。经用 bash + 桩 gh 实际回放决策块验证:第 1 轮的 livelock 已真正修复

给予肯定(已验证): livelock 已解决(真实 cutoff 下,1 小时前的 marker 会拦截,3 小时前的会放行 → 上限为每 PR 每 2 小时一次);代码注释诚实降级为"必要但不充分、并非 main 健康之证明";CAS、写前身份校验、先算免费 jq 再走 compare、失败后 fall-through 到反馈;per-selector 守卫测试较旧的计数断言是真进步。

1.(中 — 有效性/描述准确性,非阻塞) 门控仍会命中 PR 自身的 bug:红在 PR、同名绿在 main、落后——这既覆盖目标(base 继承),也覆盖"PR 自己的 diff 弄坏了检查 X"(main 从无此 diff 故绿),而后者正是迭代中 PR 的常态,二者无法区分。实测该指纹会触发 update-branch 并跳过本轮修复。现已有界(每 2 小时一次,这是 livelock 的修复),但"仅在确诊 base 继承时触发、很罕见、不是搅动源"的描述言过其实。干净且廉价的判别器确实难做(predicate 2 已被正确移除),用 marker 设界是可接受的工程取舍;最低要求:把描述改为"有界搅动"而非"零搅动"。可选:改为"本轮无新的可处理反馈时才动手"。

2.(低 — 测试覆盖) 2 小时重复窗口未被测到:BASE_UPDATE_CUTOFF 在 vitest 环境里从未设置 → 展开为 "",created_at > "" 恒真。实测:真实 cutoff 下 3 小时的 marker 会放行、空 cutoff 下则拦截。故 hasMarker 用例通过的原因是错的(只证明"有 marker",没证明"在 2h 内")。建议把 BASE_UPDATE_CUTOFF 传入并断言 >2h 的 marker 不拦截。(生产用 runner 的 GNU date,活逻辑正确,这纯属覆盖缺口。)

3.(低 — 顺序) 轮次上限门在 stale-base 之前:达到上限又卡在 stale-base 的 PR(正是本 PR 想救的"终态搁置")永不会被自动更新。实践中较窄,但 base-merge 并非一次 agent 修复轮,值得考虑是否前置。

4.(细节) autofix-base-updated 只加进扫描站过滤、未加进 3 个 address 站——无害(四处都先按 .user.login != AUTOFIX_BOT 过滤,marker 为 bot 所发,处处被排除),该处添加实为冗余;仅提示与 autofix-rearm 的先例不一致。

5.(细节) MAIN_PR_HEAD/commits/{sha}/pulls.[0]:对 squash/merge 提交(单 PR)没问题、直推时 fail-safe 为 [],但数组顺序非 API 保证,建议加一行注释。

结论:非阻塞。 机制在构造上安全(可恢复的 merge、CAS、身份门、有界),livelock 已修。主要诉求是让描述与"有界搅动"的现实一致(#1);#2 是快速测试补强;#3#5 为次要。

Reviewed with Claude Code. Findings #1 and #2 are backed by executing the PR's extracted decision block under bash with a stubbed gh.

@qwen-code-ci-bot qwen-code-ci-bot left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues found. LGTM! ✅

— qwen3.7-max via Qwen Code /review

# --jq '.status': the compare document is ~60KB; only the
# behind/diverged/ahead status is needed.
CMP_STATUS="$(gh api "repos/${REPO}/compare/${MAIN_HEAD}...${PR_HEAD_OID}" --jq '.status // ""' 2> /dev/null || echo '')"
if [[ "${CMP_STATUS}" == 'behind' || "${CMP_STATUS}" == 'diverged' ]]; then

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Suggestion] diverged status also triggers update-branch, which could introduce more semantic conflicts. The CAS + merge (revertable) controls blast radius, and the comment acknowledges this risk — acceptable trade-off.

— qwen3.8-max-preview via Qwen Code /review

# the update would merge a currently-broken main into a healthy PR. The
# signal also inherits the last PR's matrix shape (a SKIPPED platform
# job is absent, so a PR stranded on it is never unstuck — fail-safe,
# but non-deterministic). The blast radius stays recoverable, not zero:

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Suggestion] MAIN_GREEN_CHECKS is based on last-merged PR's pre-merge check-runs, not main's current tree (ci.yml has no push trigger). In semantic conflict scenarios this signal may false-positive green. The comment documents this limitation well — merge queue is the proper fix.

— qwen3.8-max-preview via Qwen Code /review

@yiliang114 yiliang114 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. Well-designed stale-base auto-update with proper safety gates (failing check must pass on main + behind/diverged + CAS + 2h marker guard). Thorough test coverage. Two inline suggestions on known trade-offs (diverged semantic conflicts, MAIN_GREEN_CHECKS limitation) — both already well-documented in comments.

— qwen3.8-max-preview via Qwen Code /review

@wenshao
wenshao added this pull request to the merge queue Jul 23, 2026
Merged via the queue into main with commit 5003ee7 Jul 23, 2026
90 of 91 checks passed
@qwen-code-dev-bot

Copy link
Copy Markdown
Collaborator

🤖 Addressed the latest review feedback (round 9/100). What changed, and what I pushed back on: · 已处理最新评审反馈(第 9/100 轮)。改动内容与我反驳保留之处如下:

Review feedback addressed (round 4, head 092b687)

Inline comments

  • [rc:3639421793] diverged status triggering update-branch — Declined. The reviewer acknowledges this is an "acceptable trade-off." The diverged case means the PR has commits main lacks AND main has commits the PR lacks — merging main in is the correct action. The CAS guard (expected_head_sha) and revertible merge control blast radius. The code comment already documents the semantic-conflict risk. No change needed.

  • [rc:3639421956] MAIN_GREEN_CHECKS sourced from last-merged PR's pre-merge check-runs — Declined. The reviewer acknowledges "merge queue is the proper fix." The limitation is already documented in the code comment (the long MAIN_GREEN_CHECKS rationale block). A re-enabled merge queue would let us source from a genuinely validated merged tree. Out of scope for this PR.

Issue-level findings (@wenshao, round 3)

  1. [Medium] Description overstates selectivityAcknowledged; PR body needs correction. The code comments are already honest ("necessary-but-NOT-sufficient signal," "NOT proof main is healthy," bounded-churn via marker). The PR body's "rare / not a churn source" claim should be corrected to "bounded churn (once per 2h per PR)." The PR body is managed by the workflow, not this commit. The optional suggestion to gate on "no new actionable feedback this scan" is a larger restructuring deferred to a follow-up.

  2. [Low] 2h repetition window unexercised in testsFixed. Added BASE_UPDATE_CUTOFF (2h-ago ISO timestamp) to the test harness env, added a markerAgeMin parameter (default 30 — within the window), and added a test case asserting a 3h-old marker does NOT block re-updating. The existing hasMarker: true case now genuinely exercises the cutoff comparison rather than passing vacuously.

  3. [Low] Round-cap gate precedes stale-baseDeclined. The round cap is a hard safety bound that should not be bypassed. A base-merge for a capped PR would re-run CI and potentially dismiss stale reviews, which is a design decision beyond this PR's scope. The reviewer acknowledges this is "narrow in practice" (a purely-stranded PR rarely burns rounds, and takeover cap is 100).

  4. [Nit] autofix-base-updated filter asymmetryFixed. Added autofix-base-updated to all 3 address-site BOT_COMMENT_FILTER regexes, matching the scan site and the autofix-rearm precedent. Updated the test assertion to require the marker at all 4 sites (removed the optional group from the regex).

  5. [Nit] .[0] from /commits/{sha}/pullsFixed. Added a 2-line comment noting the array order is not API-guaranteed, fine for a squash/merge commit (single associated PR), and fail-safe to "" on a direct push.

Verification

  • npm run build — passed
  • npm run typecheck — passed
  • npm run lint — passed
  • npx vitest run scripts/tests/qwen-autofix-workflow.test.js — 98 passed (98)
中文说明

评审反馈处理(第 4 轮,head 092b687

行内评论

  • [rc:3639421793] diverged 状态触发 update-branch — 拒绝。 评审者已确认这是"可接受的取舍"。diverged 意味着 PR 有 main 缺少的提交,且 main 有 PR 缺少的提交——合入 main 是正确操作。CAS 守卫(expected_head_sha)和可回滚的 merge 控制了影响范围。代码注释已记录了语义冲突风险。无需修改。

  • [rc:3639421956] MAIN_GREEN_CHECKS 取自最后合并 PR 的合并前 check-runs — 拒绝。 评审者已确认"合并队列才是正解"。该局限性已在代码注释中记录(MAIN_GREEN_CHECKS 的长段说明)。重新启用合并队列后,可从经过真正验证的合并树中获取。超出本 PR 范围。

Issue 级发现(@wenshao,第 3 轮)

  1. [中] 描述夸大了选择性已确认;PR 正文需修正。 代码注释已经诚实("必要但不充分的信号"、"并非 main 健康的证明"、通过 marker 实现有界搅动)。PR 正文中"罕见/不是搅动源"的说法应修正为"有界搅动(每 PR 每 2 小时一次)"。PR 正文由工作流管理,不在本次提交范围内。关于"本轮无新可处理反馈时才动手"的可选建议是较大的重构,留待后续。

  2. [低] 2 小时重复窗口未在测试中验证已修复。 在测试 harness 的 env 中添加了 BASE_UPDATE_CUTOFF(2 小时前的 ISO 时间戳),添加了 markerAgeMin 参数(默认 30——在窗口内),并添加了断言 3 小时前的 marker 不阻止重新更新的测试用例。现有的 hasMarker: true 用例现在真正验证了 cutoff 比较,而非空泛通过。

  3. [低] 轮次上限门在 stale-base 之前拒绝。 轮次上限是硬性安全边界,不应被绕过。对已达上限的 PR 执行 base-merge 会重新运行 CI 并可能驳回过期评审,这是超出本 PR 范围的设计决策。评审者已确认这在实践中"较窄"(纯搁置的 PR 很少消耗轮次,且接管上限为 100)。

  4. [细节] autofix-base-updated 过滤器不对称已修复。 在全部 3 个 address 站的 BOT_COMMENT_FILTER 正则中添加了 autofix-base-updated,与扫描站和 autofix-rearm 先例保持一致。更新了测试断言,要求所有 4 个站点都包含该 marker(移除了正则中的可选组)。

  5. [细节] /commits/{sha}/pulls.[0]已修复。 添加了 2 行注释,说明数组顺序非 API 保证,对 squash/merge 提交(单个关联 PR)没问题,直推时 fail-safe 为 ""

验证

  • npm run build — 通过
  • npm run typecheck — 通过
  • npm run lint — 通过
  • npx vitest run scripts/tests/qwen-autofix-workflow.test.js — 98 通过(98)

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/模型 qwen3.8-max-preview

qwen-code-dev-bot pushed a commit that referenced this pull request Jul 23, 2026
yiliang114 pushed a commit to yiliang114/qwen-code that referenced this pull request Jul 26, 2026
Reverts QwenLM#7602. The Fleet Shepherd (qwen-fleet-shepherd.yml) now keeps the
bot fleet within 25 commits of main by proactively update-branching,
and QwenLM#7595 already retries a stale-base gate rejection at ANY behind
distance instead of parking — so a PR no longer parks because its base
went stale. That leaves QwenLM#7602 firing only on a PR parked by a GENUINE
failure that later drifted behind main, where re-arming it just re-runs
a real failure on a fresh base — speculative, near-zero value, and it
carried its own autofix-handoff marker plus scan/report logic and tests.
The retroactive cases it was built for (PRs parked before QwenLM#7595) were
already recovered by hand.

Keeps QwenLM#7595 (reactive stale-base gate recovery below the shepherd's
threshold) and QwenLM#7554 (check-driven stale-base sync) — both cover the
sub-25-behind window and triggers the shepherd does not.

Co-authored-by: wenshao <wenshao@example.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

autofix/takeover Summon the autofix loop to manage this PR (remove to release; needs triage+)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants