Skip to content

fix(core): make loop detection result-aware for task_list polls - #9492

Open
yiliang114 wants to merge 58 commits into
mainfrom
fix/9450-task-list-loop-false-positive
Open

fix(core): make loop detection result-aware for task_list polls#9492
yiliang114 wants to merge 58 commits into
mainfrom
fix/9450-task-list-loop-false-positive

Conversation

@yiliang114

@yiliang114 yiliang114 commented Aug 19, 2026

Copy link
Copy Markdown
Collaborator

What this PR does

This PR makes the loop-detection guards result-aware for a narrow class of stateful read tools — currently only task_list. For these tools identical arguments do not imply an identical result (other teammates can mutate the shared task board between calls), so the detector now records each executed result as a privacy-safe SHA-256 fingerprint and only treats repetition as a loop when the observed results stop changing too:

  • The always-on consecutive-identical guard still fires at five consecutive identical calls, but for task_list it requires result corroboration: it halts only when every result observed within the streak is unchanged, and missing result evidence fails safe and keeps the pre-fix behavior (the DashScope 长程任务下,出现大量工具重复调用情况,导致会话被终止 #5019 protection is never loosened by a wiring gap). A changed result restarts the streak instead of halting.
  • The global-duplicate heuristic and the adaptive per-turn cap's stuck signal count post-execution (call, result fingerprint) pairs for these tools instead of raw requests, so productive polling does not accumulate toward either halt.
  • Action stagnation treats a changed result as observable progress and restarts the same-name streak.
  • Tool results are recorded into the loop detector on both reasoning-loop owners: the agent runtime (after processFunctionCalls) and the main-session continuation path in client.ts (matched by functionResponse call id). The daemon ACP path is unaffected: it has no consecutive-identical guard.
  • Loop stops become attributable (issue requirement API Key是要设成阿里云的API Key吗? #7): ReasoningLoopResult carries the exact LoopType, the interactive agent stop message includes it (Agent stopped: duplicate tool-call loop detected (consecutive_identical_tool_calls).), and the headless FINISH event plus the telemetry completion record carry it for journals.

Scope note (2026-08-26): this PR was trimmed back to the core result-aware guard, and the follow-up verification round then restored what it proved live: truncated-result fingerprint hardening is back (sandboxed verification showed oversized persisted results escape every result-aware guard via per-call unique stub paths — not an unobserved edge case) and the provider-duplicate call-id feed dedup is restored on both owners. The daemon/ACP-side twin of the cap's stuck signal stays cut — tracked separately in #10161, where it should share one tracker with core instead of mirroring the state machine. Result recording is consolidated in the two reasoning-loop owners above.

Why it's needed

Fixes the false positive in #9450: an Agent Team teammate polling task_list was stopped with "Agent stopped: duplicate tool-call loop detected." while its peers were actively completing tasks. The guards keyed on tool name + canonicalized args only and fired pre-execution, so a changed board between identical calls could never influence them — the service had no entry point for tool results at all. The report's evidence (five identical consecutive task_list(status=in_progress, owner=<peer>, blockedBy="") calls) matches the consecutive guard's threshold exactly, and the team prompt actively encourages this polling pattern. The expected behavior per the issue: same query + changing state must not halt; same query + unchanged state must still halt; deterministic tools and hard caps keep all existing protection.

Reviewer Test Plan

How to verify

Deterministic unit reproduction (no live team needed): feed five consecutive identical task_list ToolCallRequest events into LoopDetectionService.checkAlwaysOnSafeties(). On main this fires CONSECUTIVE_IDENTICAL_TOOL_CALLS on the 5th request regardless of what the executed calls returned (there was no way to report results); with this PR, recorded results that keep changing prevent the halt, recorded unchanged results still halt at the same request count, and missing result evidence halts exactly as before.

  • cd packages/core && npx vitest run src/services/loopDetectionService.test.ts — new describe block "Result-aware guards for stateful read tools (issue task_list can falsely trigger duplicate tool-call loop detection while team state changes #9450)": fail-safe, unchanged-still-halts, changing-state-survives (incl. past the adaptive 100-call cap), mid-streak change restarts, deterministic tools unchanged, callId pairing, result-aware global duplicate, result-aware action stagnation, retry/reset semantics.
  • cd packages/core && npx vitest run src/agents/runtime/agent-headless.test.ts -t "issue #9450" — end-to-end through the agent runtime that produced the report: 8 identical task_list polls with a changing board complete without LOOP_DETECTED; a frozen board still halts at the 5th request (4 executions) and the FINISH event carries loopType: consecutive_identical_tool_calls.

Evidence (Before & After)

Non-UI change (guard internals); the only user-visible string changes on an actual loop stop (detector name appended). Test output:

Before (main): repro test shows checkAlwaysOnSafeties fires CONSECUTIVE_IDENTICAL_TOOL_CALLS on the 5th identical task_list request and the service exposes no result-recording API.

After (this PR): loopDetectionService.test.ts 145/145, agent-headless.test.ts 68/68, client.test.ts 370/370, agent-interactive.test.ts 25/25, qwen-logger.test.ts 43/43; full packages/core suite shows no new failures versus a clean baseline at the same commit (the pre-existing failures are machine-environment issues and reproduce identically on the unmodified baseline); typecheck clean.

Tested on

OS Status
🍏 macOS ⚠️ not tested
🪟 Windows ⚠️ not tested
🐧 Linux ✅ tested

Environment (optional)

Unit + integration tests only (npm ci, npx vitest run, npx tsc --noEmit on packages/core and packages/cli). No live multi-agent run against a real model.

Risk & Scope

  • Main risk or tradeoff: a genuinely stuck task_list poll whose results keep changing (e.g. an oscillating board) is no longer stopped by the consecutive/global guards — it remains bounded by the unchanged-state detection, the adaptive cap's hard backstop, and turn limits; the halt point for truly unchanged loops is unchanged (same request count as today, so the DashScope 长程任务下,出现大量工具重复调用情况,导致会话被终止 #5019 emission bound is preserved).
  • Not validated / out of scope: live multi-agent E2E with real model traffic; send_message/task_update deliberately stay argument-only per the issue's narrow scope; the daemon ACP path has no consecutive-identical guard, and making its adaptive-cap stuck signal result-aware is deferred to Make daemon/ACP adaptive-cap stuck signal result-aware for stateful reads (follow-up from #9492) #10161 (issue requirement OpenAI API Error: 401 Incorecct API Key provided #6); the alternating-pattern detector is untouched.
  • Breaking changes / migration notes: none — recordToolResult/recordToolResultByCallId are additive, ReasoningLoopResult.loopType and AgentFinishEvent.loopType are optional, and all existing guard behavior for non-stateful tools is unchanged.

Linked Issues

Closes #9450

中文说明

本 PR 做了什么

本 PR 让循环检测守卫对一窄类有状态读取工具(目前仅 task_list)变为结果感知:对这类工具,相同参数并不意味着相同结果(其他 teammate 可能在两次调用之间修改共享任务板),因此检测器现在会把每次执行结果记录为隐私安全的 SHA-256 指纹,只有当观察到的结果也不再变化时才把重复判定为循环:

  • 始终启用的连续相同调用守卫仍在连续 5 次相同调用时触发,但对 task_list 需要结果佐证:仅当该连续段内观察到的结果全部未变化时才终止;缺少结果证据时失败保持安全(维持修复前行为),DashScope 长程任务下,出现大量工具重复调用情况,导致会话被终止 #5019 的防护不会因接线缺口而放松。结果发生变化时重置连续段而不是终止。
  • 全局重复启发式与自适应每回合上限的卡滞信号对这类工具改为按执行后的(调用, 结果指纹)对计数,而不是按请求计数, productive 轮询不会再向这两个终止条件累积。
  • 动作停滞检测把结果变化视为可观察的进展,重置同名连续计数。
  • 工具结果在两个推理循环宿主上都会记录到循环检测器:agent 运行时(processFunctionCalls 之后)与主会话续接路径(client.ts,通过 functionResponse 的 callId 配对)。daemon ACP 路径不受影响:该路径没有连续相同守卫。
  • 循环终止变为可归因(issue 要求 API Key是要设成阿里云的API Key吗? #7):ReasoningLoopResult 携带精确的 LoopType,交互式 agent 的停止信息包含它(Agent stopped: duplicate tool-call loop detected (consecutive_identical_tool_calls).),headless 的 FINISH 事件与遥测完成记录也携带它,供日志归因。

范围说明(2026-08-26): 本 PR 已瘦身回核心结果感知守卫,随后的验证轮又把被证明真实可达的部分找了回来:截断结果指纹加固已恢复(沙箱验证证明超大持久化结果会经由逐次调用唯一的 stub 路径逃逸所有结果感知守卫——并非未观测边界);provider 重复 callId 的守卫喂入去重在两个宿主上均已恢复。daemon/ACP 侧上限卡滞信号的孪生实现仍保持砍掉状态——单开 #10161 跟踪,应与 core 共享同一份跟踪器,而不是镜像状态机。结果记录收敛到上述两个推理循环宿主。

为什么需要

修复 #9450 的误杀:Agent Team 的 teammate 在 peer 仍在持续完成任务时轮询 task_list,被 "Agent stopped: duplicate tool-call loop detected." 终止。守卫仅以工具名 + 规范化参数为键,且在执行前触发,两次调用之间任务板的变化根本无法影响判定——服务完全没有工具结果的入口。报告证据(五次连续相同的 task_list(status=in_progress, owner=<peer>, blockedBy="") 调用)与该连续守卫的阈值完全吻合,且团队提示词本身就鼓励这种轮询模式。按 issue 的期望行为:相同查询 + 状态变化不得终止;相同查询 + 状态不变仍要终止;确定性工具与硬上限保留全部既有保护。

评审测试计划

如何验证

确定性单元复现(无需实时团队):向 LoopDetectionService.checkAlwaysOnSafeties() 输入五次连续相同的 task_list ToolCallRequest 事件。在 main 上,无论执行结果如何,第 5 次请求都会触发 CONSECUTIVE_IDENTICAL_TOOL_CALLS(当时没有任何上报结果的途径);本 PR 之后,持续变化的已记录结果会阻止终止,全部未变化的已记录结果仍在同一请求数处终止,缺少结果证据时与修复前行为完全一致。

  • cd packages/core && npx vitest run src/services/loopDetectionService.test.ts —— 新增 describe 块 "Result-aware guards for stateful read tools (issue task_list can falsely trigger duplicate tool-call loop detection while team state changes #9450)":失败保持安全、结果全不变仍终止、状态持续变化可存活(含超过自适应 100 次上限)、连续段中途变化后重置、确定性工具行为不变、callId 配对、结果感知的全局重复、结果感知的动作停滞、retry/reset 语义。
  • cd packages/core && npx vitest run src/agents/runtime/agent-headless.test.ts -t "issue #9450" —— 端到端贯穿产生报告的 agent 运行时:8 次相同 task_list 轮询且任务板持续变化时完整跑完、不出现 LOOP_DETECTED;任务板冻结时仍在第 5 次请求处终止(执行 4 次),FINISH 事件携带 loopType: consecutive_identical_tool_calls

证据(修复前/后)

非 UI 改动(守卫内部逻辑);唯一的用户可见字符串变化发生在真实循环终止时(附加检测器名称)。测试输出:

修复前(main):复现测试显示 checkAlwaysOnSafeties 在第 5 次相同 task_list 请求时触发 CONSECUTIVE_IDENTICAL_TOOL_CALLS,且服务不存在任何结果记录 API。

修复后(本 PR):loopDetectionService.test.ts 145/145、agent-headless.test.ts 68/68、client.test.ts 370/370、agent-interactive.test.ts 25/25、qwen-logger.test.ts 43/43;packages/core 全量套件相对同一 commit 的干净基线无新增失败(既有失败为本机环境问题,在未修改的基线上同样复现);typecheck 干净。

测试环境

OS 状态
🍏 macOS ⚠️ 未测试
🪟 Windows ⚠️ 未测试
🐧 Linux ✅ 已测试

环境(可选)

仅单元测试 + 集成测试(npm cinpx vitest run、packages/core 与 packages/cli 的 npx tsc --noEmit)。未做真实模型的实时多 agent 运行。

风险与范围

关联 Issue

Closes #9450

Identical task_list arguments do not imply an identical result: teammates
mutate the shared task board between calls. The argument-only loop guards
falsely halted polling teammates with 'duplicate tool-call loop detected'
while the board kept changing.

Record executed tool results into LoopDetectionService (agent runtime after
processFunctionCalls; main-session continuations via functionResponse callId
pairing) as privacy-safe SHA-256 fingerprints. For the stateful read tool
(task_list only), the consecutive-identical guard, the global-duplicate
heuristic, the adaptive cap stuck signal, and action stagnation now require
the observed results to be unchanged too. Missing result evidence fails safe
and keeps the pre-fix behavior, preserving the DashScope #5019 protection.

Loop stops become attributable: ReasoningLoopResult carries the exact
LoopType, the interactive stop message and the headless FINISH event /
telemetry completion record include it.
@qwen-code-ci-bot

qwen-code-ci-bot commented Aug 19, 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 19, 2026

Copy link
Copy Markdown
Collaborator

Re-run at 4bbf8eabd801 — fourth pass on an unchanged head; gate findings re-verified against the current diff and description, all standing. One correction this pass, on the size policy.

Template ✓ — all sections present, bilingual.

Problem: observed bug with real evidence — unchanged. #9450 carries structured local evidence (five identical task_list(status=in_progress, owner=<peer>, blockedBy="") polls, an exact match for the consecutive guard's threshold) and was reproduced on main by @wenshao's A/B earlier in this thread. Not theoretical hardening.

Direction: aligned — sits squarely in the multi-agent roadmap area, and a safety guard that halts a coordinating teammate mid-flight is a real defect.

Size: core paths (packages/core/src/**) — recomputed this pass from the file stats: 575 production lines vs 1,296 test lines, no generated/schema. Correction vs prior passes: the 500-line maintainer-awareness threshold is part of the two-tier core gate, which protects core from external PRs — maintainer-authored PRs are exempt (AGENTS.md), and the author here is a repo admin. Prior passes applied the cap anyway and deferred; that deferral reason does not hold for this PR, so it no longer bars the bot's approval. The fix type means no Tier 1 gate applies regardless.

Approach: unchanged from the last pass — per-key consecutive result counting for the oscillation axis and the stub full-output digest for the oversized axis are the right shape. The description matches the diff (hardening restored, daemon twin cut and tracked in #10161). What remains of @wenshao's note 7.2 is one line: the description still doesn't spell out that the Full output sha256: digest line is product-wide and model-visible — it lands on every oversized tool result, not just task_list (re-confirmed in buildStub this pass). Description hygiene, not a code concern.

Risk: no high-risk path matches against the revert-history patterns.

Moving on to code review. 🔍

中文说明

4bbf8eabd801 上重跑 —— head 未变的第四次通过;所有门检结论已对照当前 diff 与描述复核,全部维持。本次有一处规模策略上的更正。

模板 ✓ —— 各节齐全,双语。

问题:已观测到的 bug,有真实证据 —— 结论不变。#9450 带有结构化本地证据(五次完全相同的 task_list(status=in_progress, owner=<peer>, blockedBy="") 轮询,与连续守卫阈值完全吻合),且 @wenshao 早前的本地 A/B 已在 main 上复现。不是理论性加固。

方向:对齐 —— 正处 multi-agent 路线图区域;会中途终止正在协作的 teammate 的安全守卫是真实缺陷。

规模:核心路径(packages/core/src/**)—— 本次按文件统计重新计算:575 行生产代码,测试 1,296 行,无生成/schema 代码。相对此前各次的更正: 500 行维护者关注阈值属于两层核心门禁,保护核心免受外部 PR 影响——维护者自己提交的 PR 豁免(AGENTS.md),而本 PR 作者是仓库 admin。此前各次仍套用了该封顶并推迟;该推迟理由对本 PR 不成立,不再阻止机器人批准。fix 类型,无论如何不触发 Tier 1。

方案:与上次一致 —— 振荡轴采用按 key 的连续结果计数、超大结果轴采用 stub 全量输出摘要,形态正确。描述与 diff 一致(加固已恢复,daemon 孪生实现被砍并在 #10161 跟踪)。@wenshao 备注 7.2 还剩一句:描述仍未写明 Full output sha256: 摘要行是全产品范围且模型可见的——它会出现在每一份超大工具结果上,而不只是 task_list(本次已在 buildStub 中复核)。属描述卫生问题,不是代码问题。

风险:与回滚历史高风险路径无匹配。

进入代码审查 🔍

Qwen Code · qwen3.8-max

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

@qwen-code-ci-bot

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

Copy link
Copy Markdown
Collaborator

Code review at 4bbf8eabd801 (fourth pass on an unchanged head — key claims re-traced through the diff this pass)

Independent proposal first: for the oscillation axis I would have counted consecutive identical results per repeat key — restarting at 1 whenever a result differs from its predecessor — and fed that count to both the global-duplicate guard and the adaptive cap's stuck signal, which is exactly what f34098e6 does. For the oversized-result axis I would have embedded a stable sha256 of the full pre-truncation output in the persistence stub and fingerprinted that instead of the envelope, with a path-free preview fallback for stubs that predate the digest line — exactly what 4bbf8eabd801 does. I did not find a simpler path the PR missed.

What I verified by hand (static review — I do not execute PR code):

  • Oscillation fix (f34098e6). Traced recordToolResult: statefulConsecutiveResults restarts at 1 whenever the fingerprint differs from the key's predecessor, so an A/B/A/B board never exceeds 1 and never feeds capMaxKeyRepeat or the gated global-duplicate count; a frozen board keeps accumulating even when interleaved with other calls, because the count is keyed per repeat key, not per adjacency. The turn-wide statefulPairCounts is gone from both consumers. Three new regression tests pin the heuristics-on mode, the CLI-default (skipLoopDetection=true) mode past the 100-call soft cap, and the interleaved-frozen direction (TURN_TOOL_CALL_CAP still fires).
  • Fail-safe math preserved — re-derived this pass. At the Nth identical request the guard requires resultsObserved >= N-1 before trusting the streak; I walked the arithmetic: no evidence → halt as pre-fix, partial evidence (4 results for 5 requests) → halt, all-unchanged → halt at the same request count as pre-fix, any changed result → streak restarts. The new tests pin all directions; the DashScope 长程任务下,出现大量工具重复调用情况,导致会话被终止 #5019 bound is untouched for non-stateful tools and for wiring gaps.
  • Provider-duplicate callId dedup (verify finding 3, restored). Both owners dedup the guard feed per attempt, mirroring execution-side collapse: loopGuardStreamedCallIds in agent-core.ts before checkSubagentLoop, and loopGuardFedCallIds in client.ts gating both checkAlwaysOnSafeties and addAndCheckHeuristicLoops — while the duplicate event itself still flows to consumers. Both sets clear on retry/fallback, matching the attempt's accumulated state; id-less calls are never deduped, mirroring dedupeToolCallsById. Pinned by end-to-end tests in both runtimes.
  • Oversized-stub fingerprinting (verify finding 2, restored). buildStub now embeds Full output sha256: <digest> of the full pre-truncation content; stripPersistenceEnvelope reduces stubs to <persisted-stub>sha256:<digest> before hashing. Recognition is anchored on leading producer prefixes and the digest must start its line and be exactly 64 hex chars — quoted stub markers inside peer-authored board content are not honored, so board text can't forge the envelope path (worst case is still bounded by the cap's hard backstop). Digest-less legacy stubs fall back to the path-free preview; mutations beyond the preview window are covered by the digest. All four directions pinned by unit tests.
  • Previously unpinned wiring (verify finding 4 + the round-16 review's deferred items) is now pinned: four client.test.ts tests drive the main-session ToolResult branch through real sendMessageStream turns (frozen halts with global_tool_call_duplicate, changed survives, duplicate-id desync, frozen-still-halts-with-dedup); agent-interactive.test.ts pins the detector name in the stop message; qwen-logger.test.ts pins the journal's loop_type propagation and its absence when no loop fired.
  • One micro-note, non-blocking: after an in-streak reset, lastFingerprint survives, so the new streak's first result counts as "unchanged" when it matches the pre-reset fingerprint — inflating unchangedStreak by one. I traced it again this pass: the inflation can only survive to the halt check when no result changed within the streak (any change resets the count to exact), which is precisely when halting is correct. No false halt is reachable; not worth a code change, but worth knowing when reading that block.
sequenceDiagram
    participant P1 as Model
    participant P2 as Runtime (agent-core or client.ts)
    participant P3 as LoopDetectionService
    participant P4 as task_list tool
    P1->>P2: emits identical task_list request
    P2->>P3: checkAlwaysOnSafeties (deduped per call id, checks streak with result evidence)
    P3-->>P2: pass, or halt when unchanged results corroborate the loop
    P2->>P4: execute
    P4-->>P2: board state (oversized results arrive as stubs with a full-output digest)
    P2->>P3: recordToolResult (fingerprint of stable payload only)
    P3-->>P2: pass, restart on changed result, or halt on repeated unchanged result
    P2->>P1: result, next round
Loading
Files changed (14)
File What changed
packages/core/src/services/loopDetectionService.ts Core of the fix: stateful-read registry, result fingerprints, the guards made result-aware, per-key consecutive result counting (oscillation fix), stub-envelope reduction, callId pairing
packages/core/src/services/loopDetectionService.test.ts Result-aware guard suite: fail-safe directions, oscillation in both modes, oversized-stub directions, duplicate pairing, retry/reset semantics
packages/core/src/agents/runtime/agent-core.ts Wires executed results into the detector after each batch with per-attempt callId feed dedup; carries loopType on the loop result
packages/core/src/agents/runtime/agent-headless.test.ts End-to-end runtime tests: changing board survives, frozen halts with attribution, provider-duplicate id, no stale attribution on re-execution
packages/core/src/core/client.ts Main-session wiring: records ToolResults by callId and halts like the event-loop guards; per-attempt guard-feed dedup on Retry/ModelFallback
packages/core/src/core/client.test.ts Four tests driving the ToolResult branch through sendMessageStream turns — pins the wiring that was previously revert-able with a green suite
packages/core/src/tools/truncation.ts buildStub embeds the full-output sha256 digest line; exports the label and preview size for the detector
packages/core/src/agents/runtime/agent-headless.ts Carries loopType into the FINISH event and telemetry; resets it between runs
packages/core/src/agents/runtime/agent-interactive.ts Stop message and lastRoundError name the exact detector
packages/core/src/agents/runtime/agent-interactive.test.ts Pins the detector name in the interactive stop message
packages/core/src/agents/runtime/agent-events.ts Optional loopType on the finish event
packages/core/src/telemetry/types.ts Optional loop_type on the subagent execution event
packages/core/src/telemetry/qwen-logger/qwen-logger.ts Journals loop_type when present
packages/core/src/telemetry/qwen-logger/qwen-logger.test.ts Pins journal propagation and omission of loop_type

Testing evidence — the PR's own CI, quoted via the API

This is an unattended run: PR code is never built or executed here. At head 4bbf8eabd801 CI fully settled green — both pull_request workflow runs (Security Checks, and Qwen Code CI including the ubuntu unit suite) completed with no failures; re-read via the check-runs API this pass, unchanged since the table region was finalized. Not verified here: live multi-agent runs against a real model (author-declared out of scope), and the DashScope server-side re-emission concern from @wenshao's note 7.3 remains open (no provider credentials in any sandboxed lane).

Final CI results for 4bbf8ea (auto-updated by the triage finalize job after CI completed):

Check Conclusion
Classify PR ✅ success
Dependency CVE audit ✅ success
Desktop Shell (ubuntu-22.04) ✅ success
Desktop Shell (windows-2022) ✅ success
Post Coverage Comment (ubuntu-latest, 22.x) ✅ success
Secret scan (TruffleHog) ✅ success
Test (ubuntu-latest, Node 22.x) ✅ success
web-shell E2E Smoke (ubuntu-latest, 22.x) ✅ success

One row per check name (latest run); skipped checks omitted; failures sort first. / 每个检查名一行(取最新一次运行),省略 skipped,失败项排在最前。

Sandboxed verification: landed green on exactly this head. The maintainer-triggered /verify run (actions/runs/32994114958) completed while this pass was preparing — verdict merge-ready, 60/60 scripted assertions. What prior passes were waiting on is now settled with evidence: the A/B proves the change load-bearing at 4bbf8eabd801 (base build still false-halts the #9450 oscillating poll @5; the PR build survives 120–150 polls; a frozen board still halts @5, base-parity, including the oversized-stub path that round-2's F2 escaped), and all four previous-round findings are fixed and test-pinned — mutation matrix 12/12 killed, 0 survivors, plus the flakiness gate (5 changed test files × 5 rounds, no divergence). One new nit-level Suggestion from that round (interleaved polling + missing result evidence leaves the cap's stuck signal unfed; bounded by the 1000-call hard backstop, unreachable with the current wiring) — non-blocking, noted in the risk section. A redundant second verify round (from the 18:21 /triage) is still in flight; it is advisory and covers the same head.

中文说明

4bbf8eabd801 上的代码审查(head 未变的第四次通过 —— 本次已重新追踪 diff 中的关键结论)

先给独立方案: 振荡轴我会按 repeat key 计连续相同结果数——结果与前驱不同即重置为 1——并把该计数同时喂给全局重复守卫与自适应上限的卡滞信号,这正是 f34098e6 的做法。超大结果轴我会把截断前完整输出的 sha256 嵌入持久化 stub、对摘要而非信封做指纹,并为没有摘要行的旧 stub 保留去路径预览回退——正是 4bbf8eabd801 的做法。我没有找到比 PR 更简的路径。

手工核实(静态审查——不执行 PR 代码):

  • 振荡修复(f34098e6)。 追踪 recordToolResultstatefulConsecutiveResults 在指纹与同 key 前驱不同时重置为 1,A/B/A/B 面板永远不超过 1,不会喂到 capMaxKeyRepeat 或受门控的全局重复计数;冻结面板即使与其他调用交错也持续累积(计数按 key 而非按相邻)。整回合的 statefulPairCounts 已从两个消费方移除。三个新回归测试钉住启发式开启模式、CLI 默认(skipLoopDetection=true)模式下越过 100 次软上限、以及交错冻结方向(仍触发 TURN_TOOL_CALL_CAP)。
  • 失败保持安全的数学不变 —— 本次重新推导。 第 N 次相同请求时,守卫要求 resultsObserved >= N-1 才信任该连续段;逐步验算:无证据 → 与修复前一致终止;部分证据(5 个请求只有 4 条结果)→ 终止;全部未变化 → 在与修复前相同的请求数处终止;任一结果变化 → 连续段重启。新测试钉住全部方向;DashScope 长程任务下,出现大量工具重复调用情况,导致会话被终止 #5019 的防护对非状态化工具与接线缺口均未被放松。
  • provider 重复 callId 去重(验证发现 3,已恢复)。 两个宿主都按 attempt 去重守卫喂入,与执行侧折叠对齐:agent-core.tsloopGuardStreamedCallIds(在 checkSubagentLoop 之前),client.tsloopGuardFedCallIds(同时门控 checkAlwaysOnSafetiesaddAndCheckHeuristicLoops)——重复事件本身仍流向下游消费者。两个集合在 retry/fallback 时随 attempt 状态一起清空;无 id 的调用永不去重,与 dedupeToolCallsById 一致。两个运行时均有端到端测试钉住。
  • 超大结果 stub 指纹(验证发现 2,已恢复)。 buildStub 现在嵌入完整截断前内容的 Full output sha256: <摘要>stripPersistenceEnvelope 在哈希前把 stub 归约为 <persisted-stub>sha256:<摘要>。识别锚定在生产者前缀开头,摘要行必须位于行首且恰为 64 位十六进制——同伴任务板内容中引用的 stub 标记不会被当作信封,板内容无法伪造信封路径(最坏情况仍受上限硬兜底约束)。无摘要的旧 stub 回退到去路径预览;预览窗口之外的变化由摘要覆盖。四个方向均有单元测试钉住。
  • 此前未被钉住的接线(验证发现 4 与第 16 轮评审的延迟项)现已钉住: client.test.ts 四个测试通过真实 sendMessageStream 回合驱动主会话 ToolResult 分支(冻结以 global_tool_call_duplicate 终止、变化存活、重复 id 去同步、去重后冻结仍终止);agent-interactive.test.ts 钉住停止信息中的检测器名;qwen-logger.test.ts 钉住日志 loop_type 的传播与无循环时的缺省。
  • 一个非阻塞的微观备注: 连续段内重置后 lastFingerprint 保留,新段首个结果若与重置前指纹相同会被计为"未变化",使 unchangedStreak 多 1。本次再次追踪确认:该膨胀只有在段内结果全部未变化时才能存活到终止判定(任何一次变化都会把计数重置为精确值),而那正是应当终止的情形。不存在可达的误杀;不值得改代码,但读这段代码时值得知道。

(时序图与文件清单见英文部分)

测试证据 —— PR 自身 CI,经 API 读取

无人值守运行:此处从不构建或执行 PR 代码。在 4bbf8eabd801 上 CI 已全部转绿——两个 pull_request 工作流运行(Security Checks 与含 ubuntu 单元套件的 Qwen Code CI)均成功、无失败;本次经 check-runs API 复核,与表格区域定稿后一致。此处未验证:真实模型的实时多 agent 运行(作者声明范围外);@wenshao 备注 7.3 的 DashScope 服务端重复发送问题仍未解决(任何沙箱通道都没有 provider 凭据)。

沙箱验证:已在当前 head 上落地为绿。 维护者触发的 /verify 运行(actions/runs/32994114958)在本轮准备期间完成——判定 merge-ready,脚本断言 60/60 全过。此前各次等待的内容现已有证据落地:A/B 证实该改动在 4bbf8eabd801 上载荷成立(基线构建对 #9450 的振荡轮询仍在第 5 次误杀;PR 构建 120–150 次轮询不终止;冻结面板仍在第 5 次终止、与基线一致,包括第二轮 F2 曾逃逸的超大结果 stub 路径),且上一轮全部 4 个发现均已修复并被测试钉住——变异矩阵 12/12 全杀、零幸存,抖动门亦通过(5 个变更测试文件 × 5 轮无分歧)。该轮新增一条微瑕级 Suggestion(交错轮询 + 缺失结果证据时上限卡滞信号不再喂入;受 1000 次硬兜底约束,现网接线下不可达)——非阻塞,已记入风险节。另有一轮冗余的第二次验证(来自 18:21 的 /triage)仍在进行;仅为咨询性证据,覆盖同一 head。

Qwen Code · qwen3.8-max

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

@qwen-code-ci-bot

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

Copy link
Copy Markdown
Collaborator

Confidence: 4/5 — solid; approving. The remaining items are non-blocking nits (named below), and the two things that kept prior passes at 3/5 are both resolved this pass.

Stepping back: this is the fourth pass on an unchanged head, and it's the first one where the evidence position is complete. The independent A/B I was waiting on landed green on exactly this head while this run was preparing — verdict merge-ready, 60/60 scripted assertions, all four previous-round findings fixed and test-pinned (mutation matrix 12/12 killed), flakiness gate clean. It proves the change load-bearing: the base build still false-halts the #9450 oscillating poll at the 5th request; this PR's build survives 120–150 polls of a changing board while a frozen board still halts at base parity, including the oversized-stub escape that earlier rounds caught. I re-traced the load-bearing code paths myself this pass (fail-safe streak arithmetic, per-key consecutive result counting, the anchored stub digest, the per-attempt callId feed dedup on both owners) and found nothing new to flag — the implementation matches my independent proposal and I did not find a simpler path it missed.

The second change this pass is a policy correction. Prior passes capped this at 3/5 citing the 500-production-line maintainer-awareness threshold. That threshold is part of the two-tier core gate, which exists to protect core infrastructure from external PRs — maintainer-authored PRs are explicitly exempt, and this PR's author is a repo admin. Deferring a verified, green, maintainer-authored fix over a gate that doesn't apply to it protects nothing; it just parks the merge decision on a human for no reason. So the cap comes off.

What's left, honestly named — none of it blocking:

  1. @wenshao's note 7.2, one line: the description still doesn't spell out that the Full output sha256: digest line is product-wide and model-visible (every oversized tool result, not just task_list). Worth a sentence next time the description is touched; not worth another review round.
  2. Note 7.3 (server-side re-emission bound under a live provider) stays open — no sandboxed lane has provider credentials, and the PR's risk section already owns it.
  3. The verify round's new nit: interleaved polling + missing result evidence leaves the cap's stuck signal unfed until the 1000-call hard backstop. Unreachable with the current wiring (both owners record results; the daemon has its own tracker), and the report rates it nit-level.
  4. The round-16 bot CHANGES_REQUESTED review (against the predecessor head dfadc01b19) — every deferred finding from it is test-covered on this head and re-measured by the A/B. This approval supersedes it as the bot's latest review state.

For the maintainer taking the merge: main requires two approvals, so this bot approval is one of the two votes. The daemon-side twin of the cap's stuck signal is tracked in #10161.

中文说明

置信度:4/5 —— 扎实;予以批准。剩余项均为非阻塞微瑕(列于下方);此前各次停在 3/5 的两件事本轮均已解决。

退一步看:这是 head 未变下的第四次通过,也是第一次证据面完整的一次。此前等待的独立 A/B 已在当前 head 上落地为绿——判定 merge-ready,脚本断言 60/60,上一轮全部 4 个发现均已修复并被测试钉住(变异矩阵 12/12 全杀),抖动门干净。它证实该改动载荷成立:基线构建对 #9450 的振荡轮询仍在第 5 次请求误杀;本 PR 构建在面板持续变化时 120–150 次轮询不终止,冻结面板则与基线一致地终止,包括早前各轮发现的超大结果 stub 逃逸路径。本次我亲自重新追踪了关键代码路径(失败安全的连续段算术、按 key 的连续结果计数、锚定的 stub 摘要、两个宿主上按 attempt 的 callId 喂入去重),没有新问题——实现与我的独立方案一致,我也没有找到它遗漏的更简路径。

本次的第二处变化是策略更正。此前各次以"500 行生产代码的维护者关注阈值"将本 PR 封顶在 3/5。该阈值属于两层核心门禁,其目的是保护核心基础设施免受外部 PR 影响——维护者自己提交的 PR 明确豁免,而本 PR 作者是仓库 admin。用一个不适用于本 PR 的门禁去推迟一个已验证、全绿、维护者亲自提交的修复,没有保护任何东西,只是无谓地把合并决定压给人工。因此取消该封顶。

如实列出剩余项——均不阻塞:

  1. @wenshao 备注 7.2 还差一句:描述仍未写明 Full output sha256: 摘要行是全产品范围且模型可见的(每一份超大工具结果都会带,而不只是 task_list)。下次动描述时补一句即可,不值得再开一轮审查。
  2. 备注 7.3(真实 provider 下的服务端重复发送上限)仍未解决——任何沙箱通道都没有 provider 凭据,PR 的风险章节已认领该项。
  3. 验证轮新增的微瑕:交错轮询 + 缺失结果证据时,上限的卡滞信号不再喂入,直到 1000 次硬兜底。现网接线下不可达(两个宿主都记录结果;守护进程有独立追踪器),报告评级为微瑕。
  4. 第 16 轮机器人的 CHANGES_REQUESTED 评审(针对前驱 head dfadc01b19)——其中全部延迟发现已由本 head 的测试覆盖并经 A/B 复核。本批准作为该机器人账号的最新评审状态,取代该评审。

对接手合并的维护者:main 要求两个批准,机器人批准是两票之一。上限卡滞信号的 daemon 侧孪生实现在 #10161 跟踪。

Qwen Code · qwen3.8-max

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

@github-actions

github-actions Bot commented Aug 19, 2026

Copy link
Copy Markdown
Contributor

Code Coverage Summary

Package Lines Statements Functions Branches
CLI 85.67% 85.67% 91.06% 84.63%
Core 88.77% 88.77% 90.53% 87.19%
CLI Package - Full Text Report
-------------------|---------|----------|---------|---------|-------------------
File               | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
-------------------|---------|----------|---------|---------|-------------------
All files          |   85.67 |    84.63 |   91.06 |   85.67 |                   
 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.8 |   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.81 |   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.3 |   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.77 |   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 |    86.01 |   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.73 |   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 |     87.5 |     100 |     100 | 18                
  new.ts           |     100 |      100 |     100 |     100 |                   
  settings.ts      |   99.15 |      100 |   83.33 |   99.15 | 151               
  sources.ts       |   93.42 |    87.09 |   92.85 |   93.42 | ...4-66,96-98,167 
  uninstall.ts     |   74.57 |       40 |   66.66 |   74.57 | 45-47,60-67,70-73 
  update.ts        |   96.71 |    97.05 |     100 |   96.71 | 114-118           
  utils.ts         |   75.63 |    55.55 |     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.02 |   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.75 |   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.11 |     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.97 |   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.38 |   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.46 |   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 |    77.41 |     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.1 |    84.16 |   87.81 |    86.1 |                   
  ...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 |   87.63 |    84.43 |   78.72 |   87.63 | ...5813-5815,5817 
  ...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 |      52 |    63.63 |     100 |      52 | ...59,67-70,76-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.19 |     100 |   97.12 | ...92-193,247-250 
  ...sionPicker.ts |   92.87 |    90.35 |     100 |   92.87 | ...99-501,503-505 
  ...earchInput.ts |     100 |    97.29 |     100 |     100 | 82                
  ...ngsCommand.ts |   18.75 |      100 |       0 |   18.75 | 10-25             
  ...ellHistory.ts |   93.28 |    80.95 |     100 |   93.28 | ...96,153-154,164 
  ...oryCommand.ts |   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 |       70 |     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
-------------------|---------|----------|---------|---------|-------------------
File               | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
-------------------|---------|----------|---------|---------|-------------------
All files          |   88.77 |    87.19 |   90.53 |   88.77 |                   
 src               |     100 |      100 |     100 |     100 |                   
  index.ts         |     100 |      100 |     100 |     100 |                   
 src/__mocks__/fs  |       0 |        0 |       0 |       0 |                   
  promises.ts      |       0 |        0 |       0 |       0 | 1-48              
 src/agents        |   90.26 |    84.51 |   94.55 |   90.26 |                   
  ...transcript.ts |   88.49 |    84.09 |     100 |   88.49 | ...32,640,646-650 
  ...ent-resume.ts |   85.74 |       78 |    85.1 |   85.74 | ...1803-1807,1810 
  ...ound-tasks.ts |   95.19 |    90.75 |   96.42 |   95.19 | ...1889,1897-1898 
  forkedAgent.ts   |   93.21 |    83.47 |   94.44 |   93.21 | ...94,702,707-714 
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...ent-result.ts |    96.8 |    92.68 |     100 |    96.8 | 106,129-131       
  ...n-registry.ts |   95.27 |    88.23 |   98.33 |   95.27 | ...1478,1492-1494 
  ...w-snapshot.ts |   75.73 |    72.22 |    87.5 |   75.73 | ...21,445,452-454 
  worktree-pin.ts  |     100 |    88.23 |     100 |     100 | 78,99             
 src/agents/arena  |   76.87 |    68.43 |   78.94 |   76.87 |                   
  ...gentClient.ts |   79.47 |    88.88 |   81.81 |   79.47 | ...68-183,189-204 
  ArenaManager.ts  |    75.8 |    65.46 |   78.57 |    75.8 | ...1879,1885-1886 
  arena-events.ts  |   64.44 |      100 |      50 |   64.44 | ...71-175,178-183 
  diff-summary.ts  |    87.5 |    72.34 |     100 |    87.5 | ...32-133,137-138 
  index.ts         |     100 |      100 |     100 |     100 |                   
  types.ts         |     100 |      100 |     100 |     100 |                   
 ...gents/backends |   77.32 |    86.38 |   75.52 |   77.32 |                   
  ITermBackend.ts  |   97.97 |    93.93 |     100 |   97.97 | ...78-180,255,307 
  ...essBackend.ts |   91.45 |    90.21 |   96.87 |   91.45 | ...66-467,586-592 
  TmuxBackend.ts   |    90.7 |    76.55 |   97.36 |    90.7 | ...87,697,743-747 
  detect.ts        |   31.25 |      100 |       0 |   31.25 | 34-88             
  index.ts         |     100 |      100 |     100 |     100 |                   
  iterm-it2.ts     |     100 |     92.1 |     100 |     100 | 37-38,106         
  tmux-commands.ts |    6.64 |      100 |    3.03 |    6.64 | ...93-363,386-503 
  types.ts         |     100 |      100 |     100 |     100 |                   
 ...agents/runtime |   93.43 |     87.5 |   92.44 |   93.43 |                   
  agent-context.ts |     100 |      100 |     100 |     100 |                   
  agent-core.ts    |   90.33 |    80.45 |   81.25 |   90.33 | ...2628,2674-2676 
  agent-events.ts  |     100 |      100 |     100 |     100 |                   
  ...t-headless.ts |   93.67 |       90 |   83.33 |   93.67 | ...13-514,517-518 
  ...nteractive.ts |   82.86 |    84.93 |   76.66 |   82.86 | ...35,537,544,549 
  ...statistics.ts |   98.29 |    82.55 |     100 |   98.29 | 141,165,206,239   
  agent-types.ts   |     100 |      100 |     100 |     100 |                   
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...ool-policy.ts |   98.38 |      100 |    92.3 |   98.38 | 85-86             
  ...low-budget.ts |     100 |      100 |     100 |     100 |                   
  ...-scheduler.ts |   97.43 |    96.36 |     100 |   97.43 | 128-130           
  ...ow-journal.ts |   92.78 |    78.12 |     100 |   92.78 | ...49-150,192-194 
  ...ta-literal.ts |   95.96 |    92.68 |     100 |   95.96 | ...78-379,395-396 
  ...chestrator.ts |   93.85 |    90.47 |     100 |   93.85 | ...2206,2299-2302 
  ...ow-prompts.ts |     100 |      100 |     100 |     100 |                   
  ...low-runner.ts |   95.77 |    84.16 |      95 |   95.77 | ...88,356,376-379 
  ...ow-sandbox.ts |   97.29 |    88.84 |     100 |   97.29 | ...1835,1841-1842 
  ...flow-saved.ts |    96.7 |     93.9 |     100 |    96.7 | 153-154,261-264   
  ...flow-stall.ts |    97.9 |    83.33 |     100 |    97.9 | 170-171,270       
 src/agents/tasks  |     100 |      100 |     100 |     100 |                   
  types.ts         |     100 |      100 |     100 |     100 |                   
 src/agents/team   |   84.84 |     85.8 |   91.09 |   84.84 |                   
  TeamManager.ts   |   78.24 |    83.78 |   84.12 |   78.24 | ...1907,1930-1931 
  identity.ts      |     100 |      100 |     100 |     100 |                   
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...sionBridge.ts |     100 |      100 |     100 |     100 |                   
  mailbox.ts       |   96.02 |     87.5 |     100 |   96.02 | 352-358           
  ...ptAddendum.ts |     100 |      100 |     100 |     100 |                   
  tasks.ts         |   89.29 |       83 |     100 |   89.29 | ...1000,1044-1045 
  team-events.ts   |   73.68 |      100 |   66.66 |   73.68 | 140-144,151-155   
  teamHelpers.ts   |    92.5 |    95.45 |      95 |    92.5 | ...29-330,393-403 
  types.ts         |     100 |      100 |     100 |     100 |                   
 ...eam/test-utils |   95.28 |    95.34 |   98.24 |   95.28 |                   
  ...on-harness.ts |   96.49 |    85.71 |     100 |   96.49 | 128-129,141-142   
  fake-agent.ts    |     100 |    96.96 |     100 |     100 | 189,198           
  fake-backend.ts  |   86.46 |    97.61 |   95.83 |   86.46 | 124-146           
 src/config        |   86.19 |    88.32 |    78.3 |   86.19 |                   
  approval-mode.ts |     100 |      100 |     100 |     100 |                   
  ...xtDefaults.ts |     100 |      100 |     100 |     100 |                   
  config.ts        |   84.88 |    87.73 |   76.27 |   84.88 | ...9619,9623-9625 
  ...ionManager.ts |     100 |     90.9 |     100 |     100 | 27                
  models.ts        |     100 |      100 |     100 |     100 |                   
  ...sDiscovery.ts |   97.46 |    93.05 |     100 |   97.46 | ...04,182-183,202 
  storage.ts       |   96.05 |    93.43 |   89.47 |   96.05 | ...34-735,738-739 
 ...nfirmation-bus |   98.27 |    97.22 |     100 |   98.27 |                   
  message-bus.ts   |   98.14 |    97.14 |     100 |   98.14 | 42-43             
  types.ts         |     100 |      100 |     100 |     100 |                   
 src/core          |   92.84 |    88.64 |   93.87 |   92.84 |                   
  ...on-restore.ts |   88.23 |    85.41 |     100 |   88.23 | ...60,63-64,67-68 
  baseLlmClient.ts |    88.4 |    83.68 |   81.81 |    88.4 | ...59,672,678-680 
  client.ts        |   92.43 |    88.26 |   91.83 |   92.43 | ...4629,4727-4728 
  ...tGenerator.ts |   87.45 |    88.09 |   88.88 |   87.45 | ...08-509,554-560 
  ...lScheduler.ts |   90.22 |    84.96 |   94.73 |   90.22 | ...6488,6516-6532 
  ...entContext.ts |   96.63 |    90.13 |   96.66 |   96.63 | ...42,444-445,512 
  geminiChat.ts    |     100 |      100 |     100 |     100 |                   
  geminiRequest.ts |     100 |      100 |     100 |     100 |                   
  genai-compat.ts  |     100 |      100 |     100 |     100 |                   
  ...MediaLimit.ts |     100 |       96 |     100 |     100 | 96                
  ...htProtocol.ts |    9.09 |      100 |       0 |    9.09 | ...9,62-66,69-110 
  ...ream-error.ts |     100 |      100 |     100 |     100 |                   
  llm-chat.ts      |   95.21 |    90.81 |   96.69 |   95.21 | ...5744,5789-5790 
  llm-request.ts   |     100 |      100 |     100 |     100 |                   
  logger.ts        |   87.41 |    87.02 |     100 |   87.41 | ...64-568,614-628 
  ...lay-buffer.ts |     100 |      100 |     100 |     100 |                   
  ...dispatcher.ts |     100 |      100 |     100 |     100 |                   
  ...tyDefaults.ts |     100 |      100 |     100 |     100 |                   
  ...olExecutor.ts |   93.54 |    83.33 |      50 |   93.54 | 46-47             
  output-styles.ts |     100 |      100 |     100 |     100 |                   
  ...on-helpers.ts |   95.38 |    84.31 |     100 |   95.38 | ...87,215,217-218 
  ...issionFlow.ts |   98.98 |    96.96 |     100 |   98.98 | 109               
  ...try-policy.ts |     100 |      100 |     100 |     100 |                   
  ...ell-policy.ts |   94.89 |    88.54 |     100 |   94.89 | ...51-252,297-298 
  prompts.ts       |   93.89 |    91.12 |      85 |   93.89 | ...1272,1475-1476 
  ...ing-effort.ts |     100 |      100 |     100 |     100 |                   
  ...n-recovery.ts |   95.13 |       80 |     100 |   95.13 | ...06-107,142-144 
  ...t-profiler.ts |    97.9 |    81.15 |   88.23 |    97.9 | 117,124-125,130   
  ...port-retry.ts |     100 |      100 |     100 |     100 |                   
  tokenLimits.ts   |     100 |    91.89 |     100 |     100 | 87,122-139        
  ...-arguments.ts |     100 |      100 |     100 |     100 |                   
  ...reparation.ts |     100 |      100 |     100 |     100 |                   
  ...tion-guard.ts |   90.38 |    94.73 |     100 |   90.38 | 83-87             
  ...allIdUtils.ts |   98.81 |    91.22 |     100 |   98.81 | 43,52             
  ...okTriggers.ts |   99.45 |     92.5 |     100 |   99.45 | 182,193           
  ...terruption.ts |     100 |     92.3 |     100 |     100 | 86,104            
  turn.ts          |   99.19 |    94.48 |     100 |   99.19 | 765-766,835       
  ...l-fallback.ts |     100 |      100 |     100 |     100 |                   
 ...ntentGenerator |   96.58 |    89.11 |   97.43 |   96.58 |                   
  ...tGenerator.ts |   97.66 |    88.91 |   97.43 |   97.66 | ...1494,1523,1534 
  converter.ts     |   96.19 |    89.25 |     100 |   96.19 | ...1334,1555-1557 
  index.ts         |       0 |        0 |       0 |       0 | 1-21              
  usage.ts         |     100 |      100 |     100 |     100 |                   
 ...ntentGenerator |     100 |      100 |     100 |     100 |                   
  ...tGenerator.ts |     100 |      100 |     100 |     100 |                   
  index.ts         |     100 |      100 |     100 |     100 |                   
 ...tent-generator |   89.24 |    72.72 |   94.11 |   89.24 |                   
  index.ts         |     100 |    85.71 |     100 |     100 | 51                
  ...-generator.ts |   87.54 |    71.42 |   93.75 |   87.54 | ...93-294,356-362 
 ...ntentGenerator |   95.78 |    90.51 |   96.22 |   95.78 |                   
  ...e-snapshot.ts |   97.39 |    89.65 |     100 |   97.39 | ...,49-50,151-152 
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...tGenerator.ts |   95.38 |    90.14 |   95.12 |   95.38 | ...1345-1346,1374 
  ...tDetection.ts |     100 |      100 |     100 |     100 |                   
 ...ntentGenerator |   92.33 |    90.93 |   96.58 |   92.33 |                   
  constants.ts     |     100 |      100 |     100 |     100 |                   
  converter.ts     |   91.25 |    89.66 |   96.87 |   91.25 | ...1946,2115-2130 
  errorHandler.ts  |     100 |      100 |     100 |     100 |                   
  index.ts         |   76.19 |    88.88 |      50 |   76.19 | 44-53,90-94       
  ...tGenerator.ts |      70 |    73.33 |     100 |      70 | ...07-112,121-127 
  pipeline.ts      |   95.38 |    91.56 |     100 |   95.38 | ...1461-1462,1569 
  ...ix-caching.ts |   95.23 |    92.85 |     100 |   95.23 | 45-46,69-70       
  ...ureContext.ts |     100 |      100 |     100 |     100 |                   
  ...ingOptions.ts |       0 |        0 |       0 |       0 | 1                 
  ...CallParser.ts |   92.11 |    92.25 |     100 |   92.11 | ...21-522,542-545 
  ...kingParser.ts |     100 |    96.87 |     100 |     100 | 42                
  types.ts         |       0 |        0 |       0 |       0 | 1                 
 ...rator/provider |   97.24 |       92 |   98.64 |   97.24 |                   
  dashscope.ts     |   98.42 |    95.27 |   96.55 |   98.42 | ...51-752,894-895 
  deepseek.ts      |   95.34 |    90.56 |     100 |   95.34 | ...54-155,168-169 
  default.ts       |   98.87 |       96 |     100 |   98.87 | 178,304           
  index.ts         |     100 |      100 |     100 |     100 |                   
  mimo.ts          |   94.11 |    66.66 |     100 |   94.11 | 29,52-53          
  minimax.ts       |     100 |      100 |     100 |     100 |                   
  mistral.ts       |   96.07 |    73.33 |     100 |   96.07 | 32-33             
  modelscope.ts    |     100 |      100 |     100 |     100 |                   
  openrouter.ts    |     100 |      100 |     100 |     100 |                   
  types.ts         |       0 |        0 |       0 |       0 |                   
  utils.ts         |     100 |      100 |     100 |     100 |                   
  zai.ts           |      90 |    76.31 |     100 |      90 | ...,72-73,173-175 
 src/extension     |   88.79 |    86.22 |   93.46 |   88.79 |                   
  ...ive-safety.ts |   97.77 |    93.75 |     100 |   97.77 | 100-101           
  ...-converter.ts |   80.55 |    73.66 |     100 |   80.55 | ...1133,1179-1180 
  corruptFile.ts   |     100 |       50 |     100 |     100 | 40-45             
  ...-converter.ts |     100 |      100 |     100 |     100 |                   
  ...git-client.ts |     100 |      100 |     100 |     100 |                   
  ...redentials.ts |   95.33 |    89.47 |     100 |   95.33 | ...21-122,173-175 
  ...me-refresh.ts |     100 |      100 |     100 |     100 |                   
  ...sion-store.ts |   92.82 |    89.27 |    98.3 |   92.82 | ...1641-1647,1691 
  ...ionManager.ts |   84.52 |    83.52 |      83 |   84.52 | ...3139,3177-3178 
  ...references.ts |     100 |     90.9 |     100 |     100 | ...05,129,197,200 
  ...onSettings.ts |    92.3 |     94.4 |     100 |    92.3 | ...98-501,570-571 
  ...-converter.ts |    75.9 |    85.71 |   85.71 |    75.9 | ...98,202,214-248 
  github.ts        |   92.43 |    87.52 |     100 |   92.43 | ...1293-1294,1304 
  http-client.ts   |   84.61 |       80 |     100 |   84.61 | 20-21             
  i18n.ts          |   78.26 |       96 |      50 |   78.26 | 104-110,116-123   
  index.ts         |     100 |      100 |     100 |     100 |                   
  marketplace.ts   |   88.39 |    83.11 |     100 |   88.39 | ...08,494,507-508 
  ...ork-policy.ts |   89.72 |    90.16 |     100 |   89.72 | ...36,148-154,156 
  npm.ts           |   89.02 |    81.81 |     100 |   89.02 | ...86-688,695-700 
  override.ts      |   94.11 |    93.54 |     100 |   94.11 | 63-64,81-82       
  ...-converter.ts |   94.89 |    90.41 |     100 |   94.89 | ...50-151,222-224 
  redaction.ts     |     100 |      100 |     100 |     100 |                   
  settings.ts      |   66.26 |      100 |      50 |   66.26 | 81-107,141-146    
  ...ceRegistry.ts |   94.01 |    83.33 |     100 |   94.01 | ...38-344,365-366 
  storage.ts       |     100 |      100 |     100 |     100 |                   
  ...ableSchema.ts |     100 |      100 |     100 |     100 |                   
  variables.ts     |   88.95 |    84.21 |     100 |   88.95 | ...32-235,238-241 
  ...extraction.ts |   85.77 |       81 |   89.47 |   85.77 | ...02-205,260-261 
 ...ent-plugins-v1 |   84.94 |    79.51 |     100 |   84.94 |                   
  index.ts         |     100 |      100 |     100 |     100 |                   
  manifest.ts      |   81.87 |    84.48 |     100 |   81.87 | ...55-156,161-174 
  mcp.ts           |   84.98 |    79.56 |     100 |   84.98 | ...88-389,419-420 
  paths.ts         |     100 |    94.44 |     100 |     100 | 59                
  skills.ts        |   82.31 |    63.88 |     100 |   82.31 | ...38-141,150-151 
 src/followup      |   84.78 |    82.27 |   86.84 |   84.78 |                   
  followupState.ts |   98.44 |    95.74 |     100 |   98.44 | 236-237           
  index.ts         |     100 |      100 |     100 |     100 |                   
  overlayFs.ts     |   96.29 |    88.88 |     100 |   96.29 | 78,108,122        
  speculation.ts   |   76.53 |    71.96 |   58.33 |   76.53 | ...48-749,756-757 
  ...onToolGate.ts |   97.97 |     87.5 |     100 |   97.97 | 105,110           
  ...nGenerator.ts |   86.11 |    87.17 |     100 |   86.11 | ...39-244,356-358 
 src/generated     |       0 |        0 |       0 |       0 |                   
  git-commit.ts    |       0 |        0 |       0 |       0 | 1-10              
 src/goals         |   93.59 |    90.38 |      95 |   93.59 |                   
  ...eGoalStore.ts |   87.61 |    88.88 |   86.66 |   87.61 | ...85-188,196-204 
  ...t-verifier.ts |   99.45 |    97.05 |     100 |   99.45 | 155               
  ...checkpoint.ts |   86.08 |    85.18 |     100 |   86.08 | ...29-132,142-145 
  ...ion-prompt.ts |     100 |      100 |     100 |     100 |                   
  goal-evidence.ts |    88.7 |     88.2 |   97.67 |    88.7 | ...1219,1242-1245 
  ...projection.ts |   66.66 |    72.97 |   33.33 |   66.66 | ...87,190,194-196 
  ...ersistence.ts |   87.36 |    85.96 |    87.5 |   87.36 | ...53-154,185-190 
  goal-protocol.ts |   97.56 |    96.42 |     100 |   97.56 | 322-323           
  goal-reducer.ts  |   95.75 |    93.82 |   97.36 |   95.75 | ...76,666,684-685 
  goal-runtime.ts  |   96.51 |    90.64 |   96.49 |   96.51 | ...1645-1646,1777 
  ...provenance.ts |     100 |      100 |     100 |     100 |                   
  goal-tools.ts    |   98.58 |     95.2 |   96.15 |   98.58 | ...41-242,350-351 
  ...rn-context.ts |     100 |      100 |     100 |     100 |                   
  goal-verifier.ts |   92.46 |    93.02 |     100 |   92.46 | ...69-172,185-187 
  goal-wire.ts     |       0 |        0 |       0 |       0 | 1-28              
  goalHook.ts      |   96.91 |    92.42 |     100 |   96.91 | 115-120,221-222   
  goalJudge.ts     |   95.84 |    87.09 |     100 |   95.84 | ...55-356,448-449 
  index.ts         |     100 |      100 |     100 |     100 |                   
 src/hooks         |   89.12 |     87.1 |    89.8 |   89.12 |                   
  ...okRegistry.ts |   86.48 |    77.08 |     100 |   86.48 | ...41-344,362-369 
  ...bortSignal.ts |     100 |      100 |     100 |     100 |                   
  context-usage.ts |     100 |      100 |     100 |     100 |                   
  ...terpolator.ts |   96.66 |    93.33 |     100 |   96.66 | 66-67             
  ...HookRunner.ts |   96.68 |    87.23 |     100 |   96.68 | 110-112,231-233   
  ...Aggregator.ts |   96.57 |    91.48 |     100 |   96.57 | ...20-321,402,404 
  ...entHandler.ts |   95.57 |    84.76 |   94.73 |   95.57 | ...1040-1041,1051 
  hookPlanner.ts   |   87.55 |    85.54 |   86.66 |   87.55 | ...22-226,233-244 
  hookRegistry.ts  |   92.53 |    85.43 |     100 |   92.53 | ...39,458,462,466 
  hookRunner.ts    |   75.58 |    83.23 |   87.87 |   75.58 | ...25-927,937-940 
  hookSystem.ts    |   87.64 |     98.5 |   70.83 |   87.64 | ...58-759,765-766 
  ...HookRunner.ts |   79.06 |    66.66 |      80 |   79.06 | ...33-434,452-456 
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...edCallback.ts |     100 |      100 |     100 |     100 |                   
  ...HookRunner.ts |   94.19 |    84.37 |   81.81 |   94.19 | ...76-384,458-459 
  ...SkillHooks.ts |   82.47 |    84.21 |      75 |   82.47 | 63-67,169-184     
  ...oksManager.ts |   94.87 |    90.12 |     100 |   94.87 | ...84,325,327-329 
  ssrfGuard.ts     |   86.45 |    89.13 |     100 |   86.45 | ...85,289-295,301 
  stopHookCap.ts   |     100 |      100 |     100 |     100 |                   
  trustedHooks.ts  |      90 |    52.63 |     100 |      90 | ...53,66-67,97-98 
  types.ts         |   94.25 |    96.09 |   88.88 |   94.25 | ...46-547,632-636 
  urlValidator.ts  |     100 |      100 |     100 |     100 |                   
  ...it-context.ts |     100 |      100 |     100 |     100 |                   
 src/ide           |   76.98 |    85.03 |   79.03 |   76.98 |                   
  constants.ts     |     100 |      100 |     100 |     100 |                   
  detect-ide.ts    |     100 |      100 |     100 |     100 |                   
  ide-client.ts    |   69.16 |    84.65 |   68.29 |   69.16 | ...1068,1097-1105 
  ide-installer.ts |   89.06 |    79.31 |     100 |   89.06 | ...36,143-147,160 
  ideContext.ts    |     100 |      100 |     100 |     100 |                   
  process-utils.ts |   84.84 |    71.79 |     100 |   84.84 | ...37,151,193-194 
  types.ts         |     100 |      100 |     100 |     100 |                   
 src/ipc           |   92.72 |    90.15 |    97.5 |   92.72 |                   
  inbound-gate.ts  |   98.93 |     89.1 |     100 |   98.93 | 522-524           
  peer-envelope.ts |     100 |      100 |     100 |     100 |                   
  peer-frames.ts   |   97.45 |    93.65 |     100 |   97.45 | 235-237           
  socket-path.ts   |   85.71 |    93.33 |     100 |   85.71 | 83-88             
  uds-client.ts    |   85.71 |    94.11 |      80 |   85.71 | 162-175           
  uds-inbox.ts     |   82.42 |    81.81 |     100 |   82.42 | ...33,240-250,282 
 src/lsp           |   58.96 |    70.67 |   66.49 |   58.96 |                   
  ...nfigLoader.ts |   80.55 |    72.22 |   95.65 |   80.55 | ...02-504,508-514 
  ...ionFactory.ts |   42.81 |    73.07 |      50 |   42.81 | ...76-427,433-450 
  ...Normalizer.ts |   23.09 |    13.72 |   30.43 |   23.09 | ...04-905,909-924 
  ...verManager.ts |   75.73 |     80.1 |   79.66 |   75.73 | ...1346,1352-1382 
  ...eLspClient.ts |   32.78 |    81.81 |   21.05 |   32.78 | ...89-293,299-300 
  ...LspService.ts |      60 |    73.36 |   78.26 |      60 | ...1575,1635-1645 
  configHash.ts    |     100 |      100 |     100 |     100 |                   
  constants.ts     |     100 |      100 |     100 |     100 |                   
  types.ts         |     100 |      100 |     100 |     100 |                   
 src/mcp           |    82.3 |    77.81 |   78.33 |    82.3 |                   
  configHash.ts    |     100 |      100 |     100 |     100 |                   
  constants.ts     |     100 |      100 |     100 |     100 |                   
  ...h-provider.ts |   86.95 |      100 |   33.33 |   86.95 | ...,93,97,101-102 
  ...h-provider.ts |   79.31 |    58.06 |     100 |   79.31 | ...26-933,940-942 
  ...en-storage.ts |   98.78 |    97.95 |     100 |   98.78 | 106-107           
  oauth-utils.ts   |   73.61 |    85.48 |    92.3 |   73.61 | ...46-366,392-421 
  ...n-provider.ts |   89.83 |       96 |   45.45 |   89.83 | ...43,147,151-152 
 .../token-storage |   82.12 |    88.48 |   89.28 |   82.12 |                   
  ...en-storage.ts |     100 |      100 |     100 |     100 |                   
  ...en-storage.ts |   87.08 |    87.71 |   95.23 |   87.08 | ...00-201,214-215 
  ...en-storage.ts |     100 |      100 |     100 |     100 |                   
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...en-storage.ts |   68.14 |    82.35 |   64.28 |   68.14 | ...81-295,298-314 
  types.ts         |     100 |      100 |     100 |     100 |                   
 src/memory        |    89.3 |    85.28 |   92.03 |    89.3 |                   
  ...y-document.ts |   89.52 |    84.61 |     100 |   89.52 | ...24-325,329-330 
  ...nel-memory.ts |   97.36 |    96.63 |   96.42 |   97.36 | ...91-293,367-368 
  dream.ts         |    64.6 |    72.22 |      50 |    64.6 | ...04-109,124-165 
  ...entPlanner.ts |     100 |    83.33 |     100 |     100 | 135,145           
  entries.ts       |   75.59 |    84.84 |   83.33 |   75.59 | ...56-157,172-180 
  extract.ts       |   93.82 |    84.09 |     100 |   93.82 | 78-83,122,154-157 
  ...entPlanner.ts |   91.55 |    76.74 |     100 |   91.55 | ...05,118-121,296 
  ...ionPlanner.ts |       0 |        0 |       0 |       0 | 1                 
  forget.ts        |   90.16 |    78.76 |   94.44 |   90.16 | ...06,629,642-648 
  indexer.ts       |   94.14 |       84 |     100 |   94.14 | ...32-233,334,337 
  ...kill-agent.ts |   97.94 |    89.36 |     100 |   97.94 | 82-83,179-180     
  manager.ts       |   78.51 |    83.16 |   77.77 |   78.51 | ...1487,1500-1502 
  ...ent-config.ts |    91.3 |    83.73 |   91.66 |    91.3 | ...07,416-417,421 
  memoryAge.ts     |   90.47 |    83.33 |     100 |   90.47 | 50-51             
  ...yDiscovery.ts |   93.48 |    90.09 |     100 |   93.48 | ...42,401,629-632 
  paths.ts         |     100 |      100 |     100 |     100 |                   
  ...ing-skills.ts |     100 |       72 |     100 |     100 | 31-35,73-78,97    
  prompt.ts        |   97.26 |    86.79 |     100 |   97.26 | ...10-218,222,225 
  recall.ts        |   86.86 |    86.23 |   92.85 |   86.86 | ...33-538,571-582 
  refresh.ts       |   93.58 |    89.58 |     100 |   93.58 | ...75-176,183-184 
  ...ceSelector.ts |    93.2 |    85.71 |     100 |    93.2 | ...45-146,148-149 
  remember.ts      |   98.88 |    90.38 |     100 |   98.88 | 50,70             
  scan.ts          |   93.75 |       80 |     100 |   93.75 | ...08-109,154,157 
  scopes.ts        |     100 |      100 |     100 |     100 |                   
  ...et-scanner.ts |     100 |      100 |     100 |     100 |                   
  ...entPlanner.ts |   79.76 |    76.84 |      80 |   79.76 | ...69-473,476,482 
  status.ts        |   10.52 |      100 |       0 |   10.52 | 41-98             
  store.ts         |   92.92 |    81.81 |     100 |   92.92 | ...16-117,147-148 
  ...git-status.ts |     100 |    85.71 |     100 |     100 | 27                
  ...cret-guard.ts |     100 |      100 |     100 |     100 |                   
  ...emory-sync.ts |   94.24 |    82.85 |     100 |   94.24 | ...34-236,246-247 
  types.ts         |     100 |      100 |     100 |     100 |                   
  ...ontextFile.ts |   81.21 |    81.53 |   81.81 |   81.21 | ...66-280,294-299 
 src/mocks         |       0 |        0 |       0 |       0 |                   
  msw.ts           |       0 |        0 |       0 |       0 | 1-9               
 src/models        |   92.82 |    89.39 |   91.35 |   92.82 |                   
  constants.ts     |     100 |      100 |     100 |     100 |                   
  ...tor-config.ts |   97.77 |    91.83 |     100 |   97.77 | 155,161,171       
  ...capability.ts |     100 |      100 |     100 |     100 |                   
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...nfigErrors.ts |   79.43 |    64.51 |   85.71 |   79.43 | ...,89-96,131-142 
  ...igResolver.ts |   98.71 |    93.33 |     100 |   98.71 | 166,328,334       
  modelRegistry.ts |     100 |    98.11 |     100 |     100 | 177,262           
  modelsConfig.ts  |   89.36 |    86.93 |   88.09 |   89.36 | ...1407,1436-1437 
  types.ts         |     100 |      100 |     100 |     100 |                   
 src/output        |     100 |      100 |     100 |     100 |                   
  ...-formatter.ts |     100 |      100 |     100 |     100 |                   
  types.ts         |     100 |      100 |     100 |     100 |                   
 src/permissions   |   84.29 |    91.44 |   71.54 |   84.29 |                   
  autoMode.ts      |   97.66 |    93.13 |     100 |   97.66 | ...82-589,635,712 
  ...transcript.ts |      98 |       84 |     100 |      98 | 200-201           
  classifier.ts    |      94 |    94.54 |     100 |      94 | 158-165,389-393   
  ...erousRules.ts |     100 |    90.19 |     100 |     100 | 110,133,147,175   
  ...alTracking.ts |     100 |      100 |     100 |     100 |                   
  ...e-commands.ts |   86.77 |     73.8 |     100 |   86.77 | 131-141,210-214   
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...on-manager.ts |      88 |    90.77 |   82.35 |      88 | ...1374,1480-1484 
  rule-parser.ts   |    94.9 |    92.81 |     100 |    94.9 | ...1552,1586-1588 
  ...-semantics.ts |   70.44 |    91.09 |   46.66 |   70.44 | ...2237,2311-2314 
  types.ts         |     100 |      100 |     100 |     100 |                   
 ...sifier-prompts |   99.05 |    95.23 |     100 |   99.05 |                   
  system-prompt.ts |   99.05 |    95.23 |     100 |   99.05 | 226               
 src/prompts       |   83.63 |      100 |    87.5 |   83.63 |                   
  mcp-prompts.ts   |   18.18 |      100 |       0 |   18.18 | 11-19             
  ...t-registry.ts |     100 |      100 |     100 |     100 |                   
 src/providers     |   85.14 |    80.63 |   82.85 |   85.14 |                   
  all-providers.ts |     100 |      100 |     100 |     100 |                   
  index.ts         |     100 |      100 |     100 |     100 |                   
  install.ts       |   93.11 |     84.5 |     100 |   93.11 | ...56-257,330-331 
  ...-discovery.ts |    95.4 |    94.44 |     100 |    95.4 | 31-32,42-43       
  ...der-config.ts |   75.91 |    73.48 |   78.26 |   75.91 | ...74-475,503-504 
  types.ts         |       0 |        0 |       0 |       0 | 1                 
 ...viders/presets |   98.04 |    91.66 |   63.63 |   98.04 |                   
  ...oding-plan.ts |    87.5 |      100 |       0 |    87.5 | 82-84,87-89,91-94 
  ...a-standard.ts |     100 |      100 |     100 |     100 |                   
  ...token-plan.ts |     100 |      100 |     100 |     100 |                   
  ...m-provider.ts |   97.05 |    81.25 |      75 |   97.05 | 118-119           
  deepseek.ts      |     100 |      100 |     100 |     100 |                   
  grok.ts          |     100 |      100 |     100 |     100 |                   
  idealab.ts       |     100 |      100 |     100 |     100 |                   
  minimax.ts       |     100 |      100 |     100 |     100 |                   
  modelscope.ts    |     100 |      100 |     100 |     100 |                   
  moonshot.ts      |     100 |      100 |     100 |     100 |                   
  openrouter.ts    |     100 |      100 |     100 |     100 |                   
  requesty.ts      |     100 |      100 |     100 |     100 |                   
  zai.ts           |     100 |      100 |     100 |     100 |                   
 src/qwen          |   85.36 |    78.82 |   95.94 |   85.36 |                   
  ...tGenerator.ts |    98.6 |    98.14 |     100 |    98.6 | 103-104           
  qwenOAuth2.ts    |   82.79 |    73.91 |    90.9 |   82.79 | ...1205-1221,1251 
  ...kenManager.ts |   85.36 |     76.8 |     100 |   85.36 | ...52-757,778-783 
 src/resources     |     100 |      100 |     100 |     100 |                   
  ...e-registry.ts |     100 |      100 |     100 |     100 |                   
 src/services      |   90.69 |    86.19 |   96.57 |   90.69 |                   
  ...ionTrailer.ts |     100 |      100 |     100 |     100 |                   
  ...llRegistry.ts |   98.48 |    87.28 |     100 |   98.48 | 81-82,105,474-475 
  branch-points.ts |     100 |    95.23 |     100 |     100 | ...20,211,224,327 
  ...ionService.ts |   97.72 |    96.53 |     100 |   97.72 | ...1081,1224-1232 
  ...ingService.ts |    92.6 |    88.14 |   94.73 |    92.6 | ...2856,2871-2872 
  ...ttribution.ts |   91.73 |    87.71 |      90 |   91.73 | ...80-685,826-827 
  ...utSlimming.ts |    97.2 |    94.23 |     100 |    97.2 | ...39-340,378-381 
  cronScheduler.ts |   94.17 |    90.45 |      98 |   94.17 | ...1333,1736-1737 
  cronTasksFile.ts |   96.34 |    91.96 |     100 |   96.34 | ...11,336-337,483 
  cronTasksLock.ts |   94.44 |    89.47 |     100 |   94.44 | ...02-103,132-133 
  ...eryService.ts |   96.22 |    93.54 |      90 |   96.22 | 121,155-156,161   
  ...oryService.ts |   88.17 |    79.02 |    92.3 |   88.17 | ...1303,1344-1347 
  fileReadCache.ts |    97.5 |    96.07 |     100 |    97.5 | 349-350,363-364   
  ...temService.ts |    92.8 |    84.68 |   94.11 |    92.8 | ...53,479-486,531 
  ...ratedFiles.ts |      96 |    88.23 |     100 |      96 | 119-120,146-147   
  gitInit.ts       |     100 |      100 |     100 |     100 |                   
  ...reeService.ts |   74.75 |    70.76 |   96.07 |   74.75 | ...2296,2325-2326 
  ...on-service.ts |   86.58 |    74.39 |     100 |   86.58 | ...56-460,498-499 
  ...references.ts |   98.57 |    91.42 |     100 |   98.57 | 156-157,217-218   
  ...ionService.ts |   97.85 |    94.07 |     100 |   97.85 | ...1217,1240-1241 
  ...ticsDumper.ts |   98.37 |    95.23 |     100 |   98.37 | 185-186           
  ...ureMonitor.ts |   95.82 |    90.52 |   97.05 |   95.82 | ...60,861,875-877 
  ...orRegistry.ts |   97.22 |    90.99 |     100 |   97.22 | ...55-456,609-610 
  ...ttachments.ts |   97.74 |     90.9 |     100 |   97.74 | 298-308,646       
  ...pi-history.ts |   98.94 |    89.13 |     100 |   98.94 | 43                
  ...ersistence.ts |   91.88 |    81.19 |     100 |   91.88 | ...1073-1074,1119 
  ...tory-state.ts |     100 |       95 |     100 |     100 | 31                
  ...on-service.ts |   94.61 |    92.44 |   97.22 |   94.61 | ...11-613,669-677 
  ...pr-service.ts |   96.04 |    89.74 |     100 |   96.04 | 72,98-101,190-191 
  ...ce-service.ts |    98.5 |    94.11 |    90.9 |    98.5 | 64-65             
  ...n-registry.ts |   98.74 |    94.92 |     100 |   98.74 | 601,655-656,714   
  ...ken-counts.ts |     100 |       96 |     100 |     100 | 58                
  ...ipt-reader.ts |    93.7 |    91.22 |    97.8 |    93.7 | ...2791-2792,2869 
  ...turn-state.ts |   94.11 |     90.9 |   91.66 |   94.11 | 108-112,129-130   
  ...est-helper.ts |       0 |        0 |       0 |       0 | 1-65              
  ...iter-lease.ts |   84.57 |    75.18 |   97.72 |   84.57 | ...2567,2589,2603 
  sessionRecap.ts  |   67.56 |    43.47 |     100 |   67.56 | ...60,178,180-183 
  ...ionService.ts |   88.82 |    85.68 |    91.4 |   88.82 | ...4049-4050,4091 
  sessionTitle.ts  |   96.35 |    79.71 |     100 |   96.35 | ...08-311,342-343 
  ...ContextEnv.ts |     100 |    94.73 |     100 |     100 | 76,111            
  ...ionService.ts |   84.43 |    78.45 |   97.18 |   84.43 | ...2496,2502-2507 
  ...pInhibitor.ts |   97.42 |    92.77 |     100 |   97.42 | ...30,169,369-370 
  ...e-encoding.ts |   85.96 |    76.47 |     100 |   85.96 | 58-61,64-65,78-79 
  ...Estimation.ts |     100 |    95.83 |     100 |     100 | 139               
  ...ageService.ts |   97.76 |    91.59 |   93.75 |   97.76 | ...61-262,366,567 
  ...ite-origin.ts |     100 |    93.33 |     100 |     100 | 32                
  ...UseSummary.ts |   94.63 |    88.46 |     100 |   94.63 | ...62-164,214-215 
  ...rd-service.ts |     100 |    88.37 |     100 |     100 | ...29,145-146,241 
  ...oryService.ts |   90.77 |    84.92 |     100 |   90.77 | ...43-546,598-599 
  ...l-registry.ts |   92.99 |    83.19 |     100 |   92.99 | ...66-367,377-378 
  ...reeCleanup.ts |   14.42 |      100 |   33.33 |   14.42 | 58-186            
  ...ionService.ts |   88.36 |     87.8 |     100 |   88.36 | ...48-449,465-466 
 ...icrocompaction |   98.91 |    95.08 |     100 |   98.91 |                   
  microcompact.ts  |   98.91 |    95.08 |     100 |   98.91 | ...60,769,778-779 
 ...s/visionBridge |    98.8 |    92.12 |     100 |    98.8 |                   
  ...capability.ts |     100 |      100 |     100 |     100 |                   
  ...part-utils.ts |     100 |      100 |     100 |     100 |                   
  ...ion-bridge.ts |   98.72 |    82.35 |     100 |   98.72 | 65,71             
  ...ge-service.ts |   98.61 |     94.7 |     100 |   98.61 | ...06,666,679-680 
 src/skills        |   89.78 |    86.08 |   94.73 |   89.78 |                   
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...activation.ts |     100 |    93.33 |     100 |     100 | 93,112            
  skill-curator.ts |   89.71 |    81.54 |     100 |   89.71 | ...01-902,904-907 
  skill-load.ts    |   94.84 |    87.69 |     100 |   94.84 | ...03,223,235-237 
  skill-manager.ts |   86.11 |    85.71 |   86.11 |   86.11 | ...1244,1251-1255 
  skill-paths.ts   |   90.42 |     87.5 |     100 |   90.42 | ...19-120,125-126 
  symlinkScope.ts  |     100 |      100 |     100 |     100 |                   
  types.ts         |   97.91 |    98.07 |     100 |   97.91 | 289-290           
 ...ataviz/scripts |   80.06 |    95.23 |   88.23 |   80.06 |                   
  ...te_palette.js |   80.06 |    95.23 |   88.23 |   80.06 | 261-296,306-328   
 ...s/bundled/loop |   97.48 |    95.77 |     100 |   97.48 |                   
  ...omous-loop.ts |     100 |      100 |     100 |     100 |                   
  ...-task-file.ts |   94.85 |     92.4 |     100 |   94.85 | ...56,367,375-376 
  ...k-resolver.ts |     100 |      100 |     100 |     100 |                   
 src/subagents     |   88.58 |    89.46 |    98.3 |   88.58 |                   
  ...ter-schema.ts |     100 |    98.07 |     100 |     100 | 99                
  ...tin-agents.ts |     100 |      100 |     100 |     100 |                   
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...nt-manager.ts |   85.54 |    86.59 |   97.43 |   85.54 | ...1588,1665-1666 
  types.ts         |     100 |      100 |     100 |     100 |                   
  validation.ts    |   92.46 |    95.18 |     100 |   92.46 | 47-52,63-68,71-76 
 src/telemetry     |   83.19 |    85.01 |   86.33 |   83.19 |                   
  ...ty-tracker.ts |     100 |      100 |     100 |     100 |                   
  config.ts        |     100 |      100 |     100 |     100 |                   
  constants.ts     |     100 |      100 |     100 |     100 |                   
  context-usage.ts |   96.85 |    91.07 |     100 |   96.85 | ...26-127,199-200 
  ...on-metrics.ts |   99.08 |    80.95 |     100 |   99.08 | 185,199           
  ...on-tracing.ts |   80.71 |    81.91 |   79.16 |   80.71 | ...92,499-501,517 
  ...attributes.ts |   96.98 |    91.37 |     100 |   96.98 | ...47-348,366-367 
  ...ag-metrics.ts |     100 |    77.77 |     100 |     100 | 21,40             
  ...t-loop-lag.ts |   96.85 |    85.71 |     100 |   96.85 | 170-173           
  ...-exporters.ts |   65.38 |    83.33 |      50 |   65.38 | ...08-109,112-113 
  ...ai-content.ts |    74.5 |    66.41 |   91.66 |    74.5 | ...1480,1493-1502 
  ...i-provider.ts |     100 |    99.02 |     100 |     100 | 106               
  ...ai-request.ts |   87.88 |    92.79 |   83.78 |   87.88 | ...55-561,564-568 
  gen-ai-usage.ts  |     100 |      100 |     100 |     100 |                   
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...t.circular.ts |       0 |        0 |       0 |       0 | 1-111             
  ...-processor.ts |   99.12 |    96.03 |      95 |   99.12 | 150,379-380       
  ...t.circular.ts |       0 |        0 |       0 |       0 | 1-128             
  loggers.ts       |   60.44 |    78.16 |   64.91 |   60.44 | ...1523,1540-1560 
  metrics.ts       |   80.37 |    82.35 |   80.95 |   80.37 | ...1150,1153-1164 
  otlp-urls.ts     |     100 |      100 |     100 |     100 |                   
  ...attributes.ts |     100 |      100 |     100 |     100 |                   
  ...ime-config.ts |       0 |        0 |       0 |       0 | 1                 
  sanitize.ts      |      80 |    83.33 |     100 |      80 | 35-36,41-42       
  ...rters-grpc.ts |     100 |      100 |     100 |     100 |                   
  ...rters-http.ts |     100 |      100 |     100 |     100 |                   
  sdk-impl.ts      |   94.13 |    86.66 |      75 |   94.13 | ...45,496-497,513 
  sdk.ts           |    82.7 |     90.9 |   66.66 |    82.7 | ...00-204,242-264 
  ...on-context.ts |     100 |      100 |     100 |     100 |                   
  ...ion-events.ts |     100 |      100 |     100 |     100 |                   
  ...on-tracing.ts |   91.29 |    88.88 |    97.5 |   91.29 | ...1946,1975-1978 
  ...etry-utils.ts |     100 |      100 |     100 |     100 |                   
  ...l-decision.ts |     100 |      100 |     100 |     100 |                   
  trace-context.ts |     100 |      100 |     100 |     100 |                   
  ...e-id-utils.ts |     100 |      100 |     100 |     100 |                   
  tracer.ts        |   98.56 |    88.63 |     100 |   98.56 | 52,101            
  types.ts         |   83.29 |    88.88 |   86.36 |   83.29 | ...1470,1474-1481 
  uiTelemetry.ts   |   98.87 |     95.1 |   97.05 |   98.87 | ...59,696,786-787 
 ...ry/qwen-logger |   74.14 |       80 |      70 |   74.14 |                   
  event-types.ts   |       0 |        0 |       0 |       0 |                   
  qwen-logger.ts   |   74.14 |    79.82 |   69.49 |   74.14 | ...1123,1161-1162 
 src/test-utils    |   96.38 |    98.64 |   84.09 |   96.38 |                   
  config.ts        |     100 |      100 |     100 |     100 |                   
  ...st-helpers.ts |   94.11 |       90 |     100 |   94.11 | 69-70             
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...mised-lock.ts |     100 |      100 |     100 |     100 |                   
  mock-tool.ts     |   94.85 |      100 |      80 |   94.85 | ...53,227-228,241 
  ...aceContext.ts |     100 |      100 |     100 |     100 |                   
 src/tools         |   87.56 |    86.07 |   90.21 |   87.56 |                   
  ...erQuestion.ts |   89.71 |    81.13 |    92.3 |   89.71 | ...66-367,374-375 
  ...-registrar.ts |    77.7 |    66.66 |   66.66 |    77.7 | ...72-277,292-294 
  ...ub-session.ts |   89.72 |    91.48 |   83.33 |   89.72 | ...06-307,318-325 
  cron-create.ts   |   92.26 |    97.72 |      75 |   92.26 | ...,76-77,272-281 
  cron-delete.ts   |   97.56 |      100 |   85.71 |   97.56 | 31-32             
  cron-list.ts     |   98.23 |    95.45 |   88.88 |   98.23 | 57-58             
  diffOptions.ts   |     100 |      100 |     100 |     100 |                   
  display-image.ts |   87.42 |    85.71 |    90.9 |   87.42 | ...29-134,194-195 
  edit.ts          |   82.76 |    86.88 |   82.35 |   82.76 | ...45-746,865-915 
  ...r-worktree.ts |   83.14 |    68.42 |   88.88 |   83.14 | ...84-187,278-279 
  enterPlanMode.ts |      85 |       84 |      90 |      85 | ...28-133,161-175 
  exit-worktree.ts |   83.29 |     83.8 |   94.73 |   83.29 | ...14-515,537-538 
  exitPlanMode.ts  |      95 |    85.29 |     100 |      95 | ...21-325,344,378 
  ...permission.ts |     100 |      100 |     100 |     100 |                   
  glob.ts          |   96.33 |     88.5 |     100 |   96.33 | ...24-225,373,376 
  grep.ts          |   90.73 |    86.71 |   86.36 |   90.73 | ...76-677,727-728 
  ...adTracking.ts |     100 |      100 |     100 |     100 |                   
  image-gen.ts     |   91.66 |    78.12 |   91.66 |   91.66 | ...13-214,221-222 
  list-agents.ts   |   94.11 |    83.33 |   85.71 |   94.11 | 31-32,47-48       
  loop-wakeup.ts   |   99.27 |     93.1 |     100 |   99.27 | 45                
  ls.ts            |   96.74 |    90.54 |     100 |   96.74 | 176-181,212,216   
  lsp.ts           |   72.71 |     59.9 |    90.9 |   72.71 | ...1212,1214-1215 
  ...nt-manager.ts |   82.07 |    80.15 |   85.71 |   82.07 | ...3243,3245-3246 
  mcp-client.ts    |   86.25 |    87.61 |   93.93 |   86.25 | ...2552,2556-2559 
  ...ry-timeout.ts |     100 |      100 |     100 |     100 |                   
  mcp-errors.ts    |     100 |      100 |     100 |     100 |                   
  ...pool-entry.ts |   79.21 |    85.71 |   81.57 |   79.21 | ...1342,1350-1351 
  ...ool-events.ts |       8 |      100 |       0 |       8 | 132-158           
  mcp-pool-key.ts  |    97.5 |    93.93 |     100 |    97.5 | 178-179           
  ...ce-content.ts |   96.55 |    91.17 |     100 |   96.55 | 80-82             
  mcp-retry.ts     |   97.67 |    95.65 |     100 |   97.67 | 131-132           
  ...ion-config.ts |     100 |      100 |     100 |     100 |                   
  mcp-status.ts    |     100 |      100 |     100 |     100 |                   
  mcp-tool.ts      |    98.1 |       93 |     100 |    98.1 | ...1233,1288-1289 
  ...sport-pool.ts |   83.98 |     80.3 |   88.46 |   83.98 | ...1411,1418-1422 
  ...ace-budget.ts |   87.27 |     82.6 |     100 |   87.27 | ...00-305,340-345 
  memory-config.ts |     100 |      100 |     100 |     100 |                   
  ...iable-tool.ts |     100 |    84.61 |     100 |     100 | 101,108           
  monitor.ts       |   91.82 |    83.09 |   88.46 |   91.82 | ...99,612,810-815 
  notebook-edit.ts |   85.71 |    77.39 |   82.35 |   85.71 | ...96-912,958-959 
  ...escendants.ts |   36.17 |    64.51 |   55.55 |   36.17 | ...46-310,385-390 
  ...nforcement.ts |   83.21 |    90.69 |     100 |   83.21 | 147-158,207-220   
  read-file.ts     |   95.49 |    88.61 |    87.5 |   95.49 | ...49,464,536-537 
  ...p-resource.ts |   96.85 |      100 |   91.66 |   96.85 | 92-96             
  readManyFiles.ts |   96.04 |    82.25 |     100 |   96.04 | ...41,594,604-608 
  ...d-artifact.ts |   85.68 |    81.59 |   94.73 |   85.68 | ...1071,1095-1096 
  ...t-findings.ts |   99.13 |    93.93 |    92.3 |   99.13 | 256-258           
  ...t-shutdown.ts |    87.2 |    86.66 |   77.77 |    87.2 | ...,75-79,162-165 
  ripGrep.ts       |    94.6 |    87.34 |   95.45 |    94.6 | ...33-734,740-741 
  ...-transport.ts |   71.42 |    55.55 |   71.42 |   71.42 | ...36-137,143-144 
  send-message.ts  |    81.5 |    90.69 |   66.66 |    81.5 | ...80-286,354-361 
  ...n-mcp-view.ts |   94.07 |    91.89 |    90.9 |   94.07 | 131-139           
  shell.ts         |   78.96 |    84.29 |      93 |   78.96 | ...5036,5111-5112 
  skill-utils.ts   |     100 |      100 |     100 |     100 |                   
  skill.ts         |   93.56 |    90.78 |   91.66 |   93.56 | ...49,653,701-723 
  ...-constants.ts |     100 |      100 |     100 |     100 |                   
  ...eticOutput.ts |   95.12 |      100 |      80 |   95.12 | 87-88             
  task-create.ts   |    94.4 |    93.75 |   83.33 |    94.4 | 45-49,63-64,95    
  task-list.ts     |   80.43 |    86.95 |   85.71 |   80.43 | ...67,121,125-132 
  task-stop.ts     |   93.14 |    96.29 |    87.5 |   93.14 | 39-40,54-64       
  task-update.ts   |   82.87 |     86.5 |   92.85 |   82.87 | ...54-564,588-599 
  team-create.ts   |   97.24 |     87.5 |   85.71 |   97.24 | 48-49,129-130     
  team-delete.ts   |   86.74 |    84.61 |   85.71 |   86.74 | 37-38,42-48,72-73 
  ...n-approval.ts |   92.14 |    96.96 |   81.81 |   92.14 | 38-39,42-43,93-99 
  todoWrite.ts     |   95.73 |    90.47 |   93.75 |   95.73 | ...48-552,565-570 
  ...repeat-key.ts |     100 |      100 |     100 |     100 |                   
  tool-error.ts    |     100 |      100 |     100 |     100 |                   
  tool-names.ts    |     100 |      100 |     100 |     100 |                   
  tool-registry.ts |   80.72 |    82.95 |   86.53 |   80.72 | ...1106,1114-1115 
  ...-finalizer.ts |    98.1 |    92.36 |   93.33 |    98.1 | ...34-235,237-241 
  ...iagnostics.ts |   99.06 |    97.69 |   91.66 |   99.06 | 133-134,205       
  ...-retention.ts |     100 |    95.83 |     100 |     100 | 116               
  tool-search.ts   |   96.19 |    89.79 |   93.75 |   96.19 | ...09,259-264,426 
  tool-utils.ts    |   97.46 |    96.55 |     100 |   97.46 | 26-27             
  tools.ts         |   92.93 |    92.18 |      92 |   92.93 | ...64-565,581-587 
  truncation.ts    |   90.72 |    90.35 |     100 |   90.72 | ...65-473,510-516 
  ...reapproved.ts |   99.27 |    94.11 |     100 |   99.27 | 170               
  web-fetch.ts     |   96.05 |    90.54 |   96.77 |   96.05 | ...85-786,800-801 
  web-search.ts    |   90.58 |    83.57 |      80 |   90.58 | ...1025,1083-1086 
  write-file.ts    |   87.29 |    86.15 |   89.47 |   87.29 | ...53-856,893-928 
  zoom-image.ts    |   95.76 |    93.93 |    90.9 |   95.76 | 54-59,203-204     
 src/tools/agent   |   87.26 |    88.51 |   89.71 |   87.26 |                   
  agent.ts         |   85.88 |    87.64 |   87.35 |   85.88 | ...4265,4299-4309 
  fork-profile.ts  |   93.65 |       90 |     100 |   93.65 | ...33-134,171-174 
  fork-subagent.ts |   98.73 |       95 |     100 |   98.73 | 101-102,173       
 ...tools/artifact |   95.83 |    92.51 |   88.63 |   95.83 |                   
  artifact-tool.ts |   91.69 |    88.46 |   71.42 |   91.69 | ...20-321,329-332 
  ...-publisher.ts |     100 |    85.71 |     100 |     100 | 32                
  ...-publisher.ts |   96.74 |    97.72 |    87.5 |   96.74 | 29-30,156-157     
  html.ts          |     100 |    96.77 |     100 |     100 | 122               
  ...-publisher.ts |     100 |       80 |     100 |     100 | 30                
  oss-publisher.ts |    98.1 |    91.48 |     100 |    98.1 | 43-45             
  publisher.ts     |     100 |      100 |     100 |     100 |                   
 ...tools/workflow |   89.33 |    87.68 |   82.75 |   89.33 |                   
  workflow.ts      |   89.33 |    87.68 |   82.75 |   89.33 | ...33,878,880-881 
 src/utils         |   92.78 |    89.75 |   96.89 |   92.78 |                   
  ...Controller.ts |     100 |      100 |     100 |     100 |                   
  ...ssageQueue.ts |     100 |      100 |     100 |     100 |                   
  ...cFileWrite.ts |      95 |    92.76 |     100 |      95 | ...49-550,657-661 
  auth-type.ts     |     100 |      100 |     100 |     100 |                   
  bareMode.ts      |   81.81 |      100 |      50 |   81.81 | 18-19             
  ...ry-content.ts |   98.45 |    95.79 |     100 |   98.45 | 132-133,159-160   
  browser.ts       |   86.84 |    78.94 |     100 |   86.84 | 34,36-37,65-66    
  btwUtils.ts      |   13.95 |      100 |       0 |   13.95 | 17-31,34-55       
  bundlePaths.ts   |     100 |      100 |     100 |     100 |                   
  ...on-context.ts |     100 |      100 |     100 |     100 |                   
  ...igResolver.ts |     100 |      100 |     100 |     100 |                   
  ...engthError.ts |   91.06 |    89.47 |     100 |   91.06 | ...46-147,154-155 
  ...n-branches.ts |   95.89 |    94.11 |      95 |   95.89 | ...99-500,512-525 
  ...tion-chain.ts |     100 |      100 |     100 |     100 |                   
  cronDisplay.ts   |     100 |    97.61 |     100 |     100 | 46                
  cronParser.ts    |   95.34 |    93.33 |     100 |   95.34 | 41-42,47-48,70-71 
  debugLogger.ts   |     100 |    97.18 |     100 |     100 | 79,86             
  ...qwen-model.ts |     100 |      100 |     100 |     100 |                   
  editHelper.ts    |   93.63 |     83.9 |     100 |   93.63 | ...27-428,462-463 
  editor.ts        |   97.65 |    95.45 |     100 |   97.65 | ...35-336,338-339 
  encoding.ts      |     100 |      100 |     100 |     100 |                   
  env.ts           |     100 |      100 |     100 |     100 |                   
  ...arResolver.ts |   94.28 |    88.88 |     100 |   94.28 | 28-29,125-126     
  errorParsing.ts  |     100 |      100 |     100 |     100 |                   
  ...rReporting.ts |   95.65 |    93.33 |     100 |   95.65 | 37-38             
  errors.ts        |   88.92 |    92.99 |      68 |   88.92 | ...92,394,410-411 
  fetch.ts         |   90.68 |    82.63 |     100 |   90.68 | ...72,483-484,503 
  ...ng-options.ts |     100 |      100 |     100 |     100 |                   
  file-identity.ts |     100 |      100 |     100 |     100 |                   
  fileUtils.ts     |   94.79 |    92.16 |   96.29 |   94.79 | ...2076,2084-2085 
  formatters.ts    |     100 |      100 |     100 |     100 |                   
  ...eUtilities.ts |    92.4 |    86.95 |     100 |    92.4 | ...52-158,168-169 
  ...rStructure.ts |   94.39 |    94.28 |     100 |   94.39 | ...29-132,343-348 
  getPty.ts        |   31.57 |       50 |     100 |   31.57 | 26-38             
  git-branches.ts  |    91.6 |    84.21 |    92.3 |    91.6 | ...90,405-410,570 
  ...fig-safety.ts |   97.01 |       80 |     100 |   97.01 | 53-54             
  git-ignore.ts    |     100 |      100 |     100 |     100 |                   
  gitDiff.ts       |   95.19 |    81.36 |     100 |   95.19 | ...1073,1419-1420 
  gitDirect.ts     |   98.84 |    94.28 |     100 |   98.84 | 234,318           
  ...noreParser.ts |   94.48 |    93.22 |     100 |   94.48 | ...23-124,158-159 
  gitUtils.ts      |   78.83 |    82.35 |    87.5 |   78.83 | ...22-123,164-215 
  github-prs.ts    |   96.06 |    84.09 |     100 |   96.06 | 251,350-358       
  iconvHelper.ts   |     100 |      100 |     100 |     100 |                   
  ...rePatterns.ts |     100 |      100 |     100 |     100 |                   
  image-view.ts    |   95.08 |    93.47 |     100 |   95.08 | ...62-166,234-238 
  ...lPromptIds.ts |     100 |      100 |     100 |     100 |                   
  ...on-context.ts |     100 |      100 |     100 |     100 |                   
  is-tool.ts       |     100 |      100 |     100 |     100 |                   
  jsonl-utils.ts   |   96.15 |    93.69 |     100 |   96.15 | ...86-387,429-432 
  ...-detection.ts |     100 |      100 |     100 |     100 |                   
  ...iconv-lite.ts |     100 |      100 |     100 |     100 |                   
  ...simple-git.ts |   96.77 |    91.66 |     100 |   96.77 | 38                
  ...m-headless.ts |      96 |    88.88 |     100 |      96 | 34                
  ...-constants.ts |   94.73 |     92.3 |     100 |   94.73 | 66-67             
  ...iagnostics.ts |    96.4 |     94.2 |     100 |    96.4 | ...66,293-294,376 
  ...tProcessor.ts |   94.01 |     90.1 |     100 |   94.01 | ...47-353,445-446 
  ...Inspectors.ts |     100 |      100 |     100 |     100 |                   
  modelId.ts       |   98.96 |    98.18 |     100 |   98.96 | 154               
  ...kerChecker.ts |    90.9 |    91.66 |     100 |    90.9 | 73-79             
  notebook.ts      |   94.57 |    89.91 |   95.83 |   94.57 | ...21,333,385-387 
  openaiLogger.ts  |   91.66 |    89.74 |     100 |   91.66 | ...26-228,251-256 
  osc8.ts          |   54.26 |    64.86 |   83.33 |   54.26 | ...72-195,197-257 
  partUtils.ts     |     100 |    98.64 |     100 |     100 | 211               
  pathReader.ts    |     100 |      100 |     100 |     100 |                   
  paths.ts         |   90.88 |    90.66 |     100 |   90.88 | ...28-629,631-633 
  pdf.ts           |   92.17 |    85.81 |     100 |   92.17 | ...64-565,606-611 
  ...s-liveness.ts |     100 |    93.47 |     100 |     100 | 62,72,108         
  projectPath.ts   |     100 |      100 |     100 |     100 |                   
  projectRoot.ts   |   71.73 |    78.57 |     100 |   71.73 | 54-66             
  ...ectSummary.ts |   89.62 |    72.41 |     100 |   89.62 | ...40-145,196-199 
  ...tIdContext.ts |     100 |      100 |     100 |     100 |                   
  proxyUtils.ts    |     100 |      100 |     100 |     100 |                   
  ...rDetection.ts |   71.15 |       86 |     100 |   71.15 | ...-90,96-101,147 
  ...noreParser.ts |   92.63 |    91.66 |     100 |   92.63 | ...77-178,197-198 
  rateLimit.ts     |   93.75 |    89.62 |     100 |   93.75 | ...13,218-219,262 
  ...text-range.ts |   96.98 |    87.36 |     100 |   96.98 | ...87-688,763-764 
  retry.ts         |   96.09 |    92.52 |     100 |   96.09 | ...72,563-564,582 
  retryContext.ts  |     100 |      100 |     100 |     100 |                   
  ...sification.ts |   97.63 |    97.08 |     100 |   97.63 | ...17,251-252,278 
  retryPolicy.ts   |   97.72 |    90.56 |     100 |   97.72 | 130-131           
  ripgrepUtils.ts  |   90.04 |    93.43 |   95.45 |   90.04 | ...55-565,598-599 
  ...iagnostics.ts |   83.08 |     67.5 |   92.59 |   83.08 | ...23,543-544,550 
  ...tchOptions.ts |   84.87 |    86.71 |   96.29 |   84.87 | ...71,696,725-734 
  ...odelPrefix.ts |     100 |      100 |     100 |     100 |                   
  runtimeStatus.ts |   97.77 |    91.48 |     100 |   97.77 | 172-173           
  safe-mode.ts     |     100 |      100 |     100 |     100 |                   
  safeJsonParse.ts |     100 |      100 |     100 |     100 |                   
  ...nStringify.ts |     100 |      100 |     100 |     100 |                   
  ...-child-env.ts |     100 |      100 |     100 |     100 |                   
  ...aConverter.ts |   98.22 |    98.01 |     100 |   98.22 | 100,102-103       
  ...aValidator.ts |   92.09 |    83.65 |   90.47 |   92.09 | ...60,882-883,896 
  ...r-launcher.ts |   96.35 |    93.97 |   85.71 |   96.35 | ...35-336,347-348 
  sedEditParser.ts |   91.78 |    92.18 |     100 |   91.78 | ...66-569,645-646 
  ...nIdContext.ts |     100 |       90 |     100 |     100 | 95                
  ...orageUtils.ts |   96.21 |     86.2 |     100 |   96.21 | ...70,386,466,485 
  ...-pager-env.ts |     100 |      100 |     100 |     100 |                   
  ...fety-rules.ts |     100 |     89.7 |     100 |     100 | ...01,304,309-311 
  shell-utils.ts   |   86.37 |    88.59 |     100 |   86.37 | ...2361,2368-2372 
  ...lAstParser.ts |    98.3 |    91.59 |     100 |    98.3 | ...1340-1342,1352 
  ...nlyChecker.ts |   96.33 |    96.57 |     100 |   96.33 | ...83-284,292-293 
  sideQuery.ts     |   86.82 |    86.66 |     100 |   86.82 | ...79-185,187-193 
  ...pEventSink.ts |     100 |       80 |     100 |     100 | 61                
  ...tGenerator.ts |     100 |      100 |     100 |     100 |                   
  ...ameContext.ts |     100 |      100 |     100 |     100 |                   
  symlink.ts       |   77.77 |    57.14 |     100 |   77.77 | 44,54-59          
  ...emEncoding.ts |   96.36 |    91.17 |     100 |   96.36 | 59-60,124-125     
  terminal-env.ts  |      50 |      100 |       0 |      50 | 18-19             
  terminalSafe.ts  |     100 |      100 |     100 |     100 |                   
  ...Serializer.ts |   98.72 |       90 |     100 |   98.72 | 42-43,134,201-203 
  testUtils.ts     |   53.33 |      100 |   33.33 |   53.33 | ...53,59-64,70-72 
  ...-constants.ts |     100 |      100 |     100 |     100 |                   
  textUtils.ts     |      65 |      100 |      75 |      65 | 56-75             
  thoughtUtils.ts  |     100 |    95.65 |     100 |     100 | 99                
  ...-converter.ts |   95.23 |    85.71 |     100 |   95.23 | 36-37             
  ...error-type.ts |     100 |      100 |     100 |     100 |                   
  ...name-utils.ts |     100 |      100 |     100 |     100 |                   
  ...ultCleanup.ts |   54.62 |    66.66 |      75 |   54.62 | ...03-105,108-134 
  ...Compaction.ts |   96.83 |     92.7 |     100 |   96.83 | ...37-342,344-349 
  ...pt-records.ts |   87.61 |    86.23 |     100 |   87.61 | ...80-484,514-529 
  ...-constants.ts |     100 |      100 |     100 |     100 |                   
  windowsPath.ts   |   89.47 |    79.31 |     100 |   89.47 | ...57-58,62,90-91 
  ...-directory.ts |    83.7 |    80.95 |    87.5 |    83.7 | ...37-238,252-253 
  ...ifact-path.ts |   94.11 |    92.85 |     100 |   94.11 | 32-33             
  ...aceContext.ts |   95.39 |    89.47 |     100 |   95.39 | ...16-317,321-322 
  xml.ts           |    97.8 |    87.69 |     100 |    97.8 | 98-99             
  yaml-parser.ts   |   83.87 |    77.27 |     100 |   83.87 | ...31-234,239-240 
 ...ils/filesearch |   83.94 |    80.75 |   94.78 |   83.94 |                   
  crawlCache.ts    |     100 |      100 |     100 |     100 |                   
  crawler.ts       |    82.9 |    76.81 |   95.08 |    82.9 | ...1563,1597-1598 
  fileSearch.ts    |   93.78 |    87.67 |     100 |   93.78 | ...71-272,274-275 
  fzfWorker.ts     |       0 |        0 |       0 |       0 | 1-109             
  ...rkerHandle.ts |   84.05 |    75.86 |      90 |   84.05 | ...30-334,340-341 
  ignore.ts        |     100 |    97.36 |     100 |     100 | 187               
  result-cache.ts  |     100 |    93.75 |     100 |     100 | 49                
 ...uest-tokenizer |    92.3 |      100 |   88.88 |    92.3 |                   
  ...ageFormats.ts |   81.81 |      100 |   66.66 |   81.81 | 56-61             
  textTokenizer.ts |     100 |      100 |     100 |     100 |                   
-------------------|---------|----------|---------|---------|-------------------

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

@yiliang114

Copy link
Copy Markdown
Collaborator Author

Closeout summary for exact head 91256db13225:

中文摘要

已为 result-aware loop stop 补齐 Arena 错误上报,与相邻退出路径一致;聚焦测试通过。daemon ACP cap 属于既有且超出 #9450 范围的问题,未在本 PR 引入改动。当前等待 exact-head CI。

@yiliang114

Copy link
Copy Markdown
Collaborator Author

@qwen-code /review --timeout=360

@github-actions

Copy link
Copy Markdown
Contributor

Qwen Code review request accepted. Review is queued in workflow 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.

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.

中文说明

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

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

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

Comment thread packages/core/src/agents/runtime/agent-headless.ts
Comment thread packages/core/src/agents/runtime/agent-headless.ts
Comment thread packages/core/src/services/loopDetectionService.ts
Comment thread packages/core/src/services/loopDetectionService.ts Outdated
Comment thread packages/core/src/core/client.ts
Comment thread packages/core/src/services/loopDetectionService.test.ts
Comment thread packages/core/src/services/loopDetectionService.ts Outdated
Comment thread packages/core/src/services/loopDetectionService.test.ts
Comment thread packages/core/src/agents/runtime/agent-events.ts
Comment thread packages/core/src/services/loopDetectionService.test.ts
- R1-1: declare loop_type on SubagentExecutionEvent and serialize it in
  the QwenLogger sink; previously the spread in agent-headless.ts was
  dropped at construction (excess-property spread), so LOOP_DETECTED
  stops reached the journal unattributable.
- R1-2: reset loopType at the top of AgentHeadless.execute() so a
  re-executed instance (stop-hook continuation, resident turns) never
  carries a stale loop attribution into an ERROR/FINISH record.
- R1-12: pair only stateful read tools in requestByCallId — every other
  tool is rejected by recordToolResult anyway, and the write-only entries
  pin full args objects (write_file contents) up to the eviction cap.
- R1-3: drop the dead 'key' field from requestByCallId entries; the
  consumer reads only name/args and recordToolResult recomputes the key.
- Tests: assert loop_type in the telemetry completion record (R1-5) and
  pin the re-execution attribution reset.
…9450)

- Extend the changed-results global-duplicate phase past GLOBAL_DUPLICATE_THRESHOLD rounds so an args-only mutant cannot hide.
- Add heuristic-gate tests that Retry and reset() clear result-aware pair counts (cross-prompt and replay false positives).
- Add the adaptive-cap positive-side test: an interleaved frozen poller halts with TURN_TOOL_CALL_CAP just past the soft cap.
- Add the streak-move fail-safe test: a resumed streak with insufficient fresh result evidence halts instead of trusting stale evidence.
- client.test.ts: drive sendMessageStream with paired ToolResult ids — frozen board halts with global_tool_call_duplicate, changing board keeps running.
- agent-headless: interleaved frozen task_list polling halts via the result-time guard with FINISH loopType attribution.
- agent-interactive: LOOP_DETECTED results surface the exact detector in the stop message and lastRoundError.

@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 reviewed: reverse audit — did not converge within the reverse-audit round cap of 5.

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

  • packages/core/src/agents/runtime/agent-interactive.ts:538 — [review] Stop message hard-codes 'duplicate tool-call loop' for all 11 loop types
  • packages/core/src/services/loopDetectionService.test.ts:2367 (+3 locations) — [probe] Stateful-evidence clears (Retry, reset, restart) are unpinned — mutants survive
  • packages/core/src/services/loopDetectionService.ts:296 — [review] recordToolResult's in-session-disable early return is untested
  • packages/core/src/agents/runtime/agent-core.ts:1294 — [probe] Provider-replay LOOP_DETECTED stop carries no loopType attribution
中文说明

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

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

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

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

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

Comment thread packages/core/src/services/loopDetectionService.ts
Comment thread packages/core/src/agents/runtime/agent-events.ts
Comment thread packages/core/src/telemetry/qwen-logger/qwen-logger.ts
Comment thread packages/core/src/services/loopDetectionService.ts
@yiliang114

Copy link
Copy Markdown
Collaborator Author

Patrol closeout — round fixing R2-3 / R2-9 (test-only, no production changes)

  • R2-3 (loop_type journal mapping unpinned): fixed in 2ea0eea — new logSubagentExecutionEvent block in packages/core/src/telemetry/qwen-logger/qwen-logger.test.ts (2 cases): asserts the enqueued subagent_execution record carries properties.loop_type when set, and that the key is absent when loop_type is undefined.
  • R2-9 (stateful condition of the requestByCallId population guard unpinned): fixed in 2ea0eea — new keeps task_list pairing evidence alive through a flood of non-stateful callIds case in packages/core/src/services/loopDetectionService.test.ts implementing the suggested witness (1 task_list request → 510 non-stateful callIds → resumed streak; the pre-flood callId must still pair so the halt outcome stays productive).
  • Mutation verification: dropping && stateful → flood test fails (1 failed | 112 passed, all pre-existing green); dropping/misnaming the loop_type spread → presence case fails; unconditional spread → absence case fails. All restored afterwards.
  • Verification: targeted suites green — loopDetectionService.test.ts 113 passed, qwen-logger.test.ts 43 passed; tsc --noEmit on packages/core clean.
  • Push: b0db430..2ea0eea (single non-force push).
  • Deliberately unresolved (human-gated): R1-7 ×2 (daemon/ACP parity, design fork) and R1-15 (write-only loopType, maintainer decision pending).

Not requesting /triage — the push auto-triggers 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: reverse audit — did not converge within the reverse-audit round cap of 5.

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

  • packages/core/src/agents/runtime/agent-interactive.ts:544 — [probe] LOOP_DETECTED stop message hard-codes 'duplicate tool-call loop detected' for all 11 loop types
  • packages/core/src/services/loopDetectionService.ts:456 — [probe] checkAlternatingPattern remains argument-only for stateful read tools (ABAB poller with changing results still halts under skipLoopDetection=false)
  • packages/core/src/services/loopDetectionService.ts:647 — [probe] No test pins the resultsObserved/unchangedStreak reset in checkToolCallLoop's restart branch — the #5019 fail-safe is unpinned
  • packages/core/src/agents/runtime/agent-headless.test.ts:2262 — [review] The headless keep-polling test stops one request short of re-testing the restart branch's second cycle (pollCount = 8, second crossing at request 9)
中文说明

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

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

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

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

Comment thread packages/core/src/services/loopDetectionService.ts
Comment thread packages/core/src/agents/runtime/agent-core.ts
Comment thread packages/core/src/agents/runtime/agent-events.ts
…d results (#9450)

Oversized results are rewritten into persistence stubs whose envelope embeds
a per-call unique file path (<toolResultsDir>/<callId>.txt), so fingerprinting
the whole model-visible response made every fingerprint unique and silently
disabled every result-aware guard for exactly the largest results: a frozen
task_list board over the persistence gate was never halted. Fingerprint the
semantic payload instead — strip the stub envelope and hash the
preview/truncated content that follows the stable marker.
@yiliang114

yiliang114 commented Aug 22, 2026

Copy link
Copy Markdown
Collaborator Author

Closeout — round-2 Critical bUUGp fixed and pushed.

Fixed (8b5b610): oversized tool results were defeating every result-aware guard because the model-visible finalized part embeds a persistence envelope with a per-call unique file path (<persisted-output> stub, Output too large (...) envelope, or the truncateAndSaveToFile fallback), so two back-to-back identical results produced different fingerprints. computeToolResultFingerprint now strips the envelope via stripPersistenceEnvelope (JSON.stringify replacer over all string values): a stub is reduced to a <persisted-stub> sentinel + the stable preview/truncated payload that follows the marker, so identical underlying results fingerprint identically no matter where they were persisted, while the sentinel keeps a stub from ever colliding with a small literal output matching the same payload. Both production paths (agent-core.ts recordToolResult, client.ts recordToolResultByCallId) feed finalized parts through this fingerprint.

Tests: 4 new cases under persisted oversized results (issue #9450 follow-up) — halts on a frozen oversized board despite per-call unique stub paths, keeps polling alive while the board changes, counts global duplicates on frozen oversized results, and halts an interleaved frozen oversized poller just past the adaptive soft cap; mutation-checked against the stub-path injection.

Verification: loopDetectionService.test.ts 129 passed / 1 pre-existing skip, geminiChat.test.ts 190/190 (repetitive-poll guard at the source integration point), packages/core typecheck clean, eslint clean.

One non-force push 2ea0eea..8b5b610. The bUUGp thread is replied with SHA evidence and resolved. Remaining unresolved are the R1-7 (daemon/ACP recordDaemonToolCalls needs the result too — a carrier/contract change) and R1-15 (AgentFinishEvent.loopType write-only telemetry) families, which stay open pending a maintainer decision as replied on those threads.

@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 reviewed: reverse audit — did not converge within the reverse-audit round cap of 5.

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

  • packages/core/src/agents/runtime/agent-interactive.ts:544 — [review] Stop message hard-codes 'duplicate tool-call loop detected' for every loop type — 7 of the 10 detectors render a self-contradicting attribution (unchanged code; also defer…
  • packages/core/src/services/loopDetectionService.ts:502 — [probe] checkAlternatingPattern remains argument-only for stateful read tools — ABAB task_list poller with changing results still halts under skipLoopDetection=false (unchanged code; …
  • packages/core/src/services/loopDetectionService.ts:685 — [probe] Partial result evidence is treated like no evidence — one unrecorded result in a parallel batch halts a productive poller despite every recorded result changed (probe-reproduc…
  • packages/core/src/services/loopDetectionService.test.ts:2269 — [probe] Flood test's eviction pressure comes from a hand-mirrored MAX_TRACKED_TOOL_REQUESTS constant — upward drift of the source constant silently unpins the && stateful guard …
  • packages/core/src/agents/runtime/agent-events.ts:212 — [review] R1-15 AgentFinishEvent.loopType is still write-only at HEAD — author declined for this PR (telemetry purpose fulfilled via SubagentExecutionEvent); deferred, not re-posted
中文说明

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

未审查: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。

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

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

Comment thread packages/core/src/services/loopDetectionService.ts
Comment thread packages/core/src/services/loopDetectionService.ts Outdated
Comment thread packages/core/src/services/loopDetectionService.ts Outdated
Comment thread packages/core/src/services/loopDetectionService.test.ts Outdated
@yiliang114

Copy link
Copy Markdown
Collaborator Author

Fixed in f34098e — R16-1 verified real at dfadc01: recordToolResult accumulated turn-wide (key|fingerprint) pair totals (statefulPairCounts), feeding both the gated global-duplicate halt and — via capMaxKeyRepeat — the always-on adaptive cap. A board oscillating between two byte-identical states therefore halted on the 11th poll (GLOBAL_TOOL_CALL_DUPLICATE, heuristics on) and, under the CLI default (skipLoopDetection=true), via TURN_TOOL_CALL_CAP past the 100-call soft cap — contradicting the invariant the diff's own comment states above statefulPairCounts.

Fix: per-key consecutive identical-result counting — the count restarts at 1 whenever the result differs from its predecessor for that key — replacing the turn-wide pair totals in both consumers (global-duplicate guard and the cap's stuck signal). A genuinely frozen board still accumulates even when interleaved with other calls.

Regression tests (packages/core/src/services/loopDetectionService.test.ts):

  • does not accumulate an oscillating board toward the global-duplicate halt (heuristics on) — oscillating board survives, heuristics mode
  • keeps an oscillating board alive past the adaptive cap (skipLoopDetection default) — oscillating board survives 120 calls past the soft cap, CLI-default mode
  • still halts an interleaved frozen board via the adaptive cap — frozen direction still halts with TURN_TOOL_CALL_CAP

Both oscillating tests fail against the pre-fix source (verified by temporarily reverting the fix). Full suite: 140/140 passed; core typecheck clean.

@yiliang114

Copy link
Copy Markdown
Collaborator Author

@qwen-code /triage

1 similar comment
@yiliang114

Copy link
Copy Markdown
Collaborator Author

@qwen-code /triage

@qwen-code-ci-bot

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

Copy link
Copy Markdown
Collaborator

Sandboxed verification: ⚠️ incomplete — cancelled - workflow run

The verification job was cancelled before producing a report.

中文 — 判定:⚠️ 未完成 · 已取消

验证作业在生成报告前被取消。

Qwen Code · sandboxed verification

…l guards (#9450)

The sandboxed verification of the trimmed PR reported four findings; this
restores the three behavior fixes it proved live and pins the four coverage
gaps its mutation matrix exposed:

- Oversized (persisted) results escaped every result-aware guard: the
  stub envelope embeds a per-call unique path, so hashing it verbatim
  fingerprinted uniquely every poll and a frozen board read as "changed
  every time" (probe P2: no halt in 12 polls vs base halting at 5).
  buildStub now embeds a sha256 of the full pre-truncation output
  ("Full output sha256: <hex>"), and the guard's fingerprint reduces
  leading-producer stubs to that digest — with a path-free preview/
  truncated-part payload fallback for digest-less stubs and verbatim
  treatment of non-stub text (a mid-content quoted marker never matches:
  recognition is prefix-gated and the digest label must start its line).
  Frozen oversized boards halt at the unchanged threshold regardless of
  the per-call path; mutations past the preview window stay visible.
- Provider-duplicate call ids halted a productive poller fail-safe (probe
  P3): request counts fed pre-dedup while results land once per deduped
  executed call. Both reasoning-loop owners now feed the guards one
  ToolCallRequest per call id per attempt (a per-attempt Set mirroring
  dedupeToolCallsById; id-less calls never deduped), cleared on
  retry/fallback — agent-core's subagent stream loop and client.ts's
  main-session stream.
- Coverage pins (finding F4): restored the client.ts recording-wiring
  tests (frozen halt, changed survival, duplicate-id population parity);
  added QwenLogger loop_type journal tests, the interactive stop-message
  attribution test, and the partial-evidence fail-safe fixture.

Verification: packages/core tsc clean; loopDetectionService 145/145,
agent-headless 68/68, client 370/370, agent-interactive 25/25,
qwen-logger 43/43, truncation/shell/finalizer 368/368; prettier/eslint
clean on touched files.
@yiliang114

Copy link
Copy Markdown
Collaborator Author

Addressing all four verification findings — fixes and pins are on this branch (4bbf8eabd, on top of f34098e68):

F1 — oscillating boards (fixed in f34098e68, landed while verification was running). Pair counting now counts consecutive identical results per repeat key and restarts at 1 whenever the result differs from its predecessor, so an oscillating board is changed-state progress in both regimes (heuristics-on and the CLI default); the interleaved frozen board still halts via the adaptive cap. Pinned by three regression tests (oscillation under both regimes + interleaved frozen halt). The description's Risk wording matches this behavior again.

F2 — oversized (persisted) results (fixed). The escape was real, not hypothetical — reversing the earlier scope cut. buildStub now embeds a sha256 of the full pre-truncation output (Full output sha256: <hex>), and the guard's fingerprint reduces leading-producer stubs to that digest: frozen oversized boards halt at the unchanged threshold regardless of the per-call unique path, and mutations past the preview window still fingerprint differently. Digest-less stubs fall back to their path-free visible payload; non-stub text passes through verbatim, and recognition is prefix-gated with the digest label required to start its line, so a quoted stub marker mid-content fingerprints as ordinary text. Pinned by four tests (unique-path frozen halt, beyond-preview survival, digest-less fallback both directions, quoted-marker non-hijack).

F3 — provider-duplicate call ids (fixed, both owners). The subagent stream loop (agent-core) and the main-session stream (client.ts) now feed the guards one ToolCallRequest per call id per attempt (a per-attempt Set mirroring dedupeToolCallsById; id-less calls never deduped), cleared on retry/fallback. Request counts and result evidence stay the same population. Pinned by the headless duplicate-id E2E plus the restored client-side duplicate-id tests (changed-board survival with the 8-emissions/7-ids parity check, frozen-board halt).

F4 — coverage gaps (pinned).

  • client.ts recording wiring: restored four tests driving sendMessageStream with paired functionResponse ids (frozen halt with attribution, changed survival, duplicate-id survival + parity, duplicate-id frozen halt).
  • QwenLogger loop_type journaling: two tests (present with the exact detector on loop stops; absent otherwise).
  • Interactive stop-message attribution: one test pinning Agent stopped: duplicate tool-call loop detected (consecutive_identical_tool_calls).
  • Partial-evidence fail-safe (the M2 fixture): one test recording 4-of-5 results mid-streak, still halting at the threshold.

Verification: packages/core tsc clean; loopDetectionService 145/145, agent-headless 68/68, client 370/370, agent-interactive 25/25, qwen-logger 43/43, truncation/shell/finalizer 368/368; prettier/eslint clean on touched files. Full-suite attribution against the clean-main baseline posted once the run completes.


中文:四个 findings 全部处理(修复 + 钉住测试在 4bbf8eabd,基于 f34098e68 之上)。F1 振荡面板已在 f34098e68 修复(按连续相同结果计数、结果变化即重置)并加 3 个回归测试。F2 超大结果逃逸属实、推翻此前"未观测边界"的裁剪判断:buildStub 内嵌全文 sha256,守卫把生产者前缀开头的 stub 归一到该摘要(无摘要时回退到无路径的可见载荷;正文中部引用的标记按普通文本指纹化),4 个测试钉住。F3 重复 callId 在两个推理循环宿主(agent-core / client.ts)都按每 attempt 每 callId 只喂一次守卫,重试/回退时清零。F4 覆盖缺口全部补钉:client 接线 4 个测试、QwenLogger loop_type 2 个、交互式停止消息 1 个、部分证据失败保持安全 1 个。验证:tsc 干净,各目标套件全绿,prettier/eslint 干净;全量基线对比跑完即补。

@qwen-code-ci-bot

Copy link
Copy Markdown
Collaborator

Triage re-run completed without a new review.

⚠️ The bot has neither a verdict nor a deferral on 4bbf8eabd801010c1a2df4aad5a0bb313c2bd350 — no APPROVED, CHANGES_REQUESTED, or COMMENTED review of its own. A DISMISSED one does not count: dismiss_stale_reviews voids the bot's approval on every push, which is exactly when a fresh one is needed. If this re-run was meant to review or approve, it did not, and an approval left by another account is a separate vote that does not count as the bot's own.

⚠️ 机器人在 4bbf8eabd801010c1a2df4aad5a0bb313c2bd350既没有裁决也没有 defer —— 没有属于它自己的 APPROVEDCHANGES_REQUESTEDCOMMENTED 评审。DISMISSED 不算:dismiss_stale_reviews 会在每次推送时作废机器人的批准,而那恰恰是需要一次新批准的时刻。如果这次重跑本应评审或批准,那么它没有做到;而其他账号留下的批准是另一张票,不能算作机器人自己的。

The stage comments above were updated with the latest result. View workflow run.

上方各阶段评论已更新为最新结果。查看工作流运行

@yiliang114

Copy link
Copy Markdown
Collaborator Author

@qwen-code /triage

1 similar comment
@yiliang114

Copy link
Copy Markdown
Collaborator Author

@qwen-code /triage

@qwen-code-ci-bot

qwen-code-ci-bot commented Aug 26, 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: 58 passed · 0 failed · 58 total

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

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

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

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

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

Verification report

PR #9492 deep verification (follow-up round) — fix(core): make loop detection result-aware for task_list polls

Verdict: findings — scripted assertions 58 pass / 0 fail. The central claim is proven load-bearing by A/B at the new head, the previous round's headline finding (F1, oscillating boards halted) is fixed and pinned by the new tests, and all parity/fail-safe protections hold. Three previous Suggestion-level findings (F2, F3, F4) were re-measured and still stand; no blockers.
Verified head: f34098e680fa5c2bbbf407ca3f25a404bb09734b · base tip: 83da7233a8ce8bcfe9be8a6f464dc6903d8a0c3f · merge: 6220fdf4c25508f77df8c6ed82bece13624d02bc.

中文摘要

判定:findings(脚本化断言 58 通过 / 0 失败)。核心结论在新 head 上经 A/B 证实载荷成立:基线构建在第 5 次相同 task_list 请求处终止(#9450 误杀复现),PR 构建在结果持续变化时 20 次轮询不终止;冻结面板、缺失证据(失败保持安全)、确定性工具三类行为与基线逐格一致(见 A/B 表格,01-ab-base-arm.png / 02-ab-head-arm.png)。

上一轮发现状态:F1(振荡面板被终止)已被本轮唯一新增提交 f34098e680 修复并经变异验证钉住(M7:回退该机制后 4 个测试失败);F2(超 25 000 字符持久化 stub 逃逸)、F3(provider 重复 callId 终止生产性轮询)、F4(client.ts 接线 / QwenLogger 落库 / 交互式停止消息三处覆盖缺口)均重新实测后仍然成立(均 Suggestion,无阻塞),详见状态表与 Findings。

未覆盖范围:55 个提交逐一归因(depth-2 浅克隆仅 3 个提交可达,验证的是聚合 diff);真实模型流量的多 agent 实时 E2E(PR 声明范围外);交替模式检测器(声明不变,已确认无 stateful 例外);daemon/ACP 路径(声明延迟至 #10161,diff 未触碰)。

Previous-finding status (follow-up round)

The previous round verified head dfadc01b19 (verdict findings, 30 pass / 0 fail, four Suggestions). Exactly one commit was added since: f34098e680 ("count consecutive results for stateful poll loop guards"). All rows below were re-measured at the new head, never diffed against the old report (new base tip too: 83da7233a8 vs the previous round's 4c51f8cb9c).

# Finding Severity Status at new head
1 Oscillating boards (two alternating states, every result differs from its predecessor) still halted — poll 11 with heuristics on (global_tool_call_duplicate), poll 101 under the CLI default (turn_tool_call_cap); suite pinned neither regime Suggestion fixed — the delta commit replaces turn-wide (call, result) pair totals with per-key consecutive identical-result counts that restart at 1 whenever the result differs from its predecessor. Re-measured: oscillating board survives 24 polls with heuristics on (cell O1; base halts at 5) and 120 polls past the 100-call soft cap under the CLI default (cell O2); interleaved frozen boards still halt via the adaptive cap on both arms (O3). The delta's new tests are not vacuous: reverting the mechanism (mutation M7) fails 4 tests, including the E2E headless poller whose board alternates between exactly two states.
2 Oversized (>25 000 chars) task_list results are persisted into stubs whose envelope embeds a per-call unique path (<toolResultsDir>/<callId>.txt), so every fingerprint is unique and a frozen board escapes every result-aware guard — protection loosened vs base Suggestion stands (declined-with-rationale) — re-measured: frozen board delivered as realistic per-call stubs → no halt in 12 polls at head (S1) while base halts at 5; the constant-path control halts at 5 (S2), isolating the per-call path as the cause. The scope note still lists this hardening as intentionally trimmed ("an unobserved edge case; revisit only with real evidence"); the description is unchanged. The escape is bounded only by the 1000-call hard backstop.
3 Provider-duplicate call ids halt a productive poller: request counts (raw provider stream) and result evidence (post-dedupe executions) come from different populations, so the fail-safe halts at the 5th request even with changing results Suggestion stands — re-measured (cell D1): 5 request events including a duplicated callId with 3 recorded changing results halts at the 5th request at head, exactly as at base. Safe direction (halts, never runs away); the trimmed fix (intermediate commit 1ac2a81, a per-round Set of provider call ids feeding the guard) was not restored.
4 Coverage gaps proven by the mutation matrix: client.ts ToolResult wiring, QwenLogger loop_type serialization, interactive stop message Suggestion stands, refined — re-measured in the new matrix: M4 removing the entire client.ts recording block leaves client.test.ts 366/366 green (control M4c kills 4); M5 removing the loop_type serialization leaves qwen-logger + headless 108/108 green (control M5c kills 3); M8 removing the interactive stop-message suffix leaves agent-interactive.test.ts 24/24 green — the suite never exercises any mode that renders terminateModeMessage (only 'cancelled', which returns null). New granularity: the fail-safe evidence-completeness gate (resultsObserved >= expectedResults) is also unpinned (M2 survives 207/207; the shipped probe fixture is red on the mutant, green at head).

Central claim + A/B

Central claim: for the stateful read tool task_list, the consecutive-identical guard becomes result-aware — identical calls with changing results are productive polling (no halt), identical calls with unchanged results still halt at the same request count, and missing result evidence fails safe (pre-fix behavior).

Harness: harness-ab-service.mjs drives the compiled dist/ LoopDetectionService (no mocks of the unit under test) on both trees; per-arm expectations are encoded so predicted base-arm reds count as passing assertions. Witnesses: 01-ab-base-arm.png, 02-ab-head-arm.png; raw logs logs-ab-base.txt, logs-ab-head.txt.

Cell Scenario (oracle) base 83da7233a8 head f34098e680 Expectation
C1 20 identical task_list requests, board changes after each execution halts at request 5 (consecutive_identical_tool_calls) — the #9450 false positive no halt in 20 base red / head green
C2 frozen board, results recorded halts at 5 halts at 5, consecutive_identical_tool_calls parity
C3 no results ever recorded (wiring-gap fail-safe) halts at 5 halts at 5 parity (#5019 preserved)
C4 deterministic tool (read_file), changing recorded results halts at 5 halts at 5 parity (no exemption leak)
C5 heuristics on, interleaved calls, changing results halts (global_tool_call_duplicate, request-time) no halt in 8 rounds base red / head green
C6 heuristics on, interleaved calls, frozen results halts (global_tool_call_duplicate) halts at the 6th recorded result (result-time), same loop type parity, new detection point
C7 callId pairing API (recordToolResultByCallId) API absent changing results via pairing keep the 5th request alive; unknown id → false head-only API works
O1 F1: oscillating A/B board, heuristics on, 24 polls halts at 5 (args-only) no halt (was: halt at 11 pre-delta) fixed
O2 F1: oscillating A/B board, CLI default (skipLoopDetection=true), 120 polls past the 100 soft cap halts at 5 no halt (was: halt at 101 pre-delta) fixed
O3 interleaved frozen board + fillers past the soft cap halts, turn_tool_call_cap halts, turn_tool_call_cap (result-time stuck signal) parity
S1 F2: frozen board as persisted stubs with per-call unique paths, 12 polls halts at 5 no halt (escape re-measured; trimmed hardening) stands
S2 F2 control: identical stubs with a constant path halts at 5 halts at 5 escape is the per-call path
D1 F3: 5 request events incl. a duplicated callId, 3 recorded changing results halts at 5 (args-only) halts at 5 (fail-safe; residual false positive) stands, not a regression

All 38 scripted assertions (19 per arm) passed. Base control purity: worktree at HEAD^1, only packages/core rebuilt; root node_modules symlinked (lockfile untouched — empty package.json/package-lock.json diff asserted); the nested packages/core/node_modules (ajv 8.20.0 etc.) symlinked from the identical-lockfile install, readlink -f verified; packages/core has no internal @qwen-code/* dependencies (its package.json mentions the scope only as its own name), so no workspace symlink can leak head code; base dist asserted free of result-aware code (grep -c recordToolResult0 vs 12 at head).

Targeted gates (head, unmutated): loopDetectionService.test.ts + agent-headless.test.ts 207/207; client.test.ts + qwen-logger.test.ts + agent-interactive.test.ts 431/431; tsc --noEmit (packages/core) clean. Full-suite parity: head 70 failed | 21 931 passed | 10 skipped vs base 70 failed | 21 913 passed | 10 skipped — the 64 unique failing test names are byte-identical on both arms (diff core-full-suite-{base,head}.fails.txt empty, same 8 environment files: ide-client 18, logger 31, memoryDiscovery 6, file-token-storage 5, skill-manager 4, subagent-manager 3, installationManager 2, rulesDiscovery 1), delta +17 passing = exactly the PR's 17 added tests (14 service + 3 headless), +0 failing. (The raw head count includes one extra passing test — this round's verification probe file, since removed from the tree; the +17 attribution above excludes it.)

Corrections

Carried from the previous round, still applicable: the PR body attributes the pre-existing packages/core failures to "system git predates git init -b". This container runs git 2.39.5 and the identical 70 failures reproduce on both arms at the new base tip — the identity claim is confirmed (no new failures introduced by the PR), the cause is still not (the failures are environment/mock-order issues in files the PR does not touch). No code change requested; correcting the record for the next reader.

Findings

No blockers. Three re-measured Suggestions carried from the previous round, in severity order.

F2 — Oversized (persisted) task_list results escape every result-aware guard — protection loosened vs base for results >25 000 chars (Suggestion, stands)

coreToolScheduler persists any tool result over DEFAULT_TRUNCATE_TOOL_OUTPUT_THRESHOLD (25 000 chars) into a <persisted-output> stub whose header embeds a per-call unique path <toolResultsDir>/<callId>.txt (tools/truncation.ts buildStub). extractResultText hashes the whole model-visible response, so every poll fingerprints uniquely and a frozen board reads as "changed every time". Re-measured at the new head (cell S1/S2, harness-ab-service.mjs):

  • frozen board delivered as realistic per-call stubs → no halt in 12 polls at head; base (args-only) halts at 5 — a loosening versus base for this result class;
  • identical stubs with a constant path → halts at 5, isolating the per-call path as the cause;
  • consequence: the only remaining bound for oversized stateful results is the 1000-call adaptive hard backstop.

Repro: node tmp/pr9492-verify-20260826-170042/harness-ab-service.mjs head (cells S1/S2).

This is the "truncated-result fingerprint hardening" the scope note says was cut as "an unobserved edge case; revisit only with real evidence" — the mechanism is observably live on the production path (any task_list result over 25K chars). The trimmed history contains the demonstrated fix direction (digest-anchored stub parsing, commits 8b5b610d/f4e85c74/167b0af5-family). Suggested resolution: if the cut stands by authorial decision, the description should say oversized stateful results are exempt (its "never loosened" sentence covers missing evidence only, while this is uniquely-varying evidence); otherwise restore the digest-based parsing.

F3 — Provider-duplicate call ids halt a productive poller (fail-safe) — the trimmed population fix is still missed (Suggestion, stands)

agent-core.ts feeds the guard one ToolCallRequest event per provider function call (raw chunkFunctionCalls loop, ~line 1120 — no per-round call-id Set exists at this head), while execution dedupes by call id (dedupeToolCallsById, ~line 1676) and records one result per unique id. Request counts and result evidence therefore come from different populations. Re-measured (cell D1): a changing-board poller whose second round emits the same call id twice halts at the 5th emitted request via the fail-safe (3 results observed < 4 expected → no exemption), exactly as at base — not a regression, but a residual false positive of exactly the class this PR exists to remove. Safe direction (halts, never runs away). The trimmed intermediate commit 1ac2a81 ("count deduped provider call ids once in the subagent loop guard", a per-round Set mirroring dedupeToolCallsById) fixed precisely this. Repro: node tmp/pr9492-verify-20260826-170042/harness-ab-service.mjs head (cell D1).

F4 — Coverage gaps re-proven at the new head: client.ts wiring, telemetry sink, interactive message — plus the fail-safe completeness gate (Suggestion, stands)

Mutation matrix on head (each row a real vitest run; witness 03-mutation-matrix-summary.png, live M1 run 04-m1-live-carve-out-removed.png; positive controls landed in the same file as their mutants):

# Mutation Suite Result
M1 remove result-aware carve-out in checkToolCallLoop service + headless KILLED — 8 failed | 199 passed; failures are the intended behavioral assertions (expected true to be false on changing boards)
M2 drop evidence-completeness check (state && observed>=expectedstate) service + headless + probe SURVIVED — 207/207 green; probe fixture (partial evidence: 3 of 4 results recorded, changing) is red on the mutant (expected false to be true), green at head → coverage gap, fixture shipped (fixture-partial-evidence-failsafe.test.ts)
M3 remove loopType spread from FINISH emit (agent-headless.ts) headless -t "issue #9450" KILLED — 2 failed, expected undefined to be 'consecutive_identical_tool_calls'
M4 revert the entire client.ts ToolResult recordToolResultByCallId wiring client.test.ts SURVIVED — 366/366 green: the main-session recording owner the description cites is pinned by nothing
M4c control: always-on LoopDetected yield → wrong event type client.test.ts KILLED (control) — 4 failed; the suite provably exercises client.ts
M5 remove loop_type serialization in QwenLogger.logSubagentExecutionEvent qwen-logger + headless SURVIVED — 108/108 green (the headless suite mocks logSubagentExecution, so journal attribution — issue requirement #7 — is unpinned end to end)
M5c control: drop duration_ms in logHookCallEvent qwen-logger.test.ts KILLED (control) — 3 failed
M6 control: threshold >=> service KILLED — 10 failed
M7 delta revert: turn-wide pair accumulation instead of consecutive counts service + headless KILLED — 4 failed: both oscillation tests, the past-cap survival test, and the E2E headless poller → the delta's new tests pin exactly its mechanism (not vacuous)
M8 remove the (loopType) suffix from the interactive stop message agent-interactive.test.ts SURVIVED — 24/24 green; the suite never exercises any terminate mode that renders terminateModeMessage (only 'cancelled', which returns null) — the whole function has zero test reachability

Classification: all four survivors are coverage gaps (behavior correct at head, nothing asserts it) — not dead code (each mutant changes observable behavior, proven by the probes/controls), not redundant defence. Fixtures that would pin them: fixture-partial-evidence-failsafe.test.ts (M2, shipped and measured); a client.test.ts arm driving sendMessageStream with paired functionResponse ids and asserting the halt/record (the intermediate commit b0db4304 had one before the trim, M4); a qwen-logger.test.ts case asserting loop_type in the serialized properties (M5); an agent-interactive.test.ts case whose mocked core returns LOOP_DETECTED with a loopType and asserts the suffixed message/lastRoundError (M8).

Not covered

  • Per-commit attribution: the checkout is depth-2 (3 commits reachable) while the snapshot lists 55 commits; git rev-list HEAD^1..HEAD^2 returns 1 at the shallow boundary (plausible-but-wrong number, per the shallow caveat). The aggregate HEAD^1..HEAD diff is what was verified; individual commits were not exercised separately. The delta since the previous round is exactly one commit (f34098e680), verified end to end.
  • Live multi-agent E2E with real model traffic — declared out of scope by the PR; the headless E2E tests mock the model stream (they do exercise the real agent runtime, scheduler, and loop-detector wiring).
  • Alternating-pattern detector — declared unchanged; confirmed statically that checkAlternatingPattern carries no stateful carve-out at this head (an ABAB task_list shape is still counted args-only at request time). Not re-measured behaviorally.
  • Daemon/ACP path — declared deferred to Make daemon/ACP adaptive-cap stuck signal result-aware for stateful reads (follow-up from #9492) #10161; the diff touches no daemon code (diffstat verified).
  • packages/cli suite — diff is core-only; the CLI default regime (skipLoopDetection ?? true, packages/cli/src/config/config.ts:2372) was exercised at the service level (cells O2/O3). No cli-side probe was run.
  • send_message/task_update — deliberately argument-only per the PR's declared narrow scope (STATEFUL_READ_TOOLS = {'task_list'}); not probed.
  • Probes drive the service's public API exactly as the two recording owners call it; the runtime path is covered by the PR's mocked-model headless tests, not by a live sendMessageStream.
  • The flakiness gate (changed test files × N rounds) is owned by the workflow, not this round.

Methodology

Environment: CI verify container (node:22-bookworm, node v22.23.2, git 2.39.5), merge ref refs/pull/9492/merge at depth 2; npm ci + full build completed before verification (environment contract). A/B: head dist from the workflow build; base control in tmp/base-tree (worktree at HEAD^1, only packages/core rebuilt — one rebuild obstacle fixed along the way: the worktree lacks the gitignored nested installs, so ajv/dist/2020.js and @lydell/node-pty types resolved wrong until the identical-lockfile nested packages/core/node_modules and the root node_modules were symlinked in; readlink -f verified, no internal @qwen-code/* links involved). The harness imports the compiled dist/src/services/loopDetectionService.js directly and drives checkAlwaysOnSafeties / addAndCheck / recordToolResult[ByCallId] with ToolCallRequest events and functionResponse parts shaped like production traffic (persisted-stub envelopes for F2 reproduced verbatim from tools/truncation.ts buildStub); loggers run real with getUsageStatisticsEnabled()=false (QwenLogger no-op, OTel uninitialized). Mutations were single-point source edits on head, run through vitest, reverted with git checkout (tree confirmed clean after each, probe fixture and base worktree removed at the end). Full-suite attribution compared stripped-ANSI × lines of both arms verbatim. Raw logs and rerunnable harness/fixtures live in this artifact dir (node harness-ab-service.mjs <base|head>).

Flakiness gate log

rounds=5 files=2 skipped=0
file packages/core/src/agents/runtime/agent-headless.test.ts: (cd packages/core) npx --no-install vitest run ./src/agents/runtime/agent-headless.test.ts
file packages/core/src/services/loopDetectionService.test.ts: (cd packages/core) npx --no-install vitest run ./src/services/loopDetectionService.test.ts


per-file results (P=pass F=fail I=infra-exit, one letter per run):
  packages/core/src/agents/runtime/agent-headless.test.ts: PPPPP
  packages/core/src/services/loopDetectionService.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/core/src/agents/runtime/agent-headless.test.ts: P (exit 0)
round 1 · packages/core/src/services/loopDetectionService.test.ts: P (exit 0)
round 2 · packages/core/src/agents/runtime/agent-headless.test.ts: P (exit 0)
round 2 · packages/core/src/services/loopDetectionService.test.ts: P (exit 0)
round 3 · packages/core/src/agents/runtime/agent-headless.test.ts: P (exit 0)
round 3 · packages/core/src/services/loopDetectionService.test.ts: P (exit 0)
round 4 · packages/core/src/agents/runtime/agent-headless.test.ts: P (exit 0)
round 4 · packages/core/src/services/loopDetectionService.test.ts: P (exit 0)
round 5 · packages/core/src/agents/runtime/agent-headless.test.ts: P (exit 0)
round 5 · packages/core/src/services/loopDetectionService.test.ts: P (exit 0)

Evidence images

01-ab-base-arm

02-ab-head-arm

03-mutation-matrix-summary

04-m1-live-carve-out-removed

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 commented Aug 26, 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: 60 passed · 0 failed · 60 total

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

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

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

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

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

Verification report

PR #9492 deep verification (follow-up round) — fix(core): make loop detection result-aware for task_list polls

Verdict: merge-ready — scripted assertions 60 pass / 0 fail (34 A/B harness cells, 6 stub-producer probes, 17 mutation-matrix expectations, 3 gate checks). The central claim is proven load-bearing by A/B again at the new head, and all four previous-round findings are fixed and now test-pinned (mutation matrix 12/12 killed, 0 survivors — the three previous survivors included). One new nit-level Suggestion (unreachable corner, see F-new).
Verified head: 4bbf8eabd801010c1a2df4aad5a0bb313c2bd350 · base tip: a82a11a0a4d8d4f97796ac9f56d276364dd3bd64 · merge: b8ef666db4 · follow-up round (previous report: 4 findings at head dfadc01b19, all re-measured below).

中文摘要

判定:merge-ready(脚本化断言 60 通过 / 0 失败)。核心结论在新 head 上再次经 A/B 证实载荷成立:基线构建对"结果持续变化"的相同 task_list 轮询仍在第 5 次请求误杀(#9450 复现),PR 构建 120–150 次轮询不终止;冻结面板、缺失证据(失败保持安全)、确定性工具、交错冻结面板的自适应上限终止点(第 101 次调用)均与基线逐格一致。

上一轮 4 个发现全部修复且被测试钉住(状态表见下):

  1. F1 振荡面板 — 已修复:顺序感知(连续)结果计数恢复,两种配置下 150/30 次轮询不终止;回退变异被恰好 3 个振荡/上限用例杀死。
  2. F2 超大持久化结果逃逸 — 已修复:buildStub 内嵌全量输出 sha256,守卫读取锚定摘要行;真实生产者端到端探针确认冻结面板第 5 次终止、预览窗口外的变化不终止。
  3. F3 provider 重复 callId — 已修复:两个宿主的守卫喂入去重均恢复;两处回退变异各被 1 个新用例杀死。
  4. F4 覆盖缺口 — 已修复:client.ts 接线、QwenLogger loop_type、交互式停止消息、部分证据失败保持安全四处变异全部被新增测试杀死(12/12,零幸存)。

A/B 结论:见 A/B 表格(01-ab-base-arm.png / 02-ab-head-arm.png);变异矩阵见 03-mutation-matrix-summary.png;全量套件对照见 04-full-suite-gate-both-arms.png

新发现(仅 1 条,Suggestion/微瑕,当前接线不可达):交错轮询 + 结果证据缺失时,上限卡滞信号不再由请求喂入(基线第 101 次调用终止),仅剩 1000 次硬兜底(实测第 1001 次)。两个现网宿主均记录结果、守护进程有独立追踪器,故该组合在生产不可达;描述的风险章节也把硬兜底列为残余边界,但正文"缺失证据失败保持安全"一句仅对连续守卫成立,建议补注释说明。

未覆盖范围:56 个提交逐一归因(浅克隆仅 3 个提交可达,dfadc01b 对象本地幸存故本轮 delta 可直接对照);真实模型流量的多 agent 实时 E2E(PR 声明范围外);交替模式检测器(声明不变);daemon/ACP 卡滞信号(声明延迟至 #10161)。

Previous-finding status (follow-up round)

The previous round verified head dfadc01b19 (4 Suggestions). That commit object survives in this checkout's object store, so the delta was diffed directly: 2 commits, +821/−23 across 9 files — the restored order-aware result counts (F1), the stub digest hardening (F2), the guard-feed dedup on both owners (F3), and new pinning tests (F4). Every carried-forward measurement below was re-run at the new head, not diffed against the old report.

# Finding (prev round) Severity Status at new head 4bbf8eabd8
F1 Oscillating boards still halted (heuristics-on @​11 via global_tool_call_duplicate, default @​101 via cap stuck signal), contrary to the description; suite unpinned Suggestion fixed — consecutive (order-aware) result counts restored (statefulConsecutiveResults restarts at 1 on every changed result). Re-measured C5/C7: oscillating board survives 150 polls (default regime) and 30 polls (heuristics on); base halts @​5 in both. Mutation M7 (fingerprint-blind counting) is killed by exactly the 3 oscillation/cap tests the delta added, with the frozen-board control staying green.
F2 Oversized (persisted) results escape every result-aware guard via per-call unique stub paths (>25 000 chars ⇒ never halts; base halted @​5) Suggestion fixedbuildStub now embeds Full output sha256: <sha256 of FULL content>; the guard reduces stubs to the anchored digest (stripPersistenceEnvelope/extractAnchoredStubDigest, line-anchored, 64 lowercase hex, producer-prefix-gated). Re-measured F2a–F2d + real-producer E2E: frozen oversized board halts @​5 (base parity), mutations beyond the 2000-char preview keep polling alive, digest-less stubs fall back to the path-free preview, mid-content quoted markers fingerprint as ordinary text. Mutation M8 (digest disabled) is killed by exactly the beyond-preview test.
F3 Provider duplicate call ids halt a productive poller via the fail-safe (request counts and result evidence from different populations) Suggestion fixed — guard-feed dedup restored on both owners: loopGuardStreamedCallIds in agent-core.ts and loopGuardFedCallIds in client.ts (events still flow to consumers; only the guard feed is deduped; id-less calls never deduped, mirroring execution). Mutations M9/M10 (dedup removed) are each killed by the new "counts a provider-duplicate call id once" tests (expected "spy" to be called 6 times, but got 3 times).
F4 Coverage gaps: client.ts ToolResult wiring unpinned (M4 survived), QwenLogger loop_type unpinned (M5 survived), interactive stop message had zero tests Suggestion fixed — the delta adds tests for all three plus the partial-evidence fail-safe. Re-measured matrix: M4 killed (2 red), M5 killed (1 red), M6/interactive killed (1 red), M2/partial-evidence killed (1 red). Matrix is now 12/12 killed, 0 survivors (03-mutation-matrix-summary.png).

Central claim + A/B

Central claim (unchanged from the previous round): for the stateful read tool task_list, the consecutive-identical guard becomes result-aware — identical calls with changing results are productive polling (no halt), identical calls with unchanged results still halt at the same request count, and missing result evidence fails safe (pre-fix behavior, #5019 preserved).

Harness: harness-ab-service.mjs drives the compiled dist/ LoopDetectionService (no mocks of the unit under test) on both trees, mirroring the two recording owners (checkAlwaysOnSafeties/addAndCheckHeuristicLoops on requests, recordToolResult[ByCallId] after execution). Base control: worktree at HEAD^1 with only packages/core rebuilt; root node_modules reused — clean control because the PR leaves package.json/package-lock.json untouched (diff empty) and packages/core has zero @qwen-code/* dependencies (workspace symlinks cannot leak head code; readlink -f verified both links). Base dist asserted free of result-aware code (grep -c recordToolResult → 0 vs present at head; base proto lacks recordToolResult/recordToolResultByCallId). Witnesses: 01-ab-base-arm.png, 02-ab-head-arm.png; raw logs logs/ab-{base,head}.log.

Cell Scenario (oracle) base a82a11a0a4 head 4bbf8eabd8 Expectation
API recording API present absent present arm-specific
C1 120 identical polls, board changes after each execution halts @​5 (the #9450 false positive) no halt in 120 base red / head green
C2 frozen board, results recorded halts @​5 halts @​5 consecutive_identical_tool_calls parity
C3 no results ever recorded (wiring-gap fail-safe) halts @​5 halts @​5 parity (#5019 preserved)
C4 deterministic tool (read_file), changing recorded results halts @​5 halts @​5 parity (no exemption leak)
C5 F1 · oscillating board A/B, 150 polls, default regime halts @​5 no halt in 150 base red / head green
C6 interleaved decoy + frozen board, results recorded halts @​101 calls turn_tool_call_cap halts @​101 calls turn_tool_call_cap (result-fed signal) parity — halt point does not move
C6b interleaved decoy + frozen board, no results recorded halts @​101 calls halts @​1001 calls (hard backstop only) measured asymmetry, see F-new
C7 F1 · oscillating board, 30 polls, heuristics ON halts @​5 no halt in 30 base red / head green
C8 heuristics ON · interleaved decoy · changing results halts @​ task_list req 6 (global_tool_call_duplicate, request-time) no halt in 12 rounds base red / head green
C9 heuristics ON · interleaved decoy · FROZEN results halts @​ req 6 (request-time) halts @​ result 6 (global_tool_call_duplicate, result-time) parity, new detection point
C10 partial evidence (3 of 4 results recorded) halts @​5 halts @​5 (fail-safe) parity
C11 callId pairing: 8 changing polls + unknown id n/a (API absent) no halt; unknown → false head-only
C12 callId pairing: frozen board n/a halts @​5 head-only
F2a F2 · frozen oversized board via per-call-unique stub paths (digest-bearing) halts @​5 halts @​5 parity restored (old head: no halt)
F2b F2 · oversized board mutating beyond the preview window halts @​5 no halt in 12 base red / head green
F2c F2 · digest-less legacy stub, frozen preview halts @​5 halts @​5 (preview fallback) parity
F2d F2 · quoted digest marker mid-content, changing text halts @​5 no halt in 8 (markers ignored mid-string) base red / head green
NF non-file stub branch (persistence unavailable), frozen halts @​5 halts @​5 parity
RP real persistAndTruncateToolResult E2E: frozen / mutating-beyond-preview halts @​5 / halts @​5 halts @​5 / no halt in 12 F2 proven through the actual producer

All 40 harness assertions passed (base 16 + head 18 + NF 2 + RP 4). Secondary claims re-verified: attribution (ReasoningLoopResult.loopType → FINISH event → telemetry loop_type → journal) killed by M3/M5 mutations; result recording fires from both owners (M4/M10 reverts each killed).

Targeted gates (head): loopDetectionService.test.ts 145/145, agent-headless.test.ts 68/68, client.test.ts 370/370, qwen-logger.test.ts 43/43, agent-interactive.test.ts 25/25 — all matching the PR body's claimed counts exactly; the Reviewer Test Plan's filtered run (-t "issue #9450") passes 4/4. Full packages/core suite: head 21 977 passed / 79 failed / 10 skipped vs base 21 947 passed / 79 failed / 10 skipped — the 73 unique failing test names are byte-identical on both arms (core-full-suite-fails.diff.txt empty), delta +30 passing (= the PR's new tests), +0 failing (04-full-suite-gate-both-arms.png). tsc --noEmit (packages/core) clean. (The 79 failures are pre-existing at this base tip — sampled client.telemetrySwap.test.ts: TypeError: this.config.getToolRegistry is not a function, a fixture issue in files this PR does not touch; the previous round saw 70 at the older base tip 4c51f8cb9c, the set moves with the base.)

Corrections

None new this round. The previous round corrected the PR body's attribution of the pre-existing failures to an old system git; the body no longer carries that claim, and this round's empty failure-list diff confirms the identity claim ("pre-existing failures reproduce identically on the unmodified baseline") at the new base tip.

Findings

F-new — The cap's stuck signal has no missing-evidence fail-safe for INTERLEAVED stateful polling; bounded at the 1000-call hard backstop instead of 101 (Suggestion, unreachable in current wiring)

trackCapKeyRepeat is skipped unconditionally for stateful tools (if (!stateful) in checkAlwaysOnSafeties), so the adaptive cap's stuck signal is fed only by recorded results. When no results are recorded (a wiring gap) AND the polls are interleaved with other calls (so the consecutive guard never reaches threshold), nothing accumulates and only the hard backstop remains. Measured (cell C6b, both arms): interleaved frozen task_list, results never recorded — base halts at total call 101 (request-fed stuck signal), head halts at total call 1001 (turn_tool_call_cap hard backstop). The heuristics-on twin shows the same shape: base halts at the 6th request via request-time global_tool_call_duplicate; with missing evidence the head-side result-time counterpart never fires, leaving the same 1000-call bound.

Bounding: unreachable in the current wiringcheckAlwaysOnSafeties has exactly two production consumers (agent-core.ts:938, client.ts:3774) and both record every executed task_list result (recordToolResult after processFunctionCalls; recordToolResultByCallId per functionResponse id); the daemon/ACP path runs its own per-turn tracker (acp-integration/session/Session.ts), not this service. The non-interleaved missing-evidence case remains fail-safe via the consecutive guard (halts @​5, cells C3/C10). The description's Risk section already names the hard backstop as the residual bound for stuck polls, so the behavior is inside the stated envelope; the mismatch is only that the body's "missing result evidence fails safe" sentence is scoped to the DashScope/consecutive guard but reads universal. Suggested resolution (author's call): a one-line comment on the if (!stateful) skip noting the hard-backstop-only bound for the wiring-gap case, or a fail-safe fallback (request-time counting until the first result arrives for a key). No code change is required by this report.

Mutation matrix (12/12 killed · 0 survivors)

Each row a real vitest run on head source (single-point edit, reverted with git checkout after; tree confirmed clean each time). Witnesses 03-mutation-matrix-summary.png and 05-m1-carve-out-removed-live.png (live M1 run); raw logs logs/m*.log. Positive controls landed in the same files as their mutants.

# Mutation Suite Result
M1 remove the result-aware carve-out (checkToolCallLoop) service 145 KILLED — 10 failed; expected true to be false on the changing board (control)
M7 fingerprint-blind consecutive counts (F1 revert) service 145 KILLED — 3 failed: exactly the oscillation/cap pins; frozen-board pin stays green
M8 stub digest extraction disabled (F2 revert) service 145 KILLED — 1 failed: "mutations land beyond the preview window"; frozen-oversized pin stays green via the preview fallback
M2 drop the evidence-completeness condition service 145 KILLED — 1 failed: "result evidence is only partial (fail-safe)" (prev round: SURVIVED)
MX invert the corroboration comparison (exemption always applies) service 145 KILLED — 5 failed incl. all frozen-board halt pins (vacuity check: the halt is pinned by the comparison, not just the threshold)
M6c threshold >=> (positive control) service 145 KILLED — 11 failed (control)
M3 remove loopType from the FINISH emit headless 68 KILLED — 2 failed, expected undefined to be 'consecutive_identical_tool_calls'
M9 remove agent-core guard-feed dedup (F3 revert) headless 68 KILLED — 1 failed: "counts a provider-duplicate call id once" (expected "spy" to be called 6 times, but got 3 times)
M4 disable client.ts recordToolResultByCallId wiring client 370 KILLED — 2 failed: frozen-board halt + provider-dup pins (prev round: SURVIVED)
M10 disable client guard-feed dedup (F3 revert) client 370 KILLED — 1 failed: "counts a provider-duplicate call id once"
M5 remove loop_type serialization (QwenLogger) qwen-logger 43 KILLED — 1 failed: "journals the loop detector attribution" (prev round: SURVIVED)
M6 generic interactive stop message interactive 25 KILLED — 1 failed: "surfaces the exact loop detector" (prev round: zero tests)

Every revert mutation of a restored fix (M7/M8/M9/M10) is killed by the tests this delta added, and all three previous survivors are now pinned — the suite holds down what the PR claims.

Not covered

  • Per-commit attribution: the checkout is depth-2 (git rev-list HEAD^1..HEAD^2 returns 1 at the shallow boundary while the snapshot lists 56 commits) — only the merge, base tip, and PR head are reachable. The aggregate HEAD^1..HEAD diff is what was verified. The previous head dfadc01b object happens to survive in the object store, so the delta since the previous round (+821/−23, 9 files) was diffed directly, but its intermediate commits (f34098e6 etc.) remain unreachable.
  • Live multi-agent E2E with real model traffic — declared out of scope by the PR; the headless E2E tests mock the model stream. The C6b/F-new corner is therefore a wiring analysis plus service-level measurement, not an observed production failure.
  • Alternating-pattern detector — declared unchanged (an ABAB shape of two alternating keys still trips it args-only; this PR's cells used varied-args decoys, which do not).
  • Daemon/ACP path — declared deferred to Make daemon/ACP adaptive-cap stuck signal result-aware for stateful reads (follow-up from #9492) #10161; the diff touches no daemon code (verified by diffstat); Session.ts keeps its own per-turn cap.
  • packages/cli suite — diff is core-only; the cli build ran green as part of the workflow's pre-verification build. No cli-side probe was run.
  • The F2 stub shapes were exercised through the real persistAndTruncateToolResult (file branch) and a faithful replica of the non-file branch; the shell-only truncateToolOutput "Truncated part of the output" shape is recognized by the stub grammar but is not reachable for task_list (shell-tool path), so it was not probed.
  • The harness drives the service's public API exactly as the two recording owners call it; the transport (a live sendMessageStream) is exercised by the PR's own client/headless tests, which the mutation matrix proves non-vacuous.
  • Flakiness gate (changed files × 5 rounds) is run by the workflow itself, as in the previous round.

Methodology

Environment: CI verify container (node:22-bookworm, node v22.23.2), merge ref refs/pull/9492/merge at depth 2; npm ci + full build completed before verification (dist freshness asserted by grepping the new symbols). A/B: head dist from the workflow build; base control built in tmp/base-tree (worktree at HEAD^1, only packages/core rebuilt via scripts/build_package.js with the root node_modules symlinked — realpath-verified; no internal @qwen-code/* deps in packages/core, lockfile untouched). The harness (harness-ab-service.mjs) imports the compiled dist/src/services/loopDetectionService.js directly and drives checkAlwaysOnSafeties / addAndCheckHeuristicLoops / recordToolResult[ByCallId] with production-shaped ToolCallRequest events and functionResponse parts; loggers run real with getUsageStatisticsEnabled()=false (QwenLogger no-ops) and OTel uninitialized. The oversized-stub cells were additionally verified through the real compiled persistAndTruncateToolResult (/tmp/probe-real-producer.mjs). Mutations were single-point source edits on head, run through vitest, and reverted (git checkout); the tree was confirmed clean after each. Full-suite attribution compared stripped FAIL lines of both arms verbatim (diff empty). Evidence images via scripts/verify-capture.mjs. Raw logs: logs/ab-{base,head}.log, logs/m*.log, logs/full-suite-{head,base}.log, core-full-suite-{head,base}.fails.txt; all harnesses are rerunnable (node harness-ab-service.mjs <tree> <base|head>).

Flakiness gate log

rounds=5 files=5 skipped=0
file packages/core/src/agents/runtime/agent-headless.test.ts: (cd packages/core) npx --no-install vitest run ./src/agents/runtime/agent-headless.test.ts
file packages/core/src/agents/runtime/agent-interactive.test.ts: (cd packages/core) npx --no-install vitest run ./src/agents/runtime/agent-interactive.test.ts
file packages/core/src/core/client.test.ts: (cd packages/core) npx --no-install vitest run ./src/core/client.test.ts
file packages/core/src/services/loopDetectionService.test.ts: (cd packages/core) npx --no-install vitest run ./src/services/loopDetectionService.test.ts
file packages/core/src/telemetry/qwen-logger/qwen-logger.test.ts: (cd packages/core) npx --no-install vitest run ./src/telemetry/qwen-logger/qwen-logger.test.ts


per-file results (P=pass F=fail I=infra-exit, one letter per run):
  packages/core/src/agents/runtime/agent-headless.test.ts: PPPPP
  packages/core/src/agents/runtime/agent-interactive.test.ts: PPPPP
  packages/core/src/core/client.test.ts: PPPPP
  packages/core/src/services/loopDetectionService.test.ts: PPPPP
  packages/core/src/telemetry/qwen-logger/qwen-logger.test.ts: PPPPP

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

--- per-invocation detail (full copy in the artifact) ---
round 1 · packages/core/src/agents/runtime/agent-headless.test.ts: P (exit 0)
round 1 · packages/core/src/agents/runtime/agent-interactive.test.ts: P (exit 0)
round 1 · packages/core/src/core/client.test.ts: P (exit 0)
round 1 · packages/core/src/services/loopDetectionService.test.ts: P (exit 0)
round 1 · packages/core/src/telemetry/qwen-logger/qwen-logger.test.ts: P (exit 0)
round 2 · packages/core/src/agents/runtime/agent-headless.test.ts: P (exit 0)
round 2 · packages/core/src/agents/runtime/agent-interactive.test.ts: P (exit 0)
round 2 · packages/core/src/core/client.test.ts: P (exit 0)
round 2 · packages/core/src/services/loopDetectionService.test.ts: P (exit 0)
round 2 · packages/core/src/telemetry/qwen-logger/qwen-logger.test.ts: P (exit 0)
round 3 · packages/core/src/agents/runtime/agent-headless.test.ts: P (exit 0)
round 3 · packages/core/src/agents/runtime/agent-interactive.test.ts: P (exit 0)
round 3 · packages/core/src/core/client.test.ts: P (exit 0)
round 3 · packages/core/src/services/loopDetectionService.test.ts: P (exit 0)
round 3 · packages/core/src/telemetry/qwen-logger/qwen-logger.test.ts: P (exit 0)
round 4 · packages/core/src/agents/runtime/agent-headless.test.ts: P (exit 0)
round 4 · packages/core/src/agents/runtime/agent-interactive.test.ts: P (exit 0)
round 4 · packages/core/src/core/client.test.ts: P (exit 0)
round 4 · packages/core/src/services/loopDetectionService.test.ts: P (exit 0)
round 4 · packages/core/src/telemetry/qwen-logger/qwen-logger.test.ts: P (exit 0)
round 5 · packages/core/src/agents/runtime/agent-headless.test.ts: P (exit 0)
round 5 · packages/core/src/agents/runtime/agent-interactive.test.ts: P (exit 0)
round 5 · packages/core/src/core/client.test.ts: P (exit 0)
round 5 · packages/core/src/services/loopDetectionService.test.ts: P (exit 0)
round 5 · packages/core/src/telemetry/qwen-logger/qwen-logger.test.ts: P (exit 0)

Evidence images

01-ab-base-arm

02-ab-head-arm

03-mutation-matrix-summary

04-full-suite-gate-both-arms

05-m1-carve-out-removed-live

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

Qwen Code · sandboxed verification

@qwen-code-ci-bot

Copy link
Copy Markdown
Collaborator

Triage re-run completed without a new review.

⚠️ The bot has neither a verdict nor a deferral on 4bbf8eabd801010c1a2df4aad5a0bb313c2bd350 — no APPROVED, CHANGES_REQUESTED, or COMMENTED review of its own. A DISMISSED one does not count: dismiss_stale_reviews voids the bot's approval on every push, which is exactly when a fresh one is needed. If this re-run was meant to review or approve, it did not, and an approval left by another account is a separate vote that does not count as the bot's own.

⚠️ 机器人在 4bbf8eabd801010c1a2df4aad5a0bb313c2bd350既没有裁决也没有 defer —— 没有属于它自己的 APPROVEDCHANGES_REQUESTEDCOMMENTED 评审。DISMISSED 不算:dismiss_stale_reviews 会在每次推送时作废机器人的批准,而那恰恰是需要一次新批准的时刻。如果这次重跑本应评审或批准,那么它没有做到;而其他账号留下的批准是另一张票,不能算作机器人自己的。

The stage comments above were updated with the latest result. View workflow run.

上方各阶段评论已更新为最新结果。查看工作流运行

@yiliang114

Copy link
Copy Markdown
Collaborator Author

@qwen-code /triage

1 similar comment
@yiliang114

Copy link
Copy Markdown
Collaborator Author

@qwen-code /triage

@qwen-code-ci-bot

Copy link
Copy Markdown
Collaborator

Triage re-run completed without a new review.

⚠️ The bot has neither a verdict nor a deferral on 4bbf8eabd801010c1a2df4aad5a0bb313c2bd350 — no APPROVED, CHANGES_REQUESTED, or COMMENTED review of its own. A DISMISSED one does not count: dismiss_stale_reviews voids the bot's approval on every push, which is exactly when a fresh one is needed. If this re-run was meant to review or approve, it did not, and an approval left by another account is a separate vote that does not count as the bot's own.

⚠️ 机器人在 4bbf8eabd801010c1a2df4aad5a0bb313c2bd350既没有裁决也没有 defer —— 没有属于它自己的 APPROVEDCHANGES_REQUESTEDCOMMENTED 评审。DISMISSED 不算:dismiss_stale_reviews 会在每次推送时作废机器人的批准,而那恰恰是需要一次新批准的时刻。如果这次重跑本应评审或批准,那么它没有做到;而其他账号留下的批准是另一张票,不能算作机器人自己的。

The stage comments above were updated with the latest result. View workflow run.

上方各阶段评论已更新为最新结果。查看工作流运行

@qwen-code-ci-bot

qwen-code-ci-bot commented Aug 26, 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: 52 passed · 0 failed · 52 total

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

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

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

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

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

Verification report

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

Scripted assertions: 52 passed · 0 failed · 52 total (probes reported separately as findings)

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

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

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

Verification report

PR #9492 deep verification (second follow-up round) — fix(core): make loop detection result-aware for task_list polls

Verdict: findings — scripted assertions 52 pass / 0 fail. The central claim is proven load-bearing by A/B at the new head; all four previous-round findings (F1–F4) are fixed and re-measured as fixed; the delta commit's restore is real, not cosmetic. Two new Suggestion-level findings: the producer side of the F2 fix (the stub digest line in buildStub) is pinned by no test (mutation survives), and a narrow false-positive corner where a quoted digest line inside a digest-less truncation stub collapses a changing board into "frozen" (fix direction measured).
Verified head: 4bbf8eabd801010c1a2df4aad5a0bb313c2bd350 · base tip: a82a11a0a4d8d4f97796ac9f56d276364dd3bd64 · merge: b8ef666db44e517eb756d744e7d42724563fcb92.

中文摘要

判定:findings(脚本化断言 52 通过 / 0 失败)。核心结论在新 head 上经 A/B 证实载荷成立:基线构建在第 5 次相同 task_list 请求处终止(#9450 误杀复现),PR 构建在结果持续变化时 20 次轮询不终止;冻结面板、缺失证据失败保持安全、确定性工具、自适应上限四类行为与基线逐格一致(A/B 表格,01-ab-base-arm.png / 02-ab-head-arm.png)。

上一轮发现全部修复并经重新实测:F1(振荡面板被终止)仍修复(O1/O2);F2(超 25 000 字符持久化 stub 逃逸)已修复——冻结的超大面板在新 head 第 5 次请求即终止(S1,上一轮为 12 次不终止),且预览窗口之外的变化经 sha256 摘要仍可见(S3);F3(provider 重复 callId)已在两个 owner(agent-core / client.ts)修复,变异 M11/M11c 均被新测试杀死;F4 的四个覆盖缺口(M2/M4/M5/M8)全部被 delta 新增测试钉住(变异矩阵 03-mutation-matrix-summary.png)。

新发现(均 Suggestion,无阻塞):F5 — buildStub 嵌入全文 sha256 的生产端无任何测试钉住(变异 M10 存活 185/185;消费端 M9 同文件被杀,证明 harness 有效),已测出可钉住的 fixture;F6 — 无摘要的截断 stub 中被引用于行首的 Full output sha256: <hex> 会被当真,把变化的面板折叠为"冻结"而误停(04-s5b-false-frozen-and-fix.png),已测出最小修复方向(对该 stub 形状跳过摘要提取,其余格子逐字节不变)。

未覆盖范围:56 个提交逐一归因(depth-2 浅克隆仅 3 个提交可达,验证的是聚合 diff;delta 恰好一个提交);真实模型流量的多 agent 实时 E2E(PR 声明范围外);交替模式检测器(声明不变,静态确认无 stateful 例外);daemon/ACP 路径(声明延迟至 #10161,diff 未触碰)。

Previous-finding status (follow-up round)

The previous round verified head f34098e680 (verdict findings, 58 pass / 0 fail, four Suggestions). Exactly one commit was added since: 4bbf8eabd8 ("restore the trimmed verification findings for stateful poll guards"), whose message explicitly addresses the previous round's findings. The previous head is not locally reachable (depth-2 checkout), so the aggregate HEAD^1..HEAD diff was re-verified and every carried-forward measurement was re-run at the new head and new base tip, never diffed against the old report.

# Finding Severity Status at new head
1 Oscillating boards still halted (poll 11 with heuristics on, poll 101 under the CLI default) Suggestion fixed, re-measured — cells O1/O2: oscillating board survives 24 polls with heuristics on and 120 polls past the 100-call soft cap under the CLI default at head; base halts at 5. Interleaved frozen boards still halt via the adaptive cap on both arms (O3, same halt point, poll 11).
2 Oversized (>25 000 chars) persisted stubs escape every result-aware guard via per-call unique paths — protection loosened vs base Suggestion fixed, re-measured — cell S1 flips: frozen oversized board delivered as realistic per-call persisted stubs (produced by the real persistAndTruncateToolResult) now halts at request 5 at head (previous round: no halt in 12); base halts at 5. S2 (constant path) still halts at 5 on both arms; S3 shows the digest keeps mutations beyond the 2000-char preview window visible (no halt in 12); S4 shows digest-less truncated stubs halt at 5 via the path-free payload fallback.
3 Provider-duplicate call ids halt a productive poller fail-safe (request counts and result evidence from different populations) Suggestion fixed, re-measured — the fix lives in the two reasoning-loop owners (per-attempt callId Set mirroring dedupeToolCallsById in agent-core.ts and client.ts), not the service. Mutations M11 (agent-core dedup removed) and M11c (client dedup removed) are each killed by the new runtime tests ("counts a provider-duplicate call id once so result evidence stays in sync" / "…so changed-board polls never halt"); the unmutated tests pass (651/651). Service-level D1 documents the fail-safe is intentionally preserved when evidence is incomplete (5 requests incl. a duplicate id + 3 changing results halts at 5 on both arms).
4 Coverage gaps: client.ts wiring, QwenLogger loop_type, interactive stop message, fail-safe completeness gate Suggestion fixed, re-measured — all four previous survivors are now killed: M2 (completeness gate) 3 failed, pinned by "still halts when result evidence is only partial (fail-safe)"; M4 (client wiring) 2 failed, pinned by the paired-ToolResult client tests; M5 (journal serialization) 1 failed, pinned by "journals the loop detector attribution on subagent loop stops"; M8 (interactive suffix) 1 failed, pinned by "surfaces the exact loop detector in the interactive stop message". Each kill is exactly the test the delta commit says it adds (matrix-names.txt).

Central claim + A/B

Central claim: for the stateful read tool task_list, the guards become result-aware — identical calls with changing results are productive polling (no halt), identical calls with unchanged results still halt at the same request count, and missing result evidence fails safe (pre-fix behavior).

Harness: harness-ab-service.mjs drives the compiled dist/ LoopDetectionService of each tree (no mocks of the unit under test); oversized stubs are produced by the real truncation producers (persistAndTruncateToolResult for persisted shapes, truncateAndSaveToFile for digest-less wrapped shapes) so envelopes are wire-faithful. Per-arm expectations are encoded so predicted base-arm reds count as passing assertions. Witnesses: 01-ab-base-arm.png, 02-ab-head-arm.png; raw logs logs-ab-base.txt, logs-ab-head.txt.

Cell Scenario (oracle) base a82a11a0a4 head 4bbf8eabd8 Expectation
C1 20 identical task_list requests, board changes after each execution halts at request 5 (consecutive_identical_tool_calls) — the #9450 false positive no halt in 20 base red / head green
C2 frozen board, results recorded halts at 5 halts at 5, same type parity
C3 no results ever recorded (wiring-gap fail-safe) halts at 5 halts at 5 parity
C4 deterministic tool (read_file), changing recorded results halts at 5 halts at 5 parity (no exemption leak)
C5 heuristics on, interleaved unique fillers, changing results halts (global_tool_call_duplicate, request-time) no halt in 8 rounds base red / head green
C6 heuristics on, interleaved, frozen results halts at the 6th request (request-time) halts at the 6th recorded result (result-time), same loop type parity, new detection point
C7 callId pairing API (recordToolResultByCallId) API absent paired changing results keep 8 rounds alive; unknown id → false head-only API works
O1 oscillating A/B board, heuristics on, 24 polls halts at 5 no halt fixed (F1)
O2 oscillating board, CLI default (skipLoopDetection=true), 120 polls past the 100 soft cap halts at 5 no halt fixed (F1)
O3 interleaved frozen board + unique fillers, adaptive cap 20 halts at poll 11, turn_tool_call_cap halts at poll 11, turn_tool_call_cap parity
S1 F2: frozen oversized board as per-call persisted stubs (real producer: unique path + full-output digest), 12 polls halts at 5 halts at 5 (previous round: no halt in 12) fixed
S2 control: identical stubs with a constant path halts at 5 halts at 5 parity
S3 oversized stubs, identical preview, mutations beyond the 2000-char window (digest differs) halts at 5 no halt in 12 digest sensitivity
S4 digest-less truncated-output stubs, frozen payload, per-call unique spill path halts at 5 halts at 5 (payload fallback) parity
S5a non-stub text quoting a digest line mid-content, tail changes per poll halts at 5 (args-only) no halt in 6 (verbatim fingerprint) prefix gate holds
S5b probe: digest-less truncated stub whose payload quotes a line-start digest; real truncated tail changes per poll halts at request 5 — false positive (see F6) finding
D1 5 request events incl. a duplicated callId, 3 recorded changing results halts at 5 (fail-safe) halts at 5 (fail-safe; owner-side fix pinned by M11/M11c) parity by design

All 33 harness assertions (16 base + 17 head) passed. Base control purity: worktree at HEAD^1, only packages/core rebuilt via tsc; root node_modules symlinked (lockfile untouched — empty package.json/package-lock.json diff asserted); base dist asserted free of result-aware code (grep -c recordToolResult0 vs 12 at head; FULL_OUTPUT_DIGEST_LABEL → 0 vs 4 in truncation). packages/core has no internal @qwen-code/* dependencies, so no workspace symlink can leak head code into the control.

Targeted gates (head, unmutated): the five changed test files 651/651 (base: 621/621 — delta +30 = exactly the PR's added tests); tsc --noEmit (packages/core) clean. Full-suite parity at the new base tip: head 79 failed | 21 977 passed | 10 skipped vs base 79 failed | 21 947 passed | 10 skipped — the 73 unique failing test names are byte-identical on both arms (diff base.fails.txt head.fails.txt empty; same 9 environment files: logger 25, ide-client 18, client.telemetrySwap 9, memoryDiscovery 6, file-token-storage 5, skill-manager 4, subagent-manager 3, installationManager 2, rulesDiscovery 1), delta +30 passing, +0 failing.

Corrections

The previous round corrected the PR body's attribution of the pre-existing packages/core failures to "system git predates git init -b". The current PR body no longer contains that claim, so the correction is moot; the underlying fact is re-confirmed at the new tip: the identical 79 environment failures reproduce byte-identically on both arms (container git 2.39.5), none in files the PR touches.

Findings

No blockers. Two new Suggestion-level findings.

F5 — The producer side of the F2 fix is unpinned: no test asserts buildStub embeds the full-output digest (Suggestion)

The guard-side consumer is pinned (M9 — removing stripPersistenceEnvelope from extractResultText fails "halts a frozen oversized board despite per-call unique stub paths" and "falls back to the path-free preview for digest-less stubs", expected false to be true on the intended halt assertions). But M10 — deleting the digest line from buildStub in tools/truncation.ts — survives 185/185 (truncation + service suites): the service tests hand-build their stub envelopes with an imported label, and truncation.test.ts contains zero references to the digest, so a future regression of the producer would silently drop S3's beyond-preview sensitivity with every test green. Classification: coverage gap (behavior correct at head, nothing asserts the producer), not dead code (M9 proves the consumer path load-bearing) and not redundant defence. Repro: run-mutations.py row M10 (artifact dir). Measured fix: a one-test fixture driving the real persistAndTruncateToolResult and asserting the stub contains Full output sha256: <sha256(content)> — green at head (1/1), red on the M10 mutant (1/1); run it, then delete it (probe measured, tree clean after).

F6 — A quoted line-start digest inside a digest-less truncation stub collapses a changing board into "frozen" — false-positive halt (Suggestion, boundary)

stripPersistenceEnvelope recognizes stubs by leading producer prefix, then scans the whole value for a line-start Full output sha256: <64hex> line. The TOOL_OUTPUT_TRUNCATED_PREFIX producer (truncateAndSaveToFile) never embeds a digest, so any label found inside that shape is necessarily quoted peer content — yet it is honored: probe S5b (digest-less stub whose truncated head quotes a constant digest while the retained tail changes every poll) halts a productive poller at request 5 (04-s5b-false-frozen-and-fix.png). Reachability: any tool output truncated via truncateAndSaveToFile (shell tools; also persistAndTruncateToolResult's disk-failure fallback for task_list itself) whose content contains a literal line matching the digest format — e.g. a teammate's text quoting a previous stub. Safe direction (halts, never runs away), narrow preconditions, but it is the exact false-positive class this PR exists to remove, one level down. Digest-carrying stubs are not affected (the real digest line precedes the preview, so indexOf finds it first). Measured fix: skip digest extraction for that one stub shape — scratch-patched dist re-runs the full harness at 17/17 with S5b surviving 12 polls and every other cell byte-identical (S1/S2/S3/S4/S5a unchanged). Suggested source hunk: const digest = value.startsWith(TOOL_OUTPUT_TRUNCATED_PREFIX) ? null : extractAnchoredStubDigest(value); plus a service-test variant of S5b (quoted digest in a truncated shape, changing payload) to pin it.

Not covered

  • Per-commit attribution: the checkout is depth-2 (3 commits reachable) while the snapshot lists 56 commits; git rev-list HEAD^1..HEAD^2 returns 1 at the shallow boundary (plausible-but-wrong). The previous head f34098e680 is not locally fetchable, so the delta commit's own diff could not be computed; the aggregate HEAD^1..HEAD diff is what was verified. The delta since the previous round is exactly one commit per the snapshot's commit list, verified end to end by re-measurement.
  • Live multi-agent E2E with real model traffic — declared out of scope by the PR; the headless E2E tests mock the model stream but exercise the real agent runtime, scheduler, and loop-detector wiring, with seam-counted assertions (8 executed polls / 9 stream calls asserted; 8 streamed ToolCallRequests with 7 unique callIds in the client test).
  • Alternating-pattern detector — declared unchanged; confirmed statically that checkAlternatingPattern carries no stateful carve-out at this head. Not re-measured behaviorally.
  • Daemon/ACP path — declared deferred to Make daemon/ACP adaptive-cap stuck signal result-aware for stateful reads (follow-up from #9492) #10161; the diff touches no daemon/ACP/packages/cli files (diffstat verified; the only "cli" match is core/client.ts, the main-session owner).
  • send_message/task_update — deliberately argument-only per the PR's declared narrow scope; not probed.
  • packages/cli suite and the shell/finalizer suites — not run in full; truncation.test.ts (40 tests) ran green in the M9/M10 passes.
  • The flakiness gate (changed test files × N rounds) is owned by the workflow, not this round.

Methodology

Environment: CI verify container (node:22-bookworm, node v22.23.2, git 2.39.5), merge ref refs/pull/9492/merge at depth 2; npm ci + full build completed before verification. A/B: head dist from the workflow build; base control in a scratch worktree at HEAD^1 with only packages/core rebuilt (tsc -p .), node_modules symlinked and realpath-asserted. harness-ab-service.mjs imports the compiled dist/src/services/loopDetectionService.js of each tree and drives checkAlwaysOnSafeties / addAndCheckHeuristicLoops / recordToolResult[ByCallId] with ToolCallRequest events and functionResponse parts shaped like production traffic; oversized stubs are produced by each tree's real exported truncation producers (head producer used as the post-PR input on both arms). Mutations were single-point source edits run through scoped vitest, reverted with git checkout (tree confirmed clean after each). Full-suite parity compared ANSI-stripped FAIL lines of sequential, coverage-disabled runs on both arms. The F6 fix direction was validated by a scratch patch of the compiled dist only (backup/restore verified). Raw logs, harnesses, and the mutation runner live in this artifact dir; evidence images 01–04 are captured via scripts/verify-capture.mjs.

Flakiness gate log

rounds=5 files=5 skipped=0
file packages/core/src/agents/runtime/agent-headless.test.ts: (cd packages/core) npx --no-install vitest run ./src/agents/runtime/agent-headless.test.ts
file packages/core/src/agents/runtime/agent-interactive.test.ts: (cd packages/core) npx --no-install vitest run ./src/agents/runtime/agent-interactive.test.ts
file packages/core/src/core/client.test.ts: (cd packages/core) npx --no-install vitest run ./src/core/client.test.ts
file packages/core/src/services/loopDetectionService.test.ts: (cd packages/core) npx --no-install vitest run ./src/services/loopDetectionService.test.ts
file packages/core/src/telemetry/qwen-logger/qwen-logger.test.ts: (cd packages/core) npx --no-install vitest run ./src/telemetry/qwen-logger/qwen-logger.test.ts


per-file results (P=pass F=fail I=infra-exit, one letter per run):
  packages/core/src/agents/runtime/agent-headless.test.ts: PPPPP
  packages/core/src/agents/runtime/agent-interactive.test.ts: PPPPP
  packages/core/src/core/client.test.ts: PPPPP
  packages/core/src/services/loopDetectionService.test.ts: PPPPP
  packages/core/src/telemetry/qwen-logger/qwen-logger.test.ts: PPPPP

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

--- per-invocation detail (full copy in the artifact) ---
round 1 · packages/core/src/agents/runtime/agent-headless.test.ts: P (exit 0)
round 1 · packages/core/src/agents/runtime/agent-interactive.test.ts: P (exit 0)
round 1 · packages/core/src/core/client.test.ts: P (exit 0)
round 1 · packages/core/src/services/loopDetectionService.test.ts: P (exit 0)
round 1 · packages/core/src/telemetry/qwen-logger/qwen-logger.test.ts: P (exit 0)
round 2 · packages/core/src/agents/runtime/agent-headless.test.ts: P (exit 0)
round 2 · packages/core/src/agents/runtime/agent-interactive.test.ts: P (exit 0)
round 2 · packages/core/src/core/client.test.ts: P (exit 0)
round 2 · packages/core/src/services/loopDetectionService.test.ts: P (exit 0)
round 2 · packages/core/src/telemetry/qwen-logger/qwen-logger.test.ts: P (exit 0)
round 3 · packages/core/src/agents/runtime/agent-headless.test.ts: P (exit 0)
round 3 · packages/core/src/agents/runtime/agent-interactive.test.ts: P (exit 0)
round 3 · packages/core/src/core/client.test.ts: P (exit 0)
round 3 · packages/core/src/services/loopDetectionService.test.ts: P (exit 0)
round 3 · packages/core/src/telemetry/qwen-logger/qwen-logger.test.ts: P (exit 0)
round 4 · packages/core/src/agents/runtime/agent-headless.test.ts: P (exit 0)
round 4 · packages/core/src/agents/runtime/agent-interactive.test.ts: P (exit 0)
round 4 · packages/core/src/core/client.test.ts: P (exit 0)
round 4 · packages/core/src/services/loopDetectionService.test.ts: P (exit 0)
round 4 · packages/core/src/telemetry/qwen-logger/qwen-logger.test.ts: P (exit 0)
round 5 · packages/core/src/agents/runtime/agent-headless.test.ts: P (exit 0)
round 5 · packages/core/src/agents/runtime/agent-interactive.test.ts: P (exit 0)
round 5 · packages/core/src/core/client.test.ts: P (exit 0)
round 5 · packages/core/src/services/loopDetectionService.test.ts: P (exit 0)
round 5 · packages/core/src/telemetry/qwen-logger/qwen-logger.test.ts: P (exit 0)

Evidence images

01-ab-base-arm

02-ab-head-arm

03-mutation-matrix-summary

04-s5b-false-frozen-and-fix

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

Qwen Code · sandboxed verification

@yiliang114

Copy link
Copy Markdown
Collaborator Author

@qwen-code /triage

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

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

LGTM, looks ready to ship. ✅

@qwen-code-ci-bot

qwen-code-ci-bot commented Aug 26, 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: 65 passed · 0 failed · 65 total

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

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

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

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

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

Verification report

PR #9492 deep verification (third round) — fix(core): make loop detection result-aware for task_list polls

Verdict: findings — scripted assertions 65 pass / 0 fail. No commits were added since the previous round: the merge commit (b8ef666db4), base tip (HEAD^1 = a82a11a0a4), and PR head (HEAD^2 = 4bbf8eabd8) are bit-identical to the head this report's predecessor verified, so the previous findings cannot have moved; both carried Suggestions (F5, F6) were re-measured at this head and stand, and the central claim was re-proven load-bearing by a fresh A/B.
Verified head: 4bbf8eabd801010c1a2df4aad5a0bb313c2bd350 · base tip: a82a11a0a4d8d4f97796ac9f56d276364dd3bd64 · merge: b8ef666db44e517eb756d744e7d42724563fcb92.

中文摘要

判定:findings(脚本化断言 65 通过 / 0 失败)。本轮与上一轮之间没有新提交:合并提交、base tip、PR head 三个 OID 与上一轮验证时逐位相同(内容寻址即整树相同),因此上一轮结论不会凭空变化;本轮对全部核心证据做了重新实测而非转抄:

  • 核心结论 A/B 重跑成立(表格见 Central claim,01-ab-base-arm.png / 02-ab-head-arm.png):基线构建对"结果持续变化的相同 task_list 轮询"仍在第 5 次请求误杀(task_list can falsely trigger duplicate tool-call loop detection while team state changes #9450 复现);PR 构建 20 次不终止。冻结面板、缺失证据失败保持安全、确定性工具、自适应上限、振荡面板(O1/O2)逐格与基线对照一致。
  • 上一轮 F1–F4(已修复)保持修复:O1/O2/S1/S3/D1 本轮重新实测;F3/F4 的变异杀死证据在"输入闭包逐位相同"下结转(Previous-finding status 表)。
  • F5(生产端未钉住)重新实测后仍成立:删除 buildStub 摘要行的变异 M10 存活 185/185;本轮探针(真实 persistAndTruncateToolResult)对 M10 变红、对 head 变绿(03-mutation-matrix-summary.png)。
  • F6(无摘要截断 stub 中引用行首摘要 → 误停)重新实测后仍成立,且本轮夹具更尖锐:保留的可见载荷确实逐次变化时仍在第 5 次请求终止;已测修复方向(对该 stub 形状跳过摘要提取)在 scratch dist 上 20/20、仅 S5b 翻转(04-s5b-false-frozen-and-fix.png)。

未覆盖范围:56 个提交逐一归因(depth-2,仅 3 个提交可达,本轮 delta 为 0 个提交);真实模型流量的多 agent 实时 E2E(PR 声明范围外);packages/core 全量套件双方平价(上一轮在逐位相同的树上实测为 79 失败名逐字节一致、+30 通过 / +0 失败,本轮按"输入闭包逐位相同"结转并说明比较内容);daemon/ACP 路径(声明延迟至 #10161,diffstat 确认未触碰)。

Previous-finding status (follow-up round)

The previous round verified head 4bbf8eabd801010c1a2df4aad5a0bb313c2bd350 (verdict findings, 52 pass / 0 fail: F1–F4 fixed, F5–F6 new Suggestions). Exactly zero commits were added since — the local merge commit, HEAD^1, and HEAD^2 are byte-for-byte the same OIDs the previous round cited, and a commit OID content-addresses its entire tree, so every input the previous measurements consumed (sources, lockfile, config, fixtures) is proven identical. Even so, the central A/B, both carried findings, and the targeted gates were re-run fresh this round (never diffed against the old report); only the two most expensive items are carried, and only under that identity proof (named in Not covered).

# Finding Severity Status at this head
1 Oscillating boards still halted (F1) Suggestion fixed, re-measured — cells O1/O2 re-run: oscillating board survives 24 polls with heuristics on and 120 polls past the 100-call soft cap under the CLI default at head; base halts at 5 on both.
2 Oversized persisted stubs escape the result-aware guards (F2) Suggestion fixed, re-measured — cell S1 re-run: frozen oversized board as realistic per-call persisted stubs (real persistAndTruncateToolResult) halts at request 5 at head, same as base; S3 re-run confirms digest sensitivity beyond the 2000-char preview window (no halt in 12).
3 Provider-duplicate call ids halt a productive poller (F3) Suggestion fixed — the owner-side dedup kills (M11/M11c) are carried under the proven-identical closure (zero commits were added since they were measured); the service-level population-mismatch behavior was re-measured fresh this round (cell D1: incomplete evidence fails safe at 5 on both arms).
4 Coverage gaps: client wiring, loop_type journal, interactive stop message, fail-safe gate (F4) Suggestion fixed — the M2/M4/M5/M8 kills are carried under the proven-identical closure; the unmutated gate behind them was re-run fresh: the five changed test files pass 651/651 at head (base 621/621, delta exactly +30 = the PR's added tests).
5 Producer side of the F2 fix unpinned: no test asserts buildStub embeds the full-output digest (F5) Suggestion stands, re-measured — M10 (delete the digest line from buildStub) survives 185/185 again; the pinning probe is red against M10 and green at head (see Findings).
6 Quoted line-start digest inside a digest-less truncation stub collapses a changing board into "frozen" (F6) Suggestion stands, re-measured — with a sharper fixture — the retained visible payload now provably changes every poll, yet the halt at request 5 reproduces; the measured fix direction re-verified (see Findings).

Central claim + A/B

Central claim: for the stateful read tool task_list, the guards become result-aware — identical calls with changing results are productive polling (no halt), identical calls with unchanged results still halt at the same request count, and missing result evidence fails safe (pre-fix behavior).

Harness: harness-ab-service.mjs drives the compiled dist/ LoopDetectionService of each tree (no mocks of the unit under test); oversized stubs are produced by each arm's own exported truncation producers (persistAndTruncateToolResult / truncateAndSaveToFile) so envelopes are wire-faithful. Per-arm expectations are encoded so predicted base-arm reds count as passing assertions. Witnesses: 01-ab-base-arm.png, 02-ab-head-arm.png; raw logs logs-ab-base.txt, logs-ab-head.txt.

Cell Scenario (oracle) base a82a11a0a4 head 4bbf8eabd8 Expectation
C1 20 identical task_list requests, board changes after each execution halts at request 5 (consecutive_identical_tool_calls) — the #9450 false positive no halt in 20 base red / head green
C2 frozen board, results recorded halts at 5 halts at 5, same type parity
C3 no results ever recorded (wiring-gap fail-safe) halts at 5 halts at 5 parity
C4 deterministic tool (read_file), changing recorded results (+ fresh-instance refusal probe C4b) halts at 5 halts at 5; recordToolResult returns false for non-stateful tools parity (no exemption leak)
C5 heuristics on, interleaved unique fillers, changing results halts (global_tool_call_duplicate, request-time, 6th poll) no halt in 8 rounds base red / head green
C6 heuristics on, interleaved, frozen results halts at the 6th request (request-time) halts at the 6th recorded result (result-time), same loop type parity, new detection point
C7 callId pairing API (recordToolResultByCallId) API absent paired changing results keep 8 rounds alive; unknown id → false head-only API works
O1 oscillating A/B board, heuristics on, 24 polls halts at 5 no halt fixed (F1)
O2 oscillating board, CLI default (skipLoopDetection=true), 120 polls past the 100 soft cap halts at 5 no halt fixed (F1)
O3 interleaved frozen board + unique fillers, adaptive cap 20 halts at poll 11, turn_tool_call_cap halts at poll 11, turn_tool_call_cap parity
S1 F2: frozen oversized board as per-call persisted stubs (real producer: unique path + full-output digest at head), 12 polls halts at 5 halts at 5 fixed
S2 control: identical stubs with a constant path halts at 5 halts at 5 parity
S3 oversized stubs, identical preview, mutations beyond the 2000-char window (digest differs) halts at 5 no halt in 12 digest sensitivity
S4 digest-less truncated-output stubs, frozen payload, per-call unique spill path halts at 5 halts at 5 (payload fallback) parity
S5a non-stub text quoting a digest line mid-content, tail changes per poll halts at 5 (args-only) no halt in 6 (prefix gate holds) parity of intent
S5b digest-less truncated stub whose retained head quotes a line-start digest (constant) while the retained tail changes every poll halts at 5 (args-only) halts at request 5 — false positive (see F6) finding
D1 request population incl. a duplicated callId, only 3 changing results recorded halts at 5 (fail-safe) halts at 5 (fail-safe) parity by design

All 37 harness assertions (17 base + 20 head) passed. Base control purity (methodology has the full wiring note): worktree at HEAD^1, only packages/core rebuilt (node ../../scripts/build_package.js, exit 0, 0 TS errors) against the shared root + per-package node_modules (lockfile untouched — git diff HEAD^1..HEAD -- package.json package-lock.json packages/core/package.json empty). Base dist asserted free of result-aware code: grep -c recordToolResult0 (head: 12); FULL_OUTPUT_DIGEST_LABEL/Full output sha256 in truncation → 0 (head: 4). packages/core has zero @qwen-code/* dependencies (deps and devDeps inspected) and its per-package node_modules contains no symlinks, so no workspace link can leak head code into the control.

Targeted gates (re-run fresh): the five changed test files 651/651 at head vs 621/621 at base (delta exactly +30 = the PR's added tests, +0 failing); tsc --noEmit (packages/core) clean. Full-suite parity is carried from the previous round under the proven-identical closure (see Not covered).

Corrections

None new this round. The previous round's correction (the PR body's attribution of pre-existing packages/core failures to a system-git limitation) is moot — the current body no longer contains that claim, and the underlying fact (79 environment failures reproducing identically on both arms) is the carried full-suite measurement.

Findings

No blockers. The two carried Suggestions stand, both re-measured at this head.

F5 — The producer side of the F2 fix remains unpinned: no shipped test asserts buildStub embeds the full-output digest (Suggestion, stands)

Re-measured: M10 — deleting the Full output sha256: line (and its computation) from buildStub in packages/core/src/tools/truncation.ts — survives 185/185 (the truncation + loop-detection suites; logs-m10-mutant.txt). The consumer side is pinned (positive control M9 — neutralizing stripPersistenceEnvelope in extractResultText — is killed: 2 failed | 183 passed, failing exactly "halts a frozen oversized board despite per-call unique stub paths" and "falls back to the path-free preview for digest-less stubs" with expected false to be true on the intended halt assertions; logs-m9-mutant.txt), so the harness is proven live on this file. Classification unchanged: coverage gap — behavior correct at head, nothing asserts the producer; a future regression would silently drop S3's beyond-preview sensitivity with every test green. Repro: apply M10, then cd packages/core && npx vitest run src/tools/truncation.test.ts src/services/loopDetectionService.test.ts → 185/185. Measured fix (re-confirmed this round): a scratch vitest probe — driving the real persistAndTruncateToolResult on ~33 KB of content and asserting the stub contains Full output sha256: <sha256(content)>, run during this round and deleted after, logs kept — is red against M10 (expected '<persisted-output>…' to contain 'Full output sha256: a2bad869…', logs-probe-vs-m10.txt) and green at head (1/1, logs-probe-vs-head.txt). Suggested: land that one test with the producer — its full body is kept in this artifact dir as probe-producer-digest.test.ts.

F6 — A quoted line-start digest inside a digest-less truncation stub still collapses a changing board into "frozen" — false-positive halt (Suggestion, stands; fixture now decisive)

stripPersistenceEnvelope recognizes stubs by leading producer prefix, then scans the whole value for a line-start Full output sha256: <64hex> line. The TOOL_OUTPUT_TRUNCATED_PREFIX producer (truncateAndSaveToFile) never embeds a digest, so any label found inside that shape is necessarily quoted peer content — yet it is honored. This round's fixture closes an underdeterminedness the previous cell had: the per-poll change now sits inside the retained tail (the truncated middle is what truncateAndSaveToFile removes), so the model-visible payload demonstrably differs every poll (v1…v12) while the quoted digest line stays constant — and the productive poller still halts at request 5 (ASSERT S5b in logs-ab-head.txt; witness 04-s5b-false-frozen-and-fix.png). Reachability unchanged from round 2: any tool output truncated via truncateAndSaveToFile (shell tools; also persistAndTruncateToolResult's disk-failure fallback for task_list itself) whose content contains a literal line matching the digest format. Safe direction (halts, never runs away), narrow preconditions, but it is the exact false-positive class this PR exists to remove, one level down. Re-measured fix direction: scratch-patch the compiled dist's stripPersistenceEnvelope with const digest = value.startsWith(TOOL_OUTPUT_TRUNCATED_PREFIX) ? null : extractAnchoredStubDigest(value); — the full harness then passes 20/20 with S5b surviving 12 polls and every other cell unchanged (S1/S2/S3/S4/S5a byte-identical; logs-ab-head-f6fix.txt), and the dist was restored byte-identical afterwards (sha256 da45a207… before == after). Suggested source hunk is that one line plus a service-test variant of S5b (quoted digest in a truncated shape, changing retained payload) to pin it.

Not covered

  • Per-commit attribution: the checkout is depth-2 (3 commits reachable) while the snapshot lists 56 commits; the delta since the previous round is zero commits (same HEAD^2), so there is no new per-commit surface to attribute.
  • Full-suite parity (both arms) — carried from the previous round under the proven-identical input closure. What was compared: the merge commit (b8ef666db4), base tip (a82a11a0a4), and head (4bbf8eabd8) OIDs cited by the previous report are byte-for-byte the local HEAD, HEAD^1, HEAD^2 — and a commit OID content-addresses its whole tree, so every file, the lockfile, and every fixture the full-suite runs consumed are identical; the runtime (node v22.23.2, git 2.39.5) matches the previous round's recorded environment. Carried numbers: head 79 failed | 21 977 passed | 10 skipped vs base 79 failed | 21 947 passed | 10 skipped, the 73 unique failing names byte-identical on both arms (9 environment files, none touched by the PR).
  • Full mutation matrix beyond M9/M10 (M2/M4/M5/M8/M11/M11c kills) — carried under the same identity proof; this round re-ran the consumer-side positive control (M9, killed) and the F5 mutant (M10, survives) fresh.
  • Live multi-agent E2E with real model traffic — declared out of scope by the PR.
  • Alternating-pattern detector — declared unchanged; re-confirmed statically at this head (checkAlternatingPattern carries no stateful carve-out in the source read this round). Not re-measured behaviorally.
  • Daemon/ACP path — declared deferred to Make daemon/ACP adaptive-cap stuck signal result-aware for stateful reads (follow-up from #9492) #10161; git diff --stat HEAD^1..HEAD re-confirmed this round touches no daemon/ACP/packages/cli files (14 files, all packages/core/src/**).
  • send_message/task_update — deliberately argument-only per the PR's declared narrow scope; not probed.
  • packages/cli suite and the shell/finalizer suites — not run.
  • The flakiness gate (changed test files × N rounds) is owned by the workflow, not this round.
  • No injection attempts were observed in the PR metadata (title/body/commits read as untrusted input; nothing tried to steer the verification).

Methodology

Environment: CI verify container (node:22-bookworm, node v22.23.2, git 2.39.5), merge ref refs/pull/9492/merge at depth 2; npm ci + full build completed before verification. A/B: head dist from the workflow build; base control in a scratch worktree at HEAD^1 with only packages/core rebuilt. Wiring note: the worktree initially failed to build because resolution walked up to the root node_modules/ajv 6.15.0 (v6 has no dist/2020.js) while packages/core declares ^8 — the satisfying copy lives in the main tree's git-ignored packages/core/node_modules (ajv 8.20.0, readlink -f-verified), which was symlinked into the base worktree; this is a clean control because git diff HEAD^1..HEAD over package.json/package-lock.json/packages/core/package.json is empty and that directory contains no symlinks (all real external dirs). harness-ab-service.mjs imports each tree's compiled dist/src/services/loopDetectionService.js and drives checkAlwaysOnSafeties / addAndCheckHeuristicLoops / recordToolResult[ByCallId] with ToolCallRequest events and functionResponse parts shaped like production traffic; oversized stubs are produced by the arm's own real truncation producers into real temp dirs. Mutations were single-point source edits run through scoped vitest, reverted with git checkout (tree confirmed clean after each; M9 log logs-m9-mutant.txt, M10 log logs-m10-mutant.txt, probe logs logs-probe-vs-m10.txt / logs-probe-vs-head.txt). The F6 fix direction was validated by a scratch patch of the compiled dist only, with sha256 proof of byte-identical restore. Gates: five changed test files via npx vitest run on both trees (logs-gate-head.txt, logs-gate-base.txt) and tsc --noEmit (logs-typecheck.txt). Evidence images 01–04 rendered from the real run logs via scripts/verify-capture.mjs; base worktree removed after the last base-arm run.

Flakiness gate log

rounds=5 files=5 skipped=0
file packages/core/src/agents/runtime/agent-headless.test.ts: (cd packages/core) npx --no-install vitest run ./src/agents/runtime/agent-headless.test.ts
file packages/core/src/agents/runtime/agent-interactive.test.ts: (cd packages/core) npx --no-install vitest run ./src/agents/runtime/agent-interactive.test.ts
file packages/core/src/core/client.test.ts: (cd packages/core) npx --no-install vitest run ./src/core/client.test.ts
file packages/core/src/services/loopDetectionService.test.ts: (cd packages/core) npx --no-install vitest run ./src/services/loopDetectionService.test.ts
file packages/core/src/telemetry/qwen-logger/qwen-logger.test.ts: (cd packages/core) npx --no-install vitest run ./src/telemetry/qwen-logger/qwen-logger.test.ts


per-file results (P=pass F=fail I=infra-exit, one letter per run):
  packages/core/src/agents/runtime/agent-headless.test.ts: PPPPP
  packages/core/src/agents/runtime/agent-interactive.test.ts: PPPPP
  packages/core/src/core/client.test.ts: PPPPP
  packages/core/src/services/loopDetectionService.test.ts: PPPPP
  packages/core/src/telemetry/qwen-logger/qwen-logger.test.ts: PPPPP

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

--- per-invocation detail (full copy in the artifact) ---
round 1 · packages/core/src/agents/runtime/agent-headless.test.ts: P (exit 0)
round 1 · packages/core/src/agents/runtime/agent-interactive.test.ts: P (exit 0)
round 1 · packages/core/src/core/client.test.ts: P (exit 0)
round 1 · packages/core/src/services/loopDetectionService.test.ts: P (exit 0)
round 1 · packages/core/src/telemetry/qwen-logger/qwen-logger.test.ts: P (exit 0)
round 2 · packages/core/src/agents/runtime/agent-headless.test.ts: P (exit 0)
round 2 · packages/core/src/agents/runtime/agent-interactive.test.ts: P (exit 0)
round 2 · packages/core/src/core/client.test.ts: P (exit 0)
round 2 · packages/core/src/services/loopDetectionService.test.ts: P (exit 0)
round 2 · packages/core/src/telemetry/qwen-logger/qwen-logger.test.ts: P (exit 0)
round 3 · packages/core/src/agents/runtime/agent-headless.test.ts: P (exit 0)
round 3 · packages/core/src/agents/runtime/agent-interactive.test.ts: P (exit 0)
round 3 · packages/core/src/core/client.test.ts: P (exit 0)
round 3 · packages/core/src/services/loopDetectionService.test.ts: P (exit 0)
round 3 · packages/core/src/telemetry/qwen-logger/qwen-logger.test.ts: P (exit 0)
round 4 · packages/core/src/agents/runtime/agent-headless.test.ts: P (exit 0)
round 4 · packages/core/src/agents/runtime/agent-interactive.test.ts: P (exit 0)
round 4 · packages/core/src/core/client.test.ts: P (exit 0)
round 4 · packages/core/src/services/loopDetectionService.test.ts: P (exit 0)
round 4 · packages/core/src/telemetry/qwen-logger/qwen-logger.test.ts: P (exit 0)
round 5 · packages/core/src/agents/runtime/agent-headless.test.ts: P (exit 0)
round 5 · packages/core/src/agents/runtime/agent-interactive.test.ts: P (exit 0)
round 5 · packages/core/src/core/client.test.ts: P (exit 0)
round 5 · packages/core/src/services/loopDetectionService.test.ts: P (exit 0)
round 5 · packages/core/src/telemetry/qwen-logger/qwen-logger.test.ts: P (exit 0)

Evidence images

01-ab-base-arm

02-ab-head-arm

03-mutation-matrix-summary

04-s5b-false-frozen-and-fix

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.

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 reviewed: build-and-test — Test (macos-latest, Node 22.x) and Test (windows-latest, Node 22.x) were skipped in CI; unit suites ran green on Linux in this review's build-test, the OS dimension is untested (author-disclosed).

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

  • packages/core/src/agents/runtime/agent-interactive.test.ts:333 — [review] lastRoundError loopType branch has no witness
  • packages/core/src/services/loopDetectionService.test.ts:2929 — [probe] persistedStub fixture hardcodes 2000 instead of PREVIEW_SIZE_CHARS
  • packages/core/src/services/loopDetectionService.ts:207 — [review] Producer envelope literals re-declared instead of imported
  • packages/core/src/tools/truncation.ts:532 — [review] buildStub digest line has no producer-side witness
  • packages/core/src/services/loopDetectionService.test.ts:3242 — [probe] Retry-clear test survives its own deletion (vacuous witness)
  • packages/core/src/services/loopDetectionService.test.ts:3273 — [probe] reset() clear test survives deletion of all three clears
  • packages/core/src/agents/runtime/agent-core.ts:1219 — [review] Agent-core result-time halt branch is never exercised
  • packages/core/src/agents/runtime/agent-interactive.test.ts:343 — [probe] Null-loopType fallback branches have no witness
  • packages/core/src/services/loopDetectionService.test.ts:3019 — [probe] Quoted-marker test does not discriminate the leading-prefix gate

Convergence: round 17 posted 3 inline comment(s), 3 of them reported for the first time; the previous round posted 1 (1 new). Findings keep coming back to the same files: packages/core/src/services/loopDetectionService.ts (findings in round 16; 2 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.)

Residual risk: this loop is persistently critical — Criticals stood in the previous round's work-list and stand again this round (3 Critical(s)), the rate of first-time findings is not falling (this round 3, previous 1), and the standing Critical backlog is not shrinking. The severity floor will not converge it. Recommendation: land-with-residual-risk — the exit is a maintainer risk-acceptance decision (merge, carrying the residual risk), not another review round. Residual-risk inventory for that decision (maintainer to complete):

standing Critical attack surface attacker-dependency blast radius
(each standing Critical)

Advisory only — it does not block this review.

中文说明

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

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

未审查:build-and-test — Test (macos-latest, Node 22.x) and Test (windows-latest, Node 22.x) were skipped in CI; unit suites ran green on Linux in this review's build-test, the OS dimension is untested (author-disclosed)。

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

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

残余风险:本循环处于 persistently-critical 形态——上一轮工作清单中的 Critical 本轮依然存在(本轮 3 条 Critical),首次发现的速率没有下降(本轮 3,上一轮 1),且未决 Critical 积压没有减少。severity floor 无法使其收敛。建议:land-with-residual-risk——出口是 maintainer 的风险接受决定(合入并承担残余风险),而非再开一轮评审。供该决定使用的残余风险清单(maintainer 填写):按每条未决 Critical 列出「攻击面 · 攻击者依赖性 · 影响范围」三栏。仅为建议——不阻断本次评审。

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

Comment on lines +259 to +261
for (const marker of [STUB_PREVIEW_MARKER, STUB_TRUNCATED_PART_MARKER]) {
const payloadStart = value.indexOf(marker);
if (payloadStart !== -1) {

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.

[Critical] R5-1: Still stands — re-proven at this head. The digest-less truncateAndSaveToFile stub shape degrades to head+tail fingerprinting in this fallback, so task_list boards in the (25,000, 28,000]-char band (above the truncate threshold, below the persistence gate; or any board under 28K chars with >1000 lines) whose mutations land in the truncated-away middle fingerprint identically on every poll — and the consecutive guard then halts a productive poller, re-shipping the exact #9450 false positive this PR removes. Round 5's fix (f4e85c7, digest in truncateAndSaveToFile) was reverted by the trim; buildStub got its digest back, this shape did not. Witness (probe at this head, real producer + real service): a 27,639-char board mutating only in the truncated middle halted at request 4 (haltedAt=4, consecutive_identical_tool_calls) while genuinely changing; adding the digest line to truncateAndSaveToFile's wrapped message flips the same probe to haltedAt=null.

F3-PROBE halted at request 4 ... haltedAt=4   (board changing every poll)
with digest line in truncateAndSaveToFile:  haltedAt=null

Fix: emit a FULL_OUTPUT_DIGEST_LABEL line (sha256 of the full pre-truncation content, in scope there) in truncateAndSaveToFile's wrappedMessage and its disk-failure fallback, mirroring buildStub; the detector already prefers the anchored digest, so no guard change is needed. Fix witness: add a test driving identical task_list calls whose results are real truncateAndSaveToFile-shaped stubs mutating only in the truncated middle, asserting no halt within 4 × threshold — removing the digest line must turn it red (and a frozen-board variant of the same shape must still halt).

中文说明

[Critical] R5-1:仍然成立 —— 已在本 head 上重新证实。无摘要的 truncateAndSaveToFile 存根形态在此回退分支中退化为「头 + 尾」指纹,因此处于 (25,000, 28,000] 字符区间(超过截断阈值、低于持久化门槛;或任何低于 28K 字符但超过 1000 行)的 task_list 任务板,只要变化落在被截掉的中段,每次轮询的指纹都完全相同 —— 连续守卫会终止仍在正常产出的轮询者,使本 PR 要消除的 #9450 误杀在该尺寸区间重新出现。第 5 轮的修复(f4e85c7417,在 truncateAndSaveToFile 中嵌入摘要)已被瘦身回退;buildStub 的摘要被找回,此形态没有。证据(在本 head 上用真实生产者 + 真实服务的探针):一块 27,639 字符、仅在被截中段变化的任务板在第 4 次请求即被终止(haltedAt=4consecutive_identical_tool_calls),而它每次轮询都在真实变化;在 truncateAndSaveToFile 的封装信息中加入摘要行后同一探针翻转为 haltedAt=null

修复:在 truncateAndSaveToFilewrappedMessage 及其写盘失败回退中嵌入 FULL_OUTPUT_DIGEST_LABEL 行(截断前完整内容的 sha256,该内容在此作用域内),与 buildStub 对齐;检测器已优先提取锚定摘要,守卫侧无需改动。修复见证:补一个测试,驱动结果仅在被截中段变化的真实 truncateAndSaveToFile 形态存根的相同 task_list 调用,断言 4 倍阈值内不终止 —— 移除摘要行必须使其变红(同形态的冻结任务板变体仍须终止)。

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

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Patrol note (automated sweep): this PR has hit the scope fuse — cumulative additions are +1853 (>1500-line cap) and this finding shape has recurred across five-plus review rounds without converging. Per patrol policy no more code is added from the sweep; this thread stays open for a maintainer decision on direction (the digest/fingerprint gaps are real, but each round mints new entrance variants faster than they close).

Comment on lines +2315 to +2319
results.push({
toolName: String(fc.name ?? ''),
args: (fc.args ?? {}) as Record<string, unknown>,
responseParts: finalized.responseParts,
});

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.

[Critical] R5-5: Still stands — re-proven at this head (also carries the round-7 R7-1 entrance). The guards fingerprint these post-finalization parts, and the batch-budget finalizer's fitText replacement carries no content digest: its header embeds a per-call unique artifact path and matches no STUB_PRODUCER_PREFIXES member, so the whole value fingerprints verbatim. Two directions, both probe-verified at this head: (1) missed halt — a FROZEN board whose round exceeds the default-on 200,000-char batch budget fingerprints uniquely on every poll, so unchangedStreak never grows and a genuinely stuck poller escapes every result-aware guard, running to the ~1000-call hard backstop; (2) false halt — two boards differing only beyond the retained head/tail produce byte-identical replacements, so a productive poller halts at the 5th identical request. The round-5/7 fixes (fitText digest + shared recognizer) were reverted by the trim. Witness (probe through the real enforceFunctionResponseBudget + real service at this head):

false-halt arm: boards differing only in the truncated middle ->
  byte-identical replacements (t1 === t2, no digest label), halt at request 5
  (full-board control never halts)
missed-halt arm: FROZEN board's fitted replacements all differ
  (per-call unique artifact path) -> guard never accumulates, never halts

Fix: embed the FULL_OUTPUT_DIGEST_LABEL digest of the full pre-fit content in fitText's replacement (consistent with this PR's own buildStub change) so the guard reduces the shape to the content digest regardless of the per-call artifact path. Fix witness: a frozen-board-under-fit test that halts within the threshold (red when fitText carries no digest), plus a board mutating only past the fit window that must NOT halt.

中文说明

[Critical] R5-5:仍然成立 —— 已在本 head 上重新证实(同时承载第 7 轮 R7-1 入口)。守卫对这些 finalize 后的部件做指纹,而批预算终结器的 fitText 替换不携带内容摘要:其头部内嵌每次调用唯一的产物路径,且不匹配任何 STUB_PRODUCER_PREFIXES 成员,于是整个值被逐字指纹化。两个方向均已在本 head 上用探针证实:(1) 漏检 —— 任务板冻结且某轮输出超过默认开启的 200,000 字符批预算时,每次轮询的指纹都因唯一路径而不同,unchangedStreak 永远不增长,真正卡死的轮询者逃逸所有结果感知守卫、一路跑到约 1000 次硬兜底;(2) 误杀 —— 仅在保留头/尾之外有差异的两块任务板产生字节完全相同的替换,正常轮询者在第 5 次相同请求被终止。第 5/7 轮的修复(fitText 摘要 + 共享识别器)已被瘦身回退。证据(经真实 enforceFunctionResponseBudget + 真实服务的探针):误杀臂 —— 仅被截中段有差异的任务板产生字节相同的替换(t1 === t2,无摘要行),第 5 次请求即终止(整板对照不终止);漏检臂 —— 冻结任务板的拟合替换因逐次调用唯一路径而全部不同,守卫永远无法累积、永不终止。

修复:在 fitText 的替换中嵌入拟合前完整内容的 FULL_OUTPUT_DIGEST_LABEL 摘要(与本 PR 自己对 buildStub 的改动一致),使守卫无论逐次路径如何都把该形态归约为内容摘要。修复见证:补一个批预算拟合下冻结任务板在阈值内终止的测试(fitText 不带摘要时须变红),以及一块仅在拟合窗口之外变化的任务板不得终止的测试。

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

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Patrol note (automated sweep): this PR has hit the scope fuse — cumulative additions are +1853 (>1500-line cap) and this finding shape has recurred across five-plus review rounds without converging. Per patrol policy no more code is added from the sweep; this thread stays open for a maintainer decision on direction (the digest/fingerprint gaps are real, but each round mints new entrance variants faster than they close).

Comment on lines +498 to +500
if (consecutiveCount > this.capMaxKeyRepeat) {
this.capMaxKeyRepeat = consecutiveCount;
}

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.

[Critical] R7-2: Still stands — re-proven at this head (carries the round-6 high-water-mark thread and the round-7 R7-2 core thread). This ratchet raises capMaxKeyRepeat from the per-key consecutive-identical-result count before the skipLoopDetection gate, and nothing lowers it mid-turn when results start changing — only the Retry branch and reset() clear it; ModelFallback does not (probe-verified). The round-6 fix (a separate statefulCapKeyRepeat recomputed from current streaks, 61dd8c5) was reverted by the trim. Failure shape — the common teammate pattern of waiting on peers who then make progress: 8 interleaved task_list polls against a frozen board latch the peak at 8 without halting (interleaving breaks the consecutive guard; the result-time global duplicate is gated off under the CLI default), the board thaws and every subsequent call is productive, but past 100 total calls shouldHaltOnTurnToolCallCap sees stuck = (8 >= 6) and halts the productive turn as turn_tool_call_cap. The same latch fires when the key is abandoned after the frozen phase. Witness (probe at this head, production-shaped event order):

ARM-A freeze->thaw:  firing={index: 101, loopType: "turn_tool_call_cap"}
  (softCap=100, 8 freeze rounds; every call after the thaw productive)
ARM-B never-frozen control: firing={index: 1001}  (hard backstop only)
candidate fix (recompute from current streaks): ARM-A moves 101 -> 1001,
  all 145 existing service tests stay green

Fix: disarm the stateful contribution on changed results — keep it in a separate field recomputed from the keys' current consecutive streaks (the reverted fix's shape), or decay frozen keys' streaks at Finished boundaries — so a thawed or abandoned key cannot hold the prompt-wide stuck signal. Fix witness: a freeze→thaw regression — interleaved frozen results, then changed results and diverse calls past the soft cap, asserting no halt; removing the disarm must turn it red while a still-frozen interleaved board still halts just past the soft cap.

中文说明

[Critical] R7-2:仍然成立 —— 已在本 head 上重新证实(承载第 6 轮高水位线程与第 7 轮 R7-2 核心线程)。该棘轮在 skipLoopDetection 门控之前就用按键的连续相同结果计数抬高 capMaxKeyRepeat,而结果开始变化时没有任何机制在回合中途把它降下来 —— 只有 Retry 分支和 reset() 会清零;ModelFallback 不会(已用探针证实)。第 6 轮的修复(独立的 statefulCapKeyRepeat,结果变化时从当前连续段重算,61dd8c5535)已被瘦身回退。失败形态 —— teammate 等待 peer、peer 随后开始推进的常见模式:对冻结任务板做 8 次交错 task_list 轮询把峰值锁到 8 而不终止(交错打破连续守卫;CLI 默认下结果时全局重复被门控关闭),任务板解冻后每一次调用都是有效工作,但总数超过 100 时 shouldHaltOnTurnToolCallCapstuck = (8 >= 6),以 turn_tool_call_cap 终止高产回合。冻结阶段后放弃该键的形态同样触发。证据(在本 head 上以生产事件顺序驱动的探针):冻结→解冻臂在第 101 次调用以 turn_tool_call_cap 终止(软上限 100,8 轮冻结,解冻后全部调用有效);从未冻结对照只在第 1001 次(硬兜底)终止;候选修复(从当前连续段重算)使该臂从 101 移到 1001,且现有 145 个服务测试保持全绿。

修复:在结果变化时解除有状态贡献 —— 把它放进独立字段、按键的当前连续段重算(即被回退修复的形态),或在 Finished 边界衰减冻结键的连续段 —— 使解冻或被放弃的键无法长期持有整个 prompt 的卡滞信号。修复见证:补一个冻结→解冻回归测试 —— 交错冻结结果后改为变化结果与多样化调用、越过软上限,断言不终止;移除解除逻辑必须使其变红,而仍然冻结的交错任务板仍须在软上限附近终止。

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

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Patrol note (automated sweep): this PR has hit the scope fuse — cumulative additions are +1853 (>1500-line cap) and this finding shape has recurred across five-plus review rounds without converging. Per patrol policy no more code is added from the sweep; this thread stays open for a maintainer decision on direction (the digest/fingerprint gaps are real, but each round mints new entrance variants faster than they close).

Resolve conflicts from main's Gemini->Llm rename refactor while keeping
this PR's loop-detection changes:

- agent-headless.ts: keep the loopType field; use renamed LlmChat type.
- loopDetectionService.ts: keep the Part import; import
  ServerLlmStreamEvent/LlmEventType.
- Align PR-added code/tests with the new names (client.ts,
  client.test.ts, loopDetectionService.test.ts).

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.

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 — Test (macos-latest, Node 22.x) and Test (windows-latest, Node 22.x) were skipped in CI; unit suites ran green on Linux in this review's build-test, the OS dimension is untested (author-disclosed).

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

Not reviewed: test-efficacy probe — harness could not be validated (harnessValidated: null): the probe's isolated runner tripped the package's dist-prerequisite guard, so coverage-gap claims are neither confirmed nor refuted by mutation/hunk probes.

Not explored to full depth (tool budget reached): chunk 5: could not execute loopDetectionService.test.ts (worktree has no node_modules / dist ; full npm install + build exceeds the tool budget) — verification is by ….

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

  • packages/core/src/agents/runtime/agent-interactive.test.ts:365 — [probe] lastRoundError loopType format asserted by no test
  • packages/core/src/tools/truncation.ts:537 — [probe] buildStub digest-line producer half untested
  • packages/core/src/agents/runtime/agent-core.ts:1365 — [review] Provider-duplicate stop carries null loopType — attribution collapses
  • packages/core/src/agents/runtime/agent-interactive.ts:543 — [review] Stop message says 'duplicate tool-call loop' for all 11 detector types
  • packages/core/src/agents/runtime/agent-interactive.test.ts:354 — [review] FAILED settling after a loop stop pinned by nothing
  • packages/core/src/services/loopDetectionService.test.ts:3023 — [probe] Quoted-marker test does not discriminate the leading-prefix gate
  • packages/core/src/services/loopDetectionService.ts:23 — [probe] truncateAndSaveToFile shape recognition pinned by no test
  • packages/core/src/agents/runtime/agent-headless.test.ts:2411 — [probe] Agent-core result-time halt branch never exercised
  • packages/core/src/agents/runtime/agent-headless.test.ts:2526 — [probe] Result-side single-count seam of the duplicate sync test unpinned

Convergence: round 18 posted 5 inline comment(s), 2 of them reported for the first time; the previous round posted 3 (3 new). Findings keep coming back to the same files: packages/core/src/services/loopDetectionService.ts (findings in round 17; 2 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.)

中文说明

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

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

未审查:build-and-test — Test (macos-latest, Node 22.x) and Test (windows-latest, Node 22.x) were skipped in CI; unit suites ran green on Linux in this review's build-test, the OS dimension is untested (author-disclosed)。

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

未审查:test-efficacy probe — harness could not be validated (harnessValidated: null): the probe's isolated runner tripped the package's dist-prerequisite guard, so coverage-gap claims are neither confirmed nor refuted by mutation/hunk probes。

未探索到全部深度(达到工具调用预算):chunk 5:could not execute loopDetectionService.test.ts (worktree has no node_modules / dist ; full npm install + build exceeds the tool budget) — verification is by …

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

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

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

Comment thread packages/core/src/services/loopDetectionService.ts
Comment thread packages/core/src/agents/runtime/agent-core.ts
Comment thread packages/core/src/services/loopDetectionService.ts
Comment on lines +733 to +737
// A retry replays the failed attempt's tool calls; drop the stateful
// result evidence too so the replayed attempt is judged on its own
// results (consecutive counts re-accumulate as results land, consistent
// with the capKeyCounts/globalToolCallCounts clears).
this.statefulConsecutiveResults.clear();

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.

[Critical] R18-1: The Retry branch deletes committed result evidence that a retry can never double-count. Tool results are recorded exactly once per executed call and only after the round's stream completes (client.ts records round N's result before round N+1 streams; agent-core records after processFunctionCalls), so this comment's rationale is correct for the request counters — replayed requests re-stream and would double-count — and wrong for the result counters: nothing about the replay ever re-records a result, so the clear purely deletes committed evidence. It also zeroes the adaptive cap's stuck signal for stateful tools (capMaxKeyRepeat is fed only from recordToolResult since trackCapKeyRepeat skips them), so the stuck condition cannot form between the 100 soft cap and the 1000 backstop either. Failure: a frozen task_list board commits 5 identical results (one short of the threshold-6 result-aware GLOBAL_TOOL_CALL_DUPLICATE); a transient provider Retry wipes the map; the count restarts at 1 and no re-stream of requests can rebuild it — with a retry inside any <=6-poll window the frozen poller evades the result-aware guards and runs to the 1000-call hard backstop instead of halting at ~5-6.

witness (probe): PR: firedAtTotalRecordedResult=11 (5 committed frozen results wiped by the Retry; the guard fires only after 6 fresh post-retry results) | MUTANT (clear removed): fires on the 6th committed result as designed — the probe flips.

Fix: remove this.statefulConsecutiveResults.clear(); from the Retry branch (keep the request-counter rollback) — the count re-accumulates correctly without the clear. Fix witness: record 5 identical frozen results, emit Retry, record one more identical result and assert recordToolResult returns true with GLOBAL_TOOL_CALL_DUPLICATE; with the clear in place the count restarts at 1 and the test goes red.

中文说明

[Critical] R18-1:Retry 分支删除了重试根本不可能重复计入的已提交结果证据。工具结果只在每次执行后、且仅在本轮流式完成之后记录一次(client.ts 在第 N+1 轮流式开始前记录第 N 轮的结果;agent-core 在 processFunctionCalls 之后记录),因此本处注释的理由对请求计数器成立——重放的请求会重新流式、会重复计入——但对结果计数器不成立:重放不会重新记录任何结果,这个 clear 纯粹是在删除已提交的证据。它同时把有状态工具的自适应上限卡滞信号清零(capMaxKeyRepeat 仅由 recordToolResult 喂入,trackCapKeyRepeat 跳过它们),于是卡滞条件在 100 软上限与 1000 兜底之间也无法形成。失败场景:冻结的 task_list 任务板已提交 5 次相同结果(距离阈值 6 的结果感知 GLOBAL_TOOL_CALL_DUPLICATE 还差 1 次);一次瞬态 provider Retry 清空该 map;计数从 1 重新开始且没有任何请求重流能重建它——只要任意 <=6 次轮询的窗口内出现一次 Retry,冻结的轮询者就会绕过结果感知守卫,一路跑到 1000 次硬兜底而不是在约 5-6 次处终止。

证据(探针):PR: firedAtTotalRecordedResult=11(5 次已提交的冻结结果被 Retry 清掉;守卫只在重试后又积累 6 次新结果后才触发)| MUTANT(移除 clear):按设计在第 6 次已提交结果处触发——探针翻转。

修复:从 Retry 分支移除 this.statefulConsecutiveResults.clear();(保留请求计数器的回滚)——没有这个 clear,计数也能正确重新累积。修复验收:记录 5 次相同冻结结果、发出 Retry、再记录 1 次相同结果,断言 recordToolResultGLOBAL_TOOL_CALL_DUPLICATE 返回 true;保留 clear 时计数从 1 重来,测试变红。

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

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

New shape (R18-1): claims the Retry branch deletes committed result evidence that a retry can never double-count, since tool results are recorded once per executed call after the round's stream completes. This PR is scope-fused per patrol policy (cumulative additions +1854, no new code this round), so this stays human-gated for maintainer decision alongside the existing open Criticals.

Comment on lines +255 to +258
const digest = extractAnchoredStubDigest(value);
if (digest !== null) {
return `<persisted-stub>sha256:${digest}`;
}

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.

[Critical] R18-2: A peer-quoted digest line inside a genuine digest-less stub hijacks the fingerprint. extractAnchoredStubDigest scans the WHOLE stub value: for a digest-less truncateAndSaveToFile stub (the R17-1 band — no envelope digest), a line-anchored Full output sha256: <64-hex> quoted inside the visible payload becomes the fingerprint. Peer-authored board text is interpolated verbatim (TeamManager.ts escapeEnvelopeTags defangs only <teammate_message> delimiter tokens), and teammate messages are appended at the board's end — squarely in the retained tail band. The leading-prefix gate correctly admits the value as a real stub; extraction then runs over envelope + payload, the quoted line wins, and every poll fingerprints to a constant even while the board changes — the productive poller false-halts at the 5th identical request. This is the #9450 false positive reintroduced through peer-authored content, defeating the protection the gate's own comment promises (quoted content "cannot collapse or vary the fingerprint"). Distinct from R17-1, which needs no injected content.

witness (probe through the real truncateAndSaveToFile producer): INJECTED arm fired=true at=4 (halt at the 5th identical request, consecutive_identical_tool_calls); INTERLEAVED injected arm fired=true at=5 (halt at the 6th identical result, global_tool_call_duplicate); CONTROL arm fired=false; FIX (digest extraction confined to the envelope region) fired=false on both injected arms with all 145 tests still green.

Fix: confine digest extraction to the envelope region — locate the payload marker (STUB_PREVIEW_MARKER / STUB_TRUNCATED_PART_MARKER) first and run extractAnchoredStubDigest only over the text before it, falling back to the path-free payload when no envelope digest exists. Fix witness: a digest-less stub whose payload carries a fixed digest line while the rest of the board varies per poll must not halt (fired === false); with the current whole-value search the guard halts, so the test is red today and pins the envelope-only restriction.

中文说明

[Critical] R18-2:真实无 digest stub 内部被引用的同侪内容 digest 行会劫持指纹。extractAnchoredStubDigest 扫描 stub 的完整值:对无 digest 的 truncateAndSaveToFile stub(即 R17-1 分支——信封中没有 digest),可见载荷中被引用的、行首锚定的 Full output sha256: <64-hex> 会成为指纹。同侪撰写的任务板文本被逐字插入(TeamManager.tsescapeEnvelopeTags 只解除 <teammate_message> 分隔符 token),而 teammate 消息被追加在任务板末尾——恰好落在保留的尾部区间。前缀门正确地把该值当作真实 stub 放行;随后抽取在整个"信封 + 载荷"上运行,被引用的行胜出,即使任务板持续变化,每次轮询的指纹也是常量——高效的轮询者在第 5 次相同请求处被误杀。这是经同侪撰写内容重新引入的 #9450 误杀,击败了该门控自身注释承诺的保护(被引用内容"不得折叠或改变指纹")。与 R17-1 不同——后者不需要任何注入内容。

证据(经真实 truncateAndSaveToFile 生产者的探针):INJECTED 分支 fired=true at=4(第 5 次相同请求处终止,consecutive_identical_tool_calls);INTERLEAVED 注入分支 fired=true at=5(第 6 次相同结果处终止,global_tool_call_duplicate);CONTROL 分支 fired=false;FIX(digest 抽取限定在信封区域)在两个注入分支均 fired=false,且 145 个测试全部保持绿。

修复:把 digest 抽取限定在信封区域——先定位载荷标记(STUB_PREVIEW_MARKER / STUB_TRUNCATED_PART_MARKER),只在其之前的文本上运行 extractAnchoredStubDigest,无信封 digest 时回退到不含路径的载荷。修复验收:一个无 digest stub,其载荷携带固定 digest 行而任务板其余部分逐轮变化,必须不终止(fired === false);按当前的全值搜索守卫会终止,因此该测试今天即为红,正好钉住"仅限信封"的限制。

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

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

New shape (R18-2): claims a peer-quoted digest line inside a genuine digest-less stub can hijack the fingerprint, because extractAnchoredStubDigest scans the whole stub value. This PR is scope-fused per patrol policy (cumulative additions +1854, no new code this round), so this stays human-gated for maintainer decision alongside the existing open Criticals.

@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): chunk 2: executing agent-headless.test.ts to confirm the static trace — the review worktree has no node_modules , and npm ci plus the prerequisite workspace build e…; chunk 5: did not execute loopDetectionService.test.ts — the shared review worktree has no node_modules/dist, and a full install+build was not feasible without mutating….

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

  • packages/core/src/agents/runtime/agent-interactive.test.ts:366 — [review] lastRoundError attribution unwitnessed — the test never asserts getLastRoundError()
  • packages/core/src/services/loopDetectionService.test.ts:3025 — [review] quoted-stub-marker test cannot catch the collision direction
  • packages/core/src/tools/truncation.ts:528 — [review] buildStub digest producer zero coverage — producer/consumer contract never exercised end-to-end
  • packages/core/src/agents/runtime/agent-core.ts:1240 — [review] agent-core recordToolResult halt branch unwitnessed
  • packages/core/src/core/client.test.ts:8237 — [review] changed-board liveness test can pass on a silent turn death
  • packages/core/src/core/client.test.ts:8230 — [review] frozen-board tests never assert requests stop after LoopDetected
  • packages/core/src/core/client.ts:3615 — [review] id-less stateful calls lose all cap stuck-signal (fail-safe hole in the cap tier)
  • packages/core/src/services/loopDetectionService.test.ts:3273 — [review] reset()/Retry stateful clears unwitnessed; cross-prompt count carry reachable
  • packages/core/src/agents/runtime/agent-interactive.ts:540 — [review] stop-message base label wrong for non-duplicate detectors
  • packages/core/src/services/loopDetectionService.test.ts:2985 — [review] TOOL_OUTPUT_TRUNCATED_PREFIX recognition layer has zero test witness
  • packages/core/src/agents/runtime/agent-headless.ts:412 — [review] FINISH-event loopType has zero production read sites
  • packages/core/src/services/loopDetectionService.ts:617 — [review] checkAlternatingPattern not result-aware (heuristics-on false halt)
  • packages/core/src/agents/runtime/agent-interactive.test.ts:355 — [review] status wait accepts both idle and failed, pins neither

Convergence: round 19 posted 6 inline comment(s), 2 of them reported for the first time; the previous round posted 5 (2 new). Findings keep coming back to the same files: packages/core/src/agents/runtime/agent-core.ts (findings in round 17; 1 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.)

Residual risk: this loop is persistently critical — Criticals stood in the previous round's work-list and stand again this round (6 Critical(s)), the rate of first-time findings is not falling (this round 2, previous 2), and the standing Critical backlog is not shrinking. The severity floor will not converge it. Recommendation: land-with-residual-risk — the exit is a maintainer risk-acceptance decision (merge, carrying the residual risk), not another review round. Residual-risk inventory for that decision (maintainer to complete):

standing Critical attack surface attacker-dependency blast radius
(each standing Critical)

Advisory only — it does not block this review.

中文说明

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

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

未探索到全部深度(达到工具调用预算):chunk 2:executing agent-headless.test.ts to confirm the static trace — the review worktree has no node_modules , and npm ci plus the prerequisite workspace build e…;chunk 5:did not execute loopDetectionService.test.ts — the shared review worktree has no node_modules/dist, and a full install+build was not feasible without mutating…

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

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

残余风险:本循环处于 persistently-critical 形态——上一轮工作清单中的 Critical 本轮依然存在(本轮 6 条 Critical),首次发现的速率没有下降(本轮 2,上一轮 2),且未决 Critical 积压没有减少。severity floor 无法使其收敛。建议:land-with-residual-risk——出口是 maintainer 的风险接受决定(合入并承担残余风险),而非再开一轮评审。供该决定使用的残余风险清单(maintainer 填写):按每条未决 Critical 列出「攻击面 · 攻击者依赖性 · 影响范围」三栏。仅为建议——不阻断本次评审。

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

Comment on lines +1233 to +1235
for (const toolResult of toolCallResult.results) {
if (
loopDetector.recordToolResult(

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.

[Critical] R19-1: The result-aware exemption assumes "by the Nth identical request, the prior N−1 results have been recorded", but agent-core feeds results only after the whole batch executes (this loop runs after processFunctionCalls). Whenever the threshold-crossing request is not the first request of its round, its in-round predecessor's result does not exist yet at fire time (recordToolResult increments resultsObserved only for the current key, so an in-flight predecessor cannot count). Concretely: a teammate subagent batching 3 identical task_list({}) polls in round 1 and 2 in round 2 — 5 consecutive identical requests with the board changing between every poll — gets counts 1→3 in round 1 (3 changed results fed post-batch), then round 2's second request reaches count 5: expectedResults = 4 but resultsObserved = 3, the exemption is unreachable, and the fail-safe halts a productive poller with consecutive_identical_tool_calls — the exact #9450 false positive this PR removes. The 2+3 and 1+4 splits reach it too; only splits where the 5th request opens its round (4+1, 2+2+1) don't. Every service test interleaves a result after each request, an order production never presents for a round with ≥2 task_list calls, so the suite is green.

Witness — probe driving the real LoopDetectionService in agent-core's production order:

BASE: AssertionError — halt fires on 'round2-req2' despite 3 changed boards already recorded
controls on the same run: interleaved-order changed boards → no halt; frozen boards production order → halts; no-results fail-safe → halts
FIX arm (defer the stateful halt to the result feed): all 4 contract cases pass — probe flips

Fix: account for in-flight requests in the exemption — track outstanding requests per streak (requests streamed − results recorded) and evaluate resultsObserved >= toolCallRepetitionCount - 1 - outstanding — or defer the stateful-streak halt decision to the result feed / round boundary where all prior results have been fed. Verifier measurement: deferring the halt to recordToolResult preserved the #5019 no-evidence fail-safe in the probe, while folding outstanding into the exemption relaxed it — prefer the former.

Fix witness: add a production-order test — send 3 task_list requests, feed 3 changed results, send 2 more requests, assert the 5th checkAlwaysOnSafeties returns false; remove the fix and it must go red (please run that mutation to confirm).

中文说明

结果感知豁免依赖不变量"第 N 次相同请求时前 N−1 个结果已记录",但 agent-core 在整批执行完毕后才喂送结果(此循环位于 processFunctionCalls 之后)。当触发阈值的请求不是其所在轮的第一个请求时,同轮前序请求的结果在判定时必然缺失(recordToolResult 只对当前键累加 resultsObserved,在途前序无法计入)。具体场景:teammate 子 agent 第 1 轮批内轮询 3 次 task_list({})、第 2 轮批内轮询 2 次——共 5 次连续相同请求且任务板每次都在变化:第 1 轮计数 1→3(批后喂入 3 个已变化结果),第 2 轮第 2 次请求计数到 5:expectedResults = 4resultsObserved = 3,豁免不可达,失败安全分支以 consecutive_identical_tool_calls 终止生产性轮询者——正是本 PR 要消除的 #9450 误杀。2+3、1+4 分布同样可触发;仅第 5 次请求开轮的分布(4+1、2+2+1)不会。所有服务层测试在每个请求后交替喂结果——生产环境在一轮 ≥2 次 task_list 时从不呈现该顺序,因此套件全绿。

修复:让豁免计入在途请求(按连续段跟踪未决请求数,判定 resultsObserved >= toolCallRepetitionCount - 1 - outstanding),或将状态性连续段的终止决定推迟到结果喂入/轮边界。验证者测得:把终止推迟到 recordToolResult 保留了 #5019 无证据失败安全,而把 outstanding 折进豁免会放松它——建议采用前者。

修复见证:新增生产顺序测试——连发 3 次 task_list 请求、喂入 3 个已变化结果、再连发 2 次请求,断言第 5 次 checkAlwaysOnSafeties 返回 false;移除修复必须变红(请运行该突变确认)。

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

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Verified REAL at head 2351563 (read-only code trace; no code executed or changed):

  • Request counting happens at stream time: every batched ToolCallRequest is fed to checkAlwaysOnSafeties (agent-core.ts:1142, deduped only by call id), incrementing toolCallRepetitionCount (loopDetectionService.ts:816).
  • Results are fed only after the whole batch executes: processFunctionCalls (agent-core.ts:1214) runs first, then the recordToolResult loop (agent-core.ts:1233-1235). Nothing is fed mid-round.
  • The exemption requires state.resultsObserved >= toolCallRepetitionCount - 1 (loopDetectionService.ts:846-847), and recordToolResult only increments resultsObserved for the current streak key (:465-466).

Trace: round 1 = 3 identical task_list({}) requests -> counts 1-3 (< TOOL_CALL_LOOP_THRESHOLD=5, :41), then 3 changed boards fed post-batch -> resultsObserved=3, unchangedStreak=0. Round 2: request 4 -> count 4; request 5 -> count 5 >= threshold: expectedResults=4 but resultsObserved=3 (round 2's batch has not executed yet), exemption unreachable -> halt with consecutive_identical_tool_calls despite every recorded board having changed. Any split where the 5th request does not open its round (3+2, 2+3, 1+4) hits this.

This PR is scope-fused and has been non-converging for 19 patrol rounds; recorded as needs-human-decision. No code changes this round. Leaving unresolved.

Comment on lines 3755 to +3757
) {
hasToolCalls = false;
loopGuardFedCallIds.clear();

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.

[Critical] R19-2: The diff models Retry and ModelFallback identically as attempt restarts everywhere else — this branch clears loopGuardFedCallIds for both, turn.ts clears pendingToolCalls for both, both stream consumers zero their request arrays on fallback, and the heuristic tier in the same service resets for both — but checkAlwaysOnSafeties resets its counters only in its Retry branch. After a ModelFallback the failed attempt's counted-but-never-executed tool calls stay in toolCallRepetitionCount and can never produce results, so resultsObserved is permanently N behind expectedResults in checkToolCallLoop: the changed-board restart branch is unreachable for the rest of the streak, and a productive poller whose every executed poll returns a changed board halts with consecutive_identical_tool_calls — the #9450 false positive reintroduced through the fallback path.

Witness — probe (2 identical task_list requests → ModelFallback → productive re-polls with a changed board every round):

PR code: guard fired at post-2 with loopType=consecutive_identical_tool_calls (expected 'post-2' to be null)
FIXED (ModelFallback added to the reset branch): probe passed, firedAt=null

Fix: add a ModelFallback branch to checkAlwaysOnSafeties mirroring the Retry branch — roll turnToolCallTotal back to the committed floor, resetToolCallCount(), clear capKeyCounts/capMaxKeyRepeat, clear statefulConsecutiveResults, and zero resultsObserved/unchangedStreak for all statefulRepeatState entries (or extract the Retry branch body and call it for both event types).

Fix witness: feed TOOL_CALL_LOOP_THRESHOLD−1 identical task_list requests, dispatch a ModelFallback event, continue with identical requests whose recorded results change every poll, and assert no halt within 4×threshold; removing the ModelFallback reset must turn it red (please run that mutation to confirm).

中文说明

diff 在其余所有位置把 Retry 与 ModelFallback 同等建模为尝试重启——本分支对两者清空 loopGuardFedCallIdsturn.ts 对两者清空 pendingToolCalls,两个流消费者都在回退时清零请求数组,同一服务的启发式层也对两者重置——但 checkAlwaysOnSafeties 只在 Retry 分支重置计数器。ModelFallback 之后,失败尝试中已计数但永不执行的工具调用留在 toolCallRepetitionCount 中、永不产生结果,checkToolCallLoopresultsObserved 永远落后 expectedResults N 个:变化板重启分支在该连续段剩余部分不可达,即使每次执行的轮询都返回变化板,生产性轮询者仍以 consecutive_identical_tool_calls 终止——#9450 误杀经回退路径复活。

修复:为 checkAlwaysOnSafeties 增加 ModelFallback 分支,镜像 Retry 分支——回滚 turnToolCallTotal 至已提交地板、resetToolCallCount()、清空 capKeyCounts/capMaxKeyRepeat、清空 statefulConsecutiveResults、清零所有 statefulRepeatState 条目的 resultsObserved/unchangedStreak(或抽取 Retry 分支体对两种事件共用)。

修复见证:喂入 TOOL_CALL_LOOP_THRESHOLD−1 次相同 task_list 请求、派发 ModelFallback 事件、继续以每次变化结果的相同请求轮询,断言 4×阈值内不终止;移除 ModelFallback 重置必须变红(请运行该突变确认)。

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

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Verified REAL at head 2351563 (read-only code trace; no code executed or changed):

  • checkAlwaysOnSafeties resets its counters only in the Retry branch (loopDetectionService.ts:728-744: cap rollback, resetToolCallCount, clears capKeyCounts/capMaxKeyRepeat/statefulConsecutiveResults, zeroes resultsObserved/unchangedStreak). ModelFallback has no branch: it falls through to event.type !== LlmEventType.ToolCallRequest -> return false (:745) as a no-op, even though client.ts feeds every event into the guard (:3798).
  • Everywhere else the diff models Retry and ModelFallback identically as attempt restarts: client.ts:3752-3757 clears loopGuardFedCallIds for both; turn.ts:640 and :656 clear pendingToolCalls for both; the heuristic tier resets in both the Retry case (:625) and the ModelFallback case (:652, "Mirror the replay-retry resets").

Mechanism: the failed attempt's streamed requests stay in toolCallRepetitionCount but never execute (pendingToolCalls cleared on fallback), so they can never produce results. resultsObserved is then permanently < expectedResults = count - 1 (:846), the changed-board exemption at :847 is unreachable for the rest of the streak, and a poller whose every executed poll returns a changed board halts with consecutive_identical_tool_calls — the #9450 false positive via the fallback path.

This PR is scope-fused and has been non-converging for 19 patrol rounds; recorded as needs-human-decision. No code changes this round. Leaving unresolved.

Comment thread packages/core/src/services/loopDetectionService.ts
Comment thread packages/core/src/services/loopDetectionService.ts
Comment thread packages/core/src/agents/runtime/agent-core.ts
Comment thread packages/core/src/services/loopDetectionService.ts
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.

task_list can falsely trigger duplicate tool-call loop detection while team state changes

4 participants