Skip to content

fix(cli): deliver teammate messages at tool-round boundaries, not whole-task end - #9638

Open
yiliang114 wants to merge 25 commits into
mainfrom
fix/issue-8172-teammate-round-boundary
Open

fix(cli): deliver teammate messages at tool-round boundaries, not whole-task end#9638
yiliang114 wants to merge 25 commits into
mainfrom
fix/issue-8172-teammate-round-boundary

Conversation

@yiliang114

Copy link
Copy Markdown
Collaborator

What this PR does

Teammate→leader messages in Agent Team now reach the leader at the boundary between tool-call rounds instead of waiting for the leader's entire multi-round task to finish. When a tool round completes and its results are about to be submitted back to the model, any queued teammate envelopes are drained and appended to that same submission as user text after the tool-response parts — the exact mechanism and ordering already used for mid-turn "steer" input at that site. The existing drain-on-Idle path stays untouched as the fallback for turns that end without another tool round. The queue state moved to the top of useGeminiStream so the tool-completion dispatcher can drain it, and drained batches are restored on every failure path (cancelled/preempted boundary, admission/delivery failure), so messages are never lost or delivered twice.

Why it's needed

streamingState is only Idle when nothing is responding and no tracked tool call is scheduled/validating/executing or terminal-but-unsubmitted. In a long agentic task, back-to-back tool rounds keep that condition continuously true — the isResponding dip between rounds is bridged by the just-scheduled/just-completed tool calls — so the teammate drain effect (which requires Idle) never fires until the whole task concludes. A message sent early in a multi-minute task sat queued the entire time, far beyond the "delivered when your turn ends" behavior the send_message tool description promises. The isSubmittingQueryRef guard from #4844 correctly prevents message loss but does nothing about the delay.

The issue listed possible directions without prescribing one ("not prescribing one"). This PR picks round-boundary injection because: (a) surfacing a queued-message count in the UI would only make the wait visible, not fix delivery; (b) an interrupt/cancel-and-resume path for urgent messages is materially riskier inside the live tool loop and can be layered later; (c) rewording the tool description lowers expectations without improving behavior; while round-boundary injection reuses a pattern already proven in production for steer messages, delivers between rounds without interrupting in-flight tools, and matches the reporter's verified design analysis in the issue thread (which the triage run also confirmed).

Reviewer Test Plan

How to verify

Reproduced at component level before the fix (red tests), then verified green. New tests in packages/cli/src/ui/hooks/useGeminiStream.test.tsx (describe teammate messages during multi-round tool tasks (#8172)):

  • injects queued teammate messages into the next tool-round submission instead of waiting for the whole task — the core red→green repro: message queued while a round is executing, round completes through the real handleCompletedTools path, envelope must ride the SendMessageType.ToolResult submission after the tool-response parts, with the compact ● … notification rendered at delivery; no double delivery when the state later reaches Idle. Failed before the fix (envelope stayed queued, round went out without it), passes after.
  • delivers later teammate messages after an earlier round-boundary delivery — a message arriving after a boundary delivery is not swallowed; delivered via the Idle fallback when the task ends. Failed before the fix (both messages batched at whole-task end), passes after.
  • still delivers queued teammate messages at Idle when the task ends without another tool round — regression guard for the existing fallback path (green before and after).
  • does not lose queued teammate messages when the round boundary was cancelled — regression guard: a cancelled boundary must not carry the message away in a tool-result submission; the message survives and is delivered once the state settles (green before and after).

Run: npx vitest run packages/cli/src/ui/hooks/useGeminiStream.test.tsx from repo root (or inside packages/cli). Full file: 234/234 pass. Also verified: packages/cli and packages/core npm run typecheck clean; ESLint + Prettier clean on both changed files.

Evidence (Before & After)

No live TUI capture: reproducing this in a real session requires a multi-agent team where a teammate messages the leader mid-way through the leader's long multi-round task, which could not be staged deterministically in this environment. Verification is at the component level via the red→green tests above (they drive the real handleCompletedTools/submitQuery path with the mocked scheduler, exactly where the bug lives). Marking TUI evidence as not provided rather than faking it.

Tested on

OS Status
🍏 macOS ⚠️
🪟 Windows ⚠️
🐧 Linux

Environment (optional)

Unit/component tests only (vitest under packages/cli), no live runtime.

Risk & Scope

  • Main risk or tradeoff: teammate envelopes injected via the ToolResult path share steer's known sidecar properties — dualOutput.emitUserMessage and the Notification/Teammate recordNotification branch are skipped for tool-result submissions, so the injected text is not separately journaled to the sidecar/chat-recording the way the Idle-path SendMessageType.Teammate submission is. This is identical to how steer text behaves today at the same site; the model still receives the envelope in the round's user content.
  • Delivery scope v1: this covers the normal tool-round boundary (handleCompletedTools), which is the reported case. The two exotic round-starting paths steer additionally covers via getSteerInput (duplicate-tool-response bypass and the three internal no-tool-call continuations in client.ts) are not covered for teammate messages; they fall back to the Idle drain, i.e. today's behavior, so no regression — full parity can be a follow-up if needed.
  • Not validated / out of scope: live multi-agent e2e and TUI screenshots (see Evidence); no change to TeamManager/mailbox queueing (verified correct in the issue); compaction explicitly not touched (issue author already ruled it out as an independent cause).
  • Breaking changes / migration notes: none; the Idle drain, the feat: add Agent Team experimental feature for parallel sub-agent coordination #4844 isSubmittingQueryRef race guard, and the streamingState derivation are unchanged.

Linked Issues

Fixes #8172

中文说明

这个 PR 做了什么

Agent Team 中 teammate→leader 的消息,现在会在工具调用轮次之间的边界送达 leader,而不是等 leader 的整个多轮任务全部结束。当一轮工具调用完成、结果即将回传给模型时,排队的 teammate 消息信封会被排空,并作为 user 文本追加到同一次提交的 tool-response parts 之后——与该位置既有的 mid-turn steer 输入完全相同的机制和顺序。原有的 Idle 时排空路径保持不变,作为"本轮之后没有新工具轮次"场景的兜底。队列状态移到了 useGeminiStream 顶部以便工具完成分发器排空;被排空的批次在所有失败路径(边界被取消/被抢占、准入失败/投递失败)都会还原来保证消息不丢、不重复投递。

为什么需要

streamingState 只有在没有响应中、且没有任何 tracked 工具调用处于 scheduled/validating/executing 或"已终态但未提交"状态时才为 Idle。在长 agentic 任务中,一轮接一轮的工具调用让该条件持续为真——轮次之间 isResponding 的短暂回落会被刚调度/刚完成的工具调用 bridging 掉——所以 teammate 排空 effect(要求 Idle)在整个任务结束前都不会触发。任务早期发来的消息会在队列里躺满整个任务时长(可能是几分钟),远超 send_message 工具描述承诺的"delivered when your turn ends"。#4844 引入的 isSubmittingQueryRef 守卫正确地防止了消息丢失,但解决不了延迟问题。

issue 里列了几个可能方向但没有指定任何一个("not prescribing one")。本 PR 选择轮次边界注入,理由是:(a) 在 UI 上显示排队消息数量只能让等待可见,不能修复投递;(b) 为紧急消息做中断/取消重启路径,在运行中的工具循环里风险明显更大,可以后续再做;(c) 改工具描述文案只是降低预期,不改善行为;而轮次边界注入复用了 steer 消息已在生产中验证过的模式,在不打断在途工具的前提下实现轮次间投递,并且与报告者在 issue 线程里经过代码核实的设计分析一致(triage 运行也确认了这一点)。

Reviewer 测试计划

如何验证

修复前先做了组件级复现(红测试),修复后转绿。新测试位于 packages/cli/src/ui/hooks/useGeminiStream.test.tsx(describe 块 teammate messages during multi-round tool tasks (#8172)):

  • injects queued teammate messages into the next tool-round submission instead of waiting for the whole task——核心红转绿复现:消息在一轮工具执行中入队,轮次通过真实的 handleCompletedTools 路径完成,信封必须跟随 SendMessageType.ToolResult 提交、位于 tool-response parts 之后,且投递时渲染紧凑的 ● … 通知;状态后续到 Idle 时不重复投递。修复前失败(信封留在队列里,轮次提交不带它),修复后通过。
  • delivers later teammate messages after an earlier round-boundary delivery——边界投递之后到达的消息不会被吞掉;任务结束时走 Idle 兜底投递。修复前失败(两条消息在整个任务结束时才被一起批量投递),修复后通过。
  • still delivers queued teammate messages at Idle when the task ends without another tool round——既有兜底路径的回归守护(修复前后都绿)。
  • does not lose queued teammate messages when the round boundary was cancelled——回归守护:被取消的边界不能把消息带进 tool-result 提交;消息存活并在状态稳定后送达(修复前后都绿)。

运行方式:在仓库根目录执行 npx vitest run packages/cli/src/ui/hooks/useGeminiStream.test.tsx(或在 packages/cli 内运行)。整个文件 234/234 通过。另外已验证:packages/clipackages/corenpm run typecheck 干净;两个改动文件的 ESLint + Prettier 干净。

前后对比证据

没有做 live TUI 截图:要在真实会话里复现,需要一个多 agent 团队在 leader 的长多轮任务中途给 leader 发消息,本环境无法确定性地搭出来。验证停留在组件级的红转绿测试(它们用 mocked scheduler 驱动真实的 handleCompletedTools/submitQuery 路径,正是 bug 所在的位置)。如实标注未提供 TUI 证据,不伪造。

测试环境

OS 状态
🍏 macOS ⚠️
🪟 Windows ⚠️
🐧 Linux

环境(可选)

仅单元/组件测试(packages/cli 下的 vitest),无 live runtime。

风险与范围

  • 主要风险或取舍:通过 ToolResult 路径注入的 teammate 信封与 steer 有相同的 sidecar 属性——dualOutput.emitUserMessage 和 Notification/Teammate 的 recordNotification 分支对 tool-result 提交是跳过的,所以注入的文本不会像 Idle 路径的 SendMessageType.Teammate 提交那样单独写入 sidecar/聊天记录。这与 steer 文本在同一位置的现有行为完全一致;模型仍然能在该轮的 user 内容里收到信封。
  • v1 投递范围:覆盖常规工具轮次边界(handleCompletedTools),即本 issue 报告的场景。steer 额外通过 getSteerInput 覆盖的两条特殊轮次启动路径(重复工具响应旁路、client.ts 里三条无工具调用的内部 continuation)对 teammate 消息暂不覆盖;它们会落回 Idle 兜底,即现状行为,无回归——如需要可作为后续 follow-up 做完全对齐。
  • 未验证/不在范围内:live 多 agent e2e 与 TUI 截图(见上);未改动 TeamManager/邮箱排队侧(issue 中已核实该侧正确);明确不碰 compaction(issue 作者已排除其为独立成因)。
  • 破坏性变更/迁移说明:无;Idle 排空、feat: add Agent Team experimental feature for parallel sub-agent coordination #4844isSubmittingQueryRef 竞态守卫、streamingState 推导均未改动。

关联 Issue

Fixes #8172

…le-task end

Teammate→leader messages were only drained into the leader's session
when `streamingState === Idle`. During a long multi-round agentic task
`streamingState` never reaches Idle between rounds (tool calls are
continuously scheduled/executing or terminal-but-unsubmitted), so
queued teammate messages waited for the entire task — minutes — even
though the tool description promises delivery when the current turn
ends (#8172).

Drain `teammateQueueRef` at the tool-round boundary in
`handleCompletedTools`, appending the envelopes after the
tool-response parts of the next `SendMessageType.ToolResult`
submission — the same mechanism and ordering already used for steer
messages at that exact site (tool_result blocks lead the user
message). The existing Idle drain stays as the fallback for turns
that end without another tool round.

Race/loss safety: the drain is skipped on cancelled boundaries and
generation-change-surviving continuations (mirroring steer), and the
batch is restored (idempotently) on cancel/preempt/admission/delivery
failure so messages are never lost or double-delivered. The
`isSubmittingQueryRef` guard (#4844) on the Idle path is untouched.
@qwen-code-ci-bot

qwen-code-ci-bot commented Aug 21, 2026

Copy link
Copy Markdown
Collaborator

Qwen Triage finishedview run. See the stage comments in this thread for the result.

Qwen Triage 已完成 —— 查看运行。结果见本线程中的各阶段评论。

@qwen-code-ci-bot

qwen-code-ci-bot commented Aug 21, 2026

Copy link
Copy Markdown
Collaborator

Re-run at head 1c23c6f2 — gates re-checked after the R15-1 fix commit (fix(core): restore retry entries per send).

  • Template: complete ✓ — all required sections, bilingual, honest about the scoped-out paths and the missing live-TUI capture (unchanged since the last pass).
  • Problem: observed, not theoretical — Agent Team: teammate messages queue for the entire duration of a long multi-tool-call turn, not just the next response #8172 carries a verified design analysis, and the fix was preceded by component-level red→green reproduction. Not a hardening PR.
  • Direction: unchanged and still aligned — teammate messages arriving at tool-round boundaries is exactly what the send_message tool description promises ("delivered when your turn ends"), and round-boundary injection reuses the steer site already proven in production instead of adding a new mechanism. A maintainer's live multi-agent A/B (2026-08-24) already stood in for the live-evidence lane on an earlier head.
  • Size: cross-package change touching core paths (packages/cli + packages/core): 760 production lines (use-llm-stream.ts 622, client.ts 108, llm-chat.ts 30) vs 2,483 test lines (use-llm-stream.test.tsx 2,105, client.test.ts 378). That is over the 500-line maintainer-awareness threshold for non-refactor core changes — flagged for maintainer awareness, not blocked on size (this is a fix, and size alone never requests changes here).
  • Approach: scope still feels right for what this thread converged on — every mechanism in the diff (generation-guarded drain, settlement carrier, fingerprinted retry debt) answers a named finding from earlier rounds, and I see no unrelated change or drive-by. The standing observation also stands: this is a large surface accumulated over 16 review rounds, and a maintainer should be the one to merge it.
  • Risk: no Stage 1e high-risk-path match on the current file set.

The gate passes on direction; the size escalation means this run cannot auto-approve regardless of review outcome — and the review itself found a concrete blocker at this head (see the Stage 2 comment).

中文说明

在头提交 1c23c6f2 上重跑——在 R15-1 修复提交(fix(core): restore retry entries per send)之后重新检查各项门槛。

  • 模板:完整 ✓——所有必需章节齐全、双语,对被排除在外的路径和缺失的 live-TUI 证据如实说明(与上次检查相比无变化)。
  • 问题:已观测到的问题,不是理论性加固——Agent Team: teammate messages queue for the entire duration of a long multi-tool-call turn, not just the next response #8172 带有经过核实的设计分析,修复之前先做了组件级红转绿复现。不是加固型 PR。
  • 方向:不变,仍然对齐——teammate 消息在工具轮次边界送达正是 send_message 工具描述所承诺的行为("delivered when your turn ends"),轮次边界注入复用了已在生产中验证过的 steer 注入位置,而不是新增机制。维护者在 2026-08-24 做的 live 多 agent A/B 已在较早的头提交上替代了 live 证据这一环。
  • 规模:跨包改动且触及核心路径(packages/cli + packages/core):760 生产行use-llm-stream.ts 622、client.ts 108、llm-chat.ts 30),对比 2,483 测试行use-llm-stream.test.tsx 2,105、client.test.ts 378)。超过非 refactor 类核心改动 500 行的"维护者知悉"阈值——标记提请维护者知悉,但不因规模阻断(这是 fix 类型,规模本身在这里从不作为 request changes 的理由)。
  • 方案:就本线程历轮评审收敛的结果而言,范围仍然合理——diff 中的每个机制(带代际守卫的排空、结算载体、带指纹的 retry 债务)都对应此前某一轮的具体发现,未见无关改动或顺手重构。一贯的观察也仍然成立:这是 16 轮评审累积出来的大表面积,合并决定应由维护者做出。
  • 风险:当前文件集合未命中 Stage 1e 高风险路径。

方向上通过门槛;规模升级意味着无论评审结果如何本次运行都不能自动批准——而评审本身在这个头提交上发现了一个具体阻断项(见 Stage 2 评论)。

Qwen Code · qwen3.8-max

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

@qwen-code-ci-bot

qwen-code-ci-bot commented Aug 21, 2026

Copy link
Copy Markdown
Collaborator

Code review at 1c23c6f2 — R15-1 verified fixed, but this head's own suite is red

The R15-1 fix is structurally right. The last round's Critical was the outer-finally restoreStrippedRetryEntries() gate in client.ts still deciding the re-add by the GLOBAL user-content push counter — while the adjacent carrier settlement had already abandoned exactly that assumption. This head replaces the gate with the per-send anchor R15-1 asked for, and I re-derived it from the diff rather than the closeout note:

  • LlmChat.sendMessageStream publishes the pre-push counter on the caller's request array under userContentPushSnapshotKey, with no await between publish and push (llm-chat.ts) — the comparison window around the push is empty.
  • restoreStrippedRetryEntries() and settleSteerInput() in client.ts now restore unconditionally when no snapshot was published ("this send provably never reached its push site") and compare against the published snapshot otherwise. A concurrent /btw push in the unwind window can no longer masquerade as this send's counter growth — the exact R15-1 failure shape.
  • The two early-exit catches (hook failure, Goal admission) settle the carrier and re-add the popped retry entries before rethrowing, closing the exits that bypass the settlement try/finally.
  • The new client.test.ts pins reproduce the concurrent-push window for every settle path, and the repurposed restores stripped retry entries when only a concurrent send pushes is the direct regression pin for the R15-1 shape.

Blocker: Test (ubuntu-latest, Node 22.x) fails at this head — 2 tests in the PR's own change area. The packages/core suite finishes Test Files 1 failed | 616 passed, Tests 2 failed | 22196 passed, both in client.test.ts > sendMessageStream > retry sendMessageType:

  1. does not re-add stripped retry entries when the chat already pushed them before failing
  2. does not re-add stripped retry entries when auto-compression shrank history below the pre-send length after the push

Both are pre-existing pins of the OLD global-counter gate this commit replaced, left un-updated: their mockTurnRunFn simulates the push by bumping getUserContentPushCount but never publishes userContentPushSnapshotKey, so the new code reads "no snapshot ⇒ this send never pushed ⇒ restore unconditionally", re-adds the entries, and expect(mockChat.addHistory).not.toHaveBeenCalled() fails (verified against the failure excerpt at client.test.ts:11041). The diff updated four sibling tests to publish the snapshot miniature ("Miniature of GeminiChat's contract") — these two were missed. The production behavior both tests guard is preserved: real LlmChat always publishes immediately before the push, so "already pushed ⇒ suppress" still holds in production and the fix is a test-only follow-up — give the two mocks the same miniature their siblings got (in the compression test, publish after the simulated compression, matching llm-chat.ts's order).

The rest of the delta re-checked clean: the CLI-side drain/settlement (drainTeammateQueue generation guard, settleDrainedTeammates strip-on-both-outcomes, fingerprinted retry debt, the admission-gate pre-check in retryLastPrompt) matches what earlier rounds pinned, and the 21 new use-llm-stream.test.tsx cases cover the round-boundary paths, swap drops, and the Ctrl+Y cycles. Not re-litigated: the two Suggestion-level deferrals recorded in round 15 (swap-drop comment placement; retry carrier restore branch test pairing) — still standing, still non-blocking.

Testing — the PR's own CI at 1c23c6f2, read via the API (this run executes no PR code):

The failing leg is genuinely PR-caused — both failing tests sit in the exact region this commit rewrote the contract for, and they pass on the pre-fix gate they were written against. Log excerpt (job 99070844679):

× Gemini Client (client.ts) > sendMessageStream > retry sendMessageType > does not re-add stripped retry entries when the chat already pushed them before failing
× Gemini Client (client.ts) > sendMessageStream > retry sendMessageType > does not re-add stripped retry entries when auto-compression shrank history below the pre-send length after the push
 FAIL  src/core/client.test.ts > ... > does not re-add stripped retry entries when the chat already pushed them before failing
   11041|         expect(mockChat.addHistory).not.toHaveBeenCalled();
 Test Files  1 failed | 616 passed | 1 skipped (618)
      Tests  2 failed | 22196 passed | 10 skipped (22208)

One honest caveat: the packages/cli unit suite did not complete in this run (the job ended before it finished once packages/core failed), and Integration Tests (CLI, No Sandbox) plus the macos/windows legs are skipped at this head — so a green re-run after the pin fix still needs to show the full matrix.

Check Conclusion
Test (ubuntu-latest, Node 22.x) — packages/core suite ❌ failure — client.test.ts 2 failed / 22196 passed (see findings)
Test (ubuntu-latest, Node 22.x) — packages/cli suite ⚠️ did not complete (job ended after the core failure)
Test (macos-latest / windows-latest, Node 22.x) ⏭️ skipped at this head
Integration Tests (CLI, No Sandbox) ⏭️ skipped
Integration Tests (no-AK, No Sandbox) ✅ success
Desktop Shell (ubuntu-22.04 / windows-2022) ✅ success
Security Checks (Secret scan, Dependency CVE audit) ✅ success
web-shell E2E Smoke (ubuntu-latest, Node 22.x) ⏳ queued
Qwen Code CI (workflow) 🔄 in progress

Sandboxed verification would settle the one claim CI cannot — that envelopes still arrive at round boundaries without loss or duplication under the new snapshot settlement: the /verify run triggered alongside this re-run is already in flight; re-trigger @qwen-code /verify once the suite is green.

中文说明

1c23c6f2 上的代码审查 —— R15-1 已确认修复,但该头提交自身的测试套件是红的

R15-1 的修复在结构上是正确的。 上一轮的 Critical 是 client.ts 外层 finally 里的 restoreStrippedRetryEntries() 仍在用全局 user-content push 计数器决定是否重新添加——而紧邻的载体结算早已放弃了同样的假设。这个头提交按 R15-1 要求的"按每次发送锚定"替换了该判定,且以下结论是我从 diff 重新推导的,不是照抄收尾说明:

  • LlmChat.sendMessageStream 在 push 之前、且 publish 与 push 之间没有任何 await 的情况下,把 push 前的计数器以 userContentPushSnapshotKey 发布到调用方的 request 数组上(llm-chat.ts)——push 周围的比较窗口为空。
  • client.ts 中的 restoreStrippedRetryEntries()settleSteerInput():没有发布快照时无条件恢复("这次发送确定没有到达 push 点"),有快照则与发布的快照比较。unwind 窗口内的并发 /btw push 不再能冒充本次发送的计数器增长——正是 R15-1 的失败形态。
  • 两个提前退出分支(hook 失败、Goal 准入失败)在重新抛出之前完成载体结算并把弹出的 retry 条目加回历史,堵住了绕过结算 try/finally 的出口。
  • client.test.ts 的新测试为每条结算路径复现了并发 push 窗口;改写后的 restores stripped retry entries when only a concurrent send pushes 就是 R15-1 形态的直接回归钉。

阻断项:Test (ubuntu-latest, Node 22.x) 在该头提交上失败——2 个失败用例都在本 PR 的改动区域内。 packages/core 套件结果为 Test Files 1 failed | 616 passedTests 2 failed | 22196 passed,两个失败都在 client.test.ts > sendMessageStream > retry sendMessageType

  1. does not re-add stripped retry entries when the chat already pushed them before failing
  2. does not re-add stripped retry entries when auto-compression shrank history below the pre-send length after the push

两者都是钉住旧全局计数器判定的既有测试,而本提交恰恰替换了该判定,它们没有被同步更新:其 mockTurnRunFn 只通过递增 getUserContentPushCount 模拟 push,从不发布 userContentPushSnapshotKey,于是新代码读成"无快照 ⇒ 本次发送从未 push ⇒ 无条件恢复",把条目加了回去,expect(mockChat.addHistory).not.toHaveBeenCalled() 因此失败(已对照 client.test.ts:11041 的失败摘录核实)。diff 已把四个同类测试更新为发布快照的"微缩契约"——这两个被漏掉了。这两个测试守护的生产行为其实仍然成立:真实 LlmChat 总是在 push 前一刻发布快照,"已 push ⇒ 抑制重加"在生产中不变,因此修复只需改测试——给这两个 mock 补上同类测试已有的微缩契约即可(压缩那个测试要在模拟压缩之后再发布,与 llm-chat.ts 的实际顺序一致)。

增量其余部分复查无问题:CLI 侧的排空/结算(drainTeammateQueue 的代际守卫、settleDrainedTeammates 两种结果都剥离、带指纹的 retry 债务、retryLastPrompt 里的准入门预检)与历轮钉住的行为一致,use-llm-stream.test.tsx 新增的 21 个用例覆盖了轮次边界路径、swap 丢弃与 Ctrl+Y 循环。不再重提:第 15 轮记录的两条建议级延后项(swap-drop 注释位置;retry carrier restore 分支缺测试配对)——仍然存在,仍然非阻断。

测试证据——通过 API 读取 1c23c6f2 上本 PR 自己的 CI(本次运行不执行任何 PR 代码):

失败腿确系本 PR 所致——两个失败用例恰好位于本提交重写契约的区域,且在它们为之编写的旧判定下是通过的。日志摘录见英文部分。一个如实的说明:本轮 packages/core 失败后 packages/cli 单测套件未跑完,Integration Tests (CLI, No Sandbox) 与 macos/windows 腿在该头提交上为跳过状态——因此钉修复之后的绿灯重跑仍需展示完整矩阵。

CI 明细表见英文部分的 qwen-triage-ci 区块(表格不重复翻译)。

沙箱验证可以了结 CI 无法证明的那条行为主张——新快照结算下信封仍在轮次边界送达、不丢不重:随本次重跑触发的 /verify 已在运行中;套件转绿后可再次触发 @qwen-code /verify

Qwen Code · qwen3.8-max

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

@qwen-code-ci-bot

qwen-code-ci-bot commented Aug 21, 2026

Copy link
Copy Markdown
Collaborator

Confidence: 2/5 — the R15-1 fix is structurally right and re-derived from the code, but this head ships with the PR's own suite red in the exact region it rewrote, and nothing approves on top of that.

Stepping back over the whole picture:

  • The fix matches the independent proposal. R15-1 asked for the re-add gate to move off the global counter onto a per-send push outcome; the natural design is a snapshot published at the push site with no await between, plus unconditional restore when no snapshot exists. That is exactly what 1c23c6f2 implements, with the early-exit catches settled symmetrically and regression pins for each window. No simpler correct path was missed.
  • The blocker is narrow and test-only. Two pre-existing pins of the old global-counter gate were left un-updated while four sibling tests got the new snapshot miniature. Production behavior both pins guard is preserved (real LlmChat always publishes before the push) — the commit that introduced the new contract just needs to bring its own test file along. One focused commit fixes it; the CI log excerpt and exact tests are named in the Stage 2 comment.
  • What is NOT in question this round: the mechanism set (drain/settlement/retry-debt) is the accumulated, reviewed answer to 16 rounds of findings, the maintainer's live multi-agent A/B on an earlier head confirmed the user-visible behavior, and the direction gate passed again. The two round-15 Suggestion deferrals remain standing and non-blocking.
  • Standing policy note: at 760 production lines across packages/cli + packages/core, Stage 0 escalated this PR for maintainer awareness — so even once CI is fully green, this flow caps at defer-to-maintainer rather than auto-approve. @wenshao, as the most recent human reviewer (and the one who built the live multi-agent lane), the merge call on this one is yours.

Verdict: request changes — solely for the red suite at this head. @yiliang114 the two tests named in the Stage 2 comment need the same snapshot miniature their siblings got (compression test: publish after the simulated compression); everything else in this round checks out, and a green full-matrix re-run is the remaining gate before the maintainer call.

中文说明

置信度:2/5 —— R15-1 的修复在结构上是正确的,且是从代码重新推导核实的;但该头提交携带着自身测试套件在其重写区域内变红,任何批准都不能建立在这之上。

退一步看整体:

  • 修复与独立提案一致。 R15-1 要求把重加判定从全局计数器移到"每次发送的 push 结果"上;自然的设计就是在 push 点发布快照(publish 与 push 之间无 await),无快照时无条件恢复。1c23c6f2 实现的正是这一点,两个提前退出分支也对称地完成结算,并为每个窗口补了回归钉。没有遗漏更简单的正确路径。
  • 阻断项很窄且只需改测试。 两个钉住旧全局计数器判定的既有测试没有同步更新,而四个同类测试已经换上了新的快照微缩契约。这两个测试守护的生产行为仍然成立(真实 LlmChat 总是在 push 前发布快照)——引入新契约的提交只需要把自己的测试文件带上。一个聚焦提交即可修复;CI 日志摘录和具体用例名见 Stage 2 评论。
  • 本轮不在讨论范围内的: 机制集合(排空/结算/retry 债务)是 16 轮评审发现累积出的已审答案;维护者在较早头提交上的 live 多 agent A/B 已确认用户可见行为;方向门槛再次通过。第 15 轮的两条建议级延后项仍然有效、非阻断。
  • 一贯的政策说明: 760 生产行、跨 packages/cli + packages/core,Stage 0 已将本 PR 升级为"维护者知悉"——因此即便 CI 全绿,本流程也止步于转交维护者而非自动批准。@wenshao 作为最近的人类评审(也是搭出 live 多 agent 验证的人),合并决定权在你。

结论:request changes —— 仅因该头提交上的红色套件。@yiliang114 Stage 2 评论点名的两个测试需要补上同类测试已有的快照微缩契约(压缩那个测试:在模拟压缩之后发布);本轮其余部分均核实无问题,转绿后的全矩阵重跑是维护者拍板前剩下的唯一门槛。

Qwen Code · qwen3.8-max

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

@github-actions

github-actions Bot commented Aug 21, 2026

Copy link
Copy Markdown
Contributor

Code Coverage Summary

Package Lines Statements Functions Branches
CLI 85.69% 85.69% 91.09% 84.65%
Core N/A% N/A% N/A% N/A%
CLI Package - Full Text Report
-------------------|---------|----------|---------|---------|-------------------
File               | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
-------------------|---------|----------|---------|---------|-------------------
All files          |   85.69 |    84.65 |   91.09 |   85.69 |                   
 src               |   86.45 |    82.24 |   88.23 |   86.45 |                   
  cli.ts           |   95.68 |    84.11 |     100 |   95.68 | ...60-561,565-566 
  llm.tsx          |   73.22 |    77.73 |   80.76 |   73.22 | ...1345-1349,1476 
  ...ractiveCli.ts |   89.27 |    83.13 |   89.06 |   89.27 | ...3157,3163,3229 
  ...liCommands.ts |   89.71 |    84.17 |   81.81 |   89.71 | ...31-633,650,757 
  ...ActiveAuth.ts |     100 |     87.5 |     100 |     100 | 66-80             
 ...cp-integration |   74.57 |    77.36 |   93.65 |   74.57 |                   
  acpAgent.ts      |   73.63 |    77.23 |   92.93 |   73.63 | ...02,13080-13081 
  ...k-reporter.ts |     100 |       80 |     100 |     100 | 81,84,119,141     
  authMethods.ts   |      92 |       60 |     100 |      92 | 33-34             
  ...heap-probe.ts |   97.39 |    96.66 |     100 |   97.39 | 243,264-265       
  errorCodes.ts    |     100 |      100 |     100 |     100 |                   
  ...ion-skills.ts |     100 |     87.5 |     100 |     100 | 17,28             
  generation.ts    |    97.1 |    81.25 |     100 |    97.1 | 109,112           
  ...figuration.ts |     100 |    89.65 |     100 |     100 | 79,125,142        
  ...DirContext.ts |     100 |      100 |     100 |     100 |                   
  ...ersistence.ts |   94.95 |    92.24 |     100 |   94.95 | ...13-118,227-228 
  ...management.ts |   74.75 |     66.3 |     100 |   74.75 | ...92-496,505-509 
  ...e-download.ts |    64.7 |    62.24 |    87.5 |    64.7 | ...08-609,615-619 
 ...tegration/live |    97.5 |       88 |   92.85 |    97.5 |                   
  ...en-context.ts |   95.74 |    82.35 |     100 |   95.74 | ...0,66-67,99-100 
  ...structions.ts |     100 |      100 |     100 |     100 |                   
  ...ak-to-user.ts |   96.66 |      100 |    87.5 |   96.66 | 37-38             
  ...task-tools.ts |   98.97 |      100 |   88.88 |   98.97 | 201-202           
 ...ration/service |    97.1 |    95.89 |   93.75 |    97.1 |                   
  filesystem.ts    |    97.1 |    95.89 |   93.75 |    97.1 | ...22-123,246-247 
 ...ration/session |    90.9 |    86.48 |   95.67 |    90.9 |                   
  Session.ts       |   90.27 |    85.23 |   95.03 |   90.27 | ...85,13212-13216 
  ...entTracker.ts |   96.88 |    89.36 |      90 |   96.88 | 139-145,224       
  ...projection.ts |   98.85 |    91.59 |     100 |   98.85 | 234,250,262       
  ...stop-guard.ts |     100 |    98.07 |     100 |     100 | 37,127            
  ...eplay-page.ts |   94.19 |    86.53 |     100 |   94.19 | ...53,357,437,441 
  ...y-replayer.ts |   83.41 |    93.33 |   94.11 |   83.41 | ...30-148,266-268 
  index.ts         |       0 |        0 |       0 |       0 | 1-40              
  ...ssionUtils.ts |   89.19 |     87.8 |     100 |   89.19 | ...85-304,363-365 
  ...oal-update.ts |   98.61 |    97.29 |     100 |   98.61 | 64                
  ...lure-guard.ts |   98.32 |    97.72 |     100 |   98.32 | 294-295,340-341   
  tasksSnapshot.ts |    94.3 |     87.5 |     100 |    94.3 | 65-71             
  ...on-tracker.ts |     100 |      100 |     100 |     100 |                   
  types.ts         |     100 |      100 |     100 |     100 |                   
 ...ssion/emitters |   95.65 |    92.34 |   97.14 |   95.65 |                   
  ...ageEmitter.ts |   95.36 |    92.42 |     100 |   95.36 | ...16,129-130,223 
  PlanEmitter.ts   |     100 |       90 |     100 |     100 | 66                
  base-emitter.ts  |   78.26 |    77.77 |     100 |   78.26 | 23-24,26-28       
  index.ts         |       0 |        0 |       0 |       0 | 1-10              
  ...ll-emitter.ts |   98.57 |    94.84 |     100 |   98.57 | 75-76,394-395     
 ...ession/rewrite |   96.03 |    89.79 |   94.44 |   96.03 |                   
  LlmRewriter.ts   |   94.01 |    88.23 |     100 |   94.01 | 101-102,179-183   
  ...Middleware.ts |   96.99 |    88.37 |     100 |   96.99 | 145,153-155       
  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/agent-view    |   86.63 |    80.77 |   94.01 |   86.63 |                   
  attach-lease.ts  |     100 |    97.05 |     100 |     100 | 173               
  ...t-cli-argv.ts |     100 |     92.3 |     100 |     100 | 15                
  ...ged-detach.ts |     100 |     90.9 |     100 |     100 | 40,64             
  presentation.ts  |   94.13 |    88.72 |   94.73 |   94.13 | ...57-358,382-384 
  protocol.ts      |     100 |      100 |     100 |     100 |                   
  pty-host-env.ts  |     100 |      100 |     100 |     100 |                   
  ...st-process.ts |   88.43 |    78.79 |   94.44 |   88.43 | ...1294,1384-1386 
  pty-host.ts      |   85.25 |    87.03 |   90.69 |   85.25 | ...22-524,539-540 
  ...sor-client.ts |   80.38 |    72.27 |   77.41 |   80.38 | ...22-626,652-656 
  ...r-dispatch.ts |      98 |    85.18 |     100 |      98 | 117,173,190       
  ...or-process.ts |    83.5 |    77.26 |   98.72 |    83.5 | ...4479-4482,4485 
  ...sor-runner.ts |   82.43 |    76.82 |   80.95 |   82.43 | ...69,493,496-506 
  ...sor-server.ts |   84.39 |    83.56 |    93.1 |   84.39 | ...67-568,571-588 
  ...isor-store.ts |   94.76 |    84.95 |     100 |   94.76 | ...,966,1008,1023 
  ...nal-bridge.ts |   93.98 |    91.54 |   83.33 |   93.98 | 228-238           
  ...r-sideband.ts |   94.91 |    89.36 |     100 |   94.91 | ...75-276,299-304 
 src/commands      |   90.69 |    78.53 |   65.62 |   90.69 |                   
  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        |    98.9 |      100 |      50 |    98.9 | 102               
  serve.ts         |   89.46 |    76.02 |     100 |   89.46 | ...12-915,927,938 
  sessions.ts      |     100 |      100 |      50 |     100 |                   
  update.ts        |   98.13 |    94.44 |   66.66 |   98.13 | 82-83             
 ...mmands/channel |   89.55 |    88.76 |   90.68 |   89.55 |                   
  channel-cwd.ts   |     100 |      100 |     100 |     100 |                   
  ...l-registry.ts |   94.78 |    94.59 |      90 |   94.78 | ...32-335,380-383 
  ...entry-path.ts |      75 |       50 |     100 |      75 | 8-9               
  config-utils.ts  |   96.84 |    96.22 |     100 |   96.84 | ...40-245,303-306 
  configure.ts     |    14.7 |      100 |       0 |    14.7 | 18-21,23-84       
  daemon-worker.ts |   94.07 |    85.96 |   94.33 |   94.07 | ...1292,1299-1300 
  loop-runtime.ts  |   91.66 |      100 |      50 |   91.66 | 15,22             
  ...classifier.ts |   98.53 |    96.66 |     100 |   98.53 | 115-116,161       
  ...tact-store.ts |   93.51 |    87.65 |     100 |   93.51 | ...71,288-289,337 
  pairing.ts       |      75 |      100 |      50 |      75 | 22-28,59-70       
  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       |   82.43 |    86.44 |     100 |   82.43 | ...87-191,251-253 
  set.ts           |   75.72 |    85.71 |      50 |   75.72 | 65-83,111-116     
  start.ts         |    87.7 |    83.63 |      88 |    87.7 | ...95,601-604,616 
  ...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.85 |    87.91 |   87.09 |   88.85 |                   
  consent.ts       |   72.53 |    90.32 |   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 |     90.9 |     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.63 |    57.14 |     100 |   75.63 | ...30-134,136-140 
 ...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  |   91.19 |    88.76 |   85.71 |   91.19 |                   
  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.9 |    84.84 |      80 |    92.9 | ...79-181,199-200 
  reconnect.ts     |   85.54 |    86.76 |    90.9 |   85.54 | 45-58,337-359     
  remove.ts        |     100 |       80 |     100 |     100 | 21-25             
 ...ommands/review |   91.93 |    90.42 |    93.8 |   91.93 |                   
  ab-drive.ts      |   85.22 |    90.47 |   94.11 |   85.22 | ...50-926,969-972 
  agent-prompt.ts  |   94.89 |    92.99 |   97.95 |   94.89 | ...3289,3624-3704 
  base-tree.ts     |   77.02 |    80.76 |   77.77 |   77.02 | ...63-384,386-399 
  capture-local.ts |   94.72 |    97.61 |   94.11 |   94.72 | 271,1336-1374     
  ...k-coverage.ts |   50.71 |       35 |   66.66 |   50.71 | ...40-245,279-289 
  cleanup.ts       |   92.34 |     89.5 |    90.9 |   92.34 | ...1107,1109-1110 
  comment-body.ts  |   67.85 |    87.09 |   66.66 |   67.85 | ...30,157,159-164 
  ...ent-status.ts |   94.22 |    87.32 |    90.9 |   94.22 | ...96,462,738-758 
  ...ose-review.ts |   97.37 |    94.03 |   98.73 |   97.37 | ...6486-6530,6790 
  cost-ledger.ts   |   94.58 |     94.4 |   81.25 |   94.58 | ...53-654,694-704 
  drive.ts         |   97.12 |    89.85 |     100 |   97.12 | ...83-985,990-992 
  extract-step.ts  |   91.36 |    90.62 |   88.88 |   91.36 | ...90-707,714-729 
  fetch-diff.ts    |   73.75 |      100 |   66.66 |   73.75 | 77-97             
  fetch-pr.ts      |   97.29 |    92.25 |     100 |   97.29 | ...1566,1724-1729 
  findings.ts      |    96.3 |    93.68 |     100 |    96.3 | ...1418,1427-1428 
  issue-context.ts |   88.15 |     93.1 |   85.71 |   88.15 | 249-276           
  load-rules.ts    |   26.41 |      100 |   16.66 |   26.41 | ...41-153,155-156 
  match-remote.ts  |   85.55 |     92.3 |   66.66 |   85.55 | 74-79,144-150     
  meta.ts          |   79.43 |    93.75 |   66.66 |   79.43 | 123-128,147-162   
  mock-provider.ts |   95.44 |    90.25 |   89.47 |   95.44 | 145,690-709       
  parse-args.ts    |   99.48 |    95.74 |     100 |   99.48 | 665,990,1046,1082 
  plan-diff.ts     |   71.42 |      100 |   66.66 |   71.42 | 162-197           
  pr-context.ts    |   96.22 |    88.86 |     100 |   96.22 | ...2580,2681-2697 
  presubmit.ts     |   94.32 |    90.83 |   94.11 |   94.32 | ...1219,1254-1285 
  ...ish-assets.ts |    81.3 |    82.22 |   85.71 |    81.3 | ...75-479,506-552 
  ...r-findings.ts |   90.74 |    83.75 |     100 |   90.74 | ...17-422,429-430 
  repo-context.ts  |   94.62 |    90.75 |     100 |   94.62 | ...66-467,482-487 
  ...ve-anchors.ts |   78.34 |    89.28 |      75 |   78.34 | ...83-188,200-217 
  revert-hunk.ts   |   91.48 |    87.94 |     100 |   91.48 | ...1189,1236-1239 
  run.ts           |   84.47 |    87.58 |   95.45 |   84.47 | ...00,816-870,884 
  save-artifact.ts |    94.2 |    92.46 |   94.11 |    94.2 | ...14-617,710-713 
  scratch-tree.ts  |   95.93 |       86 |     100 |   95.93 | ...91-392,461-464 
  script-lint.ts   |   81.27 |    79.38 |   88.88 |   81.27 | ...69-783,785-807 
  submit.ts        |   94.21 |       89 |   94.44 |   94.21 | ...1710,1738-1775 
  test-delta.ts    |   95.75 |     92.3 |      75 |   95.75 | 470-478           
  test-efficacy.ts |   84.03 |    80.48 |   96.07 |   84.03 | ...3249,3257-3277 
  test-plan.ts     |   94.61 |    91.79 |      95 |   94.61 | ...29-832,873-874 
 ...w/__fixtures__ |     100 |      100 |     100 |     100 |                   
  ...r-default.mjs |     100 |      100 |     100 |     100 |                   
  ...der-empty.mjs |     100 |      100 |     100 |     100 |                   
  ...der-named.mjs |     100 |      100 |     100 |     100 |                   
 ...nds/review/lib |   97.37 |    94.76 |   98.68 |   97.37 |                   
  agent-briefs.ts  |   99.08 |      100 |      50 |   99.08 | 841-842           
  ...t-identity.ts |     100 |      100 |     100 |     100 |                   
  anchors.ts       |     100 |    97.04 |     100 |     100 | ...39,175,184,231 
  assets.ts        |     100 |      100 |     100 |     100 |                   
  audit-layers.ts  |   98.67 |    96.15 |     100 |   98.67 | 288-290           
  authorization.ts |    96.5 |    95.61 |     100 |    96.5 | ...54-255,629-630 
  budget.ts        |     100 |    97.95 |     100 |     100 | 887,940           
  build-budget.ts  |     100 |      100 |     100 |     100 |                   
  certification.ts |     100 |      100 |     100 |     100 |                   
  convergence.ts   |     100 |    97.94 |    92.3 |     100 | 52,515,620,716    
  coverage.ts      |   98.97 |    95.12 |     100 |   98.97 | ...1103,1648-1649 
  deadline.ts      |   98.03 |    91.66 |     100 |   98.03 | ...20,752,820,837 
  diff-flags.ts    |     100 |        0 |     100 |     100 | 75                
  diff-plan.ts     |   99.29 |    95.79 |     100 |   99.29 | 295-296,319       
  disk.ts          |     100 |      100 |     100 |     100 |                   
  effort.ts        |     100 |      100 |     100 |     100 |                   
  failing-files.ts |     100 |    93.33 |     100 |     100 | 41                
  gh.ts            |   89.53 |    95.52 |   78.94 |   89.53 | ...47,384-385,412 
  git.ts           |   96.92 |    94.11 |     100 |   96.92 | 264-265,302-303   
  heavy.ts         |     100 |      100 |     100 |     100 |                   
  import-graph.ts  |   96.68 |     95.6 |     100 |   96.68 | 180-182,211-212   
  ...ntal-scope.ts |     100 |      100 |     100 |     100 |                   
  inline-counts.ts |     100 |      100 |     100 |     100 |                   
  ...audit-gate.ts |     100 |     97.5 |     100 |     100 | 135               
  ledger.ts        |     100 |    99.45 |     100 |     100 | 828               
  local-anchor.ts  |   93.78 |    88.75 |     100 |   93.78 | ...61,594-595,745 
  local-diff.ts    |   86.77 |    94.28 |     100 |   86.77 | ...54-564,566-574 
  ...ry-context.ts |   96.61 |    95.48 |     100 |   96.61 | ...47-450,496-499 
  md-field.ts      |     100 |      100 |     100 |     100 |                   
  merge-base.ts    |     100 |      100 |     100 |     100 |                   
  narrow-diff.ts   |     100 |      100 |     100 |     100 |                   
  npm-toolchain.ts |   98.23 |    95.29 |     100 |   98.23 | ...,822,1203,1220 
  path-rules.ts    |     100 |      100 |     100 |     100 |                   
  paths.ts         |   98.05 |    88.57 |     100 |   98.05 | 33-34             
  prompt-record.ts |   98.03 |    94.23 |     100 |   98.03 | 293-294,300       
  receipt.ts       |     100 |      100 |     100 |     100 |                   
  remote-match.ts  |   98.03 |    94.73 |     100 |   98.03 | 109-110           
  report.ts        |   92.92 |    86.66 |     100 |   92.92 | 213-214,216-220   
  ...ry-context.ts |     100 |    98.66 |     100 |     100 | 187               
  resume.ts        |     100 |      100 |     100 |     100 |                   
  retirement.ts    |     100 |    94.36 |     100 |     100 | ...58-559,760,917 
  review-footer.ts |   99.55 |    98.09 |     100 |   99.55 | 548-549           
  ...w-settings.ts |     100 |    96.42 |     100 |     100 | 99                
  roster.ts        |     100 |    97.14 |     100 |     100 | 177,222           
  round-model.ts   |     100 |      100 |     100 |     100 |                   
  run-ledger.ts    |    98.2 |    93.87 |     100 |    98.2 | ...23,541,647,670 
  same-file.ts     |     100 |       95 |     100 |     100 | 36                
  ...boxed-exec.ts |   94.26 |    89.32 |   95.65 |   94.26 | ...49-550,728-729 
  shell-quote.ts   |     100 |      100 |     100 |     100 |                   
  stale-bundle.ts  |   98.18 |    94.38 |     100 |   98.18 | 431,472,512-513   
  test-utils.ts    |   99.04 |    91.66 |     100 |   99.04 | 75                
  toolchain.ts     |     100 |      100 |     100 |     100 |                   
  transcripts.ts   |   98.09 |    95.07 |     100 |   98.09 | ...92,438,707-708 
  ...pace-scope.ts |     100 |    96.96 |     100 |     100 | 186               
  workspaces.ts    |     100 |    96.85 |     100 |     100 | 222,452,499,512   
  ...ree-reader.ts |     100 |      100 |     100 |     100 |                   
  worktree.ts      |   89.39 |    81.78 |     100 |   89.39 | ...1813-1814,1827 
 ...w/lib/platform |   94.71 |    87.89 |   97.05 |   94.71 |                   
  aone-client.ts   |   94.94 |     87.3 |     100 |   94.94 | ...92-293,299-302 
  aone.ts          |   93.06 |    89.86 |   94.73 |   93.06 | ...34,598-603,655 
  github.ts        |   99.08 |     75.8 |     100 |   99.08 | 249-250           
  registry.ts      |     100 |      100 |     100 |     100 |                   
  types.ts         |     100 |      100 |     100 |     100 |                   
 ...mands/sessions |   94.11 |    89.06 |   89.47 |   94.11 |                   
  common.ts        |     100 |      100 |     100 |     100 |                   
  list.ts          |   90.96 |    86.66 |   81.81 |   90.96 | 208-219,221-222   
  ps.ts            |     100 |    94.44 |     100 |     100 | 58                
 src/config        |   94.27 |    90.47 |   95.02 |   94.27 |                   
  ...l-fallback.ts |     100 |      100 |     100 |     100 |                   
  auth.ts          |   93.36 |    88.37 |     100 |   93.36 | ...06-307,330-331 
  ...eMcpImport.ts |   87.91 |    81.52 |     100 |   87.91 | ...63-371,453-454 
  compile-cache.ts |     100 |      100 |     100 |     100 |                   
  config.ts        |   89.71 |    90.74 |   83.78 |   89.71 | ...2546,2548-2556 
  ...cy-monitor.ts |      90 |    77.27 |     100 |      90 | ...72-73,90-92,98 
  ...ust-policy.ts |   83.02 |    88.88 |     100 |   83.02 | ...02-209,232-240 
  ...heme-names.ts |     100 |      100 |     100 |     100 |                   
  ...ScopeUtils.ts |   97.56 |    88.88 |     100 |   97.56 | 67                
  environment.ts   |   94.51 |    92.55 |   95.23 |   94.51 | ...24-625,679-680 
  ...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.13 |     100 |     100 | 47,172-178,238    
  keyBindings.ts   |    97.4 |       50 |     100 |    97.4 | 240-243           
  ...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.87 |     100 |   98.97 | 85                
  mcpApprovals.ts  |   78.57 |       92 |   86.66 |   78.57 | ...18-319,324-326 
  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.93 |     100 |   99.15 | 63                
  sandboxConfig.ts |   93.33 |    93.33 |     100 |   93.33 | ...42-147,216-217 
  session-id.ts    |     100 |      100 |     100 |     100 |                   
  ...ings-cache.ts |   96.52 |    93.93 |     100 |   96.52 | 90-91,201-202     
  settings.ts      |   91.16 |    93.02 |      90 |   91.16 | ...1037,1039-1040 
  ...ingsSchema.ts |     100 |      100 |     100 |     100 |                   
  settingsUtils.ts |   80.92 |     89.2 |   85.18 |   80.92 | ...87-605,612-620 
  ...ngsWatcher.ts |   95.54 |    88.34 |     100 |   95.54 | ...28,277-278,293 
  ...d-env-keys.ts |     100 |      100 |     100 |     100 |                   
  ...l-settings.ts |     100 |      100 |     100 |     100 |                   
  ...paths-lite.ts |   89.47 |       88 |     100 |   89.47 | 43-44,53-54,56-57 
  ...precedence.ts |   98.79 |     92.3 |     100 |   98.79 | 62                
  ...tedFolders.ts |   92.53 |    93.54 |     100 |   92.53 | ...36-337,373-384 
 ...nfig/migration |   95.23 |    78.94 |   85.71 |   95.23 |                   
  index.ts         |   95.65 |     87.5 |     100 |   95.65 | 117-118           
  scheduler.ts     |   96.55 |       80 |     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    |   75.08 |    67.64 |   71.42 |   75.08 |                   
  ...tputBridge.ts |   75.33 |    68.18 |   73.68 |   75.33 | ...09-410,418-421 
  ...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/hooks         |     100 |      100 |     100 |     100 |                   
  ...elete-hook.ts |     100 |      100 |     100 |     100 |                   
 src/i18n          |   89.68 |    88.66 |   93.02 |   89.68 |                   
  index.ts         |   73.45 |    77.77 |      90 |   73.45 | ...70-271,294-299 
  languageUtils.ts |   98.88 |    97.01 |     100 |   98.88 | 184-185           
  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 |   87.37 |    83.73 |   89.32 |   87.37 |                   
  ...ng-failure.ts |     100 |      100 |     100 |     100 |                   
  ...iveHelpers.ts |   94.95 |    91.05 |     100 |   94.95 | ...30-431,529,542 
  ...uggestions.ts |   84.29 |    70.83 |     100 |   84.29 | 70-76,92-103      
  session.ts       |   84.97 |    76.31 |   96.07 |   84.97 | ...1048,1057-1067 
  ...iagnostics.ts |    95.8 |     87.5 |   93.75 |    95.8 | ...03,277-278,289 
  types.ts         |    42.5 |      100 |   33.33 |    42.5 | ...33-634,637-638 
 ...active/control |   75.54 |    89.83 |      80 |   75.54 |                   
  ...rolContext.ts |    6.06 |        0 |       0 |    6.06 | 57-99             
  ...Dispatcher.ts |   91.95 |    92.98 |   88.88 |   91.95 | ...54-372,392,395 
  ...rolService.ts |    6.89 |        0 |       0 |    6.89 | 46-188            
 ...ol/controllers |   57.47 |     66.3 |   73.68 |   57.47 |                   
  ...Controller.ts |    42.4 |      100 |   83.33 |    42.4 | 101-105,140-223   
  ...Controller.ts |       0 |        0 |       0 |       0 | 1-56              
  ...Controller.ts |   70.04 |    62.92 |   91.66 |   70.04 | ...11-620,635-640 
  ...Controller.ts |   49.23 |       60 |      50 |   49.23 | ...07-108,111-121 
  ...Controller.ts |   53.96 |    67.08 |   66.66 |   53.96 | ...78-690,699-728 
 .../control/types |       0 |        0 |       0 |       0 |                   
  serviceAPIs.ts   |       0 |        0 |       0 |       0 | 1                 
 ...Interactive/io |   98.18 |    94.11 |   95.34 |   98.18 |                   
  ...putAdapter.ts |   98.07 |    93.21 |   98.11 |   98.07 | ...1448,1464-1465 
  ...putAdapter.ts |   96.22 |    91.66 |   85.71 |   96.22 | 52-53             
  ...nputReader.ts |     100 |    94.73 |     100 |     100 | 67                
  ...putAdapter.ts |   98.51 |      100 |   90.47 |   98.51 | 90-91,131-132     
  ...projection.ts |     100 |      100 |     100 |     100 |                   
  index.ts         |     100 |      100 |     100 |     100 |                   
 src/patches       |       0 |        0 |       0 |       0 |                   
  is-in-ci.ts      |       0 |        0 |       0 |       0 | 1-17              
 src/peerMessaging |   90.64 |    85.29 |      96 |   90.64 |                   
  ...ngContext.tsx |     100 |      100 |     100 |     100 |                   
  ...-messaging.ts |   90.45 |    85.07 |   95.83 |   90.45 | ...01-306,347-352 
 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/runtime       |    99.7 |    96.32 |     100 |    99.7 |                   
  ...livery-ipc.ts |     100 |    91.17 |     100 |     100 | 94,106,134        
  ...l-delivery.ts |     100 |      100 |     100 |     100 |                   
  cpu-percent.ts   |     100 |      100 |     100 |     100 |                   
  ...ion-source.ts |     100 |      100 |     100 |     100 |                   
  ...erver-name.ts |     100 |      100 |     100 |     100 |                   
  ...-constants.ts |     100 |      100 |     100 |     100 |                   
  ...-summaries.ts |   86.66 |       50 |     100 |   86.66 | 11,19             
  ...ber-errors.ts |     100 |    95.32 |     100 |     100 | 53,93-94,172,192  
  ...ls-mapping.ts |     100 |      100 |     100 |     100 |                   
 src/serve         |   87.42 |    84.98 |   90.73 |   87.42 |                   
  ...extra-args.ts |     100 |      100 |     100 |     100 |                   
  ...tp-enabled.ts |     100 |      100 |     100 |     100 |                   
  ...ion-bridge.ts |     100 |      100 |     100 |     100 |                   
  auth.ts          |   93.99 |     91.5 |     100 |   93.99 | ...29-430,433-435 
  ...em-adapter.ts |     100 |      100 |     100 |     100 |                   
  capabilities.ts  |     100 |    98.18 |     100 |     100 | 717               
  ...cp-command.ts |     100 |      100 |     100 |     100 |                   
  ...horization.ts |   92.79 |    93.54 |    87.5 |   92.79 | 75-80,135-136     
  ...op-mcp-ipc.ts |   81.06 |    73.68 |   94.11 |   81.06 | ...37-242,267,289 
  ...nt-service.ts |    94.1 |    86.98 |     100 |    94.1 | ...75-477,484,486 
  ...-selection.ts |     100 |      100 |     100 |     100 |                   
  ...ings-store.ts |   89.61 |    94.37 |   96.55 |   89.61 | ...64-276,528-531 
  ...ebhook-ipc.ts |    98.5 |     87.5 |     100 |    98.5 | 47                
  ...iagnostics.ts |     100 |      100 |     100 |     100 |                   
  ...worker-env.ts |     100 |      100 |     100 |     100 |                   
  ...rker-group.ts |   87.32 |    85.33 |     100 |   87.32 | ...14,820-824,842 
  ...er-manager.ts |   89.39 |    83.88 |   93.33 |   89.39 | ...98,711,722-724 
  ...horization.ts |     100 |      100 |     100 |     100 |                   
  ...tartup-ipc.ts |   97.72 |    96.66 |     100 |   97.72 | 88-89             
  ...supervisor.ts |   93.24 |    85.42 |    97.4 |   93.24 | ...1765,1819-1823 
  ...e-grouping.ts |     100 |    94.28 |     100 |     100 | 71,137            
  core-runtime.ts  |     100 |      100 |     100 |     100 |                   
  ...ub-session.ts |   90.75 |    80.47 |   94.73 |   90.75 | ...1091,1112-1117 
  ...tree-guard.ts |   93.87 |    89.81 |     100 |   93.87 | ...3227,3297-3301 
  daemon-logger.ts |   82.82 |    78.68 |   92.04 |   82.82 | ...1775,1802-1808 
  ...y-pressure.ts |     100 |    96.96 |     100 |     100 | 135               
  ...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.69 |    91.96 |     100 |   98.69 | ...1590,1592-1593 
  debug-mode.ts    |     100 |      100 |     100 |     100 |                   
  env-snapshot.ts  |   93.37 |    85.18 |     100 |   93.37 | 114-117,195-202   
  ...-scheduler.ts |   87.34 |    83.87 |     100 |   87.34 | 33-36,48-50,79-81 
  ...d-provider.ts |   92.06 |    87.09 |     100 |   92.06 | ...72,287-293,316 
  ...h-settings.ts |   94.94 |    90.45 |     100 |   94.94 | ...30,708,724,734 
  fast-path.ts     |   91.38 |       82 |   95.45 |   91.38 | ...46-555,633-634 
  ...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-149             
  ...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 |   91.58 |    86.48 |     100 |   91.58 | ...44-145,156-157 
  ...pp-sandbox.ts |   96.72 |    95.23 |     100 |   96.72 | 41-42             
  ...iders-edit.ts |     100 |    82.14 |     100 |     100 | 58-60,65,81       
  ...ory-picker.ts |     100 |    86.95 |     100 |     100 | 36,66,92          
  ...-with-auth.ts |     100 |      100 |     100 |     100 |                   
  ...ate-blocks.ts |   99.03 |    94.73 |     100 |   99.03 | 133               
  ...sion-audit.ts |     100 |      100 |   93.33 |     100 |                   
  ...nal-ledger.ts |    94.9 |    84.78 |     100 |    94.9 | ...81,302,361-362 
  rate-limit.ts    |   92.68 |    88.29 |     100 |   92.68 | ...89-291,303-305 
  ...qwen-serve.ts |   84.69 |    81.44 |   76.99 |   84.69 | ...9116,9134-9138 
  ...tup-errors.ts |     100 |      100 |     100 |     100 |                   
  sandbox.ts       |   45.52 |    59.42 |   76.92 |   45.52 | ...1050,1062-1085 
  ...-keepalive.ts |   94.31 |    88.28 |     100 |   94.31 | ...37,541-542,581 
  ...-lifecycle.ts |     100 |      100 |     100 |     100 |                   
  ...-lifecycle.ts |   89.16 |    90.29 |   86.95 |   89.16 | ...24-325,330-334 
  serve-token.ts   |     100 |      100 |     100 |     100 |                   
  server.ts        |   89.07 |    91.03 |   70.31 |   89.07 | ...3165,3196-3197 
  ...-admission.ts |   99.13 |    95.94 |     100 |   99.13 | 308-309           
  ...on-helpers.ts |     100 |      100 |     100 |     100 |                   
  ...-redaction.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 |                   
  ...ion-limits.ts |     100 |      100 |     100 |     100 |                   
  ...t-sessions.ts |   93.72 |    77.93 |     100 |   93.72 | ...51,854,867-869 
  ...l-resolver.ts |   90.32 |    66.66 |     100 |   90.32 | 16,45-46          
  ...ell-static.ts |   93.45 |    86.88 |     100 |   93.45 | ...77-280,323-326 
  ...ace-agents.ts |   66.13 |    70.57 |   92.68 |   66.13 | ...2246,2256-2266 
  ...generation.ts |    95.4 |    82.35 |   66.66 |    95.4 | 55-56,78,92       
  ...-git-state.ts |     100 |    91.93 |    90.9 |     100 | 161,172,202,265   
  ...ace-inputs.ts |     100 |      100 |     100 |     100 |                   
  ...ace-memory.ts |      83 |    74.54 |     100 |      83 | ...30-537,597-604 
  ...ers-status.ts |   98.63 |       80 |     100 |   98.63 | 108,136,186,189   
  ...tion-store.ts |   89.67 |    88.27 |   92.59 |   89.67 | ...91-400,411-414 
  ...e-registry.ts |   94.09 |    90.57 |     100 |   94.09 | ...90-591,598-599 
  ...e-remember.ts |   98.23 |    92.56 |     100 |   98.23 | ...36,340-345,386 
  ...te-runtime.ts |   89.88 |     90.9 |     100 |   89.88 | ...05-206,274-295 
  ...me-storage.ts |     100 |      100 |     100 |     100 |                   
  ...visibility.ts |     100 |      100 |     100 |     100 |                   
  ...management.ts |   72.63 |    72.83 |   96.15 |   72.63 | ...88-889,896-900 
  ...lls-status.ts |     100 |    95.45 |     100 |     100 | 152               
  ...reconciler.ts |   91.63 |    84.09 |     100 |   91.63 | ...71-273,306-307 
 ...serve/acp-http |    80.4 |    80.03 |   94.53 |    80.4 |                   
  ...r-registry.ts |   96.92 |    94.87 |     100 |   96.92 | 184-187           
  client-mcp-ws.ts |   54.85 |    58.62 |   72.72 |   54.85 | ...99-300,304-305 
  ...n-registry.ts |   93.03 |    84.13 |   98.52 |   93.03 | ...1624,1671-1682 
  dispatch.ts      |   75.71 |    76.82 |   93.44 |   75.71 | ...5649,5706-5712 
  index.ts         |   82.81 |    79.92 |   91.22 |   82.81 | ...2434,2520-2521 
  json-rpc.ts      |     100 |    96.96 |     100 |     100 | 92                
  ...ach-budget.ts |     100 |      100 |     100 |     100 |                   
  safe-ws-send.ts  |   52.94 |    71.42 |     100 |   52.94 | 33-42,47-55       
  sse-stream.ts    |   98.26 |    88.75 |     100 |   98.26 | 87-88,117         
  ...ort-stream.ts |       0 |        0 |       0 |       0 | 1                 
  ws-stream.ts     |   94.06 |    89.09 |     100 |   94.06 | 50,55,134,138-141 
 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 |   87.73 |    76.21 |    97.5 |   87.73 |                   
  ...r-emulator.ts |   93.27 |    77.77 |     100 |   93.27 | ...53-256,282-283 
  ...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 |    6.12 |    57.89 |   46.15 |    6.12 |                   
  ...helpers.d.mts |       0 |        0 |       0 |       0 | 1                 
  ...e-helpers.mjs |   97.64 |    70.96 |     100 |   97.64 | 22-23             
  ...mcp-smoke.mjs |       0 |        0 |       0 |       0 | 1-124             
  ...cceptance.mjs |       0 |        0 |       0 |       0 | 1-473             
  ...re-server.mjs |       0 |        0 |       0 |       0 | 1-59              
  ...ols-smoke.mjs |       0 |        0 |       0 |       0 | 1-268             
  real-tab.mjs     |       0 |        0 |       0 |       0 | 1-218             
  ...al-chrome.mjs |       0 |        0 |       0 |       0 | 1-223             
 .../conversations |   86.32 |    78.72 |   93.33 |   86.32 |                   
  ...e-activity.ts |     100 |      100 |     100 |     100 |                   
  ...ime-errors.ts |     100 |      100 |     100 |     100 |                   
  ...me-manager.ts |   97.88 |    94.91 |     100 |   97.88 | 64-65,92          
  ...-ownership.ts |   87.33 |    83.58 |   88.46 |   87.33 | ...57-558,601-602 
  ...-workspace.ts |   89.21 |    76.37 |     100 |   89.21 | ...52-554,568-572 
  ...on-journal.ts |   91.69 |    80.86 |     100 |   91.69 | ...46-747,753-755 
  ...on-service.ts |   83.22 |    75.11 |   89.01 |   83.22 | ...3014,3023-3025 
 src/serve/fs      |   87.77 |    82.34 |     100 |   87.77 |                   
  audit.ts         |     100 |    96.29 |     100 |     100 | 211               
  errors.ts        |     100 |      100 |     100 |     100 |                   
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...x-registry.ts |     100 |      100 |     100 |     100 |                   
  paths.ts         |   77.64 |    74.01 |     100 |   77.64 | ...65,594-598,611 
  policy.ts        |   90.52 |    89.18 |     100 |   90.52 | 172-180           
  text-cursor.ts   |   88.23 |       90 |     100 |   88.23 | 74-77,92-95       
  ...ile-system.ts |   88.02 |    81.85 |     100 |   88.02 | ...3027,3037-3038 
 src/serve/live    |    76.6 |    70.53 |    90.2 |    76.6 |                   
  discovery.ts     |   85.89 |    82.05 |    91.3 |   85.89 | ...73-579,592-593 
  ...oordinator.ts |   82.67 |    76.63 |   97.01 |   82.67 | ...1319,1351-1353 
  ...-installer.ts |    64.3 |    82.35 |   80.76 |    64.3 | ...45-446,460-472 
  ...oordinator.ts |    76.7 |    67.47 |   85.71 |    76.7 | ...1885,1976-1977 
  ...controller.ts |   67.82 |    79.66 |      75 |   67.82 | ...66-278,287-295 
  ...sk-service.ts |   82.71 |    66.15 |   93.61 |   82.71 | ...1270,1283,1290 
  ...redentials.ts |   96.26 |    93.47 |     100 |   96.26 | 91-94             
  ...me-session.ts |   65.63 |    57.24 |   88.88 |   65.63 | ...2270,2275-2282 
  ...up-context.ts |   94.85 |    77.39 |     100 |   94.85 | ...18,327-330,350 
  types.ts         |     100 |      100 |     100 |     100 |                   
 .../local-control |   82.89 |    88.77 |      90 |   82.89 |                   
  credentials.ts   |   96.42 |    95.45 |     100 |   96.42 | 109-110           
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...interfaces.ts |   43.58 |    82.75 |   42.85 |   43.58 | ...09-117,130-142 
  ...r-identity.ts |     100 |    85.71 |     100 |     100 | 61                
  service.ts       |    93.4 |       90 |     100 |    93.4 | ...20-222,313-315 
 src/serve/routes  |   86.45 |    81.77 |   95.75 |   86.45 |                   
  a2ui-action.ts   |   96.84 |     88.5 |    87.5 |   96.84 | ...70-272,309-311 
  capabilities.ts  |   98.73 |    96.15 |     100 |   98.73 | 82                
  ...nel-notify.ts |   79.16 |    85.18 |     100 |   79.16 | ...03-104,120-126 
  ...l-webhooks.ts |   93.56 |    84.09 |     100 |   93.56 | ...42,292,332,334 
  daemon-status.ts |   85.71 |    83.33 |     100 |   85.71 | 101-108           
  goals.ts         |   98.94 |    91.17 |     100 |   98.94 | 143               
  health.ts        |   99.09 |    91.42 |     100 |   99.09 | 147               
  live-setup.ts    |   33.33 |     37.5 |      50 |   33.33 | ...18-123,130-135 
  live.ts          |   84.61 |    76.47 |     100 |   84.61 | ...04,106-111,131 
  permission.ts    |   96.03 |    87.87 |     100 |   96.03 | 81-84             
  ...uled-tasks.ts |   87.95 |    84.38 |   94.59 |   87.95 | ...1730,1775-1776 
  ...r-backfill.ts |    98.5 |    93.75 |     100 |    98.5 | ...98,600,824-825 
  ...on-runtime.ts |   91.42 |       90 |     100 |   91.42 | 56-64             
  session.ts       |   86.69 |    83.06 |    94.3 |   86.69 | ...7149,7151-7152 
  sse-events.ts    |   87.01 |    84.95 |   94.44 |   87.01 | ...40-951,954,961 
  ...e-sessions.ts |    86.9 |    80.57 |     100 |    86.9 | ...81-483,486-491 
  terminal.ts      |   92.81 |    90.35 |     100 |   92.81 | ...10-313,332-335 
  usage-stats.ts   |     100 |    95.45 |     100 |     100 | 118               
  ...space-auth.ts |   85.55 |    75.64 |     100 |   85.55 | ...21-326,331,345 
  ...el-control.ts |   86.26 |    78.94 |     100 |   86.26 | ...17-318,339-347 
  ...management.ts |   90.35 |    78.94 |     100 |   90.35 | ...52-553,576-577 
  ...d-contacts.ts |   83.62 |    94.59 |     100 |   83.62 | 123,125-142       
  ...controller.ts |   83.33 |    80.47 |      90 |   83.33 | ...1056,1061,1068 
  ...extensions.ts |    89.9 |    79.35 |   93.93 |    89.9 | ...2348,2393-2394 
  ...-file-read.ts |      91 |    80.91 |     100 |      91 | ...20-621,624-625 
  ...file-write.ts |   89.72 |    79.35 |     100 |   89.72 | ...05,719-726,807 
  ...t-branches.ts |   75.04 |     66.4 |     100 |   75.04 | ...99-604,613-620 
  ...e-git-diff.ts |   97.19 |    89.58 |     100 |   97.19 | 157-158,185-187   
  ...ce-git-log.ts |     100 |       95 |     100 |     100 | 48,73             
  workspace-git.ts |   74.71 |     87.5 |     100 |   74.71 | 83-104            
  ...github-prs.ts |   88.26 |    63.46 |     100 |   88.26 | ...38-239,264-265 
  ...-lifecycle.ts |   95.23 |    75.75 |     100 |   95.23 | ...50-151,186-187 
  ...al-control.ts |   74.17 |    69.23 |     100 |   74.17 | ...18,220-226,231 
  ...management.ts |   87.14 |    84.21 |     100 |   87.14 | ...1802,1812-1817 
  ...cp-control.ts |    73.2 |    67.54 |   85.71 |    73.2 | ...27-633,644-645 
  ...ace-models.ts |   95.53 |    89.74 |     100 |   95.53 | ...52-157,296-297 
  ...ermissions.ts |    77.9 |    72.41 |     100 |    77.9 | ...69-277,298-316 
  ...e-settings.ts |   75.67 |       75 |     100 |   75.67 | ...15-726,732-733 
  ...tup-github.ts |   77.97 |    70.58 |   84.21 |   77.97 | ...46-352,397-398 
  ...ace-skills.ts |   76.41 |    86.11 |     100 |   76.41 | ...29-354,360-394 
  ...ace-status.ts |   82.57 |    74.48 |     100 |   82.57 | ...71-473,477-478 
  ...pace-tools.ts |   75.94 |    69.69 |   66.66 |   75.94 | ...59-164,193-194 
  ...pace-trust.ts |   76.92 |     67.1 |      80 |   76.92 | ...38-343,351-352 
  ...pace-voice.ts |   91.33 |    81.02 |     100 |   91.33 | ...70-673,676-678 
 src/serve/server  |   93.12 |    91.26 |   96.15 |   93.12 |                   
  access-log.ts    |   98.73 |    97.26 |     100 |   98.73 | 119,196           
  ...-timestamp.ts |     100 |      100 |     100 |     100 |                   
  aone-mrs.ts      |   91.48 |    91.35 |   81.25 |   91.48 | ...53,299-300,466 
  ...er-helpers.ts |   63.82 |    78.15 |   81.81 |   63.82 | ...16,330,332-347 
  ...w-registry.ts |    98.8 |    81.81 |     100 |    98.8 | 107               
  ...r-handlers.ts |   97.87 |       80 |     100 |   97.87 | 27                
  ...r-response.ts |   88.75 |    82.25 |     100 |   88.75 | ...61,878,941-950 
  fs-factory.ts    |     100 |    95.52 |     100 |     100 | 77,144,200        
  ...branch-ops.ts |     100 |      100 |     100 |     100 |                   
  ...list-cache.ts |   99.01 |    95.52 |     100 |   99.01 | 184-185           
  ...t-deadline.ts |     100 |      100 |     100 |     100 |                   
  ...iter-setup.ts |      65 |       80 |   33.33 |      65 | 30-35,38-43,47-48 
  ...st-helpers.ts |   95.13 |    95.14 |     100 |   95.13 | ...66-168,423-428 
  self-origin.ts   |   76.19 |       80 |     100 |   76.19 | 45-54             
  ...e-features.ts |   95.13 |     87.5 |     100 |   95.13 | 188-194           
  ...on-archive.ts |   91.29 |    89.33 |   97.61 |   91.29 | ...1133,1196-1197 
  ...ion-export.ts |   98.57 |    90.47 |     100 |   98.57 | 85                
  session-list.ts  |   97.27 |    93.89 |     100 |   97.27 | ...1183,1392-1396 
  ...pr-refresh.ts |     100 |    97.05 |     100 |     100 | 199,252,427       
  ...ry-context.ts |    87.5 |       50 |     100 |    87.5 | 49-50             
  telemetry.ts     |   99.06 |    97.26 |     100 |   99.06 | ...04,873,952-954 
 src/serve/voice   |    92.7 |    91.53 |   97.72 |    92.7 |                   
  ...ice-config.ts |   84.81 |       30 |     100 |   84.81 | 91-100,104-105    
  voice-ws.ts      |   91.58 |    93.44 |      96 |   91.58 | ...68,483,521-523 
  ...oordinator.ts |     100 |    98.24 |     100 |     100 | 176               
 ...kspace-service |   89.85 |    86.73 |    91.3 |   89.85 |                   
  index.ts         |   89.49 |    86.34 |      90 |   89.49 | ...1393-1397,1400 
  types.ts         |     100 |      100 |     100 |     100 |                   
 src/services      |    92.7 |    89.68 |   98.13 |    92.7 |                   
  ...mandLoader.ts |     100 |       95 |     100 |     100 | 107               
  ...killLoader.ts |   97.19 |    85.71 |     100 |   97.19 | 142,153-154       
  ...andService.ts |   98.73 |      100 |     100 |   98.73 | 107               
  ...mandLoader.ts |   87.09 |    83.07 |     100 |   87.09 | ...35-340,345-350 
  ...omptLoader.ts |   79.55 |    88.42 |   85.71 |   79.55 | ...48,178,245-246 
  ...mandLoader.ts |   97.77 |    92.45 |     100 |   97.77 | 176,183-184       
  ...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 |    92.85 |     100 |   96.66 | 34-35             
  ...tree-lease.ts |   92.14 |    92.42 |     100 |   92.14 | ...91-296,329-330 
  ...low-loader.ts |     100 |    96.29 |     100 |     100 | 88                
  setup-github.ts  |    90.8 |    80.95 |     100 |    90.8 | ...49-450,457-458 
  ...-args-file.ts |   93.93 |    91.66 |    87.5 |   93.93 | 208-210,224-230   
  types.ts         |     100 |      100 |     100 |     100 |                   
  ...e-keyterms.ts |   98.64 |    95.77 |     100 |   98.64 | 116,142-143       
  voice-model.ts   |     100 |      100 |     100 |     100 |                   
  voice-service.ts |    90.4 |    87.87 |     100 |    90.4 | ...81,288,353-358 
  ...e-settings.ts |     100 |    95.23 |     100 |     100 | 19                
  ...ranscriber.ts |   91.77 |    87.11 |   97.22 |   91.77 | ...96-898,901-903 
 ...s/housekeeping |      93 |    88.34 |      95 |      93 |                   
  scheduler.ts     |      93 |    88.34 |      95 |      93 | ...57-359,411-415 
 ...rvices/insight |     100 |      100 |     100 |     100 |                   
  dates.ts         |     100 |      100 |     100 |     100 |                   
 ...ght/generators |   88.94 |    86.86 |   96.29 |   88.94 |                   
  DataProcessor.ts |   88.31 |    86.84 |      95 |   88.31 | ...1368,1372-1379 
  ...tGenerator.ts |   98.24 |    85.71 |     100 |   98.24 | 47                
  ...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.25 |     100 |   97.27 |                   
  ...tProcessor.ts |     100 |      100 |     100 |     100 |                   
  ...eProcessor.ts |   94.52 |       85 |     100 |   94.52 | 46-47,93-94       
  ...tionParser.ts |     100 |      100 |     100 |     100 |                   
  ...lProcessor.ts |   97.41 |    95.83 |     100 |   97.41 | 96-99             
  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.6 |    76.66 |      80 |    94.6 |                   
  ci-env.ts        |      88 |     62.5 |     100 |      88 | 22-23,28          
  ...omMatchers.ts |   69.69 |       50 |      50 |   69.69 | 32-35,37-39,45-47 
  ...mised-lock.ts |     100 |      100 |   66.66 |     100 |                   
  ...lot-client.ts |     100 |    66.66 |     100 |     100 | 31,39             
  ...andContext.ts |     100 |      100 |     100 |     100 |                   
  render.tsx       |     100 |      100 |     100 |     100 |                   
 src/ui            |   71.09 |    78.17 |   70.65 |   71.09 |                   
  App.tsx          |   33.33 |       75 |   33.33 |   33.33 | 32-86             
  AppContainer.tsx |   76.62 |    73.37 |   71.05 |   76.62 | ...4465,4581-4587 
  ...tionNudge.tsx |    9.58 |      100 |       0 |    9.58 | 24-94             
  ...ackDialog.tsx |    30.3 |      100 |       0 |    30.3 | 26-76             
  ...tionNudge.tsx |    7.69 |      100 |       0 |    7.69 | 25-103            
  colors.ts        |   63.63 |      100 |   41.17 |   63.63 | ...52,54-55,60-61 
  constants.ts     |     100 |      100 |     100 |     100 |                   
  ...AutoUpdate.ts |   93.54 |    94.64 |      90 |   93.54 | 126,131,202-213   
  keyMatchers.ts   |   95.91 |    97.14 |     100 |   95.91 | 25-26             
  ...tic-colors.ts |     100 |      100 |     100 |     100 |                   
  ...one-update.ts |   39.81 |    77.44 |   62.16 |   39.81 | ...1193,1196-1215 
  ...ractiveUI.tsx |   68.33 |    77.27 |   41.66 |   68.33 | ...63-465,495-500 
  ...inePresets.ts |   96.27 |    83.87 |     100 |   96.27 | ...97,402,410-412 
  systemInfo.ts    |   95.09 |    90.27 |     100 |   95.09 | ...54-255,260-264 
  ...InfoFields.ts |    87.5 |    65.85 |     100 |    87.5 | ...24-125,146-147 
  textConstants.ts |     100 |      100 |     100 |     100 |                   
  types.ts         |     100 |      100 |     100 |     100 |                   
  ...e-relaunch.ts |   89.61 |    86.66 |      50 |   89.61 | 56-61,83-84       
 src/ui/auth       |   69.23 |    72.03 |   61.22 |   69.23 |                   
  AuthDialog.tsx   |   59.01 |     42.1 |   16.66 |   59.01 | ...25,332-354,358 
  ...nProgress.tsx |       0 |        0 |       0 |       0 | 1-64              
  ...etupSteps.tsx |   74.93 |    78.62 |   71.42 |   74.93 | ...92-902,918,921 
  useAuth.ts       |   94.83 |       75 |     100 |   94.83 | ...33-234,253-259 
  ...rSetupFlow.ts |   59.79 |    58.33 |     100 |   59.79 | ...82-403,420-463 
 src/ui/commands   |    84.6 |     84.5 |   91.68 |    84.6 |                   
  aboutCommand.ts  |     100 |      100 |     100 |     100 |                   
  ...or-command.ts |     100 |    95.65 |     100 |     100 | 104,182           
  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  |   63.89 |    65.71 |   65.21 |   63.89 | ...01-606,691-699 
  authCommand.ts   |     100 |      100 |     100 |     100 |                   
  branchCommand.ts |     100 |      100 |     100 |     100 |                   
  btwCommand.ts    |   94.32 |    81.25 |     100 |   94.32 | 35-36,114-119     
  bugCommand.ts    |     100 |    77.77 |     100 |     100 | 28,62             
  cdCommand.ts     |    92.3 |    82.75 |     100 |    92.3 | ...,94-99,178,187 
  clearCommand.ts  |    80.9 |    70.83 |     100 |    80.9 | ...28-129,137-146 
  commands.ts      |   97.45 |    96.66 |     100 |   97.45 | 153-155           
  ...essCommand.ts |   80.71 |     64.7 |     100 |   80.71 | ...05-206,220-223 
  ...astCommand.ts |   84.75 |    76.47 |     100 |   84.75 | ...96-102,130-135 
  ...ig-command.ts |   93.12 |    88.42 |     100 |   93.12 | ...07-315,321-323 
  ...extCommand.ts |   73.75 |    74.02 |   83.33 |   73.75 | ...72-605,616-617 
  copyCommand.ts   |    98.7 |    96.29 |     100 |    98.7 | 66-67,172,272,323 
  ...or-command.ts |   85.95 |    80.55 |   88.88 |   85.95 | ...68-274,298-309 
  deleteCommand.ts |     100 |      100 |     100 |     100 |                   
  diffCommand.ts   |     100 |    87.87 |     100 |     100 | ...63,231-232,245 
  ...ryCommand.tsx |   90.56 |    87.83 |    90.9 |   90.56 | ...75-280,327-334 
  docsCommand.ts   |     100 |     90.9 |     100 |     100 | 26                
  doctorChecks.ts  |   70.31 |    74.57 |     100 |   70.31 | ...95-301,325-341 
  doctorCommand.ts |   70.16 |    84.61 |      95 |   70.16 | ...29-679,682-816 
  dreamCommand.ts  |   85.45 |    88.88 |     100 |   85.45 | 58-65             
  editorCommand.ts |     100 |      100 |     100 |     100 |                   
  ...rt-command.ts |   80.95 |       80 |     100 |   80.95 | 49-54,69-72,93-98 
  effort-utils.ts  |     100 |      100 |     100 |     100 |                   
  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 | 95,146            
  goalCommand.ts   |     100 |    96.49 |     100 |     100 | 139,192           
  helpCommand.ts   |     100 |      100 |     100 |     100 |                   
  ...oryCommand.ts |     100 |      100 |     100 |     100 |                   
  hooksCommand.ts  |   81.25 |    65.71 |   85.71 |   81.25 | ...,86-93,131-132 
  ideCommand.ts    |   60.75 |    64.28 |   41.17 |   60.75 | ...05-306,310-324 
  ...figCommand.ts |    58.5 |    74.07 |      80 |    58.5 | ...21-331,334-343 
  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 |   94.63 |    90.66 |     100 |   94.63 | ...25-226,253-263 
  learn-command.ts |     100 |      100 |     100 |     100 |                   
  lspCommand.ts    |     100 |    86.95 |     100 |     100 | 31,102-103        
  mcpCommand.ts    |     100 |      100 |     100 |     100 |                   
  memoryCommand.ts |     100 |      100 |     100 |     100 |                   
  modelCommand.ts  |   86.28 |    86.29 |     100 |   86.28 | ...1112,1146-1151 
  peers-command.ts |     100 |    94.36 |     100 |     100 | 59,70,223,228     
  ...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.6 |       90 |     100 |    89.6 | ...72-176,212-219 
  ...oreCommand.ts |   90.96 |    86.04 |     100 |   90.96 | ...41-146,177-178 
  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.65 |    76.73 |     100 |   90.65 | ...30-733,825-832 
  ...ineCommand.ts |     100 |      100 |     100 |     100 |                   
  ...aryCommand.ts |   73.04 |     82.3 |      90 |   73.04 | ...20-547,561-565 
  tasksCommand.ts  |   77.33 |    72.13 |     100 |   77.33 | ...46-150,173-178 
  ...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    |     100 |      100 |     100 |     100 |                   
  voice-command.ts |   93.63 |       88 |     100 |   93.63 | 36,98-103         
  ...owsCommand.ts |   94.38 |    85.29 |     100 |   94.38 | ...78-183,282-287 
 src/ui/components |   73.25 |    80.22 |    77.7 |   73.25 |                   
  AboutBox.tsx     |     100 |      100 |     100 |     100 |                   
  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 |   89.06 |    90.78 |     100 |   89.06 | ...87-289,303-305 
  Composer.tsx     |   94.54 |    66.66 |     100 |   94.54 | ...-76,88,143,158 
  ...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 | 19                
  ...ification.tsx |      84 |       60 |     100 |      84 | 23-24,40-42       
  ...gProfiler.tsx |       0 |        0 |       0 |       0 | 1-36              
  ...ogManager.tsx |   11.28 |      100 |       0 |   11.28 | 71-598            
  DiffDialog.tsx   |    53.5 |     37.5 |   69.23 |    53.5 | ...32-737,747-760 
  ...ngsDialog.tsx |    8.44 |      100 |       0 |    8.44 | 37-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          
  ...gsDisplay.tsx |     100 |    96.87 |   83.33 |     100 | 69                
  ...ustDialog.tsx |     100 |      100 |     100 |     100 |                   
  Footer.tsx       |   81.27 |    69.23 |      50 |   81.27 | ...06,245,267-272 
  GoalPill.tsx     |   93.51 |    81.81 |     100 |   93.51 | 37-38,106-109,123 
  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 |   79.69 |    67.61 |     100 |   79.69 | ...17,520,523-529 
  ...ngeDialog.tsx |     100 |      100 |     100 |     100 |                   
  InputPrompt.tsx  |   86.26 |     83.3 |      80 |   86.26 | ...2231,2252,2348 
  ...Shortcuts.tsx |     100 |       88 |     100 |     100 | 98,119            
  ...Indicator.tsx |   98.18 |    97.82 |     100 |   98.18 | 161-162           
  ...firmation.tsx |   91.42 |      100 |      50 |   91.42 | 26-31             
  MainContent.tsx  |   95.88 |    96.03 |   46.15 |   95.88 | ...20,523-527,530 
  MemoryDialog.tsx |   86.59 |    80.15 |     100 |   86.59 | ...34-435,485,553 
  ...geDisplay.tsx |       0 |        0 |       0 |       0 | 1-41              
  ModelDialog.tsx  |   85.22 |    74.17 |     100 |   85.22 | ...1042,1098,1100 
  ...tsDisplay.tsx |     100 |    97.22 |     100 |     100 | 270               
  ...fications.tsx |   16.66 |      100 |       0 |   16.66 | 14-56             
  ...onsDialog.tsx |    2.13 |      100 |       0 |    2.13 | 62-133,148-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 |    8.57 |      100 |       0 |    8.57 | 24-55,58-134      
  ...geDisplay.tsx |     100 |      100 |     100 |     100 |                   
  ...ngDisplay.tsx |   21.42 |      100 |       0 |   21.42 | 13-39             
  ...hProgress.tsx |   85.25 |    88.46 |     100 |   85.25 | 121-147           
  ...ngSpinner.tsx |   67.85 |    85.71 |      50 |   67.85 | 33-50,71,78-79    
  ...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 |   92.06 |    86.36 |   83.33 |   92.06 | ...,70-72,120-123 
  ...tedDialog.tsx |     100 |      100 |     100 |     100 |                   
  ...ngsDialog.tsx |   71.55 |    73.89 |   69.23 |   71.55 | ...1252,1258-1259 
  ...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 |      28 |      100 |       0 |      28 | 18-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-171             
  ...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 |      80 |    66.66 |     100 |      80 | ...70-277,283-300 
  ...ineDialog.tsx |    93.9 |    86.88 |     100 |    93.9 | ...20,282,302-304 
  ...yTodoList.tsx |   96.36 |    88.23 |     100 |   96.36 | 138-141           
  ...nsDisplay.tsx |   95.62 |    87.09 |     100 |   95.62 | ...24-125,273-275 
  ...inalImage.tsx |     100 |    93.93 |     100 |     100 | 75,129            
  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             
  TrustDialog.tsx  |     100 |    83.33 |     100 |     100 | 72-87             
  ...ification.tsx |   36.36 |      100 |       0 |   36.36 | 15-22             
  ...Indicator.tsx |    92.5 |     87.5 |     100 |    92.5 | 50-53             
  ...ackDialog.tsx |    7.84 |      100 |       0 |    7.84 | 24-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 |    61.5 |    75.57 |    62.5 |    61.5 |                   
  ...atContent.tsx |    9.09 |      100 |       0 |    9.09 | 54-275,281-283    
  ...tChatView.tsx |     100 |    81.81 |     100 |     100 | 82                
  ...tComposer.tsx |   78.35 |     64.7 |   66.66 |   78.35 | ...64,277,303-305 
  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 |   45.51 |    70.53 |   60.86 |   45.51 |                   
  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 |    9.77 |      100 |       0 |    9.77 | 27-166            
  ...tusDialog.tsx |    5.63 |      100 |       0 |    5.63 | 33-75,80-288      
  ...topDialog.tsx |    6.17 |      100 |       0 |    6.17 | 33-213            
 ...ackground-view |   85.86 |     85.1 |   92.98 |   85.86 |                   
  ...sksDialog.tsx |   82.66 |    83.09 |   85.71 |   82.66 | ...1854,1977-1983 
  ...TasksPill.tsx |   78.84 |    94.28 |     100 |   78.84 | 64,109-129        
  ...gentPanel.tsx |   97.08 |    86.31 |     100 |   97.08 | 132,442-446,520   
  agent-forest.ts  |    99.2 |    93.93 |     100 |    99.2 | 258               
  ...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.92 |    68.21 |   70.83 |   71.92 |                   
  DiscoverTab.tsx  |   68.22 |    67.66 |   55.55 |   68.22 | ...93,656-660,664 
  InstalledTab.tsx |   75.49 |    67.44 |   83.33 |   75.49 | ...77,782-783,820 
  SourcesTab.tsx   |   71.67 |    70.47 |   77.77 |   71.67 | ...28,547,621-633 
 ...tensions/views |    50.7 |    52.38 |   20.83 |    50.7 |                   
  ...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.24 |      100 |       0 |    9.24 | 40-67,70-163      
 ...mponents/hooks |   87.11 |    81.37 |   91.89 |   87.11 |                   
  ...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.91 |    63.44 |   70.58 |   40.91 |                   
  ...ealthPill.tsx |     100 |      100 |     100 |     100 |                   
  ...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.94 |    73.51 |   57.14 |   53.94 |                   
  ...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.53 |    81.25 |     100 |   88.53 | ...64,170,175-180 
  ...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 |   90.78 |    87.65 |   86.79 |   90.78 |                   
  ...orMessage.tsx |     100 |      100 |     100 |     100 |                   
  ...ionDialog.tsx |   89.23 |     84.9 |   81.81 |   89.23 | ...75,593,611-613 
  BtwMessage.tsx   |     100 |      100 |     100 |     100 |                   
  ...upDisplay.tsx |     100 |    94.73 |     100 |     100 | ...43,289,402,432 
  ...onMessage.tsx |   93.24 |       85 |     100 |   93.24 | 73-75,77,79       
  ...nMessages.tsx |   94.11 |    95.91 |   76.92 |   94.11 | ...47-349,352-355 
  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 |   81.73 |     65.9 |      75 |   81.73 | ...10-214,222,245 
  ...tsDisplay.tsx |   95.52 |    88.31 |     100 |   95.52 | ...40,142,175-180 
  ...ssMessage.tsx |    12.5 |      100 |       0 |    12.5 | 18-59             
  ...edMessage.tsx |   21.05 |      100 |       0 |   21.05 | 23-39             
  ...sMessages.tsx |   59.04 |       50 |    37.5 |   59.04 | ...21-126,147-159 
  ...ryMessage.tsx |   13.63 |      100 |       0 |   13.63 | 23-64             
  ...onMessage.tsx |   91.87 |    82.51 |     100 |   91.87 | ...49-651,658-660 
  ...upMessage.tsx |   98.38 |    95.38 |     100 |   98.38 | 188-191,422       
  ToolMessage.tsx  |   95.04 |    89.55 |     100 |   95.04 | ...1075,1120-1122 
 ...ponents/shared |    86.4 |    82.05 |    86.6 |    86.4 |                   
  ...ctionList.tsx |     100 |      100 |      75 |     100 |                   
  ...tonSelect.tsx |     100 |      100 |     100 |     100 |                   
  ...rBoundary.tsx |     100 |      100 |     100 |     100 |                   
  MaxSizedBox.tsx  |   84.71 |    86.95 |      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 |   90.37 |    82.85 |   18.18 |   90.37 | ...60-63,65,73-76 
  StaticRender.tsx |     100 |      100 |     100 |     100 |                   
  TextInput.tsx    |    80.8 |    67.79 |      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 |   91.49 |    86.66 |   83.33 |   91.49 | ...18-846,859,959 
  text-buffer.ts   |   85.98 |    81.78 |   97.91 |   85.98 | ...2664,2762-2763 
  ...er-actions.ts |   73.93 |    67.22 |     100 |   73.93 | ...32-733,934-936 
 ...ponents/skills |    3.99 |      100 |       0 |    3.99 |                   
  ...gerDialog.tsx |    3.99 |      100 |       0 |    3.99 | 79-137,140-678    
 ...ents/subagents |   30.87 |        0 |       0 |   30.87 |                   
  constants.ts     |     100 |      100 |     100 |     100 |                   
  index.ts         |       0 |        0 |       0 |       0 | 1-11              
  reducers.tsx     |    12.1 |      100 |       0 |    12.1 | 33-190            
  types.ts         |     100 |      100 |     100 |     100 |                   
  utils.ts         |   10.95 |      100 |       0 |   10.95 | ...1,56-57,60-102 
 ...bagents/create |    9.13 |      100 |       0 |    9.13 |                   
  ...ionWizard.tsx |    7.28 |      100 |       0 |    7.28 | 34-299            
  ...rSelector.tsx |   14.75 |      100 |       0 |   14.75 | 26-85             
  ...onSummary.tsx |    4.26 |      100 |       0 |    4.26 | 27-331            
  ...tionInput.tsx |    8.63 |      100 |       0 |    8.63 | 23-177            
  ...dSelector.tsx |   33.33 |      100 |       0 |   33.33 | 20-21,26-27,36-63 
  ...nSelector.tsx |    37.5 |      100 |       0 |    37.5 | 20-21,26-27,36-58 
  ...EntryStep.tsx |   12.76 |      100 |       0 |   12.76 | 34-78             
  ToolSelector.tsx |    4.16 |      100 |       0 |    4.16 | 31-253            
 ...bagents/manage |    21.6 |    59.52 |   27.27 |    21.6 |                   
  ...ctionStep.tsx |   10.25 |      100 |       0 |   10.25 | 21-103            
  ...eleteStep.tsx |   20.93 |      100 |       0 |   20.93 | 23-62             
  ...tEditStep.tsx |   25.53 |      100 |       0 |   25.53 | ...2,37-38,51-124 
  ...ctionStep.tsx |   35.61 |    59.52 |     100 |   35.61 | ...21-433,438-440 
  ...iewerStep.tsx |   13.72 |      100 |       0 |   13.72 | 18-73             
  ...gerDialog.tsx |    6.74 |      100 |       0 |    6.74 | 35-341            
 ...mponents/views |   69.22 |    71.81 |   61.11 |   69.22 |                   
  ContextUsage.tsx |   71.49 |    64.86 |      80 |   71.49 | ...30-436,473-567 
  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    |      75 |    81.81 |     100 |      75 | 39-42,59-67       
 src/ui/contexts   |   86.47 |    82.34 |   86.48 |   86.47 |                   
  ...ewContext.tsx |   91.66 |       90 |      75 |   91.66 | ...89-193,279-289 
  AppContext.tsx   |      80 |       50 |     100 |      80 | 19-20             
  ...ewContext.tsx |   93.83 |    68.51 |   42.85 |   93.83 | ...44,281-285,317 
  ...igContext.tsx |   81.81 |       50 |     100 |   81.81 | 15-16             
  ...ssContext.tsx |   85.65 |    84.85 |     100 |   85.65 | ...1612-1614,1620 
  ...owContext.tsx |   91.07 |    81.81 |     100 |   91.07 | 47-48,60-62       
  ...deContext.tsx |     100 |      100 |      50 |     100 |                   
  ...onContext.tsx |   80.77 |       80 |    92.3 |   80.77 | ...31-434,443-446 
  ...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 | 156-157           
  ...teContext.tsx |   86.66 |       50 |     100 |   86.66 | 237-238           
  ...deContext.tsx |      80 |     87.5 |      75 |      80 | ...11-112,118-120 
  ...rtContext.tsx |     100 |      100 |     100 |     100 |                   
 src/ui/daemon     |   89.51 |    76.92 |   95.65 |   89.51 |                   
  ...ui-adapter.ts |   89.51 |    76.92 |   95.65 |   89.51 | ...59,877-878,964 
 src/ui/editors    |   93.33 |    85.71 |   66.66 |   93.33 |                   
  ...ngsManager.ts |   93.33 |    85.71 |   66.66 |   93.33 | 49,63-64          
 src/ui/hooks      |   86.42 |    84.39 |   88.61 |   86.42 |                   
  ...dProcessor.ts |   85.53 |    85.13 |     100 |   85.53 | ...-970,1017-1018 
  ...ention-ref.ts |   97.72 |       84 |     100 |   97.72 | 65                
  keyToAnsi.ts     |    3.92 |      100 |       0 |    3.92 | 19-77             
  ...esourceRef.ts |     100 |      100 |     100 |     100 |                   
  ...completion.ts |     100 |    95.45 |     100 |     100 | 95                
  ...ention-ref.ts |     100 |      100 |     100 |     100 |                   
  ...dProcessor.ts |   94.55 |    73.58 |     100 |   94.55 | ...87-288,293-294 
  ...dProcessor.ts |   86.83 |    71.86 |   83.33 |   86.83 | ...1536,1565-1569 
  ...rt-command.ts |     100 |      100 |     100 |     100 |                   
  ...sced-flush.ts |     100 |      100 |     100 |     100 |                   
  ...llm-stream.ts |   88.85 |    85.07 |   85.18 |   88.85 | ...6260,6262,6367 
  ...ng-enabled.ts |     100 |      100 |     100 |     100 |                   
  ...oice-input.ts |   92.41 |    82.08 |   66.66 |   92.41 | ...12,514-515,670 
  ...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 |   86.44 |    88.48 |     100 |   86.44 | ...14-515,525-541 
  ...ifications.ts |   87.82 |    96.77 |     100 |   87.82 | 138-152           
  ...tIndicator.ts |   88.28 |    81.57 |     100 |   88.28 | ...66,175,179-187 
  ...waySummary.ts |   96.26 |       75 |     100 |   96.26 | 126-128,170       
  ...ndTaskView.ts |   94.89 |    77.55 |     100 |   94.89 | 164-168,257,263   
  ...chedScroll.ts |     100 |      100 |     100 |     100 |                   
  ...ketedPaste.ts |    23.8 |      100 |       0 |    23.8 | 19-37             
  ...nchCommand.ts |   96.03 |    88.75 |     100 |   96.03 | ...04-205,362-365 
  ...ompletion.tsx |   97.09 |    87.23 |     100 |   97.09 | ...23-324,334-335 
  ...dMigration.ts |    92.1 |    88.88 |     100 |    92.1 | 42-44             
  useCompletion.ts |   96.29 |    90.56 |     100 |   96.29 | ...17-218,222-223 
  ...nitMessage.ts |     100 |      100 |     100 |     100 |                   
  ...extualTips.ts |   78.26 |       50 |     100 |   78.26 | ...2,75-79,96-104 
  ...eteCommand.ts |   89.52 |    90.69 |     100 |   89.52 | ...98-106,114-115 
  ...ialogClose.ts |   36.11 |       10 |     100 |   36.11 | ...89-195,202-207 
  useDiffData.ts   |   11.62 |      100 |       0 |   11.62 | 44-87             
  ...oublePress.ts |   53.12 |       75 |     100 |   53.12 | 33-35,41-54       
  ...orSettings.ts |     100 |      100 |     100 |     100 |                   
  ...Completion.ts |   99.12 |    97.67 |     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 |    93.33 |     100 |     100 | 62                
  ...ggestions.tsx |   96.47 |    78.94 |     100 |   96.47 | 121,155-156       
  ...BranchName.ts |     100 |    94.44 |     100 |     100 | 54                
  ...oryManager.ts |   98.44 |     98.9 |     100 |   98.44 | 157-160           
  ...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    
  useKeypress.ts   |     100 |      100 |     100 |     100 |                   
  ...rdProtocol.ts |   36.36 |      100 |       0 |   36.36 | 24-31             
  ...unchEditor.ts |   22.58 |      100 |      50 |   22.58 | 11-32,44-85       
  ...gIndicator.ts |     100 |    96.66 |     100 |     100 | 109               
  useLogger.ts     |      16 |      100 |       0 |      16 | 15-45             
  useMCPHealth.ts  |   10.52 |      100 |       0 |   10.52 | 36-75             
  ...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 |    94.94 |     100 |     100 | ...43,279,349,359 
  ...delCommand.ts |     100 |       96 |     100 |     100 | 61                
  ...ouseEvents.ts |   94.89 |       95 |   83.33 |   94.89 | 78-82             
  ...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 |   85.29 |    80.28 |    92.3 |   85.29 | ...36,351-361,441 
  useQwenAuth.ts   |     100 |      100 |     100 |     100 |                   
  ...lScheduler.ts |   89.13 |     86.9 |     100 |   89.13 | ...61-463,496-506 
  ...oryCommand.ts |       0 |        0 |       0 |       0 | 1-7               
  ...umeCommand.ts |   96.51 |    90.19 |     100 |   96.51 | 279,306-311       
  ...ompletion.tsx |   90.67 |    83.33 |     100 |   90.67 | ...02,105,138-141 
  ...ectionList.ts |   97.12 |    96.22 |     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 |   85.48 |    58.33 |     100 |   85.48 | 22-28,40,71       
  ...agerDialog.ts |   88.23 |      100 |     100 |   88.23 | 20,24             
  ...Completion.ts |   82.79 |    85.33 |   94.73 |   82.79 | ...86-688,696-732 
  ...tateAndRef.ts |     100 |      100 |     100 |     100 |                   
  ...tatsDialog.ts |     100 |      100 |     100 |     100 |                   
  useStatusLine.ts |   97.32 |    93.93 |     100 |   97.32 | ...18-422,518-525 
  ...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 |   67.34 |    58.82 |   66.66 |   67.34 | 52-53,61-68,79-85 
  ...rminalSize.ts |     100 |      100 |     100 |     100 |                   
  ...emeCommand.ts |    79.2 |    35.29 |     100 |    79.2 | ...15-116,120-121 
  useTimer.ts      |   97.59 |    94.73 |     100 |   97.59 | 17-18             
  ...lMigration.ts |       0 |        0 |       0 |       0 |                   
  ...rustModify.ts |     100 |    90.47 |     100 |     100 | 112,134           
  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 |    72.72 |     100 |   93.75 | 47-48,72          
  vim.ts           |      74 |    67.56 |   69.23 |      74 | ...1854-1861,1869 
 src/ui/layouts    |   91.25 |    89.47 |     100 |   91.25 |                   
  ...AppLayout.tsx |   90.99 |     87.5 |     100 |   90.99 | 61-63,111-116,152 
  ...AppLayout.tsx |   91.66 |    92.85 |     100 |   91.66 | 75-80             
 src/ui/model      |   97.91 |    98.36 |     100 |   97.91 |                   
  ...ggregation.ts |     100 |      100 |     100 |     100 |                   
  ...ming-model.ts |   97.43 |    97.72 |     100 |   97.43 | 261-265           
 src/ui/models     |   80.72 |       80 |   71.42 |   80.72 |                   
  ...ableModels.ts |   80.72 |       80 |   71.42 |   80.72 | ...,61-71,125-127 
 ...noninteractive |     100 |      100 |    6.66 |     100 |                   
  ...eractiveUi.ts |     100 |      100 |    6.66 |     100 |                   
 src/ui/selection  |   93.56 |    86.19 |     100 |   93.56 |                   
  screen-buffer.ts |   94.73 |    66.66 |     100 |   94.73 | 51-52             
  ...ion-coords.ts |     100 |      100 |     100 |     100 |                   
  ...ction-span.ts |   93.81 |     92.1 |     100 |   93.81 | ...1,45-46,99-100 
  ...tion-state.ts |     100 |      100 |     100 |     100 |                   
  ...ction-text.ts |   93.85 |    93.44 |     100 |   93.85 | 30-34,130-131     
  ...selection.tsx |   91.88 |    78.57 |     100 |   91.88 | ...16-417,446-447 
 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      |   87.98 |    86.07 |    96.1 |   87.98 |                   
  ...Colorizer.tsx |   80.31 |    85.41 |     100 |   80.31 | ...00-201,313-339 
  ...nRenderer.tsx |   80.07 |     75.6 |     100 |   80.07 | ...70,274,332-333 
  ...wnDisplay.tsx |   92.87 |     93.5 |     100 |   92.87 | ...,955,1002-1020 
  ...idDiagram.tsx |   87.79 |    95.34 |     100 |   87.79 | 156-179           
  ...eRenderer.tsx |   93.63 |    81.77 |   95.23 |   93.63 | ...47-750,803-808 
  ...odeDisplay.ts |   94.28 |    85.71 |     100 |   94.28 | 23,40             
  asciiCharts.ts   |    96.7 |     87.5 |     100 |    96.7 | 170-177,278       
  ...dWorkUtils.ts |     100 |      100 |     100 |     100 |                   
  ...boardUtils.ts |    52.9 |    74.15 |    92.3 |    52.9 | ...29,632-641,644 
  commandUtils.ts  |   98.61 |    93.27 |     100 |   98.61 | 189,217-218,424   
  computeStats.ts  |     100 |      100 |     100 |     100 |                   
  customBanner.ts  |   90.68 |    91.22 |     100 |   90.68 | ...13,324-327,334 
  displayUtils.ts  |   73.84 |    73.91 |     100 |   73.84 | ...34,36-40,42-46 
  ...coalescing.ts |     100 |      100 |     100 |     100 |                   
  formatters.ts    |   94.87 |    98.24 |     100 |   94.87 | 116-119           
  goal-runtime.ts  |   94.44 |    96.29 |     100 |   94.44 | 32-34             
  gradientUtils.ts |     100 |      100 |     100 |     100 |                   
  highlight.ts     |     100 |      100 |     100 |     100 |                   
  ...gap-notice.ts |     100 |      100 |     100 |     100 |                   
  ...oryMapping.ts |     100 |    95.65 |     100 |     100 | 45,151            
  historyUtils.ts  |   96.07 |     97.1 |     100 |   96.07 | 104-107           
  ...mage-parts.ts |   97.75 |       95 |     100 |   97.75 | 82-83             
  inline-math.ts   |   98.48 |    95.23 |     100 |   98.48 | 129-130           
  input-mouse.ts   |     100 |    85.71 |     100 |     100 | 48,93             
  isNarrowWidth.ts |     100 |      100 |     100 |     100 |                   
  ...olDetector.ts |   68.81 |       75 |   66.66 |   68.81 | ...27-132,160-161 
  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.36 |     100 |   98.72 | 145-146           
  ...t-position.ts |     100 |     87.5 |     100 |     100 | 85                
  ...geRenderer.ts |   86.51 |    70.16 |   95.12 |   86.51 | ...1286,1326-1332 
  ...alRenderer.ts |   86.69 |     71.9 |     100 |   86.69 | ...1476,1513-1519 
  ...lsBySource.ts |     100 |    95.23 |     100 |     100 | 84                
  mouse.ts         |   92.85 |    74.19 |     100 |   92.85 | ...38,145,149-152 
  osc8.ts          |   91.33 |    79.03 |     100 |   91.33 | ...73,273,277-278 
  ...red-height.ts |   98.38 |    97.14 |     100 |   98.38 | 195-197           
  ...mConstants.ts |     100 |      100 |     100 |     100 |                   
  restoreGoal.ts   |     100 |      100 |     100 |     100 |                   
  ...storyUtils.ts |   84.37 |    81.09 |     100 |   84.37 | ...03-625,759-760 
  ...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 |   95.19 |      100 |   88.88 |   95.19 | 121-126           
  ...nal-buffer.ts |     100 |      100 |     100 |     100 |                   
  ...e-renderer.ts |   90.61 |    83.44 |     100 |   90.61 | ...80,482-484,607 
  ...ize-reflow.ts |     100 |     92.3 |     100 |     100 | 57,62,209,217,347 
  ...wOptimizer.ts |     100 |    94.73 |     100 |     100 | 35,78             
  terminalSetup.ts |    4.37 |      100 |       0 |    4.37 | 44-393            
  textUtils.ts     |   98.71 |    95.72 |     100 |   98.71 | 292-293,478-479   
  ...background.ts |     100 |      100 |     100 |     100 |                   
  todoSnapshot.ts  |   95.81 |     92.3 |     100 |   95.81 | ...09-210,243-244 
  ...isplay-map.ts |     100 |      100 |     100 |     100 |                   
  updateCheck.ts   |     100 |    92.75 |     100 |     100 | 227-239,331       
  windowTitle.ts   |   96.55 |    94.73 |     100 |   96.55 | 56-57             
  ...ow-keyword.ts |     100 |      100 |     100 |     100 |                   
 ...i/utils/export |   75.03 |     60.1 |   94.59 |   75.03 |                   
  collect.ts       |   71.27 |    65.81 |      96 |   71.27 | ...90-633,655-656 
  index.ts         |     100 |      100 |     100 |     100 |                   
  normalize.ts     |   80.42 |    51.35 |     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      |   81.24 |    79.78 |   81.69 |   81.24 |                   
  ...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 |   91.09 |     92.1 |     100 |   91.09 | ...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 |       70 |     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         |   92.23 |    89.82 |   96.12 |   92.23 |                   
  ...p-profiler.ts |   98.39 |    92.59 |     100 |   98.39 | 141,185,235       
  acpModelUtils.ts |   97.36 |    95.09 |     100 |   97.36 | ...09-210,214-215 
  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       
  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        
  ...y-identity.ts |   89.22 |    85.18 |     100 |   89.22 | ...23-424,431-432 
  ...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 | 50-52,58          
  ...re-runtime.ts |     100 |      100 |     100 |     100 |                   
  ...putCapture.ts |   90.65 |    86.31 |     100 |   90.65 | ...73,371,373-374 
  ...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 
  ...tyWarnings.ts |     100 |      100 |     100 |     100 |                   
  ...lationInfo.ts |   97.81 |    94.69 |     100 |   97.81 | ...03,420-421,466 
  ...projection.ts |   95.27 |    95.58 |     100 |   95.27 | 140-145           
  jsonc-editor.ts  |   93.18 |    92.66 |     100 |   93.18 | ...80-381,384-385 
  load-undici.ts   |     100 |      100 |     100 |     100 |                   
  ...npm-update.ts |   86.64 |    77.02 |     100 |   86.64 | ...03-304,335-345 
  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 
  ...-part-list.ts |     100 |      100 |     100 |     100 |                   
  osc.ts           |   97.18 |      100 |    87.5 |   97.18 | 182-183           
  package.ts       |   88.88 |    85.71 |     100 |   88.88 | 31-32             
  paths.ts         |     100 |      100 |     100 |     100 |                   
  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 |                   
  ...xImageName.ts |     100 |    77.77 |     100 |     100 | 10,18             
  sandboxMounts.ts |     100 |      100 |     100 |     100 |                   
  ...-path-argv.ts |     100 |      100 |     100 |     100 |                   
  sessionPaths.ts  |   90.84 |    90.56 |     100 |   90.84 | ...81-182,185-186 
  shell-args.ts    |     100 |      100 |     100 |     100 |                   
  spawnWrapper.ts  |     100 |      100 |     100 |     100 |                   
  ...ate-verify.ts |     100 |      100 |     100 |     100 |                   
  ...upProfiler.ts |   98.47 |    94.66 |     100 |   98.47 | 132-133,308       
  ...upWarnings.ts |     100 |      100 |     100 |     100 |                   
  stdioHelpers.ts  |   76.66 |       90 |   83.33 |   76.66 | 93-99             
  ...alSequence.ts |     100 |    97.61 |     100 |     100 | 60                
  ...iffPreview.ts |   76.47 |       25 |     100 |   76.47 | 13,17,23-24       
  ...on-handler.ts |    73.8 |       75 |     100 |    73.8 | 17-18,25-26,67-73 
  ...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 |                   
  ...WithBackup.ts |   65.04 |    77.77 |     100 |   65.04 | 97,112,133-172    
 ...s/housekeeping |   94.35 |    94.11 |     100 |   94.35 |                   
  cleanup.ts       |   92.59 |    93.75 |     100 |   92.59 | ...02-205,209-211 
  ...eractionAt.ts |     100 |      100 |     100 |     100 |                   
  throttledOnce.ts |   95.95 |    93.93 |     100 |   95.95 | 77-78,153-154     
-------------------|---------|----------|---------|---------|-------------------
Core Package - Full Text Report
Core full-text-summary.txt not found at: coverage_artifact/core/coverage/full-text-summary.txt

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

@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 — CI landed green after the review. ✅

Comment thread packages/cli/src/ui/hooks/useGeminiStream.ts Outdated
Comment thread packages/cli/src/ui/hooks/use-llm-stream.ts
Comment thread packages/cli/src/ui/hooks/useGeminiStream.ts Outdated
Comment thread packages/cli/src/ui/hooks/useGeminiStream.test.tsx Outdated
Comment thread packages/cli/src/ui/hooks/use-llm-stream.ts
Comment thread packages/cli/src/ui/hooks/useGeminiStream.ts Outdated
Comment thread packages/cli/src/ui/hooks/useGeminiStream.ts Outdated
Comment thread packages/cli/src/ui/hooks/useGeminiStream.ts Outdated
…ot failure

Review round on #9638 found two real loss/duplication edges in the
tool-round boundary teammate drain, plus test/observability gaps:

- A drained envelope was delivered TWICE when the boundary submission
  failed after being accepted (user cancel mid-stream, terminal API
  error): GeminiChat pushes the submission's user content before any
  model attempt, yet onDeliveryFailed unconditionally requeued the
  envelope and the Idle drain resubmitted it.
- A blocking UserPromptSubmit hook permanently LOST the envelope:
  ToolResult is not in the hook's exclusion list, the blocked stream
  dispatched onDelivered, and nothing restored the drained queue.
- Boundary deliveries skipped chat recording entirely (recordNotification
  is keyed on Teammate/Notification), so resumed sessions lost both the
  notification item and the envelope from the reconstructed context.

Settle the drained batch by acceptance instead of by failure: snapshot
GeminiChat's user-content push counter (the same signal
settleSteerInput uses in client.ts) before the submission; on failure,
requeue only when the counter did not advance, and when it did, record
the delivery via recordNotification instead of redelivering. Count a
UserPromptSubmitBlocked stream as a delivery failure so blocked
submissions restore their drained payloads.

Also extract the drain protocol (splice + display marking + idempotent
restore) into one drainTeammateQueue helper shared by the boundary and
Idle paths, add debug logs at the drain/record/restore transitions, and
shrink the #8172 test harness to a wrapper over renderTestHook. New
regression tests pin the no-duplicate, hook-block restore, recording,
and survivesGenerationChange-skip behaviors (mutation-checked).
@yiliang114

Copy link
Copy Markdown
Collaborator Author

Review closeout — round pinned at fd6bce2

All 8 unresolved threads from the 07:11Z /review round triaged; all 8 verified real at head and fixed in 45e5abd (pushed fd6bce2f78..45e5abda37). Threads replied with evidence and resolved.

Criticals

  • Double delivery on post-acceptance failure — the drain now settles by acceptance, not by failure: it snapshots GeminiChat's user-content push counter (the same signal settleSteerInput uses in client.ts) before the submission; onDeliveryFailed requeues only when the counter did not advance. Cancel-mid-stream / terminal API error after acceptance no longer redelivers; pre-send failures still restore. Mutation-checked regression test added.
  • Envelope loss on blocking UserPromptSubmit hook — a UserPromptSubmitBlocked stream now counts as a delivery failure for continuation metadata, so the blocked boundary submission restores the drained batch; the push counter (unchanged by a block) gates the restore, and the hook-exempt Teammate Idle path redelivers exactly once. Mutation-checked regression test added. Residual: non-blocking hooks still see the envelope in promptText (ToolResult stays hookable — exempting it is a bigger hook-contract change, flagged in-thread).

Suggestions (all fixed)

  • Shared drainTeammateQueue() helper for boundary + Idle drains (also unifies the divergent restore edges).
  • renderBusyMultiRoundTask shrank to a wrapper over renderTestHook (which now captures the scheduler onComplete and returns the production 3-tuple).
  • Restore-path tests added for the two load-bearing edges (onDeliveryFailed post-acceptance; pre-acceptance restore + redelivery); goal-preempt / onAdmissionFailed edges remain untested with reasons in-thread (the latter is effectively unreachable for ToolResult).
  • survivesGenerationChange skip branch now pinned by a test through the real boundary path.
  • debugLogger.debug at drain / record / restore transitions.
  • Boundary deliveries now journal via recordNotification (same shape as the Teammate path) on acceptance, so resume restores the item and the envelope stays in reconstructed context — this also corrects the PR body's "identical to steer" recording claim.

VerificationuseGeminiStream.test.tsx 238/238 (234 prior + 4 new, mutation-checked), packages/cli typecheck clean, ESLint + Prettier clean on both changed files. Node note: this machine only has Node 24 (repo .nvmrc pins 22); verification ran on 24.

Comment thread packages/cli/src/ui/hooks/use-llm-stream.ts
Comment thread packages/cli/src/ui/hooks/useGeminiStream.ts Outdated
Comment thread packages/cli/src/ui/hooks/use-llm-stream.ts
Comment thread packages/cli/src/ui/hooks/useGeminiStream.ts Outdated
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

@doudouOUC doudouOUC 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.

Re-review of ba478fa7 — round-2 findings addressed, no new issues

Round-2 Criticals re-verified

R2-1 (C) userPromptBlockedRef is a hook-wide singletonFixed. The userPromptBlocked flag is now a local boolean inside processStream, set in the event loop and returned in StreamProcessingResult.userPromptBlocked. The handleCompletedTools check reads the per-submission processingResult rather than a hook-wide ref.

R2-2 (C) acceptance snapshot of GeminiChat's global user-content push counter spans too wideFixed. The acceptance/restore decision is now carried by submissionSettlement (a SteerInput-shaped object passed through the existing steerInput option), so GeminiClient calls accept()/restore() at send entry, next to the actual history push. No hook-wide counter needed.

Round-2 Suggestions re-verified

R2-3 (S) single-queue test onlyFixed. New test delivers and records every envelope in a boundary batch exercises a 2-message batch.

R2-4 (S) per-submission reset unpinnedFixed. The userPromptBlocked flag is now a local variable inside processStream, naturally reset on each submission.

Round-1 carry-over check

All 8 round-1 findings (2 Criticals, 6 Suggestions) were confirmed fixed in 45e5abda and remain fixed at ba478fa7. The two Criticals (R1-1 double-delivery, R1-2 UserPromptSubmit loss) are addressed by the settlement protocol; the remaining Suggestions are covered by the drainTeammateQueue shared protocol, the survivesGenerationChange test, debugLogger.debug calls, recordNotification journaling, and the batch-level test.

What the new commit (ba478fa7) does

The commit replaces the userPromptBlockedRef + GeminiChat push-counter snapshot approach with a submissionSettlement object that bundles steer and teammate settlement into one SteerInput-compatible carrier. The GeminiClient drives the accept()/restore() callbacks at send entry, which is the correct point to decide whether the drained batch reached the model. This eliminates the two Criticals in one clean refactor.

Code review

The changes are well-structured:

  • submissionSettlement bundles steer + teammate. When both are present, accept() calls both drainedSteer?.accept() and settleDrainedTeammates(true); restore() calls both restores. When only one is present, the other's ?. optional chaining makes it a no-op. The parts field defaults to [] when steer is absent, which is harmless.

  • settleDrainedTeammates is idempotent. The drainedTeammates variable is set to undefined after the first settlement call, so onDeliveryFailed after onDelivered (or vice versa, should a bug in the callback contract arise) is a no-op.

  • userPromptBlocked gates onDeliveryFailed. The processingResult.userPromptBlocked is OR'd with lastPromptErroredRef and goalTerminalErrorRef to trigger the onDeliveryFailed callback, which calls submissionSettlement?.restore() — the correct restore path for hook-blocked submissions.

  • onAdmissionFailed now restores steer too. This is a latent bugfix in the existing steer path — the original code only restored steer on onDeliveryFailed, not on onAdmissionFailed. The PR unifies both restore sites.

  • recordNotification journals boundary deliveries. The accepted-route calls config.getChatRecordingService()?.recordNotification() with the batch, matching the Idle-path Teammate submission's journaling. This closes R1-8.

  • Tests exercise all failure paths. The 8-test suite covers: core injection, Idle fallback, cancel-no-loss, second-message-after-boundary, accepted-then-failed mid-stream (no-redundant-delivery), UserPromptSubmit hook block + Idle recovery, multi-envelope batch, and survivesGenerationChange exclusion.

Remaining observations (none are blockers)

  1. The onAdmissionFailed steer restore is a latent bugfix. The old code did not restore steer on admission failure, which means a misbehaving admission gate could silently lose steer messages. This PR fixes it by restoring both steer and teammate on admission failure. This is correct behavior — no regression risk.

  2. No CI visibility at ba478fa7. The last CI run was at fd6bce2; the two subsequent commits (round-1 fix, round-2 fix) have not been pushed through CI. The author should be prepared for CI to catch any integration issues.

Verdict

All prior Criticals and Suggestions are addressed. The changes are correct, the failure-path coverage is thorough, and the code is clean. No new issues found.

— manual review

@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.

Partially reviewed — gaps disclosed.

Not reviewed: build-and-test — Integration Tests (CLI, No Sandbox) was skipped in CI and its suite did not run locally.

Not explored to full depth (tool budget reached): "agent 6b": none — all planned checks completed (no check was cut short)..

Deferred under the convergence posture (round 3, not a blocker) — recorded, not requested in this round:

  • packages/cli/src/ui/hooks/useGeminiStream.ts:5300 — [review] Boundary recordNotification journaling duplicates the teammate journaling contract in core client.ts
  • packages/cli/src/ui/hooks/useGeminiStream.ts:689 — [probe] The display-once guard in drainTeammateQueue is load-bearing but pinned by no test
中文说明

仅完成部分审查,审查缺口已披露。

未审查:build-and-test — Integration Tests (CLI, No Sandbox) was skipped in CI and its suite did not run locally。

未探索到全部深度(达到工具调用预算):"agent 6b"none — all planned checks completed (no check was cut short).

收敛姿态下延后(第 3 轮,非阻断)——已记录,本轮不要求修改:共 2 条(原文未翻译,列表见上方英文部分)。

— qwen3.8-max via Qwen Code /review (v0.21.15)

Comment thread packages/cli/src/ui/hooks/useGeminiStream.ts Outdated
Comment thread packages/cli/src/ui/hooks/useGeminiStream.test.tsx Outdated
Comment thread packages/cli/src/ui/hooks/use-llm-stream.test.tsx
The attached steer-input carrier (which the #8172 teammate boundary
settlement rides) was decided from a push-counter snapshot taken at
sendMessageStream generator entry, before the awaited UserPromptSubmit
hook. ToolResult submissions are not hook-exempt, so a concurrent
submission admitted during the hook await could push its own content
into the global counter and supply the observed push for a send that
never pushed: a hook-blocked or cancelled round settled as accepted,
journaling a delivery that never happened while the drained teammate
envelope was never requeued — silent message loss.

- Blocked sends and hook failures exit before the settlement
  try/finally and provably never pushed: restore the carrier
  unconditionally instead of comparing the counter.
- Re-snapshot the counter immediately before `turn.run` (after the
  hook await) so sends that reach the push compare against the
  tightest window; exits before `turn.run` restore unconditionally.
- Drop the dead push-counter fixture from useGeminiStream.test.tsx
  (nothing under test reads it at this head), correct the settlement
  wrapper comment, and pin the Idle teammate drain's goal-claim
  deferral restore path plus its exactly-once redelivery.

@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.

Partially reviewed — gaps disclosed.

Not reviewed: build-and-test — Integration Tests (CLI, No Sandbox) was skipped in CI and its suite did not run locally.

Deferred under the convergence posture (round 4, not a blocker) — recorded, not requested in this round:

  • packages/cli/src/ui/hooks/useGeminiStream.test.tsx:1630 — [probe] blocked-round test shim settles the carrier itself, masking the userPromptBlocked delivery-decision mutation
中文说明

仅完成部分审查,审查缺口已披露。

未审查:build-and-test — Integration Tests (CLI, No Sandbox) was skipped in CI and its suite did not run locally。

收敛姿态下延后(第 4 轮,非阻断)——已记录,本轮不要求修改:共 1 条(原文未翻译,列表见上方英文部分)。

— qwen3.8-max via Qwen Code /review (v0.21.15)

Comment thread packages/cli/src/ui/hooks/use-llm-stream.ts
Comment thread packages/core/src/core/client.ts Outdated
…load

When a boundary submission fails before the history push (e.g. a UserPromptSubmit hook that throws on the ToolResult prompt), the drained teammate batch is restored to the queue, but the same envelopes stay baked into lastPromptRef. A Ctrl+Y retry then re-sends them while the queue still holds them, so the leader receives the report twice (retry + Idle drain). Strip the restored envelopes from the retry payload so the queue redelivery is the single source.
restoreSteerInput duplicated settleSteerInput's idempotence guard, try/catch, and failure warning — only the decision differed. settleSteerInput now takes an optional pushCountBefore: undefined marks a send that provably never pushed and restores unconditionally. Keeps the 'settle each carrier exactly once' invariant in one closure.
@yiliang114

Copy link
Copy Markdown
Collaborator Author

@qwen-code /triage

@qwen-code-ci-bot

qwen-code-ci-bot commented Aug 21, 2026

Copy link
Copy Markdown
Collaborator

Sandboxed verification: ✅ passed — merge-ready (agent verdict) - workflow run

Ran the PR in an isolated, token-free container: A/B against the base build, mock-free harness assertions, targeted gates. Advisory evidence for human reviewers — not a review, an approval, or a CI check.

Scripted assertions: 629 passed · 0 failed · 629 total

Flakiness gate: ✅ 2 changed test file(s) x 5 identical rounds, no divergence

中文 — 判定:✅ 通过 · 可合入(agent 判定)

沙箱验证在隔离、无凭证的容器中执行了该 PR 的代码(与 base 构建 A/B 对照、无 mock harness 断言、定向门禁)。仅作为评审证据,不构成评审、批准或 CI 检查

脚本断言:629 通过 · 0 失败 · 629 总计

抖动门:✅ 2 changed test file(s) x 5 identical rounds, no divergence

Verification report

Verification report — PR #9638

Verdict: merge-ready — 629/629 scripted assertions passed, 0 unexpected failures, no blocking findings. Verified head: 7e2ebd369ea05ff31ac45a4f95e85cdd67834a3b (HEAD^2 of the merge-ref checkout; base tip 7a4566cb3b).

中文摘要
  • 结论merge-ready。629 项脚本化断言全部通过,0 项意外失败,无阻塞性发现。
  • A/B 结论:核心行为(teammate 消息在工具轮次边界随 ToolResult 提交送达,而非等整个多轮任务结束)在 base(HEAD^1)上 5 红 5 绿、head 上 10/10 全绿,红的全部是行为级断言失败(提交载荷缺信封 / 延迟到任务末尾批量送达),不是编译错误;core 侧 3 个 settle 语义测试在 base 全红(accept 被误调、restore 未调——全局 push 计数器被并发提交顶替),head 全绿。变更确为承重件。
  • 变异矩阵:11 个单点变异,9 个按预期被杀且归因一一对应(每个 core 守卫恰好只杀自己的测试);2 个存活者(userPromptBlocked 分发标志、取消边界守卫)经裁定为冗余防御/完整性报告,非合并条件。
  • 发现:无阻塞项;两条低严重度完整性记录见 Findings。
  • 未覆盖:每提交归因(浅克隆仅 1/6 提交可达,验证的是聚合 diff);live 多 agent e2e 与 TUI(PR 亦未提供);steer 的两条特殊轮次启动路径对 teammate 消息不覆盖(PR 已声明,落回 Idle 兜底即现状);boundary 投递不走 dualOutput.emitUserMessage sidecar(PR 已声明,与 steer 同址行为一致)。

Central claim + A/B

Central claim: teammate→leader messages queued during a multi-round tool task are delivered at the next tool-round boundary — appended to the SendMessageType.ToolResult submission after the tool-response parts — instead of waiting for the whole task; with no loss and no double delivery across cancelled/preempted boundaries, admission/delivery failures, hook blocks, and Ctrl+Y retries.

Secondary claims: (1) the steer-carrier settlement in GeminiClient.sendMessageStream settles by the actual push (unconditional restore on paths that provably never pushed; counter snapshot retaken after the hook await); (2) the shared drainTeammateQueue refactor preserves the Idle fallback, including Goal-gate deferral.

A/B cells: base = git worktree at HEAD^1 with the PR's test files copied in (red = the change is load-bearing); head = merge checkout. The base worktree reused the root node_modules (PR leaves package.json/lockfile untouched); cli-side core resolution goes through the package's vitest source alias into the base tree (readlink -f showed node_modules/@qwen-code/qwen-code-core → head tree, but the alias @qwen-code/qwen-code-core → <worktree>/packages/core/index.ts overrides it and neither tested file imports core subpaths); core's dist was compiled from base source inside the worktree; dists of PR-untouched packages (acp-bridge, web-templates, channels/*) were copied from head after confirming their sources are byte-identical base↔head.

#8172 test (cli) base head
injects queued teammate messages into the next tool-round submission RED — boundary submission carried only tool-response parts green
still delivers at Idle when the task ends without another tool round green green
does not lose queued messages when the round boundary was cancelled green green
delivers later teammate messages after an earlier round-boundary delivery RED — both batched at whole-task end green
does not deliver a boundary-drained envelope twice when the accepted submission then fails mid-stream RED — deferred delivery made 2 submissions green
restores a boundary-drained envelope when a UserPromptSubmit hook blocks green green
does not re-send the restored envelope when retrying (Ctrl+Y) RED — first attempt lacked the envelope green
delivers and records every envelope in a boundary batch RED green
keeps queued messages out of continuations that survive generation change green green
defers the Idle drain while a Goal owns the turn, delivers exactly once green green

Witnesses: 01-ab-cli-base-5red-5green-head-10green.png (base cell as run: 5 failed | 5 passed, behavioral assertion diffs), 04-head-cli-cell-live-10-of-10-green.png (live head cell: 10 passed | 230 skipped).

steer-settlement test (core) base head
restores a hook-blocked steer even when a concurrent push lands during the hook await REDaccept called, restore not green
restores a steer cancelled during the hook await even if a concurrent push advanced the counter REDrestore 0 calls green
restores a steer whose push rolled back even when a concurrent push landed during the hook RED — entry snapshot read growth as acceptance green

Witness: 02-ab-core-base-3red-head-3green.png. All base failures are expected-vs-actual assertion mismatches, not import/compile errors — the A/B proves behavior, not buildability.

Corrections

  • The PR body's "Full file: 234/234 pass" describes the file at the first commit; the final head file contains 240 tests, all passing (240/240 at head). Not a code issue — the description predates commits 2–6.

Findings (non-blocking, completeness)

  1. userPromptBlocked dispatch flag is a redundant defence for message safety (low). Mutation M3 (drop processingResult.userPromptBlocked from the delivery-failed condition) survived all 10 cli tests: the settlement carrier is already restored before dispatch by the client-side unconditional restore (pinned red by M8 in core) and by the test shim. Its remaining independent effect is telemetry — without it, a hook-blocked tool continuation would end its interaction span as delivered instead of error. Classification: redundant defence, keep as-is; the non-redundant sibling (client-side block-path restore) is the load-bearing hunk and is pinned.
  2. The cancelled-boundary drain guard is redundant for delivery correctness (low). Mutation M11 (drop !continuationWasCancelled() from the drain condition) survived: a cancelled boundary would drain and immediately restore via settleDrainedTeammates(false), delivery-equivalent. The guard's real role is display hygiene (no premature ● … line) and avoiding a wasted drain/restore round trip. Classification: redundant defence.

Neither survivor is a merge condition; both are defense-in-depth with their load-bearing siblings pinned red in the matrix.

Mutation matrix

Witness: 03-mutation-matrix-9killed-2survived.png; per-mutant raw logs in logs/mutant-*.txt; harness rerunnable as node mutation-matrix.mjs.

mutant reverts outcome pinned by
control-cli / control-core nothing GREEN baseline (10 / 3)
M1 boundary drain the central hunk KILLED, 5 red core repro + 4 boundary tests
M2 settle-by-acceptance if (accepted) → always restore KILLED, 4 red no-double-delivery + batch tests
M3 blocked dispatch flag drop userPromptBlocked SURVIVED (expected) redundant defence (finding 1)
M4 retry strip drop lastPromptRef strip KILLED, 1 red Ctrl+Y test
M5 recordNotification drop boundary journaling KILLED, 1 red batch record test
M6 generation-change guard drop survivesGenerationChange check KILLED, 1 red surviving-continuation test
M7 restore re-arm drop setTeammateTrigger in restore KILLED, 1 red Goal-deferral test
M11 cancel guard drop continuationWasCancelled() check SURVIVED (expected) redundant defence (finding 2)
M8 block-path counter block path compares counter KILLED, 1 red hook-blocked steer test
M9 entry snapshot drop post-hook re-snapshot KILLED, 1 red push-rollback test
M10 hook-failure settle drop catch-path settle KILLED, 1 red cancelled-in-hook test

Positive controls: M1/M8 are the known-pin mutations (the PR's red→green tests), landed in the same files they mutate; every core guard kills exactly its own test (1:1 attribution). No mutant regressed a green test to red outside its pin set.

Targeted gates

  • packages/cli useGeminiStream.test.tsx at head: 240 passed (240) (logs/head-cli-suite.txt).
  • packages/core client.test.ts at head: 361 passed (361) (logs/head-core-suite.txt).
  • npm run typecheck in packages/cli and packages/core: exit 0 both.

Not covered

  • Per-commit attribution: the depth-2 checkout exposes 1 of the 6 metadata commits; the aggregate HEAD^1..HEAD diff was verified instead.
  • Live multi-agent e2e / TUI evidence (the PR states the same; the cli harness drives the real handleCompletedTools/submitQuery path with a mocked model and a settlement shim mirroring the client contract — the shim's acceptance semantics are pinned separately in core's client.test.ts).
  • Steer's two exotic round-starting paths (duplicate-tool-response bypass, client.ts no-tool-call continuations) for teammate messages — PR-declared v1 scope; they fall back to the Idle drain (today's behavior), so no regression.
  • dualOutput.emitUserMessage sidecar for boundary deliveries — PR-declared, identical to steer at the same site; chat recording is now covered by recordNotification (pinned by M5).
  • Repo-wide lint/format gates (PR's CI covers them); only affected-workspace tests and typecheck were run here.

Methodology

Environment: CI node:22-bookworm container, merge-ref checkout (HEAD merge, HEAD^1 base tip, HEAD^2 verified head), npm ci + build pre-run. A/B base cell: scratch worktree at HEAD^1 with root node_modules symlinked, core compiled from base source, PR test files copied in; head cell: same tests on the merge checkout. Mutation matrix: 11 single-point mutants applied to head sources by mutation-matrix.mjs (each replacement asserted to occur exactly once, file restored after every run), each run against the pinned vitest selection. Raw logs in logs/, harnesses (mutation-matrix.mjs, print-evidence.mjs) in the artifact dir; captures in evidence/.

Flakiness gate log

rounds=5 files=2 skipped=0
file packages/cli/src/ui/hooks/useGeminiStream.test.tsx: (cd packages/cli) npx --no-install vitest run ./src/ui/hooks/useGeminiStream.test.tsx
file packages/core/src/core/client.test.ts: (cd packages/core) npx --no-install vitest run ./src/core/client.test.ts


per-file results (P=pass F=fail I=infra-exit, one letter per run):
  packages/cli/src/ui/hooks/useGeminiStream.test.tsx: PPPPP
  packages/core/src/core/client.test.ts: PPPPP

verdict: pass
summary: 2 changed test file(s) x 5 identical rounds, no divergence

--- per-invocation detail (full copy in the artifact) ---
round 1 · packages/cli/src/ui/hooks/useGeminiStream.test.tsx: P (exit 0)
round 1 · packages/core/src/core/client.test.ts: P (exit 0)
round 2 · packages/cli/src/ui/hooks/useGeminiStream.test.tsx: P (exit 0)
round 2 · packages/core/src/core/client.test.ts: P (exit 0)
round 3 · packages/cli/src/ui/hooks/useGeminiStream.test.tsx: P (exit 0)
round 3 · packages/core/src/core/client.test.ts: P (exit 0)
round 4 · packages/cli/src/ui/hooks/useGeminiStream.test.tsx: P (exit 0)
round 4 · packages/core/src/core/client.test.ts: P (exit 0)
round 5 · packages/cli/src/ui/hooks/useGeminiStream.test.tsx: P (exit 0)
round 5 · packages/core/src/core/client.test.ts: P (exit 0)

Evidence images

01-ab-cli-base-5red-5green-head-10green

02-ab-core-base-3red-head-3green

03-mutation-matrix-9killed-2survived

04-head-cli-cell-live-10-of-10-green

Harness scripts and raw logs are in the workflow run artifacts (7-day retention).

Qwen Code · sandboxed verification

@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. ✅

@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.

Partially reviewed — gaps disclosed. Suggestions are inline.

Not reviewed: build-and-test — Integration Tests (CLI, No Sandbox) was skipped in CI and its suite did not run locally.

Deferred under the convergence posture (round 5, not a blocker) — recorded, not requested in this round:

  • packages/cli/src/ui/hooks/useGeminiStream.ts:5347 — [probe] composite steer+teammate carrier never tested with both queues drained
中文说明

仅完成部分审查,审查缺口已披露。 建议见行内评论。

未审查:build-and-test — Integration Tests (CLI, No Sandbox) was skipped in CI and its suite did not run locally。

收敛姿态下延后(第 5 轮,非阻断)——已记录,本轮不要求修改:共 1 条(原文未翻译,列表见上方英文部分)。

— qwen3.8-max via Qwen Code /review (v0.21.15)

Comment thread packages/cli/src/ui/hooks/useGeminiStream.test.tsx Outdated
Comment thread packages/core/src/core/client.ts
Comment thread packages/cli/src/ui/hooks/useGeminiStream.ts Outdated
@yiliang114
yiliang114 enabled auto-merge August 22, 2026 01:41

@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.

Partially reviewed — gaps disclosed.

Not reviewed: build-and-test — Integration Tests (CLI, No Sandbox) was skipped in CI and its suite did not run locally.

Deferred under the convergence posture (round 6, not a blocker) — recorded, not requested in this round:

  • packages/cli/src/ui/hooks/useGeminiStream.test.tsx:1960 — [review] R5-1 still stands (round 5, code unchanged since): Ctrl+Y test rebuilds the renderBusyMultiRoundTask harness inline; the two settlement shims have drifted (shared shim accep…
  • packages/core/src/core/client.ts:2761 — [review] R5-2 still stands (round 5, code unchanged since): hook-failure catch settles the carrier unconditionally, but the sibling goal-admission catch (~2821) still rethrows without settling (covere…
  • packages/cli/src/ui/hooks/useGeminiStream.ts:5330 — [review] R5-3 still stands (round 5, code unchanged since): the trailing-match strip guard is load-bearing but pinned by no test — an unconditional strip leaves all tests passing
  • packages/cli/src/ui/hooks/useGeminiStream.test.tsx:394 — [review] Scheduler mock updated to the production 3-tuple here, but four sibling mocks in the same file were left on the stale 4-tuple (mockCancelAllToolCalls in the markToolsAsSubmit…
  • packages/cli/src/ui/hooks/useGeminiStream.ts:4031 — [probe] userPromptBlocked delivery-settlement condition is not effectively pinned — removing it leaves 240/240 tests green (test shim settles the carrier before the decision runs)
  • packages/cli/src/ui/hooks/useGeminiStream.ts:5351 — [probe] Composite steer+teammate carrier never tested with both queues drained — an either/or accept mutant survives 240/240 (re-report of the round-5 deferred probe)
  • packages/cli/src/ui/hooks/useGeminiStream.ts:5388 — [probe] Boundary onAdmissionFailed restore is untested — deleting it survives all 240 tests (silent message loss if regressed)
中文说明

仅完成部分审查,审查缺口已披露。

未审查:build-and-test — Integration Tests (CLI, No Sandbox) was skipped in CI and its suite did not run locally。

收敛姿态下延后(第 6 轮,非阻断)——已记录,本轮不要求修改:共 7 条(原文未翻译,列表见上方英文部分)。

— qwen3.8-max via Qwen Code /review (v0.21.15)

Comment thread packages/core/src/core/client.ts Outdated
GeminiChat now publishes the user-content push counter on the request
array immediately before pushing it into history, and GeminiClient
settles the attached steer/teammate carrier against that push-site
snapshot instead of a client-side one: a snapshot taken before turn.run
still covers the send-lock and tryCompress awaits ahead of the push,
where a concurrently admitted send (/btw) can push and supply the
counter growth that reads as acceptance for a send that then exits
before its own push (silent teammate loss plus a false delivery
journal). A send that exits before the publish never pushed and
restores unconditionally.

Also settle the attached carrier on the Goal turn admission failure
path, which rethrows before the settlement try/finally and would
otherwise leak the carrier (drained messages neither delivered nor
requeued) for future attachers without their own onDeliveryFailed
fallback.
…ntract

The Ctrl+Y test rebuilt ~40 lines of the renderBusyMultiRoundTask harness
inline because the shared shim settled in a finally (a throwing stream
accepted) while the real GeminiClient restores on any pre-push exit. Fold
the inline harness back into the shared one and align the single shim with
the real contract: blocked sends and pre-push throws restore, while a push
that landed (first event observed / completed stream) accepts — including
mid-stream failures and consumer abandonment after the first event.

@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.

Partially reviewed — gaps disclosed.

2 Suggestion-level finding(s) this review confirmed are already reported on this PR and are not repeated:

  • userPromptBlocked delivery-settlement condition unpinned by tests (packages/cli/src/ui/hooks/useGeminiStream.ts:4058) — already reported and deferred in the round-6/7/9 review bodies (review 4998826762)
  • onAdmissionFailed carrier restore untested (packages/cli/src/ui/hooks/useGeminiStream.ts:5616) — already reported and deferred in the round-6/9 review bodies (review 4998826762)

Not reviewed: build-and-test — Integration Tests (CLI, No Sandbox) was skipped in CI and its suite did not run locally.

Not reviewed: reverse audit — did not converge within the reverse-audit round cap of 5.

Deferred under the convergence posture (round 12, not a blocker) — recorded, not requested in this round:

  • packages/cli/src/ui/hooks/useGeminiStream.test.tsx:1966 — [review] no test pins the production-normal full-fingerprint re-attach path (positive tests exercise only the fallback fingerprint)
  • packages/cli/src/ui/hooks/useGeminiStream.test.tsx:1639 — [probe] settlement shim accepts cancel-before-push streams the real client restores

Convergence: round 12 posted 4 inline comment(s), 4 of them reported for the first time; the previous round posted 2 (2 new). Findings keep coming back to the same files: packages/cli/src/ui/hooks/useGeminiStream.ts (findings in round 11; 4 more now). The rate of new findings is not falling. A cluster that keeps producing siblings usually means the fixes are treating instances of a shared root cause — triaging that cause before the next round, or splitting an independent cluster into its own pull request, tends to end the loop faster than fixing them one at a time. Batching the remaining fixes and verifying them before the next push keeps the loop from re-deriving the same set; this PR's reviews already resolve to a critical posting floor. (Observation only — nothing was withheld from this review because of this observation.)

中文说明

仅完成部分审查,审查缺口已披露。

本轮确认的 2 条建议级发现已在 PR 上报告过,不再重复发布(列表见上方英文部分)。

未审查:build-and-test — Integration Tests (CLI, No Sandbox) was skipped in CI and its suite did not run locally。

未审查:reverse audit — did not converge within the reverse-audit round cap of 5。

收敛姿态下延后(第 12 轮,非阻断)——已记录,本轮不要求修改:共 2 条(原文未翻译,列表见上方英文部分)。

收敛情况:第 12 轮发布了 4 条行内评论,其中 4 条是首次提出;上一轮发布了 2 条(其中 2 条首次提出)。发现反复回到同一批文件:packages/cli/src/ui/hooks/useGeminiStream.ts(第 11 轮已出过发现,本轮又有 4 条)。新发现的产出速度没有下降。一个不断再生兄弟发现的簇,通常意味着逐条修复只在处理同一根因的实例——先定位并处理该根因,或把独立的簇拆成单独的 PR,通常比逐条修复更快结束循环。把剩余修复攒成一批、验证后再推送,可以避免循环反复推导同一组发现;本 PR 的评审已解析为 critical 发布下限。(仅为观察——本轮评审未因此扣留任何内容。)

— qwen3.8-max via Qwen Code /review (v0.22.0)

Comment thread packages/cli/src/ui/hooks/use-llm-stream.ts
Comment thread packages/cli/src/ui/hooks/useGeminiStream.ts Outdated
Comment thread packages/cli/src/ui/hooks/use-llm-stream.ts
Comment thread packages/cli/src/ui/hooks/useGeminiStream.ts Outdated
yiliang114 and others added 2 commits August 25, 2026 14:13
…es, and team swaps

Four Criticals from the round-14 review of the boundary envelope retry
debt mechanism:

1. TeamManager swap leaked in-flight boundary batches: the swap handler
   cleared only the queue, while a batch already drained into a
   tool-round submission survived in the settlement closure and its
   restore requeued it into the NEW team's session. A queue generation
   counter now makes the restore drop the batch and the settlement skip
   journal/debt once a swap moved the generation.

2. Retry debt was one-shot: reattach consumed the debt and nothing
   recorded debt for the retry's own re-pushed entry, so an envelope
   surviving one retry could be permanently popped by a later retry of a
   different payload while the journal claimed delivered. The consumed
   records now transfer into a settlement carrier on the retry's own
   submission: accept records debt for the retry's pushed entry, restore
   re-records the original records (core re-adds popped entries as-is
   when the push never landed).

3. Debt was consumed during argument evaluation before submitQuery's
   admission gate ran, so a lease-rejected Ctrl+Y permanently discarded
   it. retryLastPrompt now bails on isSubmittingQueryRef before
   evaluating the debt (for Retry the gate rejects exactly when the
   lease is held, and the path to the gate is synchronous).

4. Debt was recorded only when the accept-time strip matched
   lastPromptRef, but a concurrent submission admitted during the
   time-to-first-token window overwrites it and the orphan pop drops the
   accepted entry regardless. Debt is now recorded unconditionally on
   accept; the retry-time orphan check still keeps double delivery
   impossible.

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
…p guards

Regression pins for the four round-14 Criticals:

- a boundary batch restored after a TeamManager swap is dropped, never
  resubmitted into the new team's session
- an accepted-after-swap batch is neither journaled nor recorded as
  retry debt against the new team
- an envelope re-attached by one retry stays protected when that retry's
  own entry is orphaned by a later different payload (debt transfers
  through the retry's settlement carrier)
- a lease-rejected Ctrl+Y does not discard the debt (no history scan, no
  submission, debt still usable afterwards)
- a concurrent /btw overwriting lastPromptRef before the accept
  settlement no longer suppresses debt recording

Adds a non-awaiting startToolRound helper to the multi-round harness so
tests can hold the boundary submission in flight.

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
@yiliang114
yiliang114 requested a review from qqqys as a code owner August 25, 2026 06:18
@yiliang114

Copy link
Copy Markdown
Collaborator Author

Closeout — all 4 round-14 Criticals verified real at 001f8dbf4 and fixed (single non-force push 001f8dbf4..c6aee9558, fixes in d2a610ef5 + test pins in c6aee9558):

  1. Swap-surviving drained batch (:703) — queue generation counter: a TeamManager swap bumps it; drain's restore drops batches from a moved generation, and settleDrainedTeammates skips journal/debt for them, so an in-flight batch can't resurface into the new team's session. Documented tradeoff in-thread: an accepted-after-swap batch is dropped from journal/debt even if its push technically landed on the outgoing session (chosen over attributing old-team messages to the new team).
  2. One-shot debt (:4273) — consumed debt transfers into a steerInput settlement carrier on the retry's own submission (core settles it at push time for Retry): accept records debt for the retry's pushed entry; restore strips + re-records originals.
  3. Debt consumed before the admission gate (:4423)retryLastPrompt pre-checks isSubmittingQueryRef before evaluating debt — for Retry that's exactly the gate condition, synchronous to it — so a lease-rejected Ctrl+Y keeps the debt.
  4. Debt gated on strip match (:5524) — the accept branch records debt unconditionally; the retry-time orphan + fingerprint check still prevents double delivery.

Verification: useGeminiStream.test.tsx 251 passing (246 baseline + 5 new pins, incl. a startToolRound harness helper), packages/cli typecheck clean; every fix mutation-checked (each revert fails its pin). Threads: 4/4 replied with fix SHAs + resolved. Push auto-triggered CI + the review lane.

@yiliang114

Copy link
Copy Markdown
Collaborator Author

@qwen-code /triage

@qwen-code-ci-bot

qwen-code-ci-bot commented Aug 25, 2026

Copy link
Copy Markdown
Collaborator

Sandboxed verification: ✅ passed — merge-ready (agent verdict) - workflow run

Ran the PR in an isolated, token-free container: A/B against the base build, mock-free harness assertions, targeted gates. Advisory evidence for human reviewers — not a review, an approval, or a CI check.

Scripted assertions: 2592 passed · 0 failed · 2592 total

Flakiness gate: ✅ 2 changed test file(s) x 5 identical rounds, no divergence

中文 — 判定:✅ 通过 · 可合入(agent 判定)

沙箱验证在隔离、无凭证的容器中执行了该 PR 的代码(与 base 构建 A/B 对照、无 mock harness 断言、定向门禁)。仅作为评审证据,不构成评审、批准或 CI 检查

脚本断言:2592 通过 · 0 失败 · 2592 总计

抖动门:✅ 2 changed test file(s) x 5 identical rounds, no divergence

Verification report

Verdict: merge-ready — 2592/2592 scripted assertions passed, 0 unexpected failures, no new blocking findings. Verified head: c6aee9558564761598471d87f2df2095d038065a (HEAD^2; base tip db78bdecad = HEAD^1). Follow-up round after the merge-ready report at head 001f8dbf; delta = commits 17–18 (d2a610ef5f production hardening of the retry-debt mechanism, c6aee95585 regression pins for it).

中文摘要
  • 结论merge-ready。2592 项脚本化断言全部通过,0 项意外失败,无新阻塞性发现。
  • A/B 结论(在新 head 重跑):base(HEAD^1=db78bdecad,浅 worktree + head 测试文件 + 惰性 Symbol shim)上 cli 整文件 13 红 / 238 绿(251)——13 个红全部是 Agent Team: teammate messages queue for the entire duration of a long multi-tool-call turn, not just the next response #8172 测试(9 个旧红 + c18 五个新钉住测试中的 4 个;另一项"swap 后 accept 不记账"在 base 上平凡绿——无 drain 即无可记账),core 结算套件 5 红 / 367 绿(372);head 上 cli 251/251、core 372/372 全绿——中心变更仍为承重件。见 01-ab-…/04-raw-red-lists-…
  • 增量验证(提交 17–18):head−c17(仅反演生产 hunk、保留全部测试)恰好 5 红——全部是 c18 的新钉住测试、且全部为行为级断言不符;c18 的测试文件变更用跨测试文件变异 A/B 验证——对未改动生产代码做单点变异(重新引入四个 Critical 各一个变异体 R1–R5),在旧测试文件(001f8dbf)全部存活、在新测试文件各被恰好一条对应钉住测试杀死(C1 排空变异两臂均被杀死作为阳性对照,M3/M11 携带变异两臂均存活),无 killed→survived 回退。见 02-mutation-ab-…
  • 上轮发现状态:三条低严重度发现重新测量后维持(M3、M11 两臂 15/20 全存活——冗余防御;发布 hunk 在 client.test.ts 372 条 + geminiChat.test.ts 370 条原生测试下均无钉住——覆盖缺口,mock-free 探针双向杀死)。信息项 4(指纹退化窗口)维持且现有两处调用点;信息项 5(重试债一次性消费)已被 c17 的 Critical 2/3 修复,状态 superseded。
  • 新发现:无。对 c17 新机制做了兄弟面扫描(Idle 排空的 restore 侧受共享代号守卫覆盖、Idle 路径无记账/债簿记;准入预检与门之间无 await、Retry 绕过 prepareQueryForGemini、waitForReservationSettlement 永不 reject),未发现逃逸形状。
  • 未覆盖:提交 1–16 的逐提交归因沿用上轮(本轮以聚合 A/B + 全量变异矩阵在新 head 重测);live 多 agent e2e/TUI(PR 亦声明);steer 两条特殊轮次启动路径对 teammate 不覆盖(PR 声明 v1 范围);接受时刻扫描顶替窗口(发现 4)无法确定性搭出。

Previous-finding status (round at 001f8dbf → new head c6aee955)

# finding severity status at new head
1 userPromptBlocked dispatch flag is redundant defence for message safety (telemetry-only effect) low stands, re-measured: M3 survives both arms at the new head (old tests 15/15, new tests 20/20; logs/matrix-M3-*.txt). Load-bearing siblings still kill (C1: 9 red old arm, 13 red new arm). Classification unchanged: redundant defence, keep as-is.
2 cancelled-boundary drain guard is redundant for delivery correctness (display hygiene + wasted round trip) low stands, re-measured: M11 survives both arms (15/15 old, 20/20 new; logs/matrix-M11-*.txt). Classification unchanged.
3 the geminiChat.ts push-site publication hunk is not pinned by any test in the repo low stands, re-measured and widened: M12a survives the full client.test.ts (372/372) AND all 370 native tests of geminiChat.test.ts (the suite's sole red under M12a is the probe itself). The mock-free probe kills it (expected undefined to be +0, logs/probe-m12a.txt), probe green at head (2/2, logs/probe-head.txt). Delta commits added no geminiChat.test.ts coverage, so the gap persists. Recommendation unchanged: port the two VERIFY-PROBE cases into geminiChat.test.ts. Not a merge condition.
4 informational: degraded fingerprint window at accept time stands, widened: capturePushedTeammateEntry (the backwards scan for the youngest entry carrying every envelope text) is now called from TWO accept sites — the boundary settlement and the new retry carrier's accept — so the documented displacement window (a concurrent byte-identical push between push and settlement degrades the fingerprint to envelope-text containment) applies to both. Code comment names the tradeoff; no exploit demonstrated.
5 informational: retry-debt consumption is one-shot (cleared on every evaluation incl. unreadable history) superseded — fixed by c17 (Criticals 2+3): consumption now runs only after the admission pre-check passes, the history-unreadable path leaves the debt untouched for a later retry (asserted in reattachOrphanedRetryEnvelopes's catch), and consumed records transfer into the retry's settlement carrier (accept re-records debt for the re-pushed entry; restore re-records the originals after stripping them out of lastPromptRef). Pin: keeps an envelope protected when the retry that re-attached it is itself orphaned… kills R3 (the one-shot shape re-introduced).
corr. PR body's "Full file: 234/234 pass" superseded again: the file at this head holds 251 tests, 251/251 green. Description predates the later commits; not a code issue.

Declined/deferred rows were re-measured, not diffed: M3, M11, and M12 were re-run as fresh mutations at c6aee955 (the delta touches none of those guards — it is cli retry-debt machinery only), and finding 5's mechanism was re-read in the new code rather than carried by description.

Central claim + A/B (re-run at the new head)

Central claim: teammate→leader messages queued during a multi-round tool task are delivered at the next tool-round boundary — appended to the SendMessageType.ToolResult submission after the tool-response parts — with no loss and no double delivery across cancelled/preempted boundaries, admission/delivery failures, hook blocks, and Ctrl+Y retries; settlement is decided by the push-site snapshot GeminiChat publishes; accepted-but-terminally-failed rounds survive the Ctrl+Y path via journaled retry debt; and (delta) that debt is swap-safe in flight, transfers through the retry's own re-pushed entry, survives lease-rejected retries, and is recorded even when a concurrent submission overwrote the stored payload.

Cells: base = scratch worktree at HEAD^1 (db78bdecad, removed after capture) with the PR test files copied in (core test file's userContentPushSnapshotKey import shimmed to an inert local Symbol — 0 refs in base source and base dist asserted). Base reused the root node_modules (PR leaves package.json/package-lock.json untouched — diff empty). Internal-link hygiene: the base tree's node_modules/@qwen-code/* links were rebuilt to point INTO the base tree (readlink -f node_modules/@qwen-code/qwen-code-coretmp/base-tree/packages/core), the nested packages/{cli,core}/node_modules symlinked from head contain no @qwen-code entries, dists of PR-untouched workspace packages (acp-bridge, web-templates, channels/*git diff HEAD^1..HEAD over them empty) were symlinked to satisfy the vitest build-prerequisite guard, base core dist was rebuilt from base source and content-asserted (0 userContentPushSnapshotKey refs in production dist; the only dist refs are the compiled shimmed test file itself), cli-side core resolution goes through the vitest source alias into the base tree (../core/index.ts).

suite base (no PR) head (PR)
cli useGeminiStream.test.tsx 13 failed | 238 passed (251) — the 9 pre-existing #8172 reds plus 4 of the 5 new c18 pins (04-raw-red-lists-…) 251/251
core client.test.ts (settlement races) 5 failed | 367 passed (372) — same 5 race reds as prior rounds 372/372

The one new pin that is trivially green on base — does not journal or record retry debt for a boundary batch accepted after a TeamManager swap — holds there because base never drains (nothing to journal, retry payload never carries the envelope); it is load-bearing at head, where it goes red under R2 and under head−c17. All base failures are expected-vs-actual assertion mismatches, zero load/collection errors. Witness: 01-ab-cli-core-base-reds-vs-head-green.png, 04-raw-red-lists-base-and-delta.png; raw logs logs/base-cli-suite.txt, logs/base-core-suite.txt, logs/head-cli-suite.txt, logs/head-core-suite.txt.

Delta validation since the previous round (commits 17–18)

Commit objects 17–18 exist locally though the shallow walk reports one reachable commit; their diffs were computed directly (d17.diff, d18.diff in the artifact). c17 touches only useGeminiStream.ts (+249/−89); c18 is test-only (+566, five pins and the non-awaiting startToolRound helper).

c17 is load-bearing — reverse-apply its production hunks (tests stay intact) and exactly the five c18 pins go red, each failing the behavioral assertion it exists for, the other 15 #8172 tests staying green:

build #8172 selection red tests
base (no PR) 13 failed | 238 passed the 13 rows above
head − c17 5 failed | 15 passed swap-restore drop (spy called 2 times, expected 1), accepted-after-swap (recordNotification called once, expected never), retry-transfer ('new question' missing the envelope part), lease-held (historyScan called once, expected never), unconditional-debt ('/btw status check' missing the envelope part)
head (all commits) 0 failed | 20 passed

Witness: 01-ab-… (delta row), logs/delta-minus-c17.txt.

c18's pins are load-bearing — mutation A/B across the test files: single-point mutants of the UNMODIFIED head production file, run against the old test file (001f8dbf) and the new one (c6aee955), nothing else changed. Each Rn re-introduces exactly one of the four round-14 Criticals:

mutant reverts old tests (15) new tests (20) killer on the new arm
CONTROL (unmutated) green green
R1 Critical 1 restore-side generation guard SURVIVED KILLED (1) drops a boundary-drained teammate batch restored after a TeamManager swap…
R2 Critical 1 accept-side swapped skip SURVIVED KILLED (1) does not journal or record retry debt for a boundary batch accepted after a TeamManager swap
R3 Critical 2 retry settlement carrier SURVIVED KILLED (1) keeps an envelope protected when the retry that re-attached it is itself orphaned…
R4 Critical 3 lease pre-check in retryLastPrompt SURVIVED KILLED (1) does not discard retry debt when Ctrl+Y is pressed while the submission lease is held
R5 Critical 4 unconditional debt on accept (re-gated on strip match) SURVIVED KILLED (1) records retry debt even when a concurrent submission overwrote the stored payload…
C1 (positive control) the central boundary drain KILLED (9) KILLED (13) both arms — harness live on both
M3 (carried finding 1) drop userPromptBlocked SURVIVED SURVIVED — (redundant defence)
M11 (carried finding 2) drop the cancelled-boundary guard SURVIVED SURVIVED — (redundant defence)

No mutant regressed killed→survived across the test-file change. Every Rn kill is attributed to exactly one test — the corresponding c18 pin (matrix-results.json carries the per-cell failing names). Witness: 02-mutation-ab-old-vs-new-test-file.png; raw logs logs/matrix-*.txt; rerunnable as node mutation-matrix.mjs (occurrences asserted per edit, git status clean after every cell).

Admission-window claim verified (c17's Critical-3 comment): between retryLastPrompt's isSubmittingQueryRef pre-check and submitQuery's gate there is no await (reattachOrphanedRetryEnvelopes and clearRetryCountdown are synchronous); for SendMessageType.Retry the gate rejects exactly when the lease is held (Retry is never a turn continuation nor /btw), the second gate shares the same render snapshot as retryLastPrompt's own state check, Retry bypasses prepareQueryForGemini ({ queryToSend: query, shouldProceed: true } literal), there is no other early return between the gates and the client call, and waitForReservationSettlement is .catch()-wrapped at its source so it cannot reject. Consumption therefore always ends in a carrier settlement — accept (debt re-recorded for the re-pushed entry) or restore (originals re-recorded, envelopes stripped back out of lastPromptRef).

Sibling sweep on the swap guard: the Idle-drain path shares drainTeammateQueue, so its restore is covered by the same generation guard; it performs no journal/debt bookkeeping on acceptance (the Teammate submission IS the delivery), so there is no new-team leak to skip there. A swap-then-swap-back still drops (generation +2 ≠ captured), consistent with the queue having been cleared twice. No escaping shape found.

Corrections

  • Carried and still true: the PR body's "234/234" describes the test file at the first commit; it now holds 251 tests, all passing. Not a code issue.
  • The Reviewer Test Plan's run command (npx vitest run packages/cli/src/ui/hooks/useGeminiStream.test.tsx from the repo root) WORKS despite the repo's general "don't run vitest from the root" guidance — the root vitest.config.ts collects the file and all 251 pass (logs/root-run-plan-command.txt). No correction needed; recorded so the next verifier does not assume the command is broken.

Findings (non-blocking)

  1. userPromptBlocked dispatch flag remains a redundant defence (low, carried, re-measured at c6aee955). M3 survives both arms (15/15 old, 20/20 new); its independent effect is telemetry only — settlement safety is held by the client-side unconditional restores. Keep as-is.
  2. Cancelled-boundary drain guard remains redundant for delivery correctness (low, carried, re-measured). M11 survives both arms; the guard's role is display hygiene (no premature ● …) and avoiding a drain/restore round trip. Keep as-is.
  3. The geminiChat.ts push-site publication hunk remains unpinned by any repo test (low, carried, re-measured and widened). M12a survives the full client.test.ts (372/372) and all 370 native tests of geminiChat.test.ts; only the external mock-free probe kills it, and the probe is green at head (2/2) with the string-send validity control staying green under the mutant. Behavior verified correct by probe + base-cell reds, so this is a test to add, not code to change — port the two VERIFY-PROBE cases (array publication value + string no-carrier) into geminiChat.test.ts. Not a merge condition.
  4. Informational, carried and widened: degraded fingerprint window at accept time. capturePushedTeammateEntry's backwards scan can be displaced only by a concurrent push carrying byte-identical envelope texts; c17 added a second call site (the retry carrier's accept), so the documented window now covers both the boundary acceptance and the retry re-push acceptance. No exploit demonstrated; the window needs a byte-identical concurrent push inside a sub-event span, which the component harness cannot stage deterministically.
  5. Informational, resolved: the one-shot retry debt (prior finding 5) is fixed by c17. See the status table row — consumption is admission-gated, unreadable history preserves the debt, and consumed records transfer through the retry's settlement carrier. R3 (the old one-shot shape re-introduced) is killed by exactly the transfer pin.

Targeted gates

  • packages/cli useGeminiStream.test.tsx at head: 251 passed (251) (logs/head-cli-suite.txt); also green from the repo root per the PR's own command (logs/root-run-plan-command.txt).
  • packages/core client.test.ts at head: 372 passed (372) (logs/head-core-suite.txt).
  • npm run typecheck equivalent (tsc --noEmit) in packages/cli and packages/core: exit 0 both (logs/typecheck-cli.txt, logs/typecheck-core.txt).
  • Flakiness gate: 2 changed test files × 5 identical rounds, PPPPP both, verdict pass (logs/flake-gate.txt, per-round logs logs/flake-r*). Witness for the M12 probe cells and all gates: 03-m12-probe-and-gates-flake.png.

Not covered

  • Per-commit attribution for commits 1–16 as standalone builds: the shallow walk reports one reachable commit; commit objects 17–18 (and their trees) exist locally, which the delta controls above exploit; commits 1–16 were individually exercised in the prior two rounds and their aggregate behavior is re-measured here by the A/B, the delta revert, and the full mutation matrix at the new head. The merge commits carry no PR content.
  • Live multi-agent e2e / TUI evidence (the PR states the same; the cli harness drives the real handleCompletedTools/submitQuery/retryLastPrompt paths with a mocked model and a settlement shim mirroring the client contract, whose acceptance semantics are pinned in core's client.test.ts and by the base-cell reds). This round's harness replays the bug's wire shapes, not a live team's timing.
  • Steer's two exotic round-starting paths (duplicate-tool-response bypass, client.ts no-tool-call continuations) for teammate messages — PR-declared v1 scope; they fall back to the Idle drain (today's behavior), so no regression.
  • dualOutput.emitUserMessage sidecar for boundary deliveries — PR-declared, identical to steer at the same site; chat recording covered by recordNotification (re-asserted by the R2/swap-accept cell at this head).
  • The accept-time scan displacement window (finding 4) beyond its named bounds — demonstrating it would require a concurrent byte-identical push inside a sub-event window, which the component harness cannot stage deterministically.
  • Repo-wide lint/format gates (the PR's CI covers them); only affected-workspace tests and typecheck were run here.

Methodology

Assertion counting: every test execution with an encoded expectation counts one assertion — expected base/delta/mutant reds count as PASSED control expectations (fail counts unexpected outcomes only). Primary cells (head/base suites, delta, probe, M12 suites, root-run) and the mutation matrix are counted at test level (matrix cells run distinct mutants, so each execution is a distinct assertion context); the flakiness gate is counted at round level (10 rounds — the same assertions repeated to measure stability); typecheck counts 2. Sum: 2265 primary + 315 matrix + 10 flake rounds + 2 typecheck = 2592.

Environment: CI node:22-bookworm container, merge-ref checkout (HEAD 2a3d13d135 merge, HEAD^1 base tip db78bdecad, HEAD^2 verified head c6aee95585), npm ci + build pre-run. A/B base cell: scratch worktree at HEAD^1 (removed after capture) with root node_modules reused (lockfile untouched — git diff HEAD^1..HEAD over all package manifests empty); the base tree's node_modules/@qwen-code/* links rebuilt to resolve INTO the base tree (realpath-asserted: qwen-code-coretmp/base-tree/packages/core), head's nested packages/{cli,core}/node_modules symlinked for external deps (verified free of @qwen-code entries), dists of PR-untouched workspace packages symlinked past the vitest build-prerequisite guard, base core dist compiled from base source (tsc --build via the repo's own build script) and content-asserted, PR test files copied in with the documented inert-symbol shim for the core file. Delta control: git apply -R of the c17 production diff (tests intact), run, restored. Test-file mutation A/B: mutation-matrix.mjs (occurrence asserted per edit, files restored via git checkout, git status clean after every cell), selections -t "#8172" against the old (001f8dbf) and new test files. Probe: two temporary VERIFY-PROBE tests patched into geminiChat.test.ts (probe-patch.mjs), green at head, publication-red under M12a, restored. Flake gate: flake-gate.sh, 5 rounds × 2 files. Raw logs in logs/; harnesses (mutation-matrix.mjs, mutants-cli.mjs, probe-patch.mjs, print-*.mjs, flake-gate.sh, d17.diff, d18.diff) and matrix-results.json in the artifact dir; captures in evidence/.

Flakiness gate log

rounds=5 files=2 skipped=0
file packages/cli/src/ui/hooks/useGeminiStream.test.tsx: (cd packages/cli) npx --no-install vitest run ./src/ui/hooks/useGeminiStream.test.tsx
file packages/core/src/core/client.test.ts: (cd packages/core) npx --no-install vitest run ./src/core/client.test.ts


per-file results (P=pass F=fail I=infra-exit, one letter per run):
  packages/cli/src/ui/hooks/useGeminiStream.test.tsx: PPPPP
  packages/core/src/core/client.test.ts: PPPPP

verdict: pass
summary: 2 changed test file(s) x 5 identical rounds, no divergence

--- per-invocation detail (full copy in the artifact) ---
round 1 · packages/cli/src/ui/hooks/useGeminiStream.test.tsx: P (exit 0)
round 1 · packages/core/src/core/client.test.ts: P (exit 0)
round 2 · packages/cli/src/ui/hooks/useGeminiStream.test.tsx: P (exit 0)
round 2 · packages/core/src/core/client.test.ts: P (exit 0)
round 3 · packages/cli/src/ui/hooks/useGeminiStream.test.tsx: P (exit 0)
round 3 · packages/core/src/core/client.test.ts: P (exit 0)
round 4 · packages/cli/src/ui/hooks/useGeminiStream.test.tsx: P (exit 0)
round 4 · packages/core/src/core/client.test.ts: P (exit 0)
round 5 · packages/cli/src/ui/hooks/useGeminiStream.test.tsx: P (exit 0)
round 5 · packages/core/src/core/client.test.ts: P (exit 0)

Evidence images

01-ab-cli-core-base-reds-vs-head-green

02-mutation-ab-old-vs-new-test-file

03-m12-probe-and-gates-flake

04-raw-red-lists-base-and-delta

Harness scripts and raw logs are in the workflow run artifacts (7-day retention).

Qwen Code · sandboxed verification

@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. ✅

@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.

Partially reviewed — gaps disclosed.

1 Suggestion-level finding(s) this review confirmed are already reported on this PR and are not repeated:

  • retry debt accumulates unboundedly in sessions that never retry (packages/cli/src/ui/hooks/useGeminiStream.ts:5710-5713) — already reported and deferred in the round-11 review body (review 5013385570, reported at line 5462; code moved by la…

Not reviewed: build-and-test — Integration Tests (CLI, No Sandbox) was skipped in CI and its suite did not run locally.

Not reviewed: reverse audit — did not converge within the reverse-audit round cap of 5.

Deferred under the convergence posture (round 13, not a blocker) — recorded, not requested in this round:

  • packages/core/src/core/geminiChat.ts:2928 — [review] push-snapshot publication (producer half of the settlement contract) has no test
  • packages/cli/src/ui/hooks/useGeminiStream.ts:4086 — [review] userPromptBlocked → onDeliveryFailed wiring is not falsifiable by any test
  • packages/cli/src/ui/hooks/useGeminiStream.ts:4586 — [probe] retry carrier's restore branch (strip-then-re-record) has no paired test
  • packages/cli/src/ui/hooks/useGeminiStream.ts:5727 — [probe] mixed steer + teammate boundary drain is unreachable by any test
  • packages/cli/src/ui/hooks/useGeminiStream.test.tsx:2544 — [review] createExecutingToolCall('call-r1') passes an argument to a zero-parameter factory (TS2554, masked by tsconfig exclude)
  • packages/core/src/core/client.ts:4308 — [review] pushInitiated=false settlement arm untested; its comment misnames the triggers
  • packages/core/src/core/client.test.ts:13180 — [review] Goal-admission carrier test cannot exercise the R13-2 defect (Goal sends pop nothing and trip a different branch)
  • packages/core/src/core/client.ts:2601 — [review] the snapshot's two-hop pass-by-reference chain is pinned by no test
  • packages/core/src/core/client.ts:2885 — [review] catch-site settlement comment names the wrong idempotence mechanism

Convergence: round 13 posted 2 inline comment(s), 2 of them reported for the first time; the previous round posted 4 (4 new). Findings keep coming back to the same files: packages/cli/src/ui/hooks/useGeminiStream.ts (findings in round 12; 1 more now). A cluster that keeps producing siblings usually means the fixes are treating instances of a shared root cause — triaging that cause before the next round, or splitting an independent cluster into its own pull request, tends to end the loop faster than fixing them one at a time. (Observation only — nothing was withheld from this review because of this observation.)

中文说明

仅完成部分审查,审查缺口已披露。

本轮确认的 1 条建议级发现已在 PR 上报告过,不再重复发布(列表见上方英文部分)。

未审查:build-and-test — Integration Tests (CLI, No Sandbox) was skipped in CI and its suite did not run locally。

未审查:反向审计——在 5 轮的反审轮数上限内未收敛。

收敛姿态下延后(第 13 轮,非阻断)——已记录,本轮不要求修改:共 9 条(原文未翻译,列表见上方英文部分)。

收敛情况:第 13 轮发布了 2 条行内评论,其中 2 条是首次提出;上一轮发布了 4 条(其中 4 条首次提出)。发现反复回到同一批文件:packages/cli/src/ui/hooks/useGeminiStream.ts(第 12 轮已出过发现,本轮又有 1 条)。一个不断再生兄弟发现的簇,通常意味着逐条修复只在处理同一根因的实例——先定位并处理该根因,或把独立的簇拆成单独的 PR,通常比逐条修复更快结束循环。(仅为观察——本轮评审未因此扣留任何内容。)

— qwen3.8-max via Qwen Code /review (v0.22.0)

Comment thread packages/cli/src/ui/hooks/use-llm-stream.ts
Comment thread packages/core/src/core/client.ts
yiliang114 and others added 2 commits August 25, 2026 19:01
…he carrier accept

The retry carrier's accept re-recorded debt but never stripped the
re-attached envelopes back out of lastPromptRef, so each
accept-fail-before-content-Ctrl+Y cycle re-attached the envelopes onto a
base that still carried them, appending one duplicate copy per cycle.
Mirror the boundary settlement and the carrier's own restore: strip the
consumed envelope texts before re-recording debt.

Regression test pinned and mutation-checked: reverting the strip makes
the second Ctrl+Y submit [toolResponses, envelope, envelope].

Co-authored-by: Qwen-Coder <qwen-coder@alibaba-inc.com>
…e carrier

The Goal-admission catch settles the attached carrier by restore after
the Retry orphan pop has run but before the only
restoreStrippedRetryEntries call site (inside the settlement
try/finally below), so the popped entries were permanently dropped from
history while the carrier re-recorded debt against entries that no
longer exist. Call restoreStrippedRetryEntries before settling in that
catch, and symmetrically in the hook-failure catch (a no-op today, since
hooks never fire for Retry, the only type that populates the entries).

Regression test pinned and mutation-checked: without the re-add the
Goal-admission rejection drops the orphaned entry from history.

Co-authored-by: Qwen-Coder <qwen-coder@alibaba-inc.com>
@qwen-code-ci-bot

Copy link
Copy Markdown
Collaborator

Qwen Code review did not complete successfully. The review pipeline failed before a review could be posted. A transient error is retried automatically; if you are seeing this, retry with @qwen-code /review. See workflow logs.

@yiliang114

Copy link
Copy Markdown
Collaborator Author

@qwen-code /triage

@qwen-code-ci-bot

qwen-code-ci-bot commented Aug 25, 2026

Copy link
Copy Markdown
Collaborator

Sandboxed verification: ✅ passed — merge-ready (agent verdict) - workflow run

Ran the PR in an isolated, token-free container: A/B against the base build, mock-free harness assertions, targeted gates. Advisory evidence for human reviewers — not a review, an approval, or a CI check.

Scripted assertions: 5800 passed · 0 failed · 5800 total

Flakiness gate: ✅ 2 changed test file(s) x 5 identical rounds, no divergence

中文 — 判定:✅ 通过 · 可合入(agent 判定)

沙箱验证在隔离、无凭证的容器中执行了该 PR 的代码(与 base 构建 A/B 对照、无 mock harness 断言、定向门禁)。仅作为评审证据,不构成评审、批准或 CI 检查

脚本断言:5800 通过 · 0 失败 · 5800 总计

抖动门:✅ 2 changed test file(s) x 5 identical rounds, no divergence

Verification report

Verdict: merge-ready — 5800/5800 scripted assertions passed, 0 unexpected failures, no new blocking findings. Verified head: 6e3cf5be1ff413f7190398095ff0ff0dfff79fba (HEAD^2; base tip 42b4c09ceb = HEAD^1). Follow-up round after the merge-ready report at head c6aee955; delta = commits 19–20 (fix(cli): strip accepted retry envelopes from the stored payload…, fix(core): re-add popped retry entries when pre-try catches settle the carrier). Commit 19's object is absent from the depth-2 checkout; its contribution is package-disjoint from commit 20 (cli-only vs core-only, matching their commit scopes), so the two were separated by reverting each package's production hunks independently.

中文 — 判定:✅ 通过 · 可合入(agent 判定)
  • 结论merge-ready。5800 项脚本化断言全部通过,0 项意外失败,无新阻塞性发现。
  • A/B 结论(在新 head 重跑):base(HEAD^1=42b4c09ceb 浅 worktree + head 测试文件 + 惰性 Symbol shim)上 cli 整文件 14 红 / 240 绿(254)——14 个红全部是 Agent Team: teammate messages queue for the entire duration of a long multi-tool-call turn, not just the next response #8172 测试(9 个旧红 + 上轮 c18 五个钉住测试中的 4 个 + 本轮新增的 Ctrl+Y×2 去重钉住测试;另一个"swap 后 accept 不记账"在 base 上平凡绿);core 结算套件 6 红 / 367 绿(373)——5 个旧结算竞态红 + 本轮新增的 Goal 准入重添钉住测试;head 上 cli 254/254、core 373/373 全绿。见 01-ab-base-reds-vs-head-green.png
  • 增量验证(提交 19–20,均为承重):head−c19(仅反演 cli 生产 hunk)恰好 1 红——新 Ctrl+Y×2 钉住测试以行为级不符失败(第二次重试的提交载荷 Array(3) vs 期望 Array(2),即多出一份信封副本);head−c20(仅反演 core 生产 hunk)恰好 1 红——新 Goal 准入钉住测试失败(addHistory 0 次调用,被弹出的孤儿条目未重添)。跨测试文件变异 A/B:D1/D2 两个增量变异体在旧测试文件(c6aee955)全部存活、在新测试文件各被恰好一条自己的新钉住测试杀死;R1–R5 各被同一条 c18 钉住测试杀死(与上轮一致),无 killed→survived 回退;阳性对照 C1 两臂 13/14 红。见 02-mutation-matrix-old-vs-new.png
  • 上轮发现状态:三条低严重度发现重新测量后维持(M3/M11 两臂全存活——冗余防御;发布 hunk 在 client.test.ts 373 条 + geminiChat.test.ts 377 条原生测试下均无钉住——覆盖缺口,mock-free 探针双向杀死)。信息项 4(指纹退化窗口)维持、仍是两处调用点;信息项 5 已被 c17 修复、维持 superseded。
  • 新发现:无。对增量机制做了兄弟面扫描(accept 侧 strip 的尾匹配守卫覆盖"结算前载荷被覆写";catch 中 restore 的计数器门在本会话内无并发推送者可达;hook-catch 重添经两臂变异证实为今日无操作的未来防御),未发现逃逸形状。
  • 未覆盖:提交 1–18 的逐提交归因沿用上轮(本轮以聚合 A/B + delta 反演 + 全量变异矩阵在新 head 重测);提交 19/20 无法单独按提交归因(19 的对象缺失,以包不相交反演代替);live 多 agent e2e/TUI(PR 亦声明);steer 两条特殊轮次启动路径对 teammate 不覆盖(PR 声明 v1 范围)。

Previous-finding status (round at c6aee955 → new head 6e3cf5be)

# finding severity status at new head
1 userPromptBlocked dispatch flag is redundant defence for message safety (telemetry-only effect) low stands, re-measured: M3 survives both arms at the new head (old tests 20/20, new tests 21/21; logs/matrix-run.txt, matrix-results.json). Load-bearing siblings still kill (C1: 13 red old arm, 14 red new arm). Classification unchanged: redundant defence, keep as-is.
2 cancelled-boundary drain guard is redundant for delivery correctness (display hygiene + wasted round trip) low stands, re-measured: M11 survives both arms (20/20 old, 21/21 new). Classification unchanged.
3 the geminiChat.ts push-site publication hunk is not pinned by any test in the repo low stands, re-measured: M12a survives the full client.test.ts (373/373) AND all 377 native tests of geminiChat.test.ts (378 passed + the probe = 379; the suite's sole red under M12a is the probe itself). The mock-free probe kills it (logs/probe-m12a.txt), probe green at head (2/2, logs/probe-head.txt). Delta commits added no geminiChat.test.ts coverage, so the gap persists. Recommendation unchanged: port the two VERIFY-PROBE cases into geminiChat.test.ts. Not a merge condition.
4 informational: degraded fingerprint window at accept time stands, unchanged: capturePushedTeammateEntry is still called from exactly TWO accept sites (boundary settlement at line ~5730 and the retry carrier's accept at line ~4598 — grep at the new head). The delta's accept-side strip did not add a capture site; the documented displacement window (a concurrent byte-identical push between push and settlement degrades the fingerprint to envelope-text containment) applies to both, as before. No exploit demonstrated.
5 informational: retry-debt consumption is one-shot superseded (carried): c17's fix (admission-gated consumption, unreadable-history preservation, carrier transfer) is intact at the new head; the delta c19 strip strengthens the accept side without touching consumption. R3 (the one-shot shape re-introduced) is still killed by exactly the transfer pin at this head.
corr. PR body's "Full file: 234/234 pass" superseded again: at this head the suite executes 254 tests, 254/254 green. The count reconciles exactly against the previous head: 251 (at c6aee955) − 1 (main deleted the old does not copy the objective into a synthetic Goal turn) + 3 (main added a guarded-Goal-data test and two auto-compaction-notice tests) + 1 (this PR's delta pin) = 254. Description predates the later commits; not a code issue.

Declined/deferred rows were re-measured, not diffed: M3, M11 and M12a were re-run as fresh mutations/probes at 6e3cf5be (the delta touches the retry carrier's accept closure and client.ts catches, so the closure of findings 1–3 changed and no carry-forward shortcut applied); finding 4's call-site census was re-grepped at the new head; finding 5's mechanism was re-read in the new code.

Central claim + A/B (re-run at the new head)

Central claim: teammate→leader messages queued during a multi-round tool task are delivered at the next tool-round boundary — appended to the SendMessageType.ToolResult submission after the tool-response parts — with no loss and no double delivery across cancelled/preempted boundaries, admission/delivery failures, hook blocks, and Ctrl+Y retries; settlement is decided by the push-site snapshot GeminiChat publishes; accepted-but-terminally-failed rounds survive the Ctrl+Y path via journaled retry debt; that debt is swap-safe, transfers through the retry's own re-pushed entry, survives lease-rejected retries, is recorded even when a concurrent submission overwrote the stored payload, and (delta) does not accumulate duplicate envelope copies across repeated accept→fail-before-content→Ctrl+Y cycles, while popped orphan entries are re-added even when pre-try catches settle the carrier.

Cells: base = scratch worktree at HEAD^1 (42b4c09ceb, removed after capture) with the PR test files copied in (core test file's userContentPushSnapshotKey import shimmed to an inert local Symbol — 0 refs in base source and 0 refs in the rebuilt base dist asserted). Base reused the root node_modules (PR leaves package.json/package-lock.json untouched — diff empty). Internal-link hygiene: all 23 node_modules/@qwen-code/* links were rebuilt to point INTO the base tree (readlink -f tmp/base-tree/node_modules/@qwen-code/qwen-code-core/__w/qwen-code/qwen-code/tmp/base-tree/packages/core, asserted); the nested packages/{cli,core}/node_modules symlinked from head were verified free of @qwen-code entries before linking; dists of PR-untouched workspace packages (acp-bridge, web-templates, channels/*git diff HEAD^1..HEAD over them empty) plus the generated git-commit.ts build-metadata file were symlinked to satisfy the vitest build-prerequisite guard; base core dist was rebuilt from base source (root tsc --build; the 63 pre-existing type errors are all @opentelemetry/node-pty/ignore/ajv resolution noise in telemetry/utils — zero in core/client.ts/core/geminiChat.ts; head's tsc --noEmit exits 0 on the same node_modules as an A/A control on the invocation) and content-asserted (0 userContentPushSnapshotKey refs anywhere in base dist). cli-side core resolution goes through the vitest source alias (path.resolve(__dirname, '../core/index.ts')), which resolves into whichever tree the config file lives in; all six subpath alias targets verified present in the base tree.

suite base (no PR) head (PR)
cli useGeminiStream.test.tsx (254) 14 failed | 240 passed — the 9 pre-existing #8172 reds + 4 of the 5 c18 pins + the new Ctrl+Y×2 pin 254/254
core client.test.ts (373) 6 failed | 367 passed — the 5 settlement-race reds + the new Goal-admission re-add pin 373/373

The one pin that is trivially green on base — does not journal or record retry debt for a boundary batch accepted after a TeamManager swap — holds there because base never drains (nothing to journal, retry payload never carries the envelope); it is load-bearing at head (killed by R2). All base failures are expected-vs-actual assertion mismatches (accept-vs-restore flips under concurrent pushes, missing catch settlement, duplicate envelope in the retry payload), zero load/collection errors. Witness: 01-ab-base-reds-vs-head-green.png; raw logs logs/base-cli-suite.txt, logs/base-core-suite.txt, logs/head-cli-suite.txt, logs/head-core-suite.txt.

Delta validation since the previous round (commits 19–20)

Both delta hunks are load-bearing — each reverted alone (tests stay intact; the hunks live in different packages, so each revert is attributable to its commit's package scope) and each turns exactly its own new pin red with the behavioral mismatch the pin exists for, every other test staying green:

build suite result red test (behavioral failure)
base (no PR) cli 14 failed | 240 passed; core 6 failed | 367 passed the 14 + 6 rows above
head − c19 (cli strip hunk) 1 failed | 253 passed (254) does not accumulate duplicate envelopes … (Ctrl+Y x2) — second retry payload Array(3) vs expected Array(2): tool-response + envelope + duplicate envelope
head − c20 (core catch hunks) 1 failed | 372 passed (373) re-adds popped retry entries when Goal admission rejects a Retry after the orphan popaddHistory called 0 times (popped entry dropped); the carrier still settles by restore (catch settlement predates the delta)
head (all commits) cli 254/254; core 373/373

Witness: 01-ab-base-reds-vs-head-green.png (delta rows); raw logs logs/delta-minus-c19-cli.txt, logs/delta-minus-c20-core.txt; diffs d19-cli.diff, d20-core.diff, delta-c19-c20.diff.

One attribution control: running the PREVIOUS head's test file (c6aee955) against the merge-head production code shows 2 reds OUTSIDE #8172 (sends a hidden Goal turn without user admission side effects and a sibling) — these are main-side tests whose goal_runtime_data expectations the merge commit updated, and the PR-branch test file predates them. Re-running the same old file against head − c19 − c20 (both delta hunks reverted) yields the IDENTICAL result (2 failed | 249 passed (251) in both runs, same two test names), so they are main-side expectation drift, not a delta regression. The mutation matrix's -t "#8172" selection and all head-file cells are unaffected.

The new pins are load-bearing and non-vacuous — mutation A/B across the test files: single-point mutants of the UNMODIFIED head production code, run against the old test file (c6aee955: 20 cli #8172 / 372 core tests) and the new one (6e3cf5be: 21 / 373), nothing else changed. Controls unmutated on both arms; occurrences asserted per edit; tree asserted clean after every cell:

mutant reverts old arm new arm killer on the new arm
CONTROL green green
D1 delta c19 accept-side strip SURVIVED KILLED (1) does not accumulate duplicate envelopes … (Ctrl+Y x2)
D2 delta c20 Goal-admission catch restore SURVIVED KILLED (1) re-adds popped retry entries when Goal admission rejects a Retry after the orphan pop
D3 delta c20 hook-failure catch restore SURVIVED SURVIVED — (documented no-op today: hooks never fire for Retry, the only type that populates the entries)
R1–R5 c17 Criticals 1–4 (carried) KILLED (1 each) KILLED (1 each) same c18 pins as the prior round
C1 (positive control) the central boundary drain KILLED (13) KILLED (14) both arms — harness live on both
M3 (carried F1) drop userPromptBlocked clause SURVIVED SURVIVED — (redundant defence)
M11 (carried F2) drop the cancelled-boundary guard SURVIVED SURVIVED — (redundant defence)

No mutant regressed killed→survived across the test-file change. Each Rn kill is attributed to exactly one c18 pin, each Dn kill to exactly its own new pin. D3's survival is the measurement behind its classification: the hook-failure catch cannot fire for Retry today (the hook block is guarded messageType !== SendMessageType.Retry), so removing its restore changes nothing — the code's own comment ("a no-op today … keeps this exit safe under future hook-scope changes") matches the evidence. Witness: 02-mutation-matrix-old-vs-new.png; raw logs logs/matrix-run.txt; rerunnable as node mutation-matrix.mjs; matrix-results.json carries all 26 cells.

Sibling sweep on the delta mechanism (no escaping shape found):

  • Accept-side strip: the trailing-match guard makes it a no-op when lastPromptRef was overwritten between re-attach and settlement; multiple consumed records strip in the same concatenation order the re-attach appended them; envelope parts are text-only machine text, so part.text ?? '' never mis-maps. A swap-then-swap-back still drops, consistent with the queue having been cleared twice (carried behavior).
  • The restoreStrippedRetryEntries counter gate inside the two catches could in principle be suppressed by a concurrent push advancing the per-chat counter before the catch runs — but during a Retry in flight the submission lease (isSubmittingQueryRef) blocks every other submitQuery-gated send in the same session (including /btw and Teammate submissions), and the counter is per-GeminiChat (per-session), so no concurrent pusher exists inside the pop→catch window. The gate design predates the delta; the catches inherit it consistently. Verified boundary, not a finding.
  • Ordering difference (catches restore→settle, finally settle→restore) is immaterial: cli-side settlement bookkeeping touches only cli state (lastPromptRef, debt ref), core-side restore touches only history; the re-added entries are exactly the popped entries, so the restored debt records' original fingerprints stay valid.
  • Non-Retry sends with carriers reaching the Goal-admission catch are unaffected (no popped entries; carrier restores exactly as before the delta).

Corrections

  • Carried and still true: the PR body's "234/234" describes the test file at the first commit; it now holds 254 tests, all passing. Not a code issue.
  • Carried: the Reviewer Test Plan's run command (npx vitest run packages/cli/src/ui/hooks/useGeminiStream.test.tsx from the repo root) works despite the repo's general "don't run vitest from the root" guidance. No correction needed.

Findings (non-blocking)

  1. userPromptBlocked dispatch flag remains a redundant defence (low, carried, re-measured at 6e3cf5be). M3 survives both arms (20/20 old, 21/21 new); its independent effect is telemetry only — settlement safety is held by the client-side unconditional restores. Keep as-is.
  2. Cancelled-boundary drain guard remains redundant for delivery correctness (low, carried, re-measured). M11 survives both arms; the guard's role is display hygiene (no premature ● …) and avoiding a drain/restore round trip. Keep as-is.
  3. The geminiChat.ts push-site publication hunk remains unpinned by any repo test (low, carried, re-measured). M12a survives the full client.test.ts (373/373) and all 377 native tests of geminiChat.test.ts; only the external mock-free probe kills it, and the probe is green at head (2/2) with the string-send validity control staying green under the mutant. Behavior verified correct by probe + base-cell reds, so this is a test to add, not code to change — port the two VERIFY-PROBE cases (array publication value + string no-carrier) into geminiChat.test.ts. Not a merge condition.
  4. Informational, carried: degraded fingerprint window at accept time. capturePushedTeammateEntry's backwards scan can be displaced only by a concurrent push carrying byte-identical envelope texts; still exactly two accept sites at this head. No exploit demonstrated; the window needs a byte-identical concurrent push inside a sub-event span, which the component harness cannot stage deterministically.
  5. Informational, carried as resolved: the one-shot retry debt is fixed by c17 and the delta preserves the fix (consumption stays admission-gated; the new accept-side strip only de-duplicates the stored payload).
  6. Informational, new classification: the hook-failure catch restore (D3) is an unobservable future-proofing defence today. Both arms survive its removal; the code comment documents the intent ("keeps this exit safe under future hook-scope changes"). Same family as findings 1–2; keep as-is.

Targeted gates

  • packages/cli useGeminiStream.test.tsx at head: 254 passed (254) (logs/head-cli-suite.txt).
  • packages/core client.test.ts at head: 373 passed (373) (logs/head-core-suite.txt).
  • tsc --noEmit in packages/cli and packages/core: exit 0 both (logs/typecheck-cli.txt, logs/typecheck-core.txt).
  • Flakiness gate: 2 changed test files × 5 identical rounds, PPPPP both, verdict pass (logs/flake-gate.txt, per-round logs logs/flake-r*). Witness for the probe cells and gates: 03-m12a-probe-and-gates.png.

Not covered

  • Per-commit attribution for commits 1–18 as standalone builds: the depth-2 checkout makes only HEAD^2 reachable (git rev-list HEAD^1..HEAD^2 = 1 commit vs the 20 in the metadata snapshot). Commits 1–18 were individually exercised in prior rounds and their aggregate behavior is re-measured here by the A/B, the delta reverts, and the full mutation matrix at the new head. The merge commits carry no PR content. Commit 19's object is absent locally; its contribution was separated from commit 20 by package-disjoint revert (cli-only vs core-only, matching commit scopes) rather than by the commit object itself.
  • Live multi-agent e2e / TUI evidence (the PR states the same; the cli harness drives the real handleCompletedTools/submitQuery/retryLastPrompt paths with a mocked model and a settlement shim mirroring the client contract, whose acceptance semantics are pinned in core's client.test.ts and by the base-cell reds). This round's harness replays the bug's wire shapes, not a live team's timing.
  • Steer's two exotic round-starting paths (duplicate-tool-response bypass, client.ts no-tool-call continuations) for teammate messages — PR-declared v1 scope; they fall back to the Idle drain (today's behavior), so no regression.
  • dualOutput.emitUserMessage sidecar for boundary deliveries — PR-declared, identical to steer at the same site.
  • The accept-time scan displacement window (finding 4) beyond its named bounds — demonstrating it would require a concurrent byte-identical push inside a sub-event window, which the component harness cannot stage deterministically.
  • Repo-wide lint/format gates (the PR's CI covers them); only affected-workspace tests and typecheck were run here.
  • Base-side tsc --build exits 1 on pre-existing optional-dependency type noise (telemetry/utils); the dist still emitted and was content-asserted, and head's tsc --noEmit on the same node_modules exits 0 (A/A control on the invocation), so this is not attributable to the PR.

Methodology

Assertion counting: every test execution with an encoded expectation counts one assertion — expected base/delta/mutant/probe reds count as PASSED control expectations (fail counts unexpected outcomes only). Primary cells (head/base/delta-revert suites: 254+373 each × 3 pairs; two old-file attribution controls of 251 each; probe runs 2+2+379+373) and the mutation matrix are counted at test level (26 cells × their suite sizes = 2645; each cell runs a distinct mutant, so each execution is a distinct assertion context); the flakiness gate is counted at round level (10); typecheck counts 2; four environment-hygiene checks (base-tree link realpath, dist content assert, shim presence, nested-node_modules @qwen-code-free) count 4. Sum: 2383 primary + 2645 matrix + 756 probe + 10 flake + 2 typecheck + 4 hygiene = 5800.

Environment: CI node:22-bookworm container, merge-ref checkout (HEAD f15ce79906 merge, HEAD^1 base tip 42b4c09ceb, HEAD^2 verified head 6e3cf5be1f), npm ci + build pre-run. A/B base cell: scratch worktree at HEAD^1 (removed after capture) with root node_modules reused (lockfile untouched — git diff HEAD^1..HEAD over all package manifests empty); the base tree's node_modules/@qwen-code/* links rebuilt to resolve INTO the base tree (realpath-asserted), head's nested packages/{cli,core}/node_modules symlinked for external deps (verified free of @qwen-code entries), dists of PR-untouched workspace packages and the generated git-commit.ts symlinked past the vitest build-prerequisite guard, base core dist compiled from base source and content-asserted, PR test files copied in with the documented inert-symbol shim for the core file. Delta controls: git apply -R of each package's production diff (tests intact), run, restored. Test-file mutation A/B: mutation-matrix.mjs (occurrence asserted per edit, files restored via git checkout, git status clean after every cell), selections -t "#8172" for cli against the old (c6aee955) and new test files. Probe: probe-m12a.mjs patches two temporary VERIFY-PROBE tests into geminiChat.test.ts (green at head, publication-red under M12a, restored). Flake gate: flake-gate.sh, 5 rounds × 2 files. Raw logs in logs/; harnesses (mutation-matrix.mjs, probe-m12a.mjs, print-ab.mjs, print-matrix.mjs, flake-gate.sh, d19-cli.diff, d20-core.diff, delta-c19-c20.diff) and matrix-results.json in the artifact dir; captures in evidence/.

Flakiness gate log

rounds=5 files=2 skipped=0
file packages/cli/src/ui/hooks/useGeminiStream.test.tsx: (cd packages/cli) npx --no-install vitest run ./src/ui/hooks/useGeminiStream.test.tsx
file packages/core/src/core/client.test.ts: (cd packages/core) npx --no-install vitest run ./src/core/client.test.ts


per-file results (P=pass F=fail I=infra-exit, one letter per run):
  packages/cli/src/ui/hooks/useGeminiStream.test.tsx: PPPPP
  packages/core/src/core/client.test.ts: PPPPP

verdict: pass
summary: 2 changed test file(s) x 5 identical rounds, no divergence

--- per-invocation detail (full copy in the artifact) ---
round 1 · packages/cli/src/ui/hooks/useGeminiStream.test.tsx: P (exit 0)
round 1 · packages/core/src/core/client.test.ts: P (exit 0)
round 2 · packages/cli/src/ui/hooks/useGeminiStream.test.tsx: P (exit 0)
round 2 · packages/core/src/core/client.test.ts: P (exit 0)
round 3 · packages/cli/src/ui/hooks/useGeminiStream.test.tsx: P (exit 0)
round 3 · packages/core/src/core/client.test.ts: P (exit 0)
round 4 · packages/cli/src/ui/hooks/useGeminiStream.test.tsx: P (exit 0)
round 4 · packages/core/src/core/client.test.ts: P (exit 0)
round 5 · packages/cli/src/ui/hooks/useGeminiStream.test.tsx: P (exit 0)
round 5 · packages/core/src/core/client.test.ts: P (exit 0)

Evidence images

01-ab-base-reds-vs-head-green

02-mutation-matrix-old-vs-new

03-m12a-probe-and-gates

Harness scripts and raw logs are in the workflow run artifacts (7-day retention).

Qwen Code · sandboxed verification

@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 — both round-13 Criticals verified fixed at this head against the code itself. ✅

@netbrah

netbrah commented Aug 27, 2026

Copy link
Copy Markdown
Contributor

@qwen-code-ci-bot I have not checked but one thing, is does it cover both leader sending to Agent team members as well. I.e. will the recipient team member also get messages at the tool call boundary? Because I see the issue go both ways currently

Adopt main's Gemini->Llm rename refactor while keeping this PR's
tool-round boundary delivery logic:

- use-llm-stream.ts: keep drainTeammateQueue() drain/restore protocol
  at the Idle drain site; rename geminiClient refs to llmClient.
- client.ts / client.test.ts: import userContentPushSnapshotKey from
  llm-chat.js; align test type refs to LlmChat/LlmEventType.
- geminiChat.ts: keep main's deprecation shim; port the
  userContentPushSnapshotKey export and the pre-push snapshot
  publication into llm-chat.ts.
- use-llm-stream.test.tsx: align PR-added tests with renamed
  identifiers (MockedLlmClientClass, ServerLlmEventType,
  responseSubmittedToLlm, useLlmStream).

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.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.

Partially reviewed — gaps disclosed.

4 Suggestion-level finding(s) this review confirmed are already reported on this PR and are not repeated:

  • push-snapshot publication (producer half of the settlement contract) has no direct test — already deferred in rounds 7/8/9/13 (reviews 4999300995, 5005382385, 5008201023, 5017676649; geminiChat.ts:2626/2637/2928, now llm-chat.ts:2984)
  • onAdmissionFailed boundary carrier restore unpinned by tests — already deferred in rounds 6/9/12 (review 4998826762; useGeminiStream.ts:5388/5616, now use-llm-stream.ts:5775)
  • retry debt accumulates unboundedly in sessions that never retry — already deferred in rounds 11/13 (review 5013385570; useGeminiStream.ts:5462/5710-5713, now use-llm-stream.ts:5718)
  • retry carrier's restore branch (strip-then-re-record) has no paired test — already deferred in round 13 (review 5017676649; useGeminiStream.ts:4586, now use-llm-stream.ts:4603)

Not reviewed: build-and-test — Integration Tests (CLI, No Sandbox) was skipped in CI and its suite did not run locally.

Not reviewed: reverse audit — an auditor ran and opened its brief, but no agent was launched with the prompt the CLI built — the launch was written by hand, and what the agent was actually asked is not what this skill certifies.

Test Plan (not a blocker): packages/cli/src/ui/hooks/useGeminiStream.test.tsxno such file or directory.

Deferred under the convergence posture (round 14, not a blocker) — recorded, not requested in this round:

  • packages/cli/src/ui/hooks/use-llm-stream.ts:4438 — [review] orphan-pop stop predicate hand-duplicated instead of calling core's exported isSystemReminderContent
中文说明

仅完成部分审查,审查缺口已披露。

本轮确认的 4 条建议级发现已在 PR 上报告过,不再重复发布(列表见上方英文部分)。

未审查:build-and-test — Integration Tests (CLI, No Sandbox) was skipped in CI and its suite did not run locally。

未审查:反向审计——有审计 agent 运行并打开了自己的 brief,但没有 agent 是用 CLI 构建的 prompt 启动的——启动 prompt 是手写的,agent 实际被要求做的并不是本 skill 所认证的内容。

Test Plan(非阻断):packages/cli/src/ui/hooks/useGeminiStream.test.tsxno such file or directory

收敛姿态下延后(第 14 轮,非阻断)——已记录,本轮不要求修改:共 1 条(原文未翻译,列表见上方英文部分)。

— qwen3.8-max via Qwen Code /review (v0.22.2)

yiliang114 and others added 2 commits August 29, 2026 00:41
Bring in #10402 (test(ci): make release classifier stub module-safe),
which fixes the classify-release-notes helper-test failure this branch's
last CI run hit; no conflicts.

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.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.

Partially reviewed — gaps disclosed.

2 Suggestion-level finding(s) this review confirmed are already reported on this PR and are not repeated:

  • real-chat snapshot publication has no test pairing (llm-chat.ts:2984) — already reported and deferred in rounds 7/8/9/13 (reviews 4999300995, 5005382385, 5008201023, 5017676649)
  • boundary onAdmissionFailed carrier restore untested (use-llm-stream.ts:5776) — already reported and deferred in rounds 6/9/12 (review 4998826762)

Not reviewed: reverse audit — did not converge within the reverse-audit round cap of 5.

Not reviewed: build-and-test — Integration Tests (CLI, No Sandbox) was skipped in CI and its suite did not run locally.

Not reviewed: build-and-test — the packages/cli unit suite never completed (killed at its full deadline under host load average ~125); the PR's own test file passes 254/254 standalone and the five mid-run failing files were measured pre-existing against the merge base.

Test Plan (not a blocker): packages/cli/src/ui/hooks/useGeminiStream.test.tsxno such file or directory.

Deferred under the convergence posture (round 15, not a blocker) — recorded, not requested in this round:

  • packages/cli/src/ui/hooks/use-llm-stream.ts:719 — [review] swap-drop rationale comment attached to the requeue branch it contradicts
  • packages/cli/src/ui/hooks/use-llm-stream.test.tsx:3203 — [test] retry carrier restore branch (debt re-record) has zero test pairing

Mechanism health: this round did not close cleanly, so it withholds the incremental anchor — and the round it recovered had no anchor this round could use either — none at all, one with no certifier, one certified by an identity other than the one this round runs under, or one this round's fetch refused or resolved to the head — so the next review re-reads the whole diff unless recovery grafts an earlier own anchor that the round running it can use onto the complete work list this round leaves behind, and keeps doing so until a round's marker carries an anchor again or a graft lands that the round running it can use. (Stated, not acted on — this changes nothing about what the round posts.)

中文说明

仅完成部分审查,审查缺口已披露。

本轮确认的 2 条建议级发现已在 PR 上报告过,不再重复发布(列表见上方英文部分)。

未审查:reverse audit — did not converge within the reverse-audit round cap of 5。

未审查:build-and-test — Integration Tests (CLI, No Sandbox) was skipped in CI and its suite did not run locally。

未审查:build-and-test — the packages/cli unit suite never completed (killed at its full deadline under host load average ~125); the PR's own test file passes 254/254 standalone and the five mid-run failing files were measured pre-existing against the merge base。

Test Plan(非阻断):packages/cli/src/ui/hooks/useGeminiStream.test.tsxno such file or directory

收敛姿态下延后(第 15 轮,非阻断)——已记录,本轮不要求修改:共 2 条(原文未翻译,列表见上方英文部分)。

机制健康:本轮未能干净收尾,因而扣留了增量锚点,而它恢复到的那一轮也没有留下本轮可用的锚点——要么完全没有、要么没有认证者、要么由本轮运行身份之外的身份认证、要么被本轮的获取拒绝或解析为头提交——因此下一次评审将重读整个 diff,除非恢复流程把本轮能使用的更早自有锚点嫁接到本轮留下的完整工作清单上;并会一直如此,直到某一轮的标记重新带上锚点,或落地的嫁接能被运行该轮的评审使用。(仅陈述,不据此行动——这不改变本轮发布的任何内容。)

— qwen3.8-max via Qwen Code /review (v0.22.2)

Comment thread packages/core/src/core/client.ts
@yiliang114

Copy link
Copy Markdown
Collaborator Author

@qwen-code /triage

@qwen-code-ci-bot

qwen-code-ci-bot commented Aug 29, 2026

Copy link
Copy Markdown
Collaborator

Sandboxed verification: ❌ not passed — findings reported (agent verdict) - workflow run

Ran the PR in an isolated, token-free container: A/B against the base build, mock-free harness assertions, targeted gates. Advisory evidence for human reviewers — not a review, an approval, or a CI check.

Scripted assertions: 4706 passed · 4 failed · 4710 total

Flakiness gate: ⚠️ consistent-fail — 1 of 2 changed test file(s) failed identically in every round — deterministic, so CI owns that signal

中文 — 判定:❌ 不通过 · 报告了发现(agent 判定)

沙箱验证在隔离、无凭证的容器中执行了该 PR 的代码(与 base 构建 A/B 对照、无 mock harness 断言、定向门禁)。仅作为评审证据,不构成评审、批准或 CI 检查

脚本断言:4706 通过 · 4 失败 · 4710 总计

抖动门:⚠️ consistent-fail — 1 of 2 changed test file(s) failed identically in every round — deterministic, so CI owns that signal

Verification report

<!-- qwen-triage:verify -->
<!-- qwen-triage:verify-substantive -->

Sandboxed verification: ❌ findings — 4706 passed · 4 failed · 4710 total (agent verdict) - verified head 1c23c6f29f0f1192c43c7c422b00f0a69a2d463e

The central mechanism is proven load-bearing (A/B + mutation matrix re-run at this head), but the delta commit 1c23c6f2 ("fix(core): restore retry entries per send") changes the retry-entry settlement protocol without migrating two pre-existing core tests that encode the old contract — packages/core's unit gate is red at head (2 failed | 374 passed) in every run. Production behavior is verified correct; the fix is a two-test migration, measured green (376/376).

中文 — 判定:❌ 有发现(agent 判定)
  • 结论findings。核心机制(工具轮边界投递 teammate 消息、无丢失/无重复、结算载体、重试债务)在新 head 上经 A/B 与变异矩阵复测确认承重;但增量提交 1c23c6f2 把重试条目恢复的判定从"客户端计数器快照"改为"聊天在请求数组上发布的 push 快照",却没有迁移两条按旧契约编写的既有测试——packages/core 单测门禁在 head 上确定性地红 2 条(does not re-add stripped retry entries when the chat already pushed them before failing…when auto-compression shrank history…01-head-two-broken-tests.png)。
  • A/B 结论:base(HEAD^1=52e13e42,仅反演 3 个生产文件 + 惰性 Symbol shim)cli 14 红 / 240 绿(254),全部为 Agent Team: teammate messages queue for the entire duration of a long multi-tool-call turn, not just the next response #8172 投递测试;core 6 红 / 370 绿(376),全部为 PR 新增结算钉住测试;head cli 254/254 全绿。增量提交承重:反演其门控(D4)后新钉住测试恰好 1 红、两条旧测试回绿——对称翻转(02-delta-d4-symmetric-flip.png)。
  • 生产行为正确:真实 LlmChat 在 push 前同步发布快照;Turn 按引用透传请求数组;字符串载荷经 flatMapTextParts 归一为数组;无 LlmChat 子类。即"push 已落地 ⇒ 抑制恢复;未 push ⇒ 无条件恢复"在真实路径成立,红的两条是 mock 仍按旧契约只加计数器、不发布快照。
  • 修复已测量:把两条测试的 mock turn 迁移到新契约(发布快照后再模拟 push,与 PR 自有新测试同款)→ 376/376 全绿,生产代码零改动。
  • 上轮发现:F1/F2/F6 冗余防御、F3 发布 hunk 无原生钉住(探针双向杀死)、F4/F5 信息项,均在新 head 复测后维持。
  • 未覆盖:提交 1–23 逐提交归因(浅克隆);live 多 agent e2e/TUI;steer 特殊轮次路径对 teammate 不覆盖(PR 声明);core 全量套件中 12 个文件 87 条环境性失败(HOME 路径假设/负载超时,与 PR 无关,不计入断言)。
Verification report

Verdict: findings — 4706 passed · 4 failed · 4710 total (the 4 fails are the same two PR-broken tests observed in two independent head runs). Verified head: 1c23c6f29f0f1192c43c7c422b00f0a69a2d463e (HEAD^2; base tip 52e13e4224 = HEAD^1). Follow-up round after the merge-ready report at head 6e3cf5be; delta = commits 21–24 (three main merges, incl. the useGeminiStreamuse-llm-stream rename, plus substantive core commit 1c23c6f2 "fix(core): restore retry entries per send"). The depth-2 checkout makes only the aggregate diff exercisable; 1c23c6f2 was separated by reverting its gate hunks (D4) with tests intact.

Previous-finding status (round at 6e3cf5be → new head 1c23c6f2)

# finding severity status at new head
1 userPromptBlocked dispatch flag is redundant defence (telemetry-only effect) low stands, re-measured: M3 survives at the new head (21/21 #8172 green under the mutant; C1 still kills 14). Keep as-is.
2 cancelled-boundary drain guard is redundant for delivery correctness low stands, re-measured: M11 survives (21/21). Keep as-is.
3 the push-site publication hunk is not pinned by any repo test low stands, re-measured: M12a survives the full client.test.ts (374/376 — only the two known PR-broken reds) AND all 385 native tests of llm-chat.test.ts (green at head too); the injected VERIFY-PROBE pair kills it (array probe red under M12a, string validity control green) and is green at head 2/2. Not a merge condition; recommendation unchanged (port the two probe cases into llm-chat.test.ts).
4 informational: degraded fingerprint window at accept time stands: capturePushedTeammateEntry still called from exactly two accept sites (lines 4597, 5720 at this head). No exploit demonstrated.
5 informational: one-shot retry debt fixed (c17) stands: admission-gated consumption intact; the delta's snapshot gate does not touch consumption; D4's revert left the transfer pin green.
6 informational: hook-failure catch restore is unobservable future-proofing stands, re-measured: D3 survives client.test.ts at this head (only the two known reds).
corr PR body names useGeminiStream.test.tsx and 4 tests superseded: main renamed the file to use-llm-stream.test.tsx; the #8172 describe now holds 21 tests. The 4 tests the body names all exist and behave as described (A/B + matrix). The body's run command needs the new filename.

Declined/deferred rows were re-measured, not diffed: M3/M11/D3 re-run as fresh mutants at 1c23c6f2; M12a re-run against both suites plus the probe; F4's census re-grepped; F5's mechanism re-read in the new code. The delta touched client.ts's retry gate and the two old tests' closure, so no carry-forward shortcut applied to any row.

Central claim + A/B (re-run at the new head)

Central claim: teammate→leader messages queued during a multi-round tool task are delivered at the next tool-round boundary (appended to the SendMessageType.ToolResult submission after the tool-response parts) with no loss and no double delivery across cancelled/preempted boundaries, admission/delivery failures, hook blocks, TeamManager swaps, and Ctrl+Y retries; settlement is decided by the push-site snapshot the chat publishes on the request array; accepted-but-terminally-failed rounds survive via journaled retry debt; and (delta) the retry-entry restore decision is per-send via that snapshot.

Base cell = HEAD tree with the three production files (use-llm-stream.ts, client.ts, llm-chat.ts) reverted to their HEAD^1 contents — byte-identical to a base worktree because git diff HEAD^1..HEAD --name-only is exactly those 3 production files + 2 test files — with the PR test files kept and the core test file's userContentPushSnapshotKey import shimmed to an inert local Symbol (0 refs in base production, asserted). Restored via git checkout afterwards; tree clean.

suite base (no PR) head (PR)
cli use-llm-stream.test.tsx (254) 14 failed | 240 passed — all 14 are #8172 delivery/debt tests (logs/base-cli-reds.txt) 254/254
core client.test.ts (376) 6 failed | 370 passed — the 6 settlement/catch pins the PR adds (logs/base-core-reds.txt); the two old suppression tests green at base 2 failed | 374 passed — the two pre-existing tests broken by the delta (see F7)

Witnesses: 03-ab-base-vs-head.png (table), 01-head-two-broken-tests.png (the two head reds as they print). Note: the delta pin restores stripped retry entries when only a concurrent send pushes is trivially green at base (the base setup's extra counter read consumes the mock's one-shot 0), so its load-bearing proof is the D4 flip below, not the base cell.

Delta validation (1c23c6f2) — D4 reverts only the retry gate to the old client-side counter (pushCountAfterStrip); everything else stays at head:

build old test: pushed-before-fail old test: compression-shrink delta pin: concurrent-push restore
head (snapshot gate) RED RED green
head − D4 (old gate) green green RED (addHistory calls: 0)

Witness: 02-delta-d4-symmetric-flip.png. The delta is load-bearing and pinned by exactly its new test; the same delta is what flips the two pre-existing tests red — the PR changed the contract on the production side and updated its new tests but not these two.

Findings

F7 (blocking): the delta's protocol change leaves two pre-existing core tests red — the affected workspace's unit gate fails at head. does not re-add stripped retry entries when the chat already pushed them before failing and …when auto-compression shrank history below the pre-send length after the push (client.test.ts:10927/10979) fail deterministically at 1c23c6f2 (observed in 4 independent runs). They mock the chat's push by bumping getUserContentPushCount inside the mock turn without publishing userContentPushSnapshotKey on the request — the old contract. Under the new gate, absence of the snapshot means "provably never pushed" ⇒ unconditional restore ⇒ addHistory called once ⇒ expect(...).not.toHaveBeenCalled() fails. Reproduce: cd packages/core && npx vitest run src/core/client.test.ts -t "does not re-add stripped retry entries".

Production behavior is correct: flatMapTextParts normalizes every send (incl. string Retry payloads) to a fresh Part[] before turn.run (client.ts:3567/3769); Turn.run passes req by reference into chat.sendMessageStream (turn.ts:614); the real LlmChat.sendMessageStream publishes the snapshot on that same array synchronously immediately before history.push (llm-chat.ts:2978-2987); no LlmChat subclass or alternate sendMessageStream implementation exists. So "push landed ⇒ snapshot present ⇒ suppress" and "exited pre-push ⇒ no snapshot ⇒ restore" both hold on every real path; the two tests' mocks are the only non-conforming chat left in the repo.

Measured fix (test-side only, mirrors the PR's own new tests' miniature contract): switch both tests' mockTurnRunFn.mockReturnValue(...) to mockImplementation((_model, request) => { request[userContentPushSnapshotKey] = pushCount; return <same generator>; }), assertions unchanged. Result: 376/376 green (logs/fix-two-tests-suite.txt); reverted afterwards (this round must not modify the PR). Suggested diff:

suggested fix (packages/core/src/core/client.test.ts, both tests)
// in 'does not re-add stripped retry entries when the chat already pushed them before failing'
mockTurnRunFn.mockImplementation((_model, request) => {
  (request as unknown as Record<PropertyKey, unknown>)[
    userContentPushSnapshotKey
  ] = pushCount;
  return (async function* () {
    pushCount++;
    yield* [] as ServerLlmStreamEvent[];
    throw new Error('retry failed after push, before first event');
  })();
});

// in '…when auto-compression shrank history below the pre-send length after the push'
mockTurnRunFn.mockImplementation((_model, request) => {
  (request as unknown as Record<PropertyKey, unknown>)[
    userContentPushSnapshotKey
  ] = pushCount;
  return (async function* () {
    historyRef.length = 0;
    historyRef.push({ role: 'user', parts: [{ text: 'summary' }] });
    historyRef.push(orphanedPrompt);
    pushCount++;
    yield* [] as ServerLlmStreamEvent[];
    throw new Error('failed after compression+push, before first event');
  })();
});

F1–F3, F6 (low, carried, re-measured) — see status table. Classifications unchanged: M3/M11 redundant defences, D3 unobservable future-proofing, M12a coverage gap (probe kills it both directions; port the probe into llm-chat.test.ts). None is a merge condition.

F4, F5 (informational, carried) — fingerprint displacement window at accept time (two accept sites, no exploit demonstrated); one-shot retry debt remains fixed.

Targeted gates

  • cli use-llm-stream.test.tsx at head: 254/254 (5 identical rounds, 05-flake-gate-cli.png).
  • core client.test.ts at head: 2 failed | 374 passed (F7).
  • core llm-chat.test.ts at head: 385/385; cli Session.test.ts (push-counter consumer): 722/722.
  • Full packages/core workspace suite at head: 13 failed files / 89 failed tests — 12 files (87 tests) environmental (HOME-path assertions /home/test vs /__w/_temp/verify-agent-home, timeouts under a loaded runner, timing thresholds); those files are byte-identical at base and none imports the changed modules (import census), so they are excluded from the assertion counts and from F7; the 13th file is client.test.ts (F7).
  • tsc --noEmit in packages/cli and packages/core: exit 0 both.

Not covered

  • Per-commit attribution for commits 1–23 as standalone builds (depth-2 checkout; git rev-list HEAD^1..HEAD^2 = 1 vs 24 in the metadata). Commits 1–20 were individually exercised in prior rounds; the aggregate is re-measured here (A/B + full matrix at the new head); 1c23c6f2 separated by the D4 revert.
  • Live multi-agent e2e / TUI evidence (PR states the same; the cli harness drives the real handleCompletedTools/submitQuery/retryLastPrompt paths).
  • Steer's two exotic round-starting paths for teammate messages and the dualOutput.emitUserMessage sidecar — PR-declared v1 scope.
  • The 12 environmentally failing core test files (not run at base; argued by byte-identity + import census + failure signatures rather than an A/A run).
  • Repo-wide lint/format gates (the PR's CI covers them).

Methodology

Assertion counting: every test execution with an encoded expectation counts one assertion; expected base/delta/mutant/probe reds count as PASSED control expectations; fail counts only unexpected outcomes — the 4 fails are the two PR-broken tests observed in two independent head runs. Cells counted: head cli 254; head core ×2 runs 374+374; D4 376; base cli 254; base core 376; C1/M3/M11 21 each; D3 376; M12a core 376; M12a native 385; probe 2+2; fix cell 376; head llm-chat 385; Session 722; flake rounds 5; typecheck 2; hygiene 4 (diff file list == 5 files; base production 0 snapshot refs; tree clean after every phase; no LlmChat subclass). Sum 4706 pass + 4 fail = 4710. Witness re-runs for the two captures and the superseded broken-D4 run are not double-counted. Environment: CI node:22-bookworm container, merge-ref checkout, npm ci + build pre-run. Harnesses in the artifact dir: mutate.py (D4/C1/M3/M11/D3/M12a with occurrence assertions), probe.py (VERIFY-PROBE inject/eject into llm-chat.test.ts), fix-two-tests.py (measured fix); raw logs in logs/; captures in evidence/.

Flakiness gate log

rounds=5 files=2 skipped=0
file packages/cli/src/ui/hooks/use-llm-stream.test.tsx: (cd packages/cli) npx --no-install vitest run ./src/ui/hooks/use-llm-stream.test.tsx
file packages/core/src/core/client.test.ts: (cd packages/core) npx --no-install vitest run ./src/core/client.test.ts


per-file results (P=pass F=fail I=infra-exit, one letter per run):
  packages/cli/src/ui/hooks/use-llm-stream.test.tsx: PPPPP
  packages/core/src/core/client.test.ts: FFFFF

verdict: consistent-fail
summary: 1 of 2 changed test file(s) failed identically in every round — deterministic, so CI owns that signal

--- per-invocation detail (full copy in the artifact) ---
round 1 · packages/cli/src/ui/hooks/use-llm-stream.test.tsx: P (exit 0)
round 1 · packages/core/src/core/client.test.ts: F (exit 1)
--- output tail · round 1 · packages/core/src/core/client.test.ts ---
��[39m Gemini Client (client.ts)�[2m > �[22mgenerateContent with fast model�[2m > �[22mshould use fast model authType for retry, not main model authType�[32m 142�[2mms�[22m�[39m
   �[32m✓�[39m Gemini Client (client.ts)�[2m > �[22mgenerateContent with fast model�[2m > �[22mshould cache per-model content generators�[32m 174�[2mms�[22m�[39m
   �[32m✓�[39m Gemini Client (client.ts)�[2m > �[22mgenerateContent with fast model�[2m > �[22mshould resolve model across authTypes when main authType misses�[32m 148�[2mms�[22m�[39m
   �[32m✓�[39m Gemini Client (client.ts)�[2m > �[22mgenerateContent with fast model�[2m > �[22mshould clear per-model generator cache on resetChat�[32m 175�[2mms�[22m�[39m
   �[32m✓�[39m Gemini Client (client.ts)�[2m > �[22mdrainSkillAndCommandReminders�[2m > �[22mfirst drain without snapshot seed announces all entries as new�[32m 151�[2mms�[22m�[39m
   �[32m✓�[39m Gemini Client (client.ts)�[2m > �[22mdrainSkillAndCommandReminders�[2m > �[22mfirst drain with snapshot seed emits nothing for seeded entries�[32m 183�[2mms�[22m�[39m
   �[32m✓�[39m Gemini Client (client.ts)�[2m > �[22mdrainSkillAndCommandReminders�[2m > �[22mdrain with a genuinely new skill emits a reminder�[32m 176�[2mms�[22m�[39m
   �[32m✓�[39m Gemini Client (client.ts)�[2m > �[22mdrainSkillAndCommandReminders�[2m > �[22mdrain with no new skills after seed emits nothing�[32m 153�[2mms�[22m�[39m
   �[32m✓�[39m Gemini Client (client.ts)�[2m > �[22mdrainSkillAndCommandReminders�[2m > �[22mremoved skill prunes its key so re-adding re-announces�[32m 169�[2mms�[22m�[39m
   �[32m✓�[39m Gemini Client (client.ts)�[2m > �[22mdrainSkillAndCommandReminders�[2m > �[22mremoved skill emits a reminder�[32m 154�[2mms�[22m�[39m
   �[32m✓�[39m Gemini Client (client.ts)�[2m > �[22mdrainSkillAndCommandReminders�[2m > �[22mpath-activated skill is announced by drain (no suppression based on shared activation set)�[32m 174�[2mms�[22m�[39m
   �[32m✓�[39m Gemini Client (client.ts)�[2m > �[22mdrainSkillAndCommandReminders�[2m > �[22mpath-activated skill re-announces after disable/re-enable�[32m 173�[2mms�[22m�[39m
   �[32m✓�[39m Gemini Client (client.ts)�[2m > �[22mdrainSkillAndCommandReminders�[2m > �[22mreturns early when Skill tool is not registered�[32m 152�[2mms�[22m�[39m
   �[32m✓�[39m Gemini Client (client.ts)�[2m > �[22mdrainSkillAndCommandReminders�[2m > �[22mreturns early and logs when collectAvailableSkillEntries throws�[32m 182�[2mms�[22m�[39m
   �[32m✓�[39m Gemini Client (client.ts)�[2m > �[22mdrainSkillAndCommandReminders�[2m > �[22mcommand entries use cmd: key prefix and are not suppressed by activatedConditional�[32m 186�[2mms�[22m�[39m
   �[32m✓�[39m Gemini Client (client.ts)�[2m > �[22mdrainSkillAndCommandReminders�[2m > �[22mcommand entry prunes and re-announces correctly�[32m 167�[2mms�[22m�[39m
   �[32m✓�[39m Gemini Client (client.ts)�[2m > �[22mdrainSkillAndCommandReminders�[2m > �[22mseedSkillReminderDedupFromSnapshot seeds from provided entries�[32m 185�[2mms�[22m�[39m
   �[32m✓�[39m Gemini Client (client.ts)�[2m > �[22mdrainSkillAndCommandReminders�[2m > �[22mseedSkillReminderDedupFromSnapshot with empty entries resets state�[32m 187�[2mms�[22m�[39m
   �[32m✓�[39m Gemini Client (client.ts)�[2m > �[22mdrainSkillAndCommandReminders�[2m > �[22minline-announced skills consumed from config are not re-announced by drain�[32m 162�[2mms�[22m�[39m
   �[32m✓�[39m Gemini Client (client.ts)�[2m > �[22mdrainSkillAndCommandReminders�[2m > �[22minline-announced does not suppress genuinely new skills�[32m 189�[2mms�[22m�[39m
   �[32m✓�[39m Gemini Client (client.ts)�[2m > �[22m#5147 shutdown gate�[2m > �[22mskips background memory tasks after shutdown is requested�[32m 181�[2mms�[22m�[39m
   �[32m✓�[39m Gemini Client (client.ts)�[2m > �[22m#5147 shutdown gate�[2m > �[22mis idempotent when called multiple times�[32m 163�[2mms�[22m�[39m
   �[32m✓�[39m Gemini Client (client.ts)�[2m > �[22mdrainAgentReminders�[2m > �[22mreturns early when the Agent tool is not registered�[32m 194�[2mms�[22m�[39m
   �[32m✓�[39m Gemini Client (client.ts)�[2m > �[22mdrainAgentReminders�[2m > �[22mseeds current agents on first drain without emitting a reminder�[32m 197�[2mms�[22m�[39m
   �[32m✓�[39m Gemini Client (client.ts)�[2m > �[22mdrainAgentReminders�[2m > �[22mreturns early when listing agents fails�[32m 190�[2mms�[22m�[39m
   �[32m✓�[39m Gemini Client (client.ts)�[2m > �[22mdrainAgentReminders�[2m > �[22memits no reminder when agents are unchanged�[32m 180�[2mms�[22m�[39m
   �[32m✓�[39m Gemini Client (client.ts)�[2m > �[22mdrainAgentReminders�[2m > �[22mannounces added-only agents�[32m 194�[2mms�[22m�[39m
   �[32m✓�[39m Gemini Client (client.ts)�[2m > �[22mdrainAgentReminders�[2m > �[22mannounces removed-only agents�[32m 221�[2mms�[22m�[39m
   �[32m✓�[39m Gemini Client (client.ts)�[2m > �[22mdrainAgentReminders�[2m > �[22mannounces added and removed agents�[32m 172�[2mms�[22m�[39m
   �[32m✓�[39m Gemini Client (client.ts)�[2m > �[22mdrainAgentReminders�[2m > �[22mkeeps agent reminder state unchanged if history append fails�[32m 146�[2mms�[22m�[39m

�[31m⎯⎯⎯⎯⎯⎯⎯�[39m�[1m�[41m Failed Tests 2 �[49m�[22m�[31m⎯⎯⎯⎯⎯⎯⎯�[39m

�[41m�[1m FAIL �[22m�[49m src/core/client.test.ts�[2m > �[22mGemini Client (client.ts)�[2m > �[22msendMessageStream�[2m > �[22mretry sendMessageType�[2m > �[22mdoes not re-add stripped retry entries when the chat already pushed them before failing
�[31m�[1mAssertionError�[22m: expected "spy" to not be called at all, but actually been called 1 times�[90m

Received: 

�[1m  1st spy call:

�[22m    Array [
      Object {
        "parts": Array [
          Object {
            "text": "retry me",
          },
        ],
        "role": "user",
      },
    ]
�[31m�[90m

Number of calls: �[1m1�[22m
�[31m�[39m
�[36m �[2m❯�[22m src/core/client.test.ts:�[2m10976:41�[22m�[39m
    �[90m10974| �[39m        // The push counter advanced past the post-strip snapshot, so …
    �[90m10975| �[39m        // restore must be suppressed — no duplicate addHistory.
    �[90m10976| �[39m        expect(mockChat.addHistory).not.toHaveBeenCalled();
    �[90m   | �[39m                                        �[31m^�[39m
    �[90m10977| �[39m      });
    �[90m10978| �[39m

�[31m�[2m⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[1/2]⎯�[22m�[39m

�[41m�[1m FAIL �[22m�[49m src/core/client.test.ts�[2m > �[22mGemini Client (client.ts)�[2m > �[22msendMessageStream�[2m > �[22mretry sendMessageType�[2m > �[22mdoes not re-add stripped retry entries when auto-compression shrank history below the pre-send length after the push
�[31m�[1mAssertionError�[22m: expected "spy" to not be called at all, but actually been called 1 times�[90m

Received: 

�[1m  1st spy call:

�[22m    Array [
      Object {
        "parts": Array [
          Object {
            "text": "retry me",
          },
        ],
        "role": "user",
      },
    ]
�[31m�[90m

Number of calls: �[1m1�[22m
�[31m�[39m
�[36m �[2m❯�[22m src/core/client.test.ts:�[2m11041:41�[22m�[39m
    �[90m11039| �[39m        // guard would restore here — but the push counter advanced, s…
    �[90m11040| �[39m        // counter guard must suppress the re-add.
    �[90m11041| �[39m        expect(mockChat.addHistory).not.toHaveBeenCalled();
    �[90m   | �[39m                                        �[31m^�[39m
    �[90m11042| �[39m      });
    �[90m11043| �[39m

�[31m�[2m⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[2/2]⎯�[22m�[39m


�[2m Test Files �[22m �[1m�[31m1 failed�[39m�[22m�[90m (1)�[39m
�[2m      Tests �[22m �[1m�[31m2 failed�[39m�[22m�[2m | �[22m�[1m�[32m374 passed�[39m�[22m�[90m (376)�[39m
�[2m   Start at �[22m 08:12:09
�[2m   Duration �[22m 56.51s�[2m (transform 7.73s, setup 373ms, collect 10.64s, tests 36.95s, environment 0ms, prepare 391ms)�[22m

JUNIT report written to /__w/qwen-code/qwen-code/packages/core/junit.xml

round 2 · packages/cli/src/ui/hooks/use-llm-stream.test.tsx: P (exit 0)
round 2 · packages/core/src/core/client.test.ts: F (exit 1)
--- output tail · round 2 · packages/core/src/core/client.test.ts ---
mini Client (client.ts)�[2m > �[22mgenerateContent with fast model�[2m > �[22mshould use fast model authType for retry, not main model authType�[32m 157�[2mms�[22m�[39m
   �[33m�[2m✓�[22m�[39m Gemini Client (client.ts)�[2m > �[22mgenerateContent with fast model�[2m > �[22mshould cache per-model content generators �[33m 445�[2mms�[22m�[39m
   �[32m✓�[39m Gemini Client (client.ts)�[2m > �[22mgenerateContent with fast model�[2m > �[22mshould resolve model across authTypes when main authType misses�[32m 154�[2mms�[22m�[39m
   �[32m✓�[39m Gemini Client (client.ts)�[2m > �[22mgenerateContent with fast model�[2m > �[22mshould clear per-model generator cache on resetChat�[32m 156�[2mms�[22m�[39

...truncated -- full content in the run artifacts.

Evidence images

01-head-two-broken-tests

02-delta-d4-symmetric-flip

03-ab-base-vs-head

04-matrix-and-probes

05-flake-gate-cli

Harness scripts and raw logs are in the workflow run artifacts (7-day retention).

Qwen Code · sandboxed verification

@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.

Requesting changes for one concrete reason at head 1c23c6f2: the packages/core unit suite is red on this PR's own change area — two pre-existing pins of the old global-counter gate in client.test.ts (retry sendMessageType) were not updated to the new userContentPushSnapshotKey contract, while four sibling tests were. The R15-1 fix itself is structurally right (verified from the diff); this is a test-only follow-up. Details, log excerpt, and the exact fix shape are in my Stage 2 comment above.

@yiliang114 once the two pins carry the same snapshot miniature their siblings got, a green full-matrix re-run is the remaining gate before the maintainer call.

中文说明

在头提交 1c23c6f2 上因一个具体原因 request changes:packages/core 单测套件在本 PR 自己的改动区域变红——client.test.tsretry sendMessageType)里两个钉住旧全局计数器判定的既有测试没有同步更新到新的 userContentPushSnapshotKey 契约,而四个同类测试已经更新。R15-1 的修复本身在结构上是正确的(已从 diff 核实);这只需要一个改测试的后续提交。细节、日志摘录和具体修复形态见上方的 Stage 2 评论。

@yiliang114 给这两个测试补上同类测试已有的快照微缩契约后,转绿的全矩阵重跑就是维护者拍板前的唯一门槛。

Qwen Code · qwen3.8-max

The two retry-restore tests anchored the old global push-counter gate
and never published userContentPushSnapshotKey from their mocked turn,
so the per-send snapshot gate saw "no snapshot, never pushed" and
restored unconditionally. Mirror the sibling tests' GeminiChat contract
miniature: publish the counter on the request immediately before the
simulated push, after the simulated compression in the shrink test.

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Agent Team: teammate messages queue for the entire duration of a long multi-tool-call turn, not just the next response

5 participants