Skip to content

fix(memory): improve recall reliability and candidate coverage - #8716

Merged
yiliang114 merged 23 commits into
mainfrom
codex/7040-memory-recall
Aug 18, 2026
Merged

fix(memory): improve recall reliability and candidate coverage#8716
yiliang114 merged 23 commits into
mainfrom
codex/7040-memory-recall

Conversation

@yiliang114

@yiliang114 yiliang114 commented Aug 8, 2026

Copy link
Copy Markdown
Collaborator

What this PR does

Makes native memory recall reliable in two independent ways: selected memory actually reaches the model, and selection works outside ASCII.

Delivery: recall gets a 100 ms ceiling before the initial user request — not a fixed cost. The wait ends on whichever comes first: recall settling, the deterministic result being published, cancellation, or the ceiling. A result that settles inside it is delivered immediately. If it does not, the deterministic candidates that selectModelCandidateDocuments already computed for the model manifest are injected instead of nothing, capped at two documents. Recall stays alive, so the model-selected result still lands at the existing same-query ToolResult delivery point, with fast-delivered documents excluded and the prompt rebuilt from the remainder.

Selection: the deterministic scorer, which now serves both the fast path and the selector-failure fallback, gets Unicode NFKC normalization, whole-run tokens for non-CJK letters (\p{L}-based rather than [a-z0-9], so Cyrillic, Greek, Arabic, and accented Latin produce tokens instead of none), CJK code-point bigrams, isolated-CJK rejection, lexical-match gating, field-aware weighting, and bounded query tokens. Score ties break by recency and then by input order, never by document type — an alphabetical type comparison ranks user behind every other type, and with the fast result capped at two documents that would systematically drop user-level memory from exactly the turn the fast path exists to serve. Recall also swaps the shared scanner's per-scope 200-document cap for a global, query-aware candidate set with a recency reserve and a bounded manifest. This is a change of truncation key, not a lifted ceiling: at or under 200 documents nothing was excluded by count before either, and the new 25,000-byte manifest budget is a ceiling the old path lacked; between 200 and 400 with neither scope over 200, the old path sent every document to the selector and the new one sends at most 200, so fewer reach the model; a scope over 200 is the case the change is actually for, where an old but lexically matching document was permanently invisible.

Model-first selection, cancellation, exactly-once delivery telemetry, active-tool filtering, and the existing prompt limits are preserved. No new dependency and no new public setting.

Why it's needed

The initial request originally did a zero-wait poll, so memory reached the first prompt only by luck. A 100 ms budget was the first fix, but measurement showed it is not sufficient alone: recall awaits the model selector, a network side query with a 30 s abort ceiling, so the budget is dominated by round-trip time rather than scheduler jitter. It expires on the common path, delivery falls through to ToolResult, and a turn that makes no tool call never reaches one, so the result is discarded as no_safe_delivery_point. Tool-free turns are exactly the short, context-answered questions where user memory matters most.

Separately, the deterministic fallback was ASCII-oriented and gave every non-empty document a positive score, so it could select non-matching documents and could not tokenize ordinary CJK queries.

Reviewer Test Plan

How to verify

cd packages/core
npx vitest run src/memory/recall-eval.test.ts src/memory/recall-delivery-eval.test.ts
npx vitest run src/memory/recall.test.ts src/memory/relevanceSelector.test.ts src/memory/memoryLifecycle.integration.test.ts
npx vitest run src/memory/recall-scan-latency.test.ts
npx vitest run src/core/client.test.ts -t "fast"

The two eval files print their before/after tables to stdout with --silent=false.

Behavioral cases to confirm by review: a result settling inside the budget is delivered initially; a budget miss delivers the deterministic result and leaves recall alive for ToolResult; the later delivery never repeats a fast-delivered document; cancellation inside the initial window delivers nothing; a fast result never crosses a query boundary; no-result queries stay silent; a score tie does not push a user-typed document out of the two-document fast result; a result whose every document was already fast-delivered is discarded as already_delivered rather than as a lost one, while a partial overlap still reports the cancellation reason.

Evidence (Before & After)

Full numbers, method, and limitations are in #8716 (comment).

Recall quality (recall-eval.test.ts, 51-case / 25-document labeled corpus scored against a frozen copy of the pre-change scorer):

slice metric before after
overall (n=51) Recall@5 45.2% 92.9%
overall (n=51) top-1 accuracy 46.2% 97.4%
overall (n=51) no-result precision 16.0% 75.0%
overall (n=51) no-result recall 44.4% 100.0%
english (n=11) Recall@5 100.0% 100.0%
english (n=11) top-1 accuracy 100.0% 100.0%
cjk (n=17) Recall@5 0.0% 100.0%
cjk (n=17) top-1 accuracy 0.0% 100.0%
mixed (n=5) Recall@5 80.0% 100.0%
mixed (n=5) top-1 accuracy 60.0% 100.0%
other-script (n=3) Recall@5 33.3% 100.0%
other-script (n=3) top-1 accuracy 33.3% 100.0%
semantic-no-lexical (n=3) Recall@5 0.0% 0.0%

Corpus scale, so the headline is readable: 25 documents, 51 cases. A query-blind scorer returning 5 random documents scores 20.0% Recall@5 on this pool, and a test keeps that floor at or below 25% with the measured result well clear of it.

The overall figures are held below 100% by the semantic-no-lexical slice: answerable queries that share no token with their document. Both the shipped scorer and the frozen pre-change one return nothing for all of them, so requiring a lexical match did not create that gap — but it does keep the deterministic path silent there, and the slice is measured on its own rather than folded into the quality floor.

Delivery (recall-delivery-eval.test.ts): above the budget, tool-free first-turn delivery improves 0% -> 92.9%; tool-using turns remain delivered one request later; duplicate delivery remains 0%.

Scan latency (recall-scan-latency.test.ts, new) is the measurement that was missing, and it is the one that decides whether the fast path delivers at all. Deterministic scoring costs p50 0.036 ms / p95 0.053 ms — but the fast result is only published once recall has enumerated, read, and parsed the memory tree, and this PR removed the 200-document cap for recall. Measured against a real temporary tree:

topics median time to fast result share of the 100 ms ceiling inside it?
200 ~29 ms ~29% yes
500 ~70 ms ~70% yes
1000 ~130 ms ~130% no

Two consequences. For any tree small enough to scan in time — the ordinary case, tens of topics — the fast result is in hand long before the ceiling, so the wait now ends there rather than spending the rest on a selector this design already assumes will miss the budget. On slow enough I/O the scan alone exceeds the ceiling, and the turn then pays the full budget and still delivers nothing — worse than the zero-wait behaviour this PR replaced. The crossover is machine-dependent, not a fixed topic count: an independent run on faster hardware measured 9 / 21 / 46 ms for the same three sizes and never reached the ceiling. The table above is the conservative side. Ending the wait early bounds this case rather than fixing it, and the real fix (a persistent catalog) stays out of scope.

The residual 7.1% of tool-free delivery is exactly the semantic-no-lexical slice, asserted separately: the fast path closes the timing gap, not the matching gap. Only the model selector can serve a query with no lexical match, and on a tool-free turn it never lands.

Selector latency is modeled rather than measured because a network round trip cannot be timed in a unit test, so delivery results are reported per latency scenario. Note that the delivery eval simulates the two designs rather than driving tryConsumeMemoryPrefetch, so its duplicate-delivery figure is a property of the simulation; the shipped dedupe is covered by client.test.ts ("does not re-deliver a document the fast phase already injected"), which was verified to fail when the exclusion filter is removed.

Tested on

OS Status
macOS ✅ Verified independently on head 01ef7d7d (macOS 26.6 / arm64 / Node 24.18.1): 37 files, 929 passed, 0 failed. tsc --noEmit -p packages/core clean — the sharp error below does not reproduce there. eslint clean. Both eval tables reproduce exactly. See this verification comment
Windows ⚠️ Not locally verified
Linux packages/core src/memory/ + src/core/client.test.ts — 928 passed. One unrelated pre-existing failure, team-memory-sync.test.ts > unstages the team path when the commit fails, which reproduces on the untouched branch head and passes on macOS, confirming it is environmental (sandbox git-hook). eslint clean; tsc --noEmit -p packages/core reports only the pre-existing sharp SharpConstructor type error in src/utils/image-view.ts

Environment (optional)

Not applicable.

Risk & Scope

  • Main risk or tradeoff: the fast result carries no model judgment, and it wins the initial turn whenever the deterministic scorer matches — not only when the selector is slow. onFastResult is published before recall issues the selector request, so the recall promise is never settled when the wait ends on it; the settled-recall branch is reached at the initial delivery point only when no fast result exists. Verified end-to-end against a selector settling in 15 ms: the deterministic pair is delivered and the model's picks are discarded, where the pre-change build delivered nothing at all on that same turn. This is deliberate — a model side query does not return inside a 100 ms ceiling in production, so arbitrating would spend the rest of the budget every turn to win a race that does not happen — and the selector's judgement still reaches the model at ToolResult with the fast documents excluded. Two documents bounds the cost of being wrong.
  • Not validated / out of scope: RFC: Reliable auto-memory recall — timing, quality, and telemetry #7040's full Fast/Refined design with two results from one shared scan, cross-phase exclusion, and combined budget accounting; this PR reuses the candidates the selector was already going to score. Non-recall scanner flows remain capped by the shared scanner behavior.
  • Per-turn document count: MAX_RELEVANT_DOCS = 5 bounds one prompt, not one turn. A fast delivery of two documents followed by a refined delivery of five disjoint ones puts seven in front of the model — dedupe removes repeats, not the sum. This follows directly from dropping combined fast/refined budget accounting; both prompts stay individually bounded and each body is still truncated to MAX_DOC_BODY_CHARS, so the worst case is bounded and small, but it is not five. If a hard aggregate ceiling is wanted, the cheap version is passing limit - fastDeliveredPaths.size as the refined limit.
  • Breaking changes / migration notes: none. phase is the delivery stage and strategy is the selection method. A fast delivery is always heuristic; a refined delivery is model normally and heuristic when the selector failed. MemoryRecallDiscardReason gains already_delivered, which is now recorded on every discard path — not only at the ToolResult consume point — whenever the fast phase had already delivered every selected document, so the no_safe_delivery_point bucket stops counting turns that did get their memory. A partial overlap still reports the cancellation reason.

Known limitations:

  • Scoring is substring-based, so a query token can match inside a longer word (owner inside ownership). The corpus records one such case rather than hiding it.
  • A query sharing no token with its document produces no deterministic result, so a tool-free turn asking it still ends with nothing delivered. The semantic-no-lexical slice measures this; it is a limit the fast path does not remove.
  • On slow enough I/O the memory-tree scan exceeds the initial ceiling and the turn delivers nothing. Machine-dependent crossover, bounded rather than fixed.
  • Scripts written without word separators and outside the CJK set — Thai, Khmer, Lao — now produce a token where they produced none, but the token is the whole run. That is not segmentation, and such a query will usually still match nothing.

Linked Issues

Refs #7040.

中文说明

本 PR 做了什么

本 PR 从两个互相独立的方面提升原生 memory recall 的可靠性:一是选中的记忆确实进入模型,二是非 ASCII 查询也能正确参与选择。

交付方面:初始用户请求前,recall 会获得 100 ms 上限(不是固定开销)。等待以先到者为准结束:recall 完成、确定性结果发布、取消,或到达上限。如果结果在预算内完成,就立即交付。如果没有完成,则注入 selectModelCandidateDocuments 已经为模型 manifest 计算出的确定性候选,而不是注入空结果,最多两个文档。recall 仍会继续运行,因此模型选择出的结果仍能在现有同 query 的 ToolResult 交付点进入请求;已经 fast 交付过的文档会被排除,prompt 会用剩余结果重建。

选择方面:确定性 scorer 现在同时服务 fast path 和 selector 失败 fallback,并增加 Unicode NFKC 归一化、非 CJK 字母整串 token(基于 \p{L} 而非 [a-z0-9],因此西里尔、希腊、阿拉伯和带重音拉丁文都能产生 token)、CJK code-point bigram、孤立 CJK 拒绝、词面匹配门禁、字段加权和有界 query token。同分时按 mtime 降序、再按输入顺序排列,不再按文档 type——type 字典序会把 user 排在其他所有类型之后,而 fast 结果只取两篇,这会系统性地把用户级 memory 排除在 fast path 最该服务的那类回合之外。recall 还把 shared scanner 按 scope 各自 200 篇的上限,换成了全局、感知 query 的候选集(recency reserve + 有界 manifest)。这是换了截断依据,不是抬高了天花板:总量 ≤200 时两种设计都不按数量丢弃,但新增的 25,000 字节 manifest 上限是旧路径没有的;总量在 200–400 且单个 scope 不超 200 时,旧路径会把全部文档送给 selector,新路径最多送 200 篇,候选反而变少;只有单个 scope 超过 200 时才是这次真正要解决的场景——老而词法命中的文档原本永久不可见。

模型优先选择、取消、exactly-once 交付 telemetry、active-tool 过滤和现有 prompt 限制都保持不变。没有新增依赖,也没有新增公开设置。

为什么需要

初始请求原来只做 zero-wait poll,因此记忆能否进入第一个 prompt 基本靠运气。100 ms 预算是第一步修复,但测量显示它单独不够:recall 会等待模型 selector,而模型 selector 是一次网络 side query,有 30 秒 abort 上限,所以预算主要受网络往返影响,而不是调度抖动。常见路径会超出预算,交付退到 ToolResult;如果这一轮没有工具调用,就永远到不了 ToolResult,于是结果会以 no_safe_delivery_point 被丢弃。无工具回合通常正是那些短的、靠上下文回答的问题,也是用户记忆最有价值的场景。

另外,确定性 fallback 原来偏 ASCII,并且会给每个非空文档一个正分,因此可能选中完全不匹配的文档,也无法 tokenize 常见 CJK 查询。

Reviewer 测试计划

如何验证

cd packages/core
npx vitest run src/memory/recall-eval.test.ts src/memory/recall-delivery-eval.test.ts
npx vitest run src/memory/recall.test.ts src/memory/relevanceSelector.test.ts src/memory/memoryLifecycle.integration.test.ts
npx vitest run src/memory/recall-scan-latency.test.ts
npx vitest run src/core/client.test.ts -t "fast"

两个 eval 文件会在 stdout 输出 before/after 表格,需要使用 --silent=false 查看。

代码复核时应确认这些行为:预算内完成的结果会初始交付;预算 miss 会交付确定性结果并让 recall 继续等待 ToolResult;后续交付不会重复 fast 交付过的文档;初始窗口内取消不会交付任何内容;fast 结果不会跨 query 边界;无结果查询保持静默;同分不会把 user 类型文档挤出两篇的 fast 结果;选中文档若已被 fast 全部投递,丢弃时记为 already_delivered 而不是记成"丢失",部分重叠仍记原取消原因。

证据(前后对比)

完整数字、方法和限制见 https://github.com/QwenLM/qwen-code/pull/8716#issuecomment-5264740656。

Recall 质量方面(recall-eval.test.ts,51 case / 25 文档标注语料,与变更前 scorer 的 frozen copy 对比):

分片 指标 before after
overall (n=51) Recall@5 45.2% 92.9%
overall (n=51) top-1 accuracy 46.2% 97.4%
overall (n=51) no-result precision 16.0% 75.0%
overall (n=51) no-result recall 44.4% 100.0%
english (n=11) Recall@5 100.0% 100.0%
english (n=11) top-1 accuracy 100.0% 100.0%
cjk (n=17) Recall@5 0.0% 100.0%
cjk (n=17) top-1 accuracy 0.0% 100.0%
mixed (n=5) Recall@5 80.0% 100.0%
mixed (n=5) top-1 accuracy 60.0% 100.0%
other-script (n=3) Recall@5 33.3% 100.0%
other-script (n=3) top-1 accuracy 33.3% 100.0%
semantic-no-lexical (n=3) Recall@5 0.0% 0.0%

语料规模(便于解读上面的数字):25 篇文档、51 条 case。一个不看 query、随机返回 5 篇的 scorer 在这个池子上的 Recall@5 是 20.0%,测试会把这个下限卡在 25% 以内,实测结果远高于它。

overall 不到 100% 是被 semantic-no-lexical 分片拉下来的:这些 query 可答,但与目标文档没有任何词面重叠。新旧两个 scorer 对它们都返回空,所以"要求词面匹配"并没有制造这个缺口,但它确实让确定性路径在这里保持沉默。该分片单独测量,不计入质量下限。

交付方面(recall-delivery-eval.test.ts):超过预算时,无工具 first-turn 交付从 0% 提升到 92.9%;有工具回合仍在下一次请求交付;重复交付保持 0%。

扫描延迟(recall-scan-latency.test.ts,新增)才是决定 fast path 能否交付的那个量测,之前缺失。确定性 打分成本是 p50 0.036 ms / p95 0.053 ms——但 fast 结果要等 recall 扫完并解析整棵 Memory 树才会发布,而本 PR 恰好去掉了 recall 的 200 文档上限。在真实临时 Memory 树上实测:

topics 到 fast 结果的中位耗时 占 100 ms 上限 是否赶上
200 约 29 ms 约 29%
500 约 70 ms 约 70%
1000 约 130 ms 约 130%

两个结论。对能在预算内扫完的树(普通用户的常见情况,几十篇),fast 结果远早于上限就绪,所以等待现在到此为止,不再把剩余预算花在一个本设计已经假定赶不上的 selector 上。I/O 足够慢时扫描本身就超上限,该轮会付满预算且什么都投不到——比本 PR 替换掉的零等待更差。这个临界点与机器相关而不是固定篇数:另一台更快的机器上同样三档实测 9 / 21 / 46 ms,根本没到上限。上表取的是保守的那一侧。提前结束等待只能限制这种情况,消除不了它,真正的解法(持久化 catalog)仍在范围外。

剩下的 7.1% 正好就是 semantic-no-lexical 分片,并有独立断言:fast path 解决的是时机问题,不是匹配问题。没有词面匹配的 query 只有 Model Selector 能覆盖,而无工具回合等不到 Selector。

Selector latency 是建模而不是直接测量,因为单元测试无法真实计时一次网络往返,所以交付结果按不同 latency 场景报告。另需注意:delivery eval 是对两种设计的模拟,并没有真正驱动 tryConsumeMemoryPrefetch,所以其中的"重复交付"数字是模拟自身的性质;真正的去重由 client.test.tsdoes not re-deliver a document the fast phase already injected 覆盖,该用例已验证移除 exclusion filter 时会失败。

测试平台

OS 状态
macOS ✅ 已在 head 01ef7d7d 上独立验证(macOS 26.6 / arm64 / Node 24.18.1):37 个文件、929 passed、0 failed。tsc --noEmit -p packages/core 干净——下面提到的 sharp 报错在那边不复现。eslint 干净。两个 eval 表格完全复现。见该验证评论
Windows ⚠️ 未本地验证
Linux packages/coresrc/memory/ + src/core/client.test.ts —— 928 passed。仅 1 条无关的既有失败 team-memory-sync.test.ts > unstages the team path when the commit fails,在未改动的分支 HEAD 上同样复现、且在 macOS 上通过,确认是环境问题(sandbox git hook)。eslint 干净;tsc --noEmit -p packages/core 只剩既有的 src/utils/image-view.tssharpSharpConstructor 类型报错

环境(可选)

不适用。

风险与范围

  • 主要风险或取舍:fast 结果没有模型判断,而且只要确定性 scorer 有命中,初始轮就必然是它——与 selector 快慢无关,不只是 selector 慢的时候。onFastResult 在 recall 发出 selector 请求之前就发布了,所以等待在它这里结束时 recall promise 必然未 settle;初始交付点上「优先已 settle 的 recall」那个分支,只有在完全没有 fast 结果时才走得到。端到端验证过:让 selector 在 15 ms 内返回,投的仍然是确定性那两篇,模型选的被丢弃——而同一次运行里变更前的构建什么都没投。这是有意的取舍:生产环境里模型 side query 不可能在 100 ms 内返回,为此仲裁等于每轮都花掉剩余预算去赢一场不会发生的比赛;selector 的判断仍会在 ToolResult 交付点进入模型,并排除 fast 已投的文档。最多两篇限制了错排成本。
  • 未验证 / 范围外:RFC: Reliable auto-memory recall — timing, quality, and telemetry #7040 完整 Fast/Refined 设计中的同一次 shared scan 两个结果、跨阶段排除和组合预算计算;本 PR 复用 selector 本来就要评分的候选。非 recall 的 scanner 流程仍保留 shared scanner 行为中的上限。
  • 单轮文档数量:MAX_RELEVANT_DOCS = 5 限制的是单次注入,不是单轮总量。Fast 投递 2 篇、refined 又投递 5 篇全新文档时,本轮进入模型的是 7 篇——去重只消除重复,不压缩总和。这是放弃跨阶段预算核算的直接结果;两次 prompt 各自有界、每篇 body 仍截断到 MAX_DOC_BODY_CHARS,因此最坏情况有界且不大,但它不等于 5。若需要硬性总量上限,最省事的做法是把 refined 的 limit 传成 limit - fastDeliveredPaths.size
  • 破坏性变更 / 迁移说明:无。phase 表示交付阶段,strategy 表示选择方法。fast 交付总是 heuristicrefined 交付通常是 model,selector 失败时是 heuristicMemoryRecallDiscardReason 新增 already_delivered;只要 fast 阶段已经投递了全部选中文档,现在所有丢弃路径都记这个原因,而不只是 ToolResult 交付点,这样 no_safe_delivery_point 这一桶不再统计实际已拿到 memory 的回合。部分重叠仍记原取消原因。

已知限制:

  • scoring 基于 substring,因此 query token 可能匹配到更长单词内部,例如 owner 匹配 ownership。语料中记录了这个 case,而不是隐藏它。
  • 与文档没有任何词面重叠的 query 产生不了确定性结果,这类 query 在无工具回合仍然拿不到 memory。semantic-no-lexical 分片测量了这一点;这是 fast path 不解决的边界。
  • I/O 足够慢时 Memory 树扫描会超出初始上限,该轮付满预算且什么都投不到。临界点与机器相关,是被限制住而不是被修复。
  • Thai/Khmer/Lao 这类无分词符又不在 CJK 集合内的文字,现在会产生 token(之前完全没有),但整段是一个 token。这不是分词,这类 query 通常仍然匹配不到东西。

关联 Issue

Refs #7040

@qwen-code-ci-bot

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

Copy link
Copy Markdown
Collaborator

Re-run after substantial growth since the last gate pass — the PR gained the deterministic fast path, the query-aware candidate set, and the eval corpora. Gate re-checked from scratch on db006f8.

  • Template: complete ✓ (including Risk & Scope, Tested on, and the Chinese section)
  • Problem: observed, not theoretical. Both defects are documented in RFC RFC: Reliable auto-memory recall — timing, quality, and telemetry #7040 and were reproduced on base on a real stack by a maintainer — most recently re-verified on head 01ef7d7: tool-free first turns dropped the recall result on base every time, and non-matching queries pulled irrelevant documents through the non-empty-body scoring rule. The 51-case eval corpus quantifies both (Recall@5 45.2% → 92.9%, CJK slice 0% → 100%).
  • Direction: aligned. Memory that never reaches the model is the feature not working at all, and this is the shape the RFC discussion converged on: a bounded initial wait on the existing single-result lifecycle, model-first selection kept, heuristic only as fast path and failure fallback. No new dependency, no public setting.
  • Size: core paths (packages/core/src/**). Production logic 587 lines (recall.ts 308, client.ts 197, relevanceSelector.ts 47, scan.ts 22, telemetry/types.ts 13); tests + fixtures 3,385; docs 549. That is past the 500-line awareness threshold, but the author is a repo maintainer and maintainer-authored PRs are exempt from the two-tier core gate — recording the number for the record, no escalation needed.
  • Approach: the scope grew since the first gate pass, but each addition traces to a measurement posted in this thread — the fast path exists because the selector round trip dominates the 100 ms budget, the candidate-set rework because the per-scope 200-document cap made old-but-matching documents permanently invisible, and the scan-latency test because uncapping the scan moved tree size into the budget. No drive-bys; deferred items are filed as follow-ups (Deduplicate the CJK/NFKC recall tokenizer shared by core and channels/base #9377 tokenizer dedup, Recall/forget scan-cap asymmetry: documents beyond the 200-doc cap can be recalled but never forgotten #9378 recall/forget scan-cap asymmetry).
  • Risk: no high-risk path matches; no elevated risk signals.

Moving on to code review. 🔍

中文说明

自上次门禁通过以来 PR 有显著增长——新增了确定性 fast path、query 感知的候选集以及评估语料。门禁已在 db006f8 上从头重新检查。

  • 模板:完整 ✓(含 Risk & Scope、Tested on 与中文部分)
  • 问题:已观测到,非理论性问题。两个缺陷均记录于 RFC RFC: Reliable auto-memory recall — timing, quality, and telemetry #7040,且 maintainer 已在真实环境于 base 上复现——最近一次在 head 01ef7d7 上复核:base 上无工具调用的首轮每次都丢失 recall 结果;非匹配 query 会因"正文非空即得分"规则拉入无关文档。51 条用例的评估语料对两者做了量化(Recall@5 45.2% → 92.9%,CJK 切片 0% → 100%)。
  • 方向:对齐。memory 到不了模型等于功能完全失效,且本方案正是 RFC 讨论收敛到的形态:在既有单结果生命周期上加有界首轮等待、保持 model-first 选择、启发式只作为 fast path 与失败 fallback。无新依赖、无公开配置。
  • 规模:触及核心路径(packages/core/src/**)。生产逻辑 587 行(recall.ts 308、client.ts 197、relevanceSelector.ts 47、scan.ts 22、telemetry/types.ts 13);测试 + fixture 3,385 行;文档 549 行。超过 500 行的知会阈值,但作者是仓库 maintainer,maintainer 提交的 PR 豁免两级核心门禁——仅记录数字,无需升级。
  • 方案:范围较首次门禁有增长,但每处新增都能追溯到本线程中记录的测量——fast path 的存在是因为 selector 往返耗时主导了 100 ms 预算;候选集重构是因为每 scope 200 篇上限让"旧但匹配"的文档永久不可见;scan 延迟测试是因为解除扫描上限后树的规模进入了预算。无夹带改动;推迟项已立 follow-up(Deduplicate the CJK/NFKC recall tokenizer shared by core and channels/base #9377 分词器去重、Recall/forget scan-cap asymmetry: documents beyond the 200-doc cap can be recalled but never forgotten #9378 recall/forget 扫描上限不对称)。
  • 风险:未命中高风险路径;无升级风险信号。

进入代码审查。🔍

Qwen Code · qwen3.8-max

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

@qwen-code-ci-bot

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

Copy link
Copy Markdown
Collaborator

Code review

Full re-read of the production diff at db006f8 (587 production lines across five files).

Independent baseline. For "selected memory misses a tool-free first turn" my proposal is a bounded await at the initial consume point with early exit on settle/abort, exactly-once guards, and the budget miss left pending for the ToolResult point — plus, since the selector round trip dominates any short budget, delivering the deterministic candidates the selector was already going to score. For "ASCII-only scorer that scores everything" NFKC + script-aware runs + CJK bigrams, a lexical gate, field weights, and a bounded query window. For the 200-document pre-relevance truncation, a query-aware candidate set with some bound — uncapping the scan puts tree size inside the 100 ms budget, so a bound is mandatory. The PR matches this baseline on every point; I found no simpler path it missed.

What I checked and what holds:

  • The bounded wait (tryConsumeMemoryPrefetch): the wait ends on recall settling, the fast result arriving, abort, or the 100 ms ceiling. The wakeup registration is race-free — the null-checks and the listener setup run in one synchronous step with no await between them, so the fast result cannot slip through the gap. Timer, abort listener, and onArrive are cleaned up on every exit; the post-wait guard re-checks handle identity and consumed, so a mid-wait replacement or cancellation delivers nothing stale. Cron and the ToolResult point pass waitMs = 0 and stay zero-wait, pinned by dedicated tests.
  • Fast path: onFastResult fires at most once, never after abort, reuses selectModelCandidateDocuments' already-computed lexical ranking (no extra scan or I/O), and is capped at two documents. The consequence the previous round surfaced — once the deterministic scorer matches, the fast result wins the initial turn regardless of selector speed — is now stated plainly in the comment instead of the earlier incorrect "preference order unchanged" claim, and pinned by a mutation-tested test. The final commit db006f8 is this comment correction plus that test; its production delta against the maintainer-verified 01ef7d7 is comments only.
  • Exactly-once delivery: fastDeliveredPaths excludes fast-delivered documents from the later refined prompt (rebuilt from the remainder), and already_delivered is recorded on every discard path with full overlap while a partial overlap keeps its cancellation reason — the telemetry no longer counts delivered turns as lost ones.
  • Scorer: NFKC + \p{L}-based whole-run tokens (Cyrillic/Greek/Arabic/accented Latin now tokenize), code-point bigrams for CJK runs, negative lookahead so a Latin run cannot swallow trailing CJK, score 0 without a lexical match, title 4 / description 3 / body 1 weights over the surfaced 1200-char window, type boost capped at 2, ties by recency then stable input order — never by document type, which would systematically drop user memory from a two-document cap. The query window is bounded at 64 tokens keeping both ends.
  • Candidates & manifest: model candidates bounded at 200 (180 lexical + 20 recency reserve, interleaved), the selector sees only documents that fit the new 25 KB manifest budget, and the uncapped scan is additive — indexer, forget, status, and extractionAgentPlanner keep the capped variant. The recall/forget asymmetry is filed as Recall/forget scan-cap asymmetry: documents beyond the 200-doc cap can be recalled but never forgotten #9378.

No correctness blockers, no convention violations. The remaining caveats are documented design limits, not defects: lexical-only matching is silent on semantic-only queries, per-turn document count can reach 7 (fast 2 + refined 5, individually bounded), and a very slow scan can exceed the ceiling — each named in Risk & Scope with its trade.

sequenceDiagram
    participant P1 as User
    participant P2 as GeminiClient
    participant P3 as Recall
    participant P4 as Model selector
    P1->>P2: query arrives
    P2->>P3: recall starts on UserQuery
    P3->>P3: scan tree, deterministic score
    P3-->>P2: fast result, top 2 docs
    P2-->>P1: injected into first prompt, within the 100 ms ceiling
    P3->>P4: side query with ranked candidates
    P4-->>P3: model selection settles later
    P3-->>P2: refined result at the ToolResult turn
    P2-->>P1: remaining docs, fast-delivered ones excluded
Loading
Files changed (17)
File What changed
packages/core/src/core/client.ts bounded initial wait, fast-result box on the prefetch handle, dedupe and already-delivered accounting at the consume points
packages/core/src/memory/recall.ts multilingual tokenizer, lexically-gated weighted scorer, candidate selection with recency reserve, onFastResult publication
packages/core/src/memory/relevanceSelector.ts 25 KB manifest budget; selector validates only documents included in the manifest
packages/core/src/memory/scan.ts additive uncapped scan variants used by recall only
packages/core/src/telemetry/types.ts already_delivered discard reason; phase-vs-strategy doc
packages/core/src/core/client.test.ts delivery lifecycle tests: budget pins with fake timers, fast wins, dedupe, cancellation, query boundaries
packages/core/src/memory/recall.test.ts scorer and candidate-set contract tests, cap-beyond recall
packages/core/src/memory/recall-eval.test.ts 51-case labeled corpus vs frozen pre-change scorer, quality floor
packages/core/src/memory/recall-delivery-eval.test.ts before/after delivery matrix for tool-free vs tool-using turns
packages/core/src/memory/recall-scan-latency.test.ts time-to-fast-result against real temporary trees of 200/500/1000 topics
packages/core/src/memory/fixtures/auto-memory-recall-eval.json the labeled corpus itself
packages/core/src/memory/relevanceSelector.test.ts manifest byte-budget and candidate-packing tests
packages/core/src/memory/memoryLifecycle.integration.test.ts recall beyond the 200-document cap end to end
docs/design/2026-08-08-native-memory-recall-reliability.md design doc: fast path, ceiling semantics, measured scan latency
docs/design/2026-08-09-bounded-memory-recall-candidates.md design doc: candidate-cap trade and per-turn document count
docs/design/auto-memory/memory-system.md delivery telemetry and fallback wording aligned with the code
docs/design/2026-05-15-async-memory-recall-design.md cross-reference to the reliability design doc

Testing

Unattended CI run — the evidence below is the PR's own CI on the reviewed commit, fetched via the API; I did not build or run PR code. All pull_request workflow runs for db006f8 have completed; the only in-flight item is the bot's own pull_request_target review job, which is not the test suite.

Check Conclusion
Qwen Code CI / Test (ubuntu-latest, Node 22.x) ✅ success
Qwen Code CI / Desktop Shell (ubuntu-22.04) ✅ success
Qwen Code CI / Desktop Shell (windows-2022) ✅ success
Qwen Code CI / web-shell E2E Smoke (ubuntu-latest, Node 22.x) ✅ success
Qwen Code CI / Classify PR ✅ success
Qwen Code CI / Post Coverage Comment (ubuntu-latest, 22.x) ✅ success
Security Checks / Dependency CVE audit ✅ success
Security Checks / Secret scan (TruffleHog) ✅ success
Qwen Code CI / Test (macos-latest, Node 22.x) ⏭️ skipped (merge-queue only)
Qwen Code CI / Test (windows-latest, Node 22.x) ⏭️ skipped (merge-queue only)
Qwen Code CI / Integration Tests (CLI, No Sandbox) ⏭️ skipped (merge-queue only)

The ubuntu unit suite (including the recall corpus, the delivery matrix, and the fake-timer budget pins), Desktop Shell on both OSes, and the web-shell smoke all succeeded; the skipped lanes are merge-queue-only by ci.yml design.

The central behavioural claim is substantiated beyond the unit suite by a maintainer's real-stack A/B run posted in this thread on head 01ef7d7: a recording provider with a real .qwen/memory tree showed base dropping the tool-free first delivery while head delivered the fast pair in the first request body, dedupe and already_delivered accounting behaving as specified, the scorer silent on no-token queries where base injected five irrelevant documents, and the Chinese query tokenizing where base produced none. The production delta between that head and db006f8 is a comment correction plus one test — no behaviour moved — so that evidence covers the reviewed commit.

Sandboxed verification would settle the one remaining gap: @qwen-code /verify — live-turn delivery timing on Windows/Linux is not verified on a real stack (the maintainer's runs were macOS; the unit suite ran green on ubuntu CI but merge-queue live lanes are skipped), and the timing claim is exactly what that run pins.

Not verified: live-turn behaviour on Windows/Linux beyond the CI unit suite (see above), and cancellation during the bounded wait beyond unit tests — both standing caveats, neither blocking.

中文说明

代码审查

db006f8 上完整重读了生产 diff(五个文件共 587 行生产代码)。

独立基线。 对"选中的 memory 错过无工具首轮",我的方案是:在初始消费点加有界等待,settle/abort 可提前退出,exactly-once 守卫,预算未命中留给 ToolResult 消费点——并且由于 selector 往返主导任何短预算,直接把 selector 本来就要评分的确定性候选投出去。对"ASCII-only 且什么都打分的评分器":NFKC + 按文字分组的 token + CJK bigram、词面门槛、字段权重、有界查询窗口。对 200 篇先截断后评估的问题:query 感知的候选集且必须保留某种上限——解除扫描上限后树的规模进入了 100 ms 预算。PR 在每一点上与该基线一致;我没有找到它遗漏的更简路径。

逐项核对结论:

  • 有界等待tryConsumeMemoryPrefetch):等待在 recall 完成、fast 结果到达、abort 或 100 ms 上限时结束。唤醒注册无竞态——空值检查与监听器设置在同一步同步执行、其间无 await,fast 结果不可能从缝隙溜走。每条退出路径都清理计时器、abort 监听与 onArrive;等待后的守卫重查句柄身份与 consumed,等待中被替换或取消不会投出过期结果。Cron 与 ToolResult 点传 waitMs = 0 保持零等待,有专门测试钉住。
  • Fast pathonFastResult 至多触发一次、abort 后不触发、复用 selectModelCandidateDocuments 已算好的词面排序(无额外扫描或 I/O)、上限 2 篇。上一轮被点名的后果——确定性评分器一旦匹配,fast 结果赢得首轮、与 selector 快慢无关——如今在注释中直说,取代了此前错误的"优先级顺序不变"表述,并由变异测试钉住。最后一个 commit db006f8 就是这次注释更正加该测试;相对 maintainer 已验证的 01ef7d7,其生产增量仅为注释。
  • exactly-once 投递fastDeliveredPaths 把 fast 已投的文档从后续 refined prompt 中剔除(用剩余文档重建 prompt);完全重叠时每条丢弃路径都记 already_delivered,部分重叠保留取消原因——遥测不再把已投递的回合计为丢失。
  • 评分器:NFKC + 基于 \p{L} 的整体 token(西里尔/希腊/阿拉伯/带音拉丁现在能分词)、CJK 码点 bigram、负向前瞻防止拉丁段吞掉后续 CJK、无词面匹配即 0 分、标题 4 / 描述 3 / 正文 1 且只对 1200 字符可投递窗口评分、type boost 上限 2、平分先按新近度再按稳定输入序——绝不按文档类型(那会让两篇上限系统性丢掉 user memory)。查询窗口有界 64 token 且保留两端。
  • 候选与 manifest:model 候选上限 200(180 词面 + 20 新近保留、交错排列);selector 只校验进入 25 KB manifest 预算的文档;解除上限的扫描是纯增量——indexerforgetstatusextractionAgentPlanner 仍用带限变体。recall/forget 不对称已立 Recall/forget scan-cap asymmetry: documents beyond the 200-doc cap can be recalled but never forgotten #9378

无正确性阻塞项,无规范违规。其余保留项是已记录的设计局限而非缺陷:纯词面匹配对语义型查询保持沉默、单回合计文档数可达 7(fast 2 + refined 5,各自有界)、极慢扫描可能超上限——Risk & Scope 中逐一点名并给出取舍。

测试

无人值守 CI 运行——以下证据是 PR 自身 CI 在被审 commit 上的结果,经 API 获取;我未构建或运行 PR 代码。db006f8 的所有 pull_request workflow 运行均已完成;唯一在途项是 bot 自己的 pull_request_target review 任务,不是测试套件。

ubuntu 单测(含 recall 语料、投递矩阵、假计时器预算钉子)、两个平台的 Desktop Shell、web-shell smoke 全部成功;被跳过的 lane 按 ci.yml 设计只在 merge queue 运行。

核心行为声明已有超出单测的实证:线程中 maintainer 在 head 01ef7d7 上的真实环境 A/B 验证——录制 provider + 真实 .qwen/memory 树显示:base 丢失无工具首轮投递,head 在首个请求体中投出 fast 两篇;dedupe 与 already_delivered 计数符合规范;无共同 token 的查询上评分器沉默而 base 注入了 5 篇无关文档;中文查询正常分词而 base 无法产出 token。该 head 与 db006f8 之间的生产增量是一次注释更正加一个测试——行为未变——因此该证据覆盖被审 commit。

沙箱验证可补齐唯一剩余缺口:@qwen-code /verify——Windows/Linux 上的实时回合投递时序尚未在真实环境验证(maintainer 的验证在 macOS;单测在 ubuntu CI 为绿但实时 lane 只在 merge queue 运行),而时序声明正是该运行所钉住的内容。

未验证:CI 单测之外的 Windows/Linux 实时回合行为(见上)、单测之外的等待中取消——均为既有保留项,均不构成阻塞。

Qwen Code · qwen3.8-max

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

@qwen-code-ci-bot

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

Copy link
Copy Markdown
Collaborator

Confidence: 5/5 — clean across every stage; would merge without hesitation.

Stepping back: this PR started as a bounded-wait fix and grew into the question the measurements kept forcing — "what should the first turn deliver when the selector cannot win a 100 ms race?" The answer it landed on is the honest one: publish the deterministic candidates the selector was already going to score, cap them at two, and let the model's judgement land later at the existing ToolResult point. That is not scope creep; each growth step has a measurement in this thread behind it, including the one that overturned the author's own earlier claim about wait preference — corrected in the final commit, comment and test together, after a maintainer's mutation found it.

Against my independent proposal, the PR matches on both halves and exceeds mine where it matters: I would have kept the 200-document cap and lived with old-but-matching documents staying invisible; the candidate-set rework fixes that with a bound still in place, and the asymmetry it introduces for Forget is tracked in #9378 rather than ignored. The implementation reads like it will age well — dense state machine, but every branch has a reason comment and a test that fails when the reason is removed.

The evidence chain is complete for what CI can see: green suite on the reviewed commit, a 51-case corpus scored against the frozen pre-change scorer, a scan-latency measurement that decides whether the fast path delivers at all, and a maintainer's real-stack A/B on the commit one back — whose production behaviour is byte-identical to this one. The one gap (live-turn timing on Windows/Linux) is named with its remedy above, and it does not block: the machinery is portable APIs and the platform-split CI is green.

Approving, pinned to the reviewed commit.

Qwen Code · qwen3.8-max

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

@github-actions

github-actions Bot commented Aug 8, 2026

Copy link
Copy Markdown
Contributor

Code Coverage Summary

Package Lines Statements Functions Branches
CLI 84.66% 84.66% 90.07% 83.77%
Core 88.07% 88.07% 89.6% 86.65%
CLI Package - Full Text Report
-------------------|---------|----------|---------|---------|-------------------
File               | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
-------------------|---------|----------|---------|---------|-------------------
All files          |   84.66 |    83.77 |   90.07 |   84.66 |                   
 src               |   85.69 |    81.73 |   88.03 |   85.69 |                   
  cli.ts           |   95.68 |    84.11 |     100 |   95.68 | ...60-561,565-566 
  gemini.tsx       |    73.4 |    78.04 |   80.76 |    73.4 | ...1338-1342,1469 
  ...ractiveCli.ts |   88.12 |    82.41 |   88.88 |   88.12 | ...3108,3114,3180 
  ...liCommands.ts |   88.64 |    82.96 |      80 |   88.64 | ...77-579,593,692 
  ...ActiveAuth.ts |     100 |     87.5 |     100 |     100 | 66-80             
 ...cp-integration |   72.35 |    74.78 |   91.58 |   72.35 |                   
  acpAgent.ts      |   71.76 |    74.61 |   91.13 |   71.76 | ...79,12884-12886 
  ...k-reporter.ts |     100 |       80 |     100 |     100 | 81,84,119,141     
  authMethods.ts   |      92 |       60 |     100 |      92 | 33-34             
  errorCodes.ts    |     100 |      100 |     100 |     100 |                   
  ...ion-skills.ts |     100 |    88.23 |     100 |     100 | 17,32             
  generation.ts    |    97.1 |    81.25 |     100 |    97.1 | 109,112           
  ...figuration.ts |     100 |      100 |     100 |     100 |                   
  ...DirContext.ts |     100 |      100 |     100 |     100 |                   
 ...ration/service |    97.1 |    95.83 |   93.33 |    97.1 |                   
  filesystem.ts    |    97.1 |    95.83 |   93.33 |    97.1 | ...22-123,246-247 
 ...ration/session |   91.09 |    86.16 |   96.35 |   91.09 |                   
  Session.ts       |    90.4 |    84.68 |   95.96 |    90.4 | ...16,11643-11647 
  ...entTracker.ts |    96.8 |    89.36 |      90 |    96.8 | 137-143,221       
  ...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.11 |     86.3 |     100 |   94.11 | ...11,315,395,399 
  ...y-replayer.ts |   83.17 |    92.98 |   94.11 |   83.17 | ...24-142,260-262 
  index.ts         |       0 |        0 |       0 |       0 | 1-40              
  ...ssionUtils.ts |   89.76 |    87.32 |     100 |   89.76 | ...54-270,326-328 
  ...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.7 |    93.37 |   96.87 |    95.7 |                   
  ...ageEmitter.ts |   95.25 |    93.54 |     100 |   95.25 | ...08-115,128-129 
  PlanEmitter.ts   |     100 |       90 |     100 |     100 | 66                
  base-emitter.ts  |   78.26 |       75 |     100 |   78.26 | 23-24,26-28       
  index.ts         |       0 |        0 |       0 |       0 | 1-10              
  ...ll-emitter.ts |   99.18 |    96.47 |     100 |   99.18 | 355-356           
 ...ession/rewrite |    91.8 |    89.13 |   94.44 |    91.8 |                   
  LlmRewriter.ts   |    82.4 |     86.2 |     100 |    82.4 | ...,88-89,166-170 
  ...Middleware.ts |   96.96 |    88.09 |     100 |   96.96 | 144,152-154       
  TurnBuffer.ts    |     100 |      100 |     100 |     100 |                   
  config.ts        |     100 |      100 |     100 |     100 |                   
  index.ts         |     100 |      100 |     100 |     100 |                   
  types.ts         |       0 |        0 |       0 |       0 | 1                 
 src/agent-view    |   89.03 |    81.37 |   89.09 |   89.03 |                   
  ...t-cli-argv.ts |     100 |      100 |     100 |     100 |                   
  protocol.ts      |     100 |      100 |     100 |     100 |                   
  ...sor-client.ts |   80.38 |    72.54 |   76.66 |   80.38 | ...22-626,652-656 
  ...or-process.ts |   96.61 |    89.47 |   84.61 |   96.61 | 129-130,150-151   
  ...sor-runner.ts |    84.9 |     75.6 |      85 |    84.9 | ...44,468,471-481 
  ...sor-server.ts |   85.71 |    83.06 |   95.45 |   85.71 | ...67-468,471-488 
  ...isor-store.ts |   97.73 |    81.16 |     100 |   97.73 | ...92,594,607,643 
  ...nal-bridge.ts |   93.98 |     91.3 |   83.33 |   93.98 | 228-238           
 src/commands      |   91.04 |       80 |   66.66 |   91.04 |                   
  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.79 |      100 |      50 |   98.79 | 94                
  serve.ts         |   90.08 |    77.84 |     100 |   90.08 | ...81,884-887,899 
  sessions.ts      |     100 |      100 |      50 |     100 |                   
  update.ts        |   98.13 |    94.44 |   66.66 |   98.13 | 82-83             
 ...mmands/channel |   89.08 |    88.57 |   90.64 |   89.08 |                   
  channel-cwd.ts   |     100 |      100 |     100 |     100 |                   
  ...l-registry.ts |   94.88 |    95.49 |      90 |   94.88 | ...20-323,368-371 
  ...entry-path.ts |      75 |       50 |     100 |      75 | 8-9               
  config-utils.ts  |   95.88 |    96.35 |     100 |   95.88 | ...08-213,271-274 
  configure.ts     |    14.7 |      100 |       0 |    14.7 | 18-21,23-84       
  daemon-worker.ts |   93.91 |    85.61 |   94.33 |   93.91 | ...1264,1271-1272 
  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         |    85.8 |    82.17 |      88 |    85.8 | ...85,591-594,606 
  ...ure-format.ts |   93.65 |    82.45 |     100 |   93.65 | ...42,48-49,74-75 
  status.ts        |   78.57 |    59.25 |   66.66 |   78.57 | ...36-137,150-161 
  stop.ts          |   57.83 |    82.35 |      50 |   57.83 | ...3,74-76,85-111 
 ...nds/extensions |   88.85 |    87.91 |   87.09 |   88.85 |                   
  consent.ts       |   72.53 |    90.32 |   42.85 |   72.53 | ...86-142,157-163 
  disable.ts       |     100 |       90 |     100 |     100 | 30                
  enable.ts        |     100 |    91.66 |     100 |     100 | 38                
  install.ts       |   82.95 |    81.57 |      75 |   82.95 | ...96-199,202-211 
  link.ts          |     100 |      100 |     100 |     100 |                   
  list.ts          |     100 |     90.9 |     100 |     100 | 18                
  new.ts           |     100 |      100 |     100 |     100 |                   
  settings.ts      |   99.15 |      100 |   83.33 |   99.15 | 151               
  sources.ts       |   93.42 |    87.09 |   92.85 |   93.42 | ...4-66,96-98,167 
  uninstall.ts     |   74.57 |       40 |   66.66 |   74.57 | 45-47,60-67,70-73 
  update.ts        |   96.71 |    97.05 |     100 |   96.71 | 114-118           
  utils.ts         |   75.63 |    57.14 |     100 |   75.63 | ...30-134,136-140 
 ...les/mcp-server |       0 |        0 |       0 |       0 |                   
  example.ts       |       0 |        0 |       0 |       0 | 1-60              
 ...amples/starter |       0 |        0 |       0 |       0 |                   
  example.ts       |       0 |        0 |       0 |       0 | 1-64              
 src/commands/mcp  |   90.31 |    84.61 |   83.33 |   90.31 |                   
  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          |   93.15 |    84.84 |      80 |   93.15 | ...78-180,198-199 
  reconnect.ts     |   78.85 |    66.66 |   85.71 |   78.85 | 42-55,169-191     
  remove.ts        |     100 |       80 |     100 |     100 | 21-25             
 ...ommands/review |   89.86 |    89.56 |    90.3 |   89.86 |                   
  agent-prompt.ts  |   93.94 |    92.55 |   97.43 |   93.94 | ...2755,2910-2990 
  base-tree.ts     |   76.16 |    80.76 |   77.77 |   76.16 | ...50-371,373-386 
  capture-local.ts |      70 |     90.9 |      75 |      70 | 112-116,163-194   
  ...k-coverage.ts |   50.71 |       35 |   66.66 |   50.71 | ...40-245,279-289 
  cleanup.ts       |   92.79 |     88.7 |   84.61 |   92.79 | ...43-648,650-651 
  comment-body.ts  |   69.92 |    92.85 |   66.66 |   69.92 | ...18,145,147-152 
  ...ent-status.ts |   93.03 |    83.87 |   83.33 |   93.03 | 291,531-551       
  ...ose-review.ts |   97.07 |    93.13 |   97.29 |   97.07 | ...2814,2842-2864 
  cost-ledger.ts   |   94.58 |     94.4 |   81.25 |   94.58 | ...53-654,694-704 
  drive.ts         |   76.07 |    85.71 |   81.81 |   76.07 | ...90-492,497-499 
  extract-step.ts  |   91.36 |    90.62 |   88.88 |   91.36 | ...90-707,714-729 
  fetch-diff.ts    |   73.41 |      100 |   66.66 |   73.41 | 75-95             
  fetch-pr.ts      |   98.29 |    95.83 |   90.47 |   98.29 | ...1159,1293-1298 
  findings.ts      |   96.01 |    92.08 |     100 |   96.01 | ...1227,1236-1237 
  issue-context.ts |    88.1 |     93.1 |   85.71 |    88.1 | 247-274           
  load-rules.ts    |   26.41 |      100 |   16.66 |   26.41 | ...41-153,155-156 
  match-remote.ts  |   85.54 |     92.3 |   66.66 |   85.54 | 67-72,131-136     
  meta.ts          |   76.84 |     91.3 |   66.66 |   76.84 | 91-96,115-130     
  mock-provider.ts |   95.44 |    90.25 |   89.47 |   95.44 | 145,690-709       
  parse-args.ts    |    99.4 |    95.16 |     100 |    99.4 | 472,645,701       
  plan-diff.ts     |    68.1 |      100 |   66.66 |    68.1 | 162-205           
  pr-context.ts    |   93.26 |    80.93 |     100 |   93.26 | ...1202,1264-1280 
  presubmit.ts     |   90.36 |    89.15 |      90 |   90.36 | ...50-751,837-867 
  ...ish-assets.ts |    81.3 |    82.22 |   85.71 |    81.3 | ...75-479,506-552 
  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 
  run.ts           |   84.16 |    89.06 |   94.11 |   84.16 | ...88,604-652,665 
  save-artifact.ts |   90.06 |    81.81 |   93.75 |   90.06 | ...18-321,414-417 
  script-lint.ts   |   81.14 |    79.23 |   88.88 |   81.14 | ...59-773,775-797 
  submit.ts        |   85.01 |    86.36 |      90 |   85.01 | ...99,588,615-651 
  test-delta.ts    |   87.13 |    91.46 |      75 |   87.13 | 206-237,477-485   
  test-efficacy.ts |   88.04 |    84.12 |   95.45 |   88.04 | ...2602,2610-2630 
  test-plan.ts     |   91.44 |    91.39 |   89.47 |   91.44 | ...38-839,903-920 
 ...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.7 |    95.09 |   98.62 |    97.7 |                   
  agent-briefs.ts  |      99 |      100 |      50 |      99 | 746-747           
  ...t-identity.ts |     100 |      100 |     100 |     100 |                   
  anchors.ts       |     100 |    96.42 |     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 |   93.02 |    94.11 |     100 |   93.02 | 152-158           
  budget.ts        |     100 |    97.89 |     100 |     100 | 805,845           
  coverage.ts      |    96.6 |    93.05 |     100 |    96.6 | ...1115,1669-1670 
  deadline.ts      |   98.67 |    94.05 |     100 |   98.67 | 207,618,650,718   
  diff-flags.ts    |     100 |        0 |     100 |     100 | 75                
  diff-plan.ts     |   98.73 |    93.08 |     100 |   98.73 | ...41,264,290-291 
  disk.ts          |     100 |      100 |     100 |     100 |                   
  effort.ts        |     100 |      100 |     100 |     100 |                   
  gh.ts            |   89.09 |    95.31 |   77.77 |   89.09 | ...29,366-367,394 
  git.ts           |   97.84 |    96.15 |     100 |   97.84 | 207-208           
  heavy.ts         |     100 |      100 |     100 |     100 |                   
  inline-counts.ts |     100 |      100 |     100 |     100 |                   
  ...audit-gate.ts |     100 |    97.56 |     100 |     100 | 138               
  ledger.ts        |     100 |      100 |     100 |     100 |                   
  local-diff.ts    |   84.86 |    90.38 |     100 |   84.86 | ...63-473,475-483 
  ...ry-context.ts |   96.61 |    95.48 |     100 |   96.61 | ...47-450,496-499 
  merge-base.ts    |     100 |      100 |     100 |     100 |                   
  npm-toolchain.ts |   97.36 |    95.37 |     100 |   97.36 | ...86,409,770,787 
  path-rules.ts    |     100 |      100 |     100 |     100 |                   
  paths.ts         |   91.48 |       75 |     100 |   91.48 | 31-32,35-36       
  prompt-record.ts |   98.03 |    94.23 |     100 |   98.03 | 293-294,300       
  receipt.ts       |     100 |      100 |     100 |     100 |                   
  remote-match.ts  |   97.26 |    91.42 |     100 |   97.26 | 49-50             
  report.ts        |   94.89 |    93.75 |     100 |   94.89 | 207-211           
  ...ry-context.ts |     100 |    98.66 |     100 |     100 | 187               
  retirement.ts    |     100 |    93.52 |     100 |     100 | ...38-539,729,883 
  review-footer.ts |     100 |      100 |     100 |     100 |                   
  ...w-settings.ts |     100 |    94.73 |     100 |     100 | 79                
  roster.ts        |     100 |    95.52 |     100 |     100 | 136,154,199       
  run-ledger.ts    |   98.15 |     93.7 |     100 |   98.15 | ...23,521,627,650 
  same-file.ts     |     100 |    94.11 |     100 |     100 | 35                
  shell-quote.ts   |     100 |      100 |     100 |     100 |                   
  stale-bundle.ts  |   98.11 |    94.11 |     100 |   98.11 | 416,457,497-498   
  test-utils.ts    |     100 |      100 |     100 |     100 |                   
  toolchain.ts     |     100 |      100 |     100 |     100 |                   
  transcripts.ts   |   98.05 |    95.03 |     100 |   98.05 | ...67,415,684-685 
  ...pace-scope.ts |     100 |    96.96 |     100 |     100 | 172               
  workspaces.ts    |     100 |    96.77 |     100 |     100 | 222,452,499,512   
  worktree.ts      |     100 |      100 |     100 |     100 |                   
 ...w/lib/platform |   95.48 |       75 |     100 |   95.48 |                   
  github.ts        |   95.23 |    74.28 |     100 |   95.23 | 25-28,210-211     
  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.95 |    89.87 |   96.28 |   94.95 |                   
  ...l-fallback.ts |     100 |      100 |     100 |     100 |                   
  auth.ts          |   89.35 |    83.56 |     100 |   89.35 | ...97-298,314-315 
  ...eMcpImport.ts |   87.91 |    81.52 |     100 |   87.91 | ...63-371,453-454 
  compile-cache.ts |     100 |      100 |     100 |     100 |                   
  config.ts        |   89.12 |    88.69 |   83.78 |   89.12 | ...2497,2499-2507 
  ...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 |                   
  environment.ts   |    96.5 |    93.51 |      95 |    96.5 | ...85-586,640-641 
  ...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.96 |     100 |   98.97 | 85                
  mcpApprovals.ts  |   96.55 |    95.55 |     100 |   96.55 | 223-224,229-231   
  mcpJson.ts       |     100 |      100 |     100 |     100 |                   
  mcpServers.ts    |   92.85 |     87.5 |     100 |   92.85 | 46-47             
  ...idersScope.ts |      95 |    94.73 |     100 |      95 | 11-12             
  ...abledTools.ts |     100 |      100 |     100 |     100 |                   
  ...comparison.ts |     100 |      100 |     100 |     100 |                   
  ...n-settings.ts |   99.15 |    93.75 |     100 |   99.15 | 63                
  sandboxConfig.ts |   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.27 |    92.64 |      90 |   91.27 | ...1030,1032-1033 
  ...ingsSchema.ts |     100 |      100 |     100 |     100 |                   
  ...ngsWatcher.ts |   95.54 |    88.34 |     100 |   95.54 | ...28,277-278,293 
  ...d-env-keys.ts |     100 |      100 |     100 |     100 |                   
  ...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.47 |     100 |   92.53 | ...36-337,373-384 
 ...nfig/migration |   95.23 |    78.94 |   83.33 |   95.23 |                   
  index.ts         |   95.65 |    88.88 |     100 |   95.65 | 117-118           
  scheduler.ts     |   96.55 |    77.77 |     100 |   96.55 | 19-20             
  types.ts         |       0 |        0 |       0 |       0 | 1                 
 ...ation/versions |   94.91 |      100 |     100 |   94.91 |                   
  ...-v2-shared.ts |     100 |      100 |     100 |     100 |                   
  v1-to-v2.ts      |   81.75 |      100 |     100 |   81.75 | ...28-229,231-247 
  v2-to-v3.ts      |     100 |      100 |     100 |     100 |                   
  v3-to-v4.ts      |     100 |      100 |     100 |     100 |                   
  v5-to-v4.ts      |      96 |      100 |     100 |      96 | 94-95,99          
 src/core          |     100 |      100 |     100 |     100 |                   
  auth.ts          |     100 |      100 |     100 |     100 |                   
  initializer.ts   |     100 |      100 |     100 |     100 |                   
  theme.ts         |     100 |      100 |     100 |     100 |                   
 src/dualOutput    |   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          |   85.98 |    81.92 |   89.65 |   85.98 |                   
  index.ts         |   73.45 |    77.77 |      90 |   73.45 | ...70-271,294-299 
  languages.ts     |   93.07 |     92.3 |   85.71 |   93.07 | ...35,164-169,184 
  ...nslateKeys.ts |     100 |      100 |     100 |     100 |                   
  ...lationDict.ts |   93.33 |    66.66 |     100 |   93.33 | 15                
 src/i18n/locales  |     100 |      100 |     100 |     100 |                   
  ca.js            |     100 |      100 |     100 |     100 |                   
  de.js            |     100 |      100 |     100 |     100 |                   
  en.js            |     100 |      100 |     100 |     100 |                   
  fr.js            |     100 |      100 |     100 |     100 |                   
  ja.js            |     100 |      100 |     100 |     100 |                   
  pt.js            |     100 |      100 |     100 |     100 |                   
  ru.js            |     100 |      100 |     100 |     100 |                   
  zh-TW.js         |     100 |      100 |     100 |     100 |                   
  zh.js            |     100 |      100 |     100 |     100 |                   
 ...nonInteractive |   80.98 |    77.27 |   84.12 |   80.98 |                   
  session.ts       |   84.97 |    76.31 |   96.07 |   84.97 | ...1048,1057-1067 
  types.ts         |    42.5 |      100 |   33.33 |    42.5 | ...31-632,635-636 
 ...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 |   45.95 |    69.03 |   55.26 |   45.95 |                   
  ...Controller.ts |    42.4 |      100 |   83.33 |    42.4 | 101-105,140-223   
  ...Controller.ts |       0 |        0 |       0 |       0 | 1-56              
  ...Controller.ts |   55.01 |    67.14 |   58.33 |   55.01 | ...15-624,639-644 
  ...Controller.ts |   49.23 |       60 |      50 |   49.23 | ...07-108,111-121 
  ...Controller.ts |   40.64 |    68.11 |   46.66 |   40.64 | ...72-684,693-722 
 .../control/types |       0 |        0 |       0 |       0 |                   
  serviceAPIs.ts   |       0 |        0 |       0 |       0 | 1                 
 ...Interactive/io |   98.12 |    94.18 |   95.29 |   98.12 |                   
  ...putAdapter.ts |   97.98 |    93.23 |   98.07 |   97.98 | ...1416,1432-1433 
  ...putAdapter.ts |      96 |    91.66 |   85.71 |      96 | 51-52             
  ...nputReader.ts |     100 |    94.73 |     100 |     100 | 67                
  ...putAdapter.ts |   98.49 |      100 |   90.47 |   98.49 | 85-86,126-127     
  ...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/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.61 |    95.04 |     100 |   99.61 |                   
  ...livery-ipc.ts |     100 |     90.9 |     100 |     100 | 94,106,134        
  ...l-delivery.ts |     100 |      100 |     100 |     100 |                   
  cpu-percent.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         |   88.14 |     84.7 |   90.94 |   88.14 |                   
  ...tp-enabled.ts |     100 |      100 |     100 |     100 |                   
  ...ion-bridge.ts |     100 |      100 |     100 |     100 |                   
  auth.ts          |   93.43 |    92.95 |     100 |   93.43 | ...20-321,324-326 
  ...em-adapter.ts |     100 |      100 |     100 |     100 |                   
  capabilities.ts  |     100 |    98.07 |     100 |     100 | 688               
  ...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.89 |     100 |    94.1 | ...75-477,484,486 
  ...-selection.ts |     100 |      100 |     100 |     100 |                   
  ...ings-store.ts |   89.64 |    94.11 |   96.29 |   89.64 | ...57-269,521-524 
  ...ebhook-ipc.ts |    98.5 |    86.66 |     100 |    98.5 | 47                
  ...iagnostics.ts |     100 |      100 |     100 |     100 |                   
  ...worker-env.ts |     100 |      100 |     100 |     100 |                   
  ...rker-group.ts |   87.27 |     85.2 |     100 |   87.27 | ...10,816-820,838 
  ...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 |   92.54 |    84.53 |   97.14 |   92.54 | ...1489,1543-1547 
  ...e-grouping.ts |     100 |    94.28 |     100 |     100 | 71,137            
  core-runtime.ts  |     100 |      100 |     100 |     100 |                   
  ...ub-session.ts |    90.1 |    77.83 |   94.73 |    90.1 | ...1014,1021-1026 
  ...tree-guard.ts |   92.89 |    87.55 |     100 |   92.89 | ...2766,2836-2840 
  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.64 |    91.77 |     100 |   98.64 | ...1503,1505-1506 
  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.41 |     100 |   94.94 | ...30,708,724,734 
  fast-path.ts     |   90.99 |    81.38 |   95.45 |   90.99 | ...33-542,608-609 
  ...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 |    90.9 |    85.71 |     100 |    90.9 | ...30-131,142-143 
  ...iders-edit.ts |     100 |    82.14 |     100 |     100 | 58-60,65,81       
  ...ory-picker.ts |     100 |    86.95 |     100 |     100 | 36,66,92          
  ...sion-audit.ts |     100 |      100 |   93.33 |     100 |                   
  rate-limit.ts    |   92.68 |    88.29 |     100 |   92.68 | ...89-291,303-305 
  ...qwen-serve.ts |    84.1 |    80.95 |   76.15 |    84.1 | ...7893,7911-7915 
  ...tup-errors.ts |     100 |      100 |     100 |     100 |                   
  ...-keepalive.ts |   94.25 |    87.96 |     100 |   94.25 | ...28,532-533,572 
  ...-lifecycle.ts |     100 |      100 |     100 |     100 |                   
  ...-lifecycle.ts |   89.16 |    90.29 |   86.95 |   89.16 | ...24-325,330-334 
  server.ts        |   91.02 |    90.54 |   73.27 |   91.02 | ...2902,2932-2933 
  ...-admission.ts |   98.24 |     94.8 |     100 |   98.24 | 79-80,303-304     
  ...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 |   92.18 |    88.37 |     100 |   92.18 | ...21-224,267-270 
  ...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.58 |       79 |     100 |   98.58 | 106,134,174,177   
  ...tion-store.ts |   89.67 |    88.27 |   92.59 |   89.67 | ...91-400,411-414 
  ...e-registry.ts |   94.98 |     90.5 |     100 |   94.98 | ...67-568,575-576 
  ...e-remember.ts |   98.23 |    92.56 |     100 |   98.23 | ...36,340-345,386 
  ...te-runtime.ts |    89.4 |    90.47 |     100 |    89.4 | ...89-190,258-279 
  ...me-storage.ts |     100 |      100 |     100 |     100 |                   
  ...visibility.ts |     100 |      100 |     100 |     100 |                   
  ...management.ts |   72.63 |    72.72 |      96 |   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 |   79.37 |    80.17 |   94.04 |   79.37 |                   
  ...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      |   73.78 |    76.77 |   91.37 |   73.78 | ...5363,5420-5426 
  index.ts         |   82.41 |    80.11 |   91.07 |   82.41 | ...2375,2459-2460 
  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 |   89.46 |    86.19 |   95.23 |   89.46 |                   
  ...e-activity.ts |     100 |      100 |     100 |     100 |                   
  ...ime-errors.ts |     100 |      100 |     100 |     100 |                   
  ...me-manager.ts |     100 |      100 |     100 |     100 |                   
  ...-ownership.ts |   85.33 |    81.31 |   88.46 |   85.33 | ...73-577,597-598 
  ...-workspace.ts |   88.26 |    82.53 |     100 |   88.26 | ...33-234,246-247 
  ...ion-source.ts |     100 |      100 |     100 |     100 |                   
 src/serve/fs      |   87.27 |    82.01 |     100 |   87.27 |                   
  audit.ts         |     100 |    96.15 |     100 |     100 | 204               
  errors.ts        |     100 |      100 |     100 |     100 |                   
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...x-registry.ts |     100 |      100 |     100 |     100 |                   
  paths.ts         |   77.64 |    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 |   87.37 |    81.39 |     100 |   87.37 | ...2811,2821-2822 
 src/serve/live    |   77.87 |    69.57 |   90.13 |   77.87 |                   
  ...en-context.ts |   95.74 |    81.25 |     100 |   95.74 | ...0,66-67,99-100 
  discovery.ts     |   85.42 |    80.66 |    90.9 |   85.42 | ...69-575,588-589 
  ...structions.ts |     100 |      100 |     100 |     100 |                   
  ...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 |   75.99 |    65.18 |   85.71 |   75.99 | ...1883,1974-1975 
  ...controller.ts |   67.82 |    79.31 |   72.72 |   67.82 | ...66-278,287-295 
  ...ak-to-user.ts |   96.66 |      100 |   83.33 |   96.66 | 37-38             
  ...sk-service.ts |   86.28 |    60.95 |   93.33 |   86.28 | ...1167,1191-1198 
  ...task-tools.ts |      99 |      100 |   85.71 |      99 | 205-206           
  ...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 |                   
 src/serve/routes  |   85.52 |    80.36 |   94.69 |   85.52 |                   
  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.92 |     90.9 |     100 |   98.92 | 143               
  health.ts        |   99.09 |    91.17 |     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    |     100 |     92.3 |     100 |     100 | 50,98             
  ...uled-tasks.ts |   87.52 |    84.22 |   93.33 |   87.52 | ...1383,1426-1427 
  ...on-runtime.ts |   91.42 |       90 |     100 |   91.42 | 56-64             
  session.ts       |   85.17 |    81.17 |      91 |   85.17 | ...5939,5941-5942 
  sse-events.ts    |   86.85 |    85.64 |   94.11 |   86.85 | ...18-929,932,939 
  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.11 |    79.31 |      90 |   83.11 | ...1033,1039,1042 
  ...extensions.ts |   88.46 |    75.19 |    93.1 |   88.46 | ...2037,2082-2083 
  ...-file-read.ts |      91 |    80.91 |     100 |      91 | ...20-621,624-625 
  ...file-write.ts |   89.58 |    79.16 |     100 |   89.58 | ...84,698-705,786 
  ...t-branches.ts |   75.43 |    66.66 |     100 |   75.43 | ...13-618,627-634 
  ...e-git-diff.ts |   97.32 |    90.56 |     100 |   97.32 | 161-162,189-191   
  ...ce-git-log.ts |     100 |    93.18 |     100 |     100 | 52,77,188         
  workspace-git.ts |   77.08 |    89.65 |     100 |   77.08 | 97-118            
  ...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 
  ...management.ts |   87.47 |       85 |     100 |   87.47 | ...1733,1743-1748 
  ...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.04 |    72.99 |     100 |   75.04 | ...79-690,696-697 
  ...tup-github.ts |   77.97 |    70.58 |   84.21 |   77.97 | ...46-352,397-398 
  ...ace-skills.ts |    76.9 |    87.15 |     100 |    76.9 | ...29-354,360-394 
  ...ace-status.ts |   82.94 |     74.5 |     100 |   82.94 | ...84-486,490-491 
  ...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  |   91.79 |    89.23 |      97 |   91.79 |                   
  access-log.ts    |    98.7 |    97.18 |     100 |    98.7 | 118,189           
  ...er-helpers.ts |   63.82 |    77.96 |   81.81 |   63.82 | ...16,330,332-347 
  ...w-registry.ts |    98.8 |    81.81 |     100 |    98.8 | 107               
  ...r-handlers.ts |   97.29 |       75 |     100 |   97.29 | 17                
  ...r-response.ts |    86.7 |    72.77 |     100 |    86.7 | ...57,774,837-846 
  fs-factory.ts    |     100 |    94.54 |     100 |     100 | 42,103,159        
  ...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.09 |     100 |   95.13 | ...66-168,423-428 
  self-origin.ts   |   76.19 |       80 |     100 |   76.19 | 45-54             
  ...e-features.ts |      95 |     87.5 |     100 |      95 | 182-188           
  ...on-archive.ts |   89.73 |    86.22 |   97.36 |   89.73 | ...78,905,933-934 
  ...ion-export.ts |     100 |    94.73 |     100 |     100 | 64                
  session-list.ts  |   95.86 |    93.37 |     100 |   95.86 | ...-848,1026-1030 
  telemetry.ts     |   99.04 |    97.43 |     100 |   99.04 | ...37,652,797-799 
 src/serve/voice   |    92.7 |    91.48 |   97.67 |    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.21 |     100 |     100 | 176               
 ...kspace-service |    90.9 |    87.96 |    91.3 |    90.9 |                   
  index.ts         |   90.41 |    87.29 |      90 |   90.41 | ...1505-1509,1512 
  types.ts         |     100 |      100 |     100 |     100 |                   
 src/services      |   92.69 |    89.52 |   98.06 |   92.69 |                   
  ...mandLoader.ts |     100 |    88.88 |     100 |     100 | 105-118           
  ...killLoader.ts |   97.19 |    85.29 |     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.29 |   83.33 |   79.55 | ...48,178,245-246 
  ...mandLoader.ts |   97.77 |    92.15 |     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.15 |     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 | ...99-901,904-906 
 ...rvices/insight |     100 |      100 |     100 |     100 |                   
  dates.ts         |     100 |      100 |     100 |     100 |                   
 ...ght/generators |   88.91 |     86.8 |   96.15 |   88.91 |                   
  DataProcessor.ts |   88.28 |    86.77 |   94.73 |   88.28 | ...1362,1366-1373 
  ...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.04 |     100 |   97.27 |                   
  ...tProcessor.ts |     100 |      100 |     100 |     100 |                   
  ...eProcessor.ts |   94.52 |    84.21 |     100 |   94.52 | 46-47,93-94       
  ...tionParser.ts |     100 |      100 |     100 |     100 |                   
  ...lProcessor.ts |   97.41 |    95.65 |     100 |   97.41 | 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.09 |    79.16 |   77.77 |   94.09 |                   
  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 |                   
  ...andContext.ts |     100 |      100 |     100 |     100 |                   
  render.tsx       |     100 |      100 |     100 |     100 |                   
 src/ui            |   73.28 |    75.61 |   67.39 |   73.28 |                   
  App.tsx          |   33.33 |       75 |   33.33 |   33.33 | 32-86             
  AppContainer.tsx |   74.45 |    72.14 |   69.44 |   74.45 | ...4188,4304-4310 
  ...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        |      60 |      100 |   35.29 |      60 | ...52,54-55,60-61 
  constants.ts     |     100 |      100 |     100 |     100 |                   
  keyMatchers.ts   |   95.91 |    97.14 |     100 |   95.91 | 25-26             
  ...tic-colors.ts |     100 |      100 |     100 |     100 |                   
  ...ractiveUI.tsx |   71.42 |     74.5 |    62.5 |   71.42 | ...10,337,404-409 
  ...inePresets.ts |   96.27 |    83.87 |     100 |   96.27 | ...97,402,410-412 
  textConstants.ts |     100 |      100 |     100 |     100 |                   
  types.ts         |     100 |      100 |     100 |     100 |                   
 src/ui/auth       |   58.76 |    66.66 |   51.06 |   58.76 |                   
  AuthDialog.tsx   |   59.01 |     42.1 |   16.66 |   59.01 | ...25,332-354,358 
  ...nProgress.tsx |       0 |        0 |       0 |       0 | 1-64              
  ...etupSteps.tsx |   60.21 |    70.73 |   57.69 |   60.21 | ...90,794,803,806 
  useAuth.ts       |   94.83 |       75 |     100 |   94.83 | ...33-234,253-259 
  ...rSetupFlow.ts |   43.18 |    33.33 |      50 |   43.18 | ...78-399,416-459 
 src/ui/commands   |   83.35 |    83.55 |   89.88 |   83.35 |                   
  aboutCommand.ts  |     100 |      100 |     100 |     100 |                   
  agentsCommand.ts |   83.78 |      100 |      60 |   83.78 | 30-32,42-44       
  ...odeCommand.ts |    93.1 |    95.23 |     100 |    93.1 | 77-82             
  arenaCommand.ts  |   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 | 27,61             
  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 
  ...essCommand.ts |   68.06 |    54.05 |      75 |   68.06 | ...96-197,211-214 
  ...astCommand.ts |   84.17 |       75 |     100 |   84.17 | ...,91-97,125-130 
  ...ig-command.ts |   93.12 |    88.42 |     100 |   93.12 | ...07-315,321-323 
  ...extCommand.ts |   69.07 |     72.6 |   84.61 |   69.07 | ...78-611,622-623 
  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 |   81.64 |    87.67 |    90.9 |   81.64 | ...73-278,325-332 
  docsCommand.ts   |     100 |     90.9 |     100 |     100 | 25                
  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.48 |       75 |     100 |   80.48 | 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 | 96,147            
  goalCommand.ts   |     100 |    96.49 |     100 |     100 | 139,192           
  helpCommand.ts   |     100 |      100 |     100 |     100 |                   
  ...oryCommand.ts |     100 |      100 |     100 |     100 |                   
  hooksCommand.ts  |   81.13 |    65.71 |   85.71 |   81.13 | ...,86-93,131-132 
  ideCommand.ts    |   60.75 |    64.28 |   41.17 |   60.75 | ...05-306,310-324 
  ...figCommand.ts |   52.83 |    81.25 |      70 |   52.83 | ...74-319,321-330 
  initCommand.ts   |   91.86 |       80 |     100 |   91.86 | 48,83-88          
  ...ghtCommand.ts |   77.87 |    71.42 |     100 |   77.87 | ...44-245,250-272 
  ...ageCommand.ts |   94.44 |    90.14 |     100 |   94.44 | ...13-214,241-251 
  learn-command.ts |     100 |      100 |     100 |     100 |                   
  lspCommand.ts    |     100 |    86.95 |     100 |     100 | 31,101-102        
  mcpCommand.ts    |     100 |      100 |     100 |     100 |                   
  memoryCommand.ts |     100 |      100 |     100 |     100 |                   
  modelCommand.ts  |   85.02 |    82.53 |     100 |   85.02 | ...1089,1123-1128 
  ...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.22 |    72.13 |     100 |   77.22 | ...46-150,172-177 
  ...tupCommand.ts |     100 |      100 |     100 |     100 |                   
  themeCommand.ts  |     100 |      100 |     100 |     100 |                   
  toolsCommand.ts  |     100 |      100 |     100 |     100 |                   
  trustCommand.ts  |     100 |      100 |     100 |     100 |                   
  types.ts         |     100 |      100 |     100 |     100 |                   
  ...te-command.ts |     100 |    94.11 |     100 |     100 | 74,148            
  vimCommand.ts    |   54.54 |      100 |      50 |   54.54 | 19-29             
  voice-command.ts |   93.57 |       88 |     100 |   93.57 | 35,97-102         
  ...owsCommand.ts |   92.92 |       85 |   66.66 |   92.92 | ...72-177,276-281 
 src/ui/components |   72.78 |    79.76 |   77.58 |   72.78 |                   
  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 |   88.65 |    90.41 |     100 |   88.65 | ...84-286,300-302 
  Composer.tsx     |   94.49 |    66.66 |     100 |   94.49 | ...-76,88,143,157 
  ...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          
  ...ustDialog.tsx |     100 |      100 |     100 |     100 |                   
  Footer.tsx       |   81.27 |    69.23 |      50 |   81.27 | ...06,245,267-272 
  ...ngSpinner.tsx |   68.42 |    85.71 |      50 |   68.42 | 35-52,73,80-81    
  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.28 |    66.99 |     100 |   79.28 | ...08,511,514-520 
  ...ngeDialog.tsx |     100 |      100 |     100 |     100 |                   
  InputPrompt.tsx  |   84.26 |    82.94 |      80 |   84.26 | ...2215,2236,2332 
  ...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.58 |    95.06 |   46.15 |   95.58 | ...79,482-486,489 
  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.08 |     100 |   85.22 | ...1041,1097,1099 
  ...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           
  ...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.49 |    73.89 |   69.23 |   71.49 | ...1244,1250-1251 
  ...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-172             
  ...tivityTab.tsx |    3.94 |      100 |       0 |    3.94 | 27-275            
  StatsDialog.tsx  |    8.64 |      100 |       0 |    8.64 | ...76-111,130-322 
  StatsDisplay.tsx |     100 |      100 |     100 |     100 |                   
  ...ciencyTab.tsx |    78.9 |    56.52 |     100 |    78.9 | ...26,213,262-288 
  ...atmapView.tsx |    8.98 |      100 |       0 |    8.98 | 20-107            
  ...essionTab.tsx |      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 |   55.05 |    69.09 |      50 |   55.05 |                   
  ...atContent.tsx |    9.09 |      100 |       0 |    9.09 | 54-275,281-283    
  ...tChatView.tsx |   21.05 |      100 |       0 |   21.05 | 21-39             
  ...tComposer.tsx |   69.48 |    33.33 |   66.66 |   69.48 | ...51,269,277-279 
  AgentFooter.tsx  |   15.38 |      100 |       0 |   15.38 | 28-65             
  AgentHeader.tsx  |   15.38 |      100 |       0 |   15.38 | 27-64             
  AgentTabBar.tsx  |    87.9 |    63.88 |     100 |    87.9 | ...88,110-118,136 
  ...oryAdapter.ts |     100 |    91.83 |     100 |     100 | 103,109-110,138   
  index.ts         |       0 |        0 |       0 |       0 | 1-12              
 ...mponents/arena |   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.34 |    84.91 |   92.98 |   85.34 |                   
  ...sksDialog.tsx |   81.87 |    82.77 |   85.71 |   81.87 | ...1853,1965-1971 
  ...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.26 |    86.89 |   85.57 |   90.26 |                   
  ...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 |   92.06 |    82.35 |     100 |   92.06 | 58-60,62,64       
  ...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.63 |     100 |   91.87 | ...49-651,658-660 
  ...upMessage.tsx |   98.38 |    95.38 |     100 |   98.38 | 188-191,422       
  ToolMessage.tsx  |   93.06 |    86.32 |   93.75 |   93.06 | ...1037,1082-1084 
 ...ponents/shared |   86.29 |    82.41 |   94.17 |   86.29 |                   
  ...ctionList.tsx |     100 |      100 |      75 |     100 |                   
  ...tonSelect.tsx |     100 |      100 |     100 |     100 |                   
  EnumSelector.tsx |     100 |    96.42 |     100 |     100 | 58                
  ...rBoundary.tsx |     100 |      100 |     100 |     100 |                   
  MaxSizedBox.tsx  |   84.71 |    86.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 |   81.48 |    84.84 |     100 |   81.48 | 46-66,73-76       
  StaticRender.tsx |     100 |      100 |     100 |     100 |                   
  TextInput.tsx    |    80.8 |    67.24 |      80 |    80.8 | ...36-240,252-258 
  ...ontroller.tsx |     100 |    81.81 |     100 |     100 | 59-62             
  ...apsedTime.tsx |     100 |      100 |     100 |     100 |                   
  ...Indicator.tsx |     100 |      100 |     100 |     100 |                   
  ...lizedList.tsx |   91.49 |    86.66 |   83.33 |   91.49 | ...18-846,859,959 
  text-buffer.ts   |   85.98 |    81.81 |   97.91 |   85.98 | ...2664,2762-2763 
  ...er-actions.ts |   73.93 |    67.22 |     100 |   73.93 | ...32-733,934-936 
 ...ponents/skills |    3.96 |      100 |       0 |    3.96 |                   
  ...gerDialog.tsx |    3.96 |      100 |       0 |    3.96 | 79-137,140-681    
 ...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 |    70.1 |    72.89 |   61.11 |    70.1 |                   
  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    |     100 |      100 |     100 |     100 |                   
 src/ui/contexts   |   84.16 |    81.83 |   85.13 |   84.16 |                   
  ...ewContext.tsx |   64.83 |    88.88 |      50 |   64.83 | ...16-219,225-235 
  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 | 235-236           
  ...deContext.tsx |      80 |     87.5 |      75 |      80 | ...11-112,118-120 
  ...rtContext.tsx |     100 |      100 |     100 |     100 |                   
 src/ui/daemon     |   88.35 |    73.51 |   95.45 |   88.35 |                   
  ...ui-adapter.ts |   88.35 |    73.51 |   95.45 |   88.35 | ...74,792-793,879 
 src/ui/editors    |   93.33 |    85.71 |   66.66 |   93.33 |                   
  ...ngsManager.ts |   93.33 |    85.71 |   66.66 |   93.33 | 49,63-64          
 src/ui/hooks      |   85.96 |    83.96 |   87.78 |   85.96 |                   
  ...dProcessor.ts |   85.53 |     85.2 |     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.62 |    73.58 |     100 |   94.62 | ...87-288,293-294 
  ...dProcessor.ts |   86.86 |    71.67 |   83.33 |   86.86 | ...1540,1562-1566 
  ...rt-command.ts |     100 |      100 |     100 |     100 |                   
  ...sced-flush.ts |     100 |      100 |     100 |     100 |                   
  ...ng-enabled.ts |     100 |      100 |     100 |     100 |                   
  ...oice-input.ts |   92.36 |    81.95 |   66.66 |   92.36 | ...00,502-503,658 
  ...ke-repaint.ts |     100 |      100 |     100 |     100 |                   
  ...amingState.ts |   12.22 |      100 |       0 |   12.22 | 54-157            
  ...agerDialog.ts |   88.23 |      100 |     100 |   88.23 | 20,24             
  ...dScrollbar.ts |     100 |      100 |     100 |     100 |                   
  ...ationFrame.ts |      42 |       75 |     100 |      42 | 42-44,53-59,62-87 
  ...odeCommand.ts |   58.82 |      100 |     100 |   58.82 | 28,33-48          
  ...enaCommand.ts |      85 |      100 |     100 |      85 | 23-24,29          
  ...aInProcess.ts |   27.92 |       80 |      25 |   27.92 | ...69-170,173-175 
  ...Completion.ts |   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 |   95.53 |    83.01 |     100 |   95.53 | ...64-165,289-292 
  ...ompletion.tsx |   97.09 |    87.09 |     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       
  ...miniStream.ts |   87.36 |    84.33 |   77.77 |   87.36 | ...5692-5694,5696 
  ...BranchName.ts |     100 |    94.44 |     100 |     100 | 54                
  ...oryManager.ts |   98.38 |    98.85 |     100 |   98.38 | 141-144           
  ...ooksDialog.ts |    87.5 |      100 |     100 |    87.5 | 19,23             
  ...stListener.ts |     100 |      100 |     100 |     100 |                   
  ...nAuthError.ts |   76.19 |       50 |     100 |   76.19 | 39-40,43-45       
  ...putHistory.ts |   92.59 |    85.71 |     100 |   92.59 | 63-64,72,94-96    
  ...storyStore.ts |     100 |    94.11 |     100 |     100 | 69                
  useKeypress.ts   |     100 |      100 |     100 |     100 |                   
  ...rdProtocol.ts |   36.36 |      100 |       0 |   36.36 | 24-31             
  ...unchEditor.ts |   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 |     97.4 |     100 |     100 | 175,262           
  ...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 |   95.34 |    77.14 |     100 |   95.34 | 124-125,227-232   
  ...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.85 |    85.13 |   94.73 |   82.85 | ...78-680,688-724 
  ...tateAndRef.ts |     100 |      100 |     100 |     100 |                   
  ...tatsDialog.ts |     100 |      100 |     100 |     100 |                   
  useStatusLine.ts |   97.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/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.13 |     100 |   93.56 |                   
  screen-buffer.ts |   94.73 |    64.28 |     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.61 |    85.68 |   95.81 |   87.61 |                   
  ...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.46 |     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.38 |    92.38 |     100 |   98.38 | 108,136-137,343   
  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 
  formatters.ts    |   94.87 |    98.24 |     100 |   94.87 | 116-119           
  goal-runtime.ts  |   91.42 |       95 |     100 |   91.42 | 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 |     100 |     100 | 44,103            
  historyUtils.ts  |   96.03 |     97.1 |     100 |   96.03 | 103-106           
  ...mage-parts.ts |   97.75 |    94.59 |     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 |   82.86 |    79.48 |     100 |   82.86 | ...88-610,741-742 
  ...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.11 |     100 |     100 | 33,76             
  terminalSetup.ts |    4.37 |      100 |       0 |    4.37 | 44-393            
  textUtils.ts     |   97.94 |    95.49 |   94.11 |   97.94 | ...82-283,443-444 
  ...background.ts |     100 |      100 |     100 |     100 |                   
  todoSnapshot.ts  |   90.42 |    92.85 |     100 |   90.42 | ...06-207,240-241 
  ...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.27 |    79.64 |   81.94 |   81.27 |                   
  ...d-recorder.ts |     6.2 |        0 |       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         |   81.57 |    87.31 |    92.7 |   81.57 |                   
  ...p-profiler.ts |   98.39 |    92.59 |     100 |   98.39 | 141,185,235       
  acpModelUtils.ts |   97.36 |    95.19 |     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       
  ...ng-failure.ts |     100 |      100 |     100 |     100 |                   
  checks.ts        |   33.33 |      100 |       0 |   33.33 | 23-28             
  ...-api-error.ts |     100 |    96.42 |     100 |     100 | 14                
  cleanup.ts       |   84.05 |    94.11 |      80 |   84.05 | 80,111-121        
  commands.ts      |   97.45 |    96.66 |     100 |   97.45 | 153-155           
  ...Calculator.ts |     100 |      100 |     100 |     100 |                   
  cpuProfiler.ts   |   70.73 |    73.23 |   88.88 |   70.73 | ...27,430-431,438 
  deepMerge.ts     |     100 |    89.65 |     100 |     100 | 41-43,49          
  ...re-runtime.ts |     100 |      100 |     100 |     100 |                   
  ...ScopeUtils.ts |   97.56 |    88.88 |     100 |   97.56 | 67                
  doctorChecks.ts  |   70.31 |    74.57 |     100 |   70.31 | ...95-301,325-341 
  ...putCapture.ts |   90.65 |    86.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 
  ...AutoUpdate.ts |    93.1 |       94 |      90 |    93.1 | 103,108,179-190   
  ...tyWarnings.ts |     100 |      100 |     100 |     100 |                   
  ...lationInfo.ts |   97.68 |    94.28 |     100 |   97.68 | ...64,381-382,427 
  ...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 
  languageUtils.ts |   98.88 |    97.01 |     100 |   98.88 | 184-185           
  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 
  ...iveHelpers.ts |   95.13 |    91.79 |     100 |   95.13 | ...53-454,552,565 
  osc.ts           |   97.18 |      100 |    87.5 |   97.18 | 182-183           
  package.ts       |   88.88 |    85.71 |     100 |   88.88 | 31-32             
  ...uggestions.ts |   84.29 |    70.83 |     100 |   84.29 | 70-76,92-103      
  processUtils.ts  |    92.3 |       80 |     100 |    92.3 | 45-46             
  readStdin.ts     |   93.67 |    94.11 |   85.71 |   93.67 | 79-83             
  relaunch.ts      |   95.87 |    89.28 |     100 |   95.87 | 103-105,131       
  resolvePath.ts   |     100 |      100 |     100 |     100 |                   
  runBudget.ts     |   99.35 |    96.77 |     100 |   99.35 | 119               
  sandbox-path.ts  |     100 |      100 |     100 |     100 |                   
  sandbox.ts       |   45.52 |    57.35 |   76.92 |   45.52 | ...1040,1052-1075 
  ...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 
  settingsUtils.ts |   82.35 |    89.57 |      90 |   82.35 | ...25-743,750-758 
  spawnWrapper.ts  |     100 |      100 |     100 |     100 |                   
  ...ate-verify.ts |     100 |      100 |     100 |     100 |                   
  ...one-update.ts |   39.81 |    77.44 |   62.16 |   39.81 | ...1193,1196-1215 
  ...upProfiler.ts |   98.47 |    94.66 |     100 |   98.47 | 132-133,308       
  ...upWarnings.ts |     100 |      100 |     100 |     100 |                   
  stdioHelpers.ts  |     100 |       90 |     100 |     100 | 23                
  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 
  ...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 
  ...e-relaunch.ts |   89.61 |    86.66 |      50 |   89.61 | 56-61,83-84       
  ...entEmitter.ts |     100 |      100 |     100 |     100 |                   
  ...ansionHook.ts |     100 |      100 |     100 |     100 |                   
  ...upWarnings.ts |   87.75 |       75 |     100 |   87.75 | 47-48,53-54,57-58 
  version.ts       |     100 |    66.66 |     100 |     100 | 11                
  ...ingHandler.ts |     100 |      100 |     100 |     100 |                   
  ...WithBackup.ts |   65.04 |    77.77 |     100 |   65.04 | 97,112,133-172    
 ...s/housekeeping |   93.51 |    90.95 |   96.96 |   93.51 |                   
  cleanup.ts       |   92.59 |    93.75 |     100 |   92.59 | ...02-205,209-211 
  ...eractionAt.ts |     100 |      100 |     100 |     100 |                   
  scheduler.ts     |      93 |    88.34 |      95 |      93 | ...57-359,411-415 
  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.07 |    86.65 |    89.6 |   88.07 |                   
 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.45 |    84.65 |   94.88 |   90.45 |                   
  ...transcript.ts |   88.49 |    84.09 |     100 |   88.49 | ...32,640,646-650 
  ...ent-resume.ts |   85.59 |    77.75 |   83.33 |   85.59 | ...1794-1798,1801 
  ...ound-tasks.ts |   94.63 |    90.13 |   96.38 |   94.63 | ...1773,1793-1796 
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...ent-result.ts |    96.8 |    92.68 |     100 |    96.8 | 106,129-131       
  ...n-registry.ts |   94.79 |     87.7 |     100 |   94.79 | ...1067,1081-1083 
  ...w-snapshot.ts |   92.12 |    77.14 |     100 |   92.12 | ...65,189,196-198 
 src/agents/arena  |   76.94 |    68.22 |   78.94 |   76.94 |                   
  ...gentClient.ts |   79.47 |    88.88 |   81.81 |   79.47 | ...68-183,189-204 
  ArenaManager.ts  |   75.89 |     65.2 |   78.57 |   75.89 | ...1887,1893-1894 
  arena-events.ts  |   64.44 |      100 |      50 |   64.44 | ...71-175,178-183 
  diff-summary.ts  |    87.5 |    72.34 |     100 |    87.5 | ...32-133,137-138 
  index.ts         |     100 |      100 |     100 |     100 |                   
  types.ts         |     100 |      100 |     100 |     100 |                   
 ...gents/backends |   78.09 |    85.23 |   76.28 |   78.09 |                   
  ITermBackend.ts  |   97.97 |    93.93 |     100 |   97.97 | ...78-180,255,307 
  ...essBackend.ts |    90.9 |    85.36 |   93.33 |    90.9 | ...70,672,674-675 
  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 |   91.22 |    86.83 |   89.31 |   91.22 |                   
  agent-context.ts |     100 |      100 |     100 |     100 |                   
  agent-core.ts    |   85.07 |     76.8 |   77.77 |   85.07 | ...2291,2337-2339 
  agent-events.ts  |     100 |      100 |     100 |     100 |                   
  ...t-headless.ts |   93.49 |    89.41 |   83.33 |   93.49 | ...96-497,500-501 
  ...nteractive.ts |   81.01 |    82.35 |   76.66 |   81.01 | ...33,535-538,541 
  ...statistics.ts |   98.29 |    82.55 |     100 |   98.29 | 141,165,206,239   
  agent-types.ts   |     100 |      100 |     100 |     100 |                   
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...ool-policy.ts |   98.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 |   91.76 |    75.86 |     100 |   91.76 | ...38-139,179-181 
  ...chestrator.ts |   92.92 |    90.57 |   84.61 |   92.92 | ...2012,2061-2064 
  ...ow-prompts.ts |     100 |      100 |     100 |     100 |                   
  ...low-runner.ts |   94.85 |     87.5 |   92.85 |   94.85 | ...93,260,280-283 
  ...ow-sandbox.ts |   96.85 |    91.28 |     100 |   96.85 | ...1705,1711-1712 
  ...flow-saved.ts |   96.51 |    94.36 |     100 |   96.51 | 134-135,234-237   
  ...flow-stall.ts |    97.9 |    83.33 |     100 |    97.9 | 138-139,236       
 src/agents/tasks  |     100 |      100 |     100 |     100 |                   
  types.ts         |     100 |      100 |     100 |     100 |                   
 src/agents/team   |   82.67 |    84.54 |   88.97 |   82.67 |                   
  TeamManager.ts   |    73.6 |    80.82 |   79.62 |    73.6 | ...1706,1729-1730 
  identity.ts      |     100 |      100 |     100 |     100 |                   
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...sionBridge.ts |     100 |      100 |     100 |     100 |                   
  mailbox.ts       |   96.02 |    87.23 |     100 |   96.02 | 352-358           
  ...ptAddendum.ts |     100 |      100 |     100 |     100 |                   
  tasks.ts         |   89.24 |    82.82 |     100 |   89.24 | ...-994,1038-1039 
  team-events.ts   |   60.52 |      100 |      50 |   60.52 | ...40-144,151-155 
  teamHelpers.ts   |   91.71 |    94.54 |      95 |   91.71 | ...18-319,355-365 
  types.ts         |     100 |      100 |     100 |     100 |                   
 ...eam/test-utils |   94.39 |    94.35 |   98.21 |   94.39 |                   
  ...on-harness.ts |   96.49 |       85 |     100 |   96.49 | 128-129,141-142   
  fake-agent.ts    |   98.49 |    95.16 |     100 |   98.49 | 201-203           
  fake-backend.ts  |   86.46 |    97.61 |   95.83 |   86.46 | 124-146           
 src/config        |   84.21 |    86.79 |   75.31 |   84.21 |                   
  approval-mode.ts |     100 |      100 |     100 |     100 |                   
  ...xtDefaults.ts |     100 |      100 |     100 |     100 |                   
  config.ts        |   83.52 |    86.51 |   73.78 |   83.52 | ...8844,8848-8849 
  constants.ts     |     100 |      100 |     100 |     100 |                   
  models.ts        |     100 |      100 |     100 |     100 |                   
  storage.ts       |   94.39 |    91.57 |   88.23 |   94.39 | ...45-446,449-450 
 ...nfirmation-bus |   98.27 |    97.14 |     100 |   98.27 |                   
  message-bus.ts   |   98.14 |    97.05 |     100 |   98.14 | 42-43             
  types.ts         |     100 |      100 |     100 |     100 |                   
 src/core          |    92.5 |    88.26 |   93.34 |    92.5 |                   
  baseLlmClient.ts |    88.4 |     83.8 |   81.81 |    88.4 | ...59,672,678-680 
  client.ts        |   92.64 |    88.04 |   92.04 |   92.64 | ...4299,4397-4398 
  ...tGenerator.ts |   86.34 |    87.34 |   84.61 |   86.34 | ...96-497,542-548 
  ...lScheduler.ts |   90.05 |    84.67 |   96.15 |   90.05 | ...6219,6247-6263 
  geminiChat.ts    |    94.7 |    90.12 |   95.53 |    94.7 | ...5052,5100-5101 
  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 |                   
  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 | 49-50             
  ...on-helpers.ts |   93.49 |    78.57 |     100 |   93.49 | ...10-211,228-229 
  ...issionFlow.ts |   98.97 |    96.96 |     100 |   98.97 | 107               
  ...try-policy.ts |     100 |      100 |     100 |     100 |                   
  ...ell-policy.ts |   94.89 |    88.54 |     100 |   94.89 | ...51-252,297-298 
  prompts.ts       |   93.64 |    91.42 |   83.33 |   93.64 | ...1209,1412-1413 
  ...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        
  ...reparation.ts |     100 |      100 |     100 |     100 |                   
  ...tion-guard.ts |   90.38 |    94.73 |     100 |   90.38 | 83-87             
  ...allIdUtils.ts |   98.41 |    93.47 |     100 |   98.41 | 36,45             
  ...okTriggers.ts |   99.45 |    92.43 |     100 |   99.45 | 182,193           
  ...terruption.ts |     100 |     92.3 |     100 |     100 | 86,104            
  turn.ts          |   99.19 |    94.48 |     100 |   99.19 | 680-681,750       
  ...l-fallback.ts |     100 |      100 |     100 |     100 |                   
 ...ntentGenerator |   96.33 |    88.12 |   96.15 |   96.33 |                   
  ...tGenerator.ts |   97.24 |    86.72 |   94.87 |   97.24 | ...1436,1465,1476 
  converter.ts     |   96.19 |    89.25 |     100 |   96.19 | ...1329,1550-1552 
  index.ts         |       0 |        0 |       0 |       0 | 1-21              
  usage.ts         |     100 |      100 |     100 |     100 |                   
 ...ntentGenerator |   88.78 |    72.36 |   89.47 |   88.78 |                   
  ...tGenerator.ts |   87.18 |    71.83 |   88.88 |   87.18 | ...58-364,382-383 
  index.ts         |     100 |       80 |     100 |     100 | 50                
 ...ntentGenerator |   96.12 |     91.3 |    90.9 |   96.12 |                   
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...tGenerator.ts |   96.06 |    90.75 |   90.47 |   96.06 | ...1309-1310,1338 
  ...tDetection.ts |     100 |      100 |     100 |     100 |                   
 ...ntentGenerator |   91.86 |    90.62 |   95.61 |   91.86 |                   
  constants.ts     |     100 |      100 |     100 |     100 |                   
  converter.ts     |    91.3 |    89.49 |   96.87 |    91.3 | ...1942,2111-2126 
  errorHandler.ts  |     100 |      100 |     100 |     100 |                   
  index.ts         |   68.25 |    82.35 |      50 |   68.25 | 44-53,74-78,90-94 
  ...tGenerator.ts |    66.4 |    70.58 |   88.88 |    66.4 | ...51-157,168-169 
  pipeline.ts      |   95.48 |    91.27 |     100 |   95.48 | ...1309,1317,1416 
  ...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.24 |     92.4 |     100 |   92.24 | ...28-529,549-552 
  ...kingParser.ts |     100 |    96.87 |     100 |     100 | 42                
  types.ts         |       0 |        0 |       0 |       0 | 1                 
 ...rator/provider |   97.39 |    92.28 |    98.5 |   97.39 |                   
  dashscope.ts     |   98.36 |    95.08 |   96.42 |   98.36 | ...08-709,851-852 
  deepseek.ts      |   94.91 |    89.36 |     100 |   94.91 | ...31-132,145-146 
  default.ts       |   99.18 |    97.05 |     100 |   99.18 | 208               
  index.ts         |     100 |      100 |     100 |     100 |                   
  mimo.ts          |   94.11 |    66.66 |     100 |   94.11 | 29,52-53          
  minimax.ts       |     100 |      100 |     100 |     100 |                   
  mistral.ts       |   96.07 |    73.33 |     100 |   96.07 | 32-33             
  modelscope.ts    |     100 |      100 |     100 |     100 |                   
  types.ts         |       0 |        0 |       0 |       0 |                   
  utils.ts         |     100 |      100 |     100 |     100 |                   
  zai.ts           |   92.13 |    82.14 |     100 |   92.13 | ...,39-40,135-137 
 src/extension     |   87.71 |    84.62 |   92.57 |   87.71 |                   
  ...ive-safety.ts |     100 |      100 |     100 |     100 |                   
  ...-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 |                   
  ...me-refresh.ts |     100 |      100 |     100 |     100 |                   
  ...sion-store.ts |   90.94 |    86.26 |   97.91 |   90.94 | ...1230-1236,1280 
  ...ionManager.ts |   83.89 |    82.86 |   81.72 |   83.89 | ...2832,2861-2862 
  ...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        |   90.48 |    82.71 |     100 |   90.48 | ...4,994-995,1005 
  http-client.ts   |   84.61 |       80 |     100 |   84.61 | 20-21             
  i18n.ts          |   78.26 |       96 |      50 |   78.26 | 104-110,116-123   
  index.ts         |     100 |      100 |     100 |     100 |                   
  marketplace.ts   |   88.39 |    83.11 |     100 |   88.39 | ...08,494,507-508 
  ...ork-policy.ts |   89.72 |       90 |     100 |   89.72 | ...36,148-154,156 
  npm.ts           |   89.02 |    81.81 |     100 |   89.02 | ...86-688,695-700 
  override.ts      |   94.11 |    93.33 |     100 |   94.11 | 63-64,81-82       
  ...-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.14 |     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      |   79.94 |    79.28 |    90.9 |   79.94 |                   
  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   |   71.88 |    65.71 |   71.42 |   71.88 | ...55-656,663-664 
  ...onToolGate.ts |   97.97 |     87.5 |     100 |   97.97 | 105,110           
  ...nGenerator.ts |   72.03 |    81.15 |   83.33 |   72.03 | ...68-219,331-333 
 src/generated     |       0 |        0 |       0 |       0 |                   
  git-commit.ts    |       0 |        0 |       0 |       0 | 1-10              
 src/goals         |   92.96 |    89.06 |   94.34 |   92.96 |                   
  ...eGoalStore.ts |   87.61 |    88.88 |   86.66 |   87.61 | ...85-188,196-204 
  ...t-verifier.ts |   96.27 |     90.9 |     100 |   96.27 | ...20,143-146,163 
  ...checkpoint.ts |   81.48 |    76.19 |     100 |   81.48 | ...02-105,115-118 
  goal-evidence.ts |   88.34 |    87.06 |    97.5 |   88.34 | ...1162,1185-1188 
  ...projection.ts |   66.66 |    72.97 |   33.33 |   66.66 | ...87,190,194-196 
  ...ersistence.ts |   87.29 |    85.71 |    87.5 |   87.29 | ...53-154,185-190 
  goal-protocol.ts |   96.87 |    95.65 |     100 |   96.87 | 200-201           
  goal-reducer.ts  |      95 |    92.34 |   97.05 |      95 | ...43,520,538-539 
  goal-runtime.ts  |   96.89 |    89.95 |   95.74 |   96.89 | ...1315-1316,1437 
  goal-tools.ts    |   98.38 |    94.05 |   95.45 |   98.38 | ...98-199,300-301 
  ...rn-context.ts |     100 |      100 |     100 |     100 |                   
  goal-verifier.ts |   92.46 |    92.85 |     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         |   88.07 |    86.35 |   88.54 |   88.07 |                   
  ...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    |   62.65 |    72.34 |   66.66 |   62.65 | ...70-771,780-781 
  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 |   78.75 |       75 |   66.66 |   78.75 | 62-66,137-152     
  ...oksManager.ts |   94.87 |    88.88 |     100 |   94.87 | ...84,325,327-329 
  ssrfGuard.ts     |   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/lsp           |   58.96 |    70.57 |   66.14 |   58.96 |                   
  ...nfigLoader.ts |   80.55 |       72 |   95.45 |   80.55 | ...02-504,508-514 
  ...ionFactory.ts |   42.81 |    73.07 |      50 |   42.81 | ...76-427,433-450 
  ...Normalizer.ts |   23.09 |    13.72 |   30.43 |   23.09 | ...04-905,909-924 
  ...verManager.ts |   75.73 |     80.1 |   79.66 |   75.73 | ...1346,1352-1382 
  ...eLspClient.ts |   32.78 |       80 |   16.66 |   32.78 | ...89-293,299-300 
  ...LspService.ts |      60 |    73.36 |   78.26 |      60 | ...1575,1635-1645 
  configHash.ts    |     100 |      100 |     100 |     100 |                   
  constants.ts     |     100 |      100 |     100 |     100 |                   
  types.ts         |     100 |      100 |     100 |     100 |                   
 src/mcp           |    82.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.19 |   89.28 |   82.12 |                   
  ...en-storage.ts |     100 |      100 |     100 |     100 |                   
  ...en-storage.ts |   87.08 |    87.03 |   95.23 |   87.08 | ...00-201,214-215 
  ...en-storage.ts |     100 |      100 |     100 |     100 |                   
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...en-storage.ts |   68.14 |    82.35 |   64.28 |   68.14 | ...81-295,298-314 
  types.ts         |     100 |      100 |     100 |     100 |                   
 src/memory        |    88.1 |    84.51 |   90.62 |    88.1 |                   
  ...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 
  const.ts         |   94.28 |     92.3 |     100 |   94.28 | 66-67             
  dream.ts         |    64.6 |    72.22 |      50 |    64.6 | ...04-109,124-165 
  ...entPlanner.ts |     100 |    83.33 |     100 |     100 | 136,146           
  entries.ts       |   75.59 |    84.84 |   83.33 |   75.59 | ...56-157,172-180 
  extract.ts       |   92.41 |    79.41 |     100 |   92.41 | 56-61,100,119-122 
  ...entPlanner.ts |   91.59 |    76.74 |     100 |   91.59 | ...05,114-117,293 
  ...ionPlanner.ts |       0 |        0 |       0 |       0 | 1                 
  forget.ts        |   81.83 |       75 |   83.33 |   81.83 | ...51,474,478-507 
  indexer.ts       |   94.14 |       84 |     100 |   94.14 | ...32-233,334,337 
  ...kill-agent.ts |   97.94 |    89.36 |     100 |   97.94 | 82-83,179-180     
  manager.ts       |    78.4 |    82.29 |   77.77 |    78.4 | ...1482,1495-1497 
  ...ent-config.ts |   86.99 |    82.69 |   86.36 |   86.99 | ...69,389,396-402 
  memoryAge.ts     |   90.47 |    83.33 |     100 |   90.47 | 50-51             
  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.36 |   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.89 |    90.19 |     100 |   98.89 | 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 |   77.24 |    74.07 |   72.22 |   77.24 | ...52-456,459,465 
  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 |     87.5 |     100 |     100 | 30                
  ...cret-guard.ts |     100 |      100 |     100 |     100 |                   
  ...emory-sync.ts |   94.24 |    82.85 |     100 |   94.24 | ...34-236,246-247 
  types.ts         |     100 |      100 |     100 |     100 |                   
  ...ontextFile.ts |   81.21 |     79.1 |   81.81 |   81.21 | ...63-277,291-296 
 src/mocks         |       0 |        0 |       0 |       0 |                   
  msw.ts           |       0 |        0 |       0 |       0 | 1-9               
 src/models        |   92.55 |    88.62 |   91.13 |   92.55 |                   
  constants.ts     |     100 |      100 |     100 |     100 |                   
  ...tor-config.ts |   97.77 |    91.83 |     100 |   97.77 | 155,161,171       
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...nfigErrors.ts |   74.22 |       44 |   84.61 |   74.22 | ...,67-74,106-117 
  ...igResolver.ts |   98.71 |    93.33 |     100 |   98.71 | 166,328,334       
  modelRegistry.ts |     100 |    98.11 |     100 |     100 | 177,261           
  modelsConfig.ts  |   89.36 |    86.93 |   88.09 |   89.36 | ...1404,1433-1434 
  types.ts         |     100 |      100 |     100 |     100 |                   
 src/output        |     100 |      100 |     100 |     100 |                   
  ...-formatter.ts |     100 |      100 |     100 |     100 |                   
  types.ts         |     100 |      100 |     100 |     100 |                   
 src/permissions   |   83.79 |    91.16 |   71.07 |   83.79 |                   
  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 |    89.36 |     100 |     100 | 110,133,147,175   
  ...alTracking.ts |     100 |      100 |     100 |     100 |                   
  ...e-commands.ts |   86.77 |     73.8 |     100 |   86.77 | 131-141,210-214   
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...on-manager.ts |   86.63 |    88.88 |      80 |   86.63 | ...1111,1217-1221 
  rule-parser.ts   |   94.49 |    92.72 |     100 |   94.49 | ...1447,1481-1483 
  ...-semantics.ts |   70.44 |    91.09 |   46.66 |   70.44 | ...2237,2311-2314 
  types.ts         |     100 |      100 |     100 |     100 |                   
 ...sifier-prompts |   99.04 |    95.23 |     100 |   99.04 |                   
  system-prompt.ts |   99.04 |    95.23 |     100 |   99.04 | 220               
 src/prompts       |   83.63 |      100 |    87.5 |   83.63 |                   
  mcp-prompts.ts   |   18.18 |      100 |       0 |   18.18 | 11-19             
  ...t-registry.ts |     100 |      100 |     100 |     100 |                   
 src/providers     |   83.71 |     78.6 |   81.25 |   83.71 |                   
  all-providers.ts |     100 |      100 |     100 |     100 |                   
  index.ts         |     100 |      100 |     100 |     100 |                   
  install.ts       |   93.11 |     84.5 |     100 |   93.11 | ...56-257,330-331 
  ...der-config.ts |   75.85 |    74.04 |   78.26 |   75.85 | ...73-474,502-503 
  types.ts         |       0 |        0 |       0 |       0 | 1                 
 ...viders/presets |   97.82 |    91.66 |   63.63 |   97.82 |                   
  ...oding-plan.ts |   87.34 |      100 |       0 |   87.34 | 81-83,86-88,90-93 
  ...a-standard.ts |     100 |      100 |     100 |     100 |                   
  ...token-plan.ts |     100 |      100 |     100 |     100 |                   
  ...m-provider.ts |   97.05 |    81.25 |      75 |   97.05 | 118-119           
  deepseek.ts      |     100 |      100 |     100 |     100 |                   
  grok.ts          |     100 |      100 |     100 |     100 |                   
  idealab.ts       |     100 |      100 |     100 |     100 |                   
  minimax.ts       |     100 |      100 |     100 |     100 |                   
  modelscope.ts    |     100 |      100 |     100 |     100 |                   
  openrouter.ts    |     100 |      100 |     100 |     100 |                   
  requesty.ts      |     100 |      100 |     100 |     100 |                   
  zai.ts           |     100 |      100 |     100 |     100 |                   
 src/qwen          |   85.41 |    78.76 |   95.89 |   85.41 |                   
  ...tGenerator.ts |   98.64 |    98.18 |     100 |   98.64 | 105-106           
  qwenOAuth2.ts    |   82.79 |    73.75 |   90.62 |   82.79 | ...1205-1221,1251 
  ...kenManager.ts |   85.36 |    76.61 |     100 |   85.36 | ...52-757,778-783 
 src/resources     |     100 |      100 |     100 |     100 |                   
  ...e-registry.ts |     100 |      100 |     100 |     100 |                   
 src/services      |   90.41 |    85.96 |   96.94 |   90.41 |                   
  ...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.51 |    96.15 |     100 |   97.51 | ...,929,1072-1080 
  ...ingService.ts |   91.92 |    86.38 |    94.8 |   91.92 | ...2365,2392-2393 
  ...ttribution.ts |   91.73 |    87.71 |      90 |   91.73 | ...80-685,826-827 
  ...utSlimming.ts |    97.2 |    94.17 |     100 |    97.2 | ...39-340,378-381 
  cronScheduler.ts |   94.17 |    90.45 |      98 |   94.17 | ...1333,1736-1737 
  cronTasksFile.ts |   96.31 |    91.81 |     100 |   96.31 | ...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 |    73.7 |    68.49 |   95.83 |    73.7 | ...2196,2225-2226 
  ...on-service.ts |   87.38 |       72 |     100 |   87.38 | ...01-305,343-344 
  ...references.ts |   98.39 |    88.88 |     100 |   98.39 | 154-155,215-216   
  ...ionService.ts |   98.26 |    97.35 |     100 |   98.26 | ...13-714,761-762 
  ...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 |    88.88 |     100 |   98.94 | 43                
  ...ersistence.ts |   91.66 |    80.75 |     100 |   91.66 | ...1060-1061,1089 
  ...tory-state.ts |     100 |       95 |     100 |     100 | 31                
  ...on-service.ts |   94.49 |    92.26 |   97.14 |   94.49 | ...98-600,656-664 
  ...ce-service.ts |    98.5 |    94.11 |    90.9 |    98.5 | 64-65             
  ...n-registry.ts |   98.73 |    96.29 |     100 |   98.73 | 584,638-639,692   
  ...ken-counts.ts |     100 |       96 |     100 |     100 | 58                
  ...ipt-reader.ts |   93.71 |    91.05 |   97.77 |   93.71 | ...2755-2756,2833 
  ...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 |   83.14 |    74.47 |   97.61 |   83.14 | ...2433,2445-2448 
  sessionRecap.ts  |   67.56 |    43.47 |     100 |   67.56 | ...60,178,180-183 
  ...ionService.ts |   89.31 |    85.86 |   96.05 |   89.31 | ...2642,2656-2676 
  sessionTitle.ts  |   95.75 |    77.41 |     100 |   95.75 | ...53-256,287-288 
  ...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 
  ...Estimation.ts |     100 |    94.11 |     100 |     100 | 118               
  ...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.72 |    84.07 |     100 |   90.72 | ...06-509,561-562 
  ...reeCleanup.ts |   14.42 |      100 |   33.33 |   14.42 | 58-186            
  ...ionService.ts |   88.36 |     87.7 |     100 |   88.36 | ...48-449,465-466 
 ...icrocompaction |    98.9 |    95.08 |     100 |    98.9 |                   
  microcompact.ts  |    98.9 |    95.08 |     100 |    98.9 | ...40,749,758-759 
 ...s/visionBridge |   98.81 |    92.12 |     100 |   98.81 |                   
  ...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             
  ...-constants.ts |     100 |      100 |     100 |     100 |                   
  ...ge-service.ts |   98.61 |     94.7 |     100 |   98.61 | ...06,666,679-680 
 src/skills        |   89.29 |    85.92 |   93.61 |   89.29 |                   
  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 |   84.82 |    85.29 |   83.33 |   84.82 | ...1243,1250-1254 
  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.03 |     100 |   97.91 | 277-278           
 ...ataviz/scripts |   80.06 |    95.23 |   88.23 |   80.06 |                   
  ...te_palette.js |   80.06 |    95.23 |   88.23 |   80.06 | 261-296,306-328   
 ...s/bundled/loop |   97.48 |    95.77 |     100 |   97.48 |                   
  ...omous-loop.ts |     100 |      100 |     100 |     100 |                   
  ...-task-file.ts |   94.85 |     92.4 |     100 |   94.85 | ...56,367,375-376 
  ...k-resolver.ts |     100 |      100 |     100 |     100 |                   
 src/subagents     |   87.72 |    89.01 |   96.55 |   87.72 |                   
  ...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 |   84.48 |    85.91 |   94.87 |   84.48 | ...1582,1659-1660 
  types.ts         |     100 |      100 |     100 |     100 |                   
  validation.ts    |   92.46 |    95.18 |     100 |   92.46 | 47-52,63-68,71-76 
 src/telemetry     |   82.41 |    84.65 |   85.74 |   82.41 |                   
  ...ty-tracker.ts |     100 |      100 |     100 |     100 |                   
  config.ts        |     100 |      100 |     100 |     100 |                   
  constants.ts     |     100 |      100 |     100 |     100 |                   
  ...on-metrics.ts |   99.08 |    80.95 |     100 |   99.08 | 185,199           
  ...on-tracing.ts |   76.92 |    75.71 |   73.68 |   76.92 | ...88,395-397,413 
  ...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.78 |    83.33 |   55.55 |   65.78 | ...04-105,108-109 
  ...ai-content.ts |    74.5 |    66.41 |   91.66 |    74.5 | ...1480,1493-1502 
  ...i-provider.ts |     100 |       99 |     100 |     100 | 99                
  ...ai-request.ts |   87.52 |    92.79 |   83.78 |   87.52 | ...55-561,564-570 
  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.73 |    78.01 |   66.66 |   60.73 | ...1507,1524-1544 
  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      |   93.89 |    86.32 |      75 |   93.89 | ...39,489-490,506 
  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.17 |    88.72 |    97.5 |   91.17 | ...1920,1949-1952 
  ...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.09 |     95.1 |   86.36 |   83.09 | ...1467,1471-1478 
  uiTelemetry.ts   |   97.18 |    93.93 |      88 |   97.18 | ...70,314,461-462 
 ...ry/qwen-logger |   74.23 |     80.7 |      70 |   74.23 |                   
  event-types.ts   |       0 |        0 |       0 |       0 |                   
  qwen-logger.ts   |   74.23 |    80.53 |   69.49 |   74.23 | ...1122,1160-1161 
 src/test-utils    |   96.38 |    98.61 |   83.33 |   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 |   78.78 |   94.85 | ...53,227-228,241 
  ...aceContext.ts |     100 |      100 |     100 |     100 |                   
 src/tools         |   86.29 |     85.1 |   88.82 |   86.29 |                   
  ...erQuestion.ts |   89.71 |    80.76 |   91.66 |   89.71 | ...66-367,374-375 
  ...-registrar.ts |    77.7 |    66.66 |   66.66 |    77.7 | ...72-277,292-294 
  ...ub-session.ts |   89.67 |     91.3 |   81.81 |   89.67 | ...03-304,315-322 
  cron-create.ts   |   90.64 |    92.85 |   72.72 |   90.64 | ...,73-74,223-231 
  cron-delete.ts   |   97.56 |      100 |   83.33 |   97.56 | 31-32             
  cron-list.ts     |   98.23 |    95.34 |    87.5 |   98.23 | 57-58             
  diffOptions.ts   |     100 |      100 |     100 |     100 |                   
  display-image.ts |   87.42 |    84.84 |   88.88 |   87.42 | ...29-134,194-195 
  edit.ts          |   82.76 |    86.77 |   81.25 |   82.76 | ...45-746,865-915 
  ...r-worktree.ts |   83.14 |    67.56 |    87.5 |   83.14 | ...84-187,278-279 
  enterPlanMode.ts |      85 |     82.6 |    87.5 |      85 | ...28-133,161-175 
  exit-worktree.ts |   83.29 |    83.65 |   94.44 |   83.29 | ...14-515,537-538 
  exitPlanMode.ts  |      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.61 |   85.71 |   90.73 | ...76-677,727-728 
  ...adTracking.ts |     100 |      100 |     100 |     100 |                   
  image-gen.ts     |   91.66 |    77.41 |    90.9 |   91.66 | ...13-214,221-222 
  list-agents.ts   |   94.02 |    82.35 |   83.33 |   94.02 | 31-32,47-48       
  loop-wakeup.ts   |   99.27 |    92.85 |     100 |   99.27 | 45                
  ls.ts            |   96.74 |    90.27 |     100 |   96.74 | 176-181,212,216   
  lsp.ts           |   72.71 |     59.5 |   90.32 |   72.71 | ...1212,1214-1215 
  ...nt-manager.ts |   82.13 |    80.47 |   85.71 |   82.13 | ...3234,3236-3237 
  mcp-client.ts    |   80.03 |    86.58 |   89.47 |   80.03 | ...2272,2276-2279 
  ...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 | ...1341,1349-1350 
  ...ool-events.ts |       8 |      100 |       0 |       8 | 132-158           
  mcp-pool-key.ts  |   97.46 |    93.93 |     100 |   97.46 | 176-177           
  ...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.35 |    93.71 |     100 |   98.35 | ...-990,1045-1046 
  ...sport-pool.ts |   83.98 |     80.3 |   88.46 |   83.98 | ...1409,1416-1420 
  ...ace-budget.ts |   87.27 |     82.6 |     100 |   87.27 | ...00-305,340-345 
  memory-config.ts |     100 |      100 |     100 |     100 |                   
  ...iable-tool.ts |     100 |    84.61 |     100 |     100 | 101,108           
  monitor.ts       |   91.82 |    83.09 |   88.46 |   91.82 | ...99,612,810-815 
  notebook-edit.ts |   85.71 |    77.08 |   81.25 |   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.52 |   86.66 |   95.49 | ...49,464,536-537 
  ...p-resource.ts |   96.85 |      100 |   91.66 |   96.85 | 92-96             
  ...d-artifact.ts |   91.18 |    86.71 |    87.5 |   91.18 | ...26-427,441-453 
  ripGrep.ts       |    94.6 |    87.26 |   95.23 |    94.6 | ...33-734,740-741 
  ...-transport.ts |   71.42 |    55.55 |   71.42 |   71.42 | ...36-137,143-144 
  send-message.ts  |   81.13 |    89.74 |    62.5 |   81.13 | ...80-286,363-371 
  ...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         |   91.39 |    92.55 |      90 |   91.39 | ...84,488,534-556 
  ...eticOutput.ts |   95.12 |      100 |      80 |   95.12 | 87-88             
  task-create.ts   |    94.4 |    93.33 |   81.81 |    94.4 | 45-49,63-64,95    
  task-list.ts     |   78.22 |    84.21 |   83.33 |   78.22 | ...66,105,109-116 
  task-stop.ts     |   93.14 |    96.15 |   85.71 |   93.14 | 39-40,54-64       
  task-update.ts   |   82.89 |    83.92 |    92.3 |   82.89 | ...14-422,454-465 
  team-create.ts   |   97.22 |    85.71 |   83.33 |   97.22 | 48-49,129-130     
  team-delete.ts   |   86.74 |    83.33 |   83.33 |   86.74 | 37-38,42-48,72-73 
  ...n-approval.ts |   92.14 |    96.77 |   77.77 |   92.14 | 38-39,42-43,93-99 
  todoWrite.ts     |   95.13 |    87.85 |   93.33 |   95.13 | ...23-527,540-545 
  tool-error.ts    |     100 |      100 |     100 |     100 |                   
  tool-names.ts    |     100 |      100 |     100 |     100 |                   
  tool-registry.ts |   78.57 |    79.59 |    82.6 |   78.57 | ...89-990,998-999 
  tool-search.ts   |   96.19 |    89.72 |   93.33 |   96.19 | ...09,259-264,426 
  tools.ts         |   93.11 |    92.53 |   91.66 |   93.11 | ...69-570,586-592 
  ...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    |   86.72 |    84.92 |   88.88 |   86.72 | ...25-828,865-900 
  zoom-image.ts    |   95.76 |    93.75 |      90 |   95.76 | 54-59,203-204     
 src/tools/agent   |   86.92 |    87.48 |   88.59 |   86.92 |                   
  agent.ts         |   85.51 |    86.38 |   86.17 |   85.51 | ...4333,4367-4377 
  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.78 |    92.51 |   88.63 |   95.78 |                   
  artifact-tool.ts |   91.46 |    88.46 |   71.42 |   91.46 | ...13-314,322-325 
  ...-publisher.ts |     100 |    85.71 |     100 |     100 | 32                
  ...-publisher.ts |   96.74 |    97.72 |    87.5 |   96.74 | 29-30,156-157     
  html.ts          |     100 |    96.77 |     100 |     100 | 122               
  ...-publisher.ts |     100 |       80 |     100 |     100 | 30                
  oss-publisher.ts |    98.1 |    91.48 |     100 |    98.1 | 43-45             
  publisher.ts     |     100 |      100 |     100 |     100 |                   
 ...s/computer-use |   90.21 |    82.17 |   78.08 |   90.21 |                   
  bootstrap.ts     |   59.42 |    80.95 |   41.66 |   59.42 | ...35-339,341-345 
  client.ts        |   80.11 |       90 |   77.77 |   80.11 | ...97,242-243,274 
  constants.ts     |     100 |    94.73 |     100 |     100 | 129,256           
  downloader.ts    |   65.29 |    52.77 |   58.33 |   65.29 | ...99-300,316-355 
  index.ts         |     100 |      100 |     100 |     100 |                   
  install-state.ts |   94.44 |    72.72 |     100 |   94.44 | 44-45             
  ...n-detector.ts |     100 |     87.5 |     100 |     100 | 50                
  schemas.ts       |     100 |      100 |     100 |     100 |                   
  tool.ts          |    96.3 |    85.71 |     100 |    96.3 | 75-76,184,252-258 
 ...tools/workflow |   86.51 |    84.81 |      75 |   86.51 |                   
  workflow.ts      |   86.51 |    84.81 |      75 |   86.51 | ...67,512,514-515 
 src/utils         |   92.97 |    89.65 |   96.93 |   92.97 |                   
  LruCache.ts      |     100 |      100 |     100 |     100 |                   
  ...Controller.ts |     100 |      100 |     100 |     100 |                   
  ...ssageQueue.ts |     100 |      100 |     100 |     100 |                   
  ...cFileWrite.ts |      95 |     92.7 |     100 |      95 | ...49-550,657-661 
  bareMode.ts      |   81.81 |      100 |      50 |   81.81 | 18-19             
  ...ry-content.ts |   98.45 |    95.45 |     100 |   98.45 | 132-133,159-160   
  browser.ts       |   86.84 |    78.94 |     100 |   86.84 | 34,36-37,65-66    
  btwUtils.ts      |   13.95 |      100 |       0 |   13.95 | 17-31,34-55       
  bundlePaths.ts   |     100 |      100 |     100 |     100 |                   
  ...on-context.ts |     100 |      100 |     100 |     100 |                   
  ...igResolver.ts |     100 |      100 |     100 |     100 |                   
  ...engthError.ts |   91.06 |    89.47 |     100 |   91.06 | ...46-147,154-155 
  ...n-branches.ts |   95.88 |    94.11 |      95 |   95.88 | ...98-499,511-524 
  ...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   |   96.66 |    96.61 |   88.88 |   96.66 | 192-196           
  editHelper.ts    |   93.63 |     83.9 |     100 |   93.63 | ...27-428,462-463 
  editor.ts        |   97.65 |    95.45 |     100 |   97.65 | ...35-336,338-339 
  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     
  ...entContext.ts |   96.63 |    90.13 |   96.66 |   96.63 | ...42,444-445,512 
  errorParsing.ts  |     100 |      100 |     100 |     100 |                   
  ...rReporting.ts |   95.65 |    93.33 |     100 |   95.65 | 37-38             
  errors.ts        |   88.92 |    92.99 |   66.66 |   88.92 | ...92,394,410-411 
  fetch.ts         |   90.68 |    82.51 |     100 |   90.68 | ...72,483-484,503 
  file-identity.ts |     100 |      100 |     100 |     100 |                   
  fileUtils.ts     |   94.87 |    92.97 |   96.15 |   94.87 | ...1907,1915-1916 
  forkedAgent.ts   |   92.45 |    82.35 |   93.75 |   92.45 | ...34,642,647-654 
  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             
  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    |   95.74 |    82.27 |     100 |   95.74 | 216,314-322       
  iconvHelper.ts   |     100 |      100 |     100 |     100 |                   
  ...rePatterns.ts |     100 |      100 |     100 |     100 |                   
  image-view.ts    |   95.08 |    93.33 |     100 |   95.08 | ...62-166,234-238 
  ...ionManager.ts |     100 |     90.9 |     100 |     100 | 27                
  ...lPromptIds.ts |     100 |      100 |     100 |     100 |                   
  ...on-context.ts |     100 |      100 |     100 |     100 |                   
  jsonl-utils.ts   |   95.41 |    93.61 |     100 |   95.41 | ...27-328,370-373 
  ...-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                
  ...iagnostics.ts |    96.4 |     94.2 |     100 |    96.4 | ...66,293-294,376 
  ...yDiscovery.ts |    92.4 |    89.13 |     100 |    92.4 | ...28,331,522-525 
  ...tProcessor.ts |   94.01 |       90 |     100 |   94.01 | ...47-353,445-446 
  ...Inspectors.ts |     100 |      100 |     100 |     100 |                   
  modelId.ts       |   98.96 |    98.21 |     100 |   98.96 | 153               
  ...kerChecker.ts |    90.9 |    91.66 |     100 |    90.9 | 73-79             
  notebook.ts      |   94.57 |    89.91 |   95.83 |   94.57 | ...21,333,385-387 
  openaiLogger.ts  |   91.66 |    89.74 |     100 |   91.66 | ...26-228,251-256 
  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.54 |     100 |   90.88 | ...25-626,628-630 
  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.15 |     100 |   96.98 | ...87-688,763-764 
  readManyFiles.ts |   95.75 |    80.86 |     100 |   95.75 | ...05,558,568-572 
  retry.ts         |   96.09 |    92.52 |     100 |   96.09 | ...67,558-559,577 
  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 
  ...sDiscovery.ts |   97.46 |    93.05 |     100 |   97.46 | ...04,182-183,202 
  ...iagnostics.ts |   83.08 |     67.5 |   92.59 |   83.08 | ...23,543-544,550 
  ...tchOptions.ts |   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.03 |    97.75 |     100 |   98.03 | 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 |      100 |     100 |     100 |                   
  ...orageUtils.ts |   96.21 |    85.34 |     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.26 |    88.58 |     100 |   86.26 | ...2295,2302-2306 
  ...lAstParser.ts |    98.3 |    91.59 |     100 |    98.3 | ...1340-1342,1352 
  ...ContextEnv.ts |     100 |       92 |     100 |     100 | 50-52             
  ...nlyChecker.ts |   96.33 |    96.57 |     100 |   96.33 | ...83-284,292-293 
  sideQuery.ts     |   86.82 |    86.66 |     100 |   86.82 | ...79-185,187-193 
  ...pEventSink.ts |     100 |       80 |     100 |     100 | 61                
  ...tGenerator.ts |     100 |      100 |     100 |     100 |                   
  ...ameContext.ts |     100 |      100 |     100 |     100 |                   
  symlink.ts       |   77.77 |       50 |     100 |   77.77 | 44,54-59          
  ...e-encoding.ts |   85.96 |    76.47 |     100 |   85.96 | 58-61,64-65,78-79 
  ...emEncoding.ts |   96.36 |    91.17 |     100 |   96.36 | 59-60,124-125     
  terminalSafe.ts  |     100 |      100 |     100 |     100 |                   
  ...Serializer.ts |   98.72 |       90 |     100 |   98.72 | 42-43,134,201-203 
  testUtils.ts     |   53.33 |      100 |   33.33 |   53.33 | ...53,59-64,70-72 
  ...-constants.ts |     100 |      100 |     100 |     100 |                   
  textUtils.ts     |      65 |      100 |      75 |      65 | 56-75             
  thoughtUtils.ts  |     100 |    95.65 |     100 |     100 | 99                
  ...-converter.ts |   95.23 |    85.71 |     100 |   95.23 | 36-37             
  ...name-utils.ts |     100 |      100 |     100 |     100 |                   
  ...-finalizer.ts |   97.66 |     90.9 |     100 |   97.66 | 165-166,168-172   
  ...-retention.ts |     100 |    95.83 |     100 |     100 | 116               
  tool-utils.ts    |    95.2 |    93.61 |     100 |    95.2 | ...58-159,162-163 
  ...ultCleanup.ts |   54.62 |       25 |      75 |   54.62 | ...03-105,108-134 
  ...Compaction.ts |   96.13 |    96.42 |     100 |   96.13 | ...34-339,341-346 
  ...pt-records.ts |   87.55 |    86.13 |     100 |   87.55 | ...78-482,512-527 
  truncation.ts    |   90.61 |    90.59 |     100 |   90.61 | ...53-461,498-504 
  windowsPath.ts   |   89.47 |    79.31 |     100 |   89.47 | ...57-58,62,90-91 
  ...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.72 |   94.73 |   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.43 |   89.47 |   84.05 | ...30-334,340-341 
  ignore.ts        |     100 |    97.36 |     100 |     100 | 187               
  result-cache.ts  |     100 |    93.75 |     100 |     100 | 49                
 ...uest-tokenizer |   69.76 |    75.47 |   85.29 |   69.76 |                   
  ...eTokenizer.ts |   65.72 |    74.02 |    92.3 |   65.72 | ...65-466,479-533 
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...tTokenizer.ts |   68.39 |    69.49 |    90.9 |   68.39 | ...24-325,327-328 
  ...ageFormats.ts |   76.92 |      100 |   33.33 |   76.92 | 46-49,56-57       
  textTokenizer.ts |     100 |      100 |     100 |     100 |                   
  types.ts         |       0 |        0 |       0 |       0 | 1                 
-------------------|---------|----------|---------|---------|-------------------

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

@qwen-code-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

@qwen-code /triage

@qwen-code-ci-bot

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

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

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

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

Verification report

PR 8716 Deep Verification — fix(memory): improve recall delivery and multilingual fallback

Verdict: merge-ready — 781 scripted assertions passed, 0 failed.
Verified head: ec0c7460d055582b961f205ff109efc7252bc568 (merge commit 86311c7, base tip ee2e5be).

Assertion breakdown (all executed, none projected): head vitest gate 362; scorer A/B
corpus at head 37; delivery A/B 8 (4 head cells + 4 base cells with per-arm encoded
expectations); PR test files against base source 362 (A/B control: the observed red set
of 23 is exactly the predicted new-behavior set, so every test matched its encoded
expectation); mutation matrix 7 (1 unmutated-green control + 6 mutants killed); gates 5
(typecheck clean, eslint clean, eslint liveness probe, base-dist and head-dist code
identity checks).

中文摘要
  • 结论merge-ready。781 项脚本化断言全部通过,0 失败。
  • A/B 结论(核心主张):在完全相同的 harness 下,head 的 100 ms 有界等待把「40 ms 内完成的 recall」从 base 的遗漏(0 ms 零等待轮询,dispatch @​8 ms 时无 memory)翻转为投递(dispatch @​42 ms 时首个模型请求携带 memory prompt);永不 settle 的 recall 在 head 上精确等待 100 ms 后放行且不被中止(dispatch 时刻 aborted=false),base 立即放行;等待期间父级 abort 在 head 上 21 ms 内提前结束等待且无过期投递。见 02-delivery-ab-head-bounded-wait.png / 03-delivery-ab-base-zero-wait-miss.png
  • A/B 结论(fallback 评分器):37 格标注语料(中/日/韩/英/混合/NFKC/半角片假名/康熙部首/扩展 B 区汉字/标点切分/连字)head 37/37 通过,base 在 21 格上错误(CJK 查询零 token、无词面匹配仍因「正文非空 +1」选中无关文档);长查询计时阶梯证明 token 上限生效(base 随查询增长 6.0→42.5 ms,head 恒定 ~3 ms)。见 01-scorer-ab-37-cells-flip.png
  • 测试非空洞:PR 新增测试在 base 源码上按预期红 23 格(22 recall + 1 client),失败信息为行为性期望值不符;6/6 突变体全部被杀灭,无存活,阳性对照成立。
  • 未覆盖:逐 commit 归因(浅克隆仅可达 head);真实模型 selector 链路端到端(与 base 相同,未改动);Windows/macOS 平台差异(纯 JS 无平台分支);200 文档候选上限(PR 声明范围外)。

Central claim and A/B proof

Central claim: the UserQuery initial request now waits up to 100 ms for an in-flight
managed-memory recall; a result settling inside the budget is injected into the first
model request; a deadline miss leaves the recall running (not aborted) for the existing
ToolResult delivery point. Secondary claims: (1) the selector-failure fallback scorer
handles CJK/mixed/NFKC queries and stops selecting lexically non-matching documents;
(2) cancellation during the bounded wait ends it early with no stale delivery.

Control construction: git worktree add tmp/base-tree HEAD^1 (merge-ref checkout, so
HEAD^1 = base tip), packages/core rebuilt there with the repo's own tsc; harnesses
import each tree's compiled dist/ by absolute path. packages/core has no
@qwen-code/* dependencies, and readlink -f on both dist entry points resolved
inside their own trees, so no workspace symlink could leak head code into the control.
The PR touches no package.json/lockfile, so sharing the root node_modules (plus a
symlink of core's own nested node_modules, identical versions) is a clean control.
Emitted code identity was asserted directly: base dist carries the old
split(/[^a-z0-9]+/) tokenizer and no INITIAL_MEMORY_RECALL_WAIT_MS; head dist the
inverse.

Delivery A/B (verifier-authored cells, identical file in both trees, run via the repo's vitest)

cell observable oracle head base
AB-A: recall settles after 40 ms memory prompt in first turn.run request; dispatch latency delivered, dispatch @​42 ms missed, dispatch @​8 ms
AB-B: recall settles synchronously (positive control, both arms) memory prompt present delivered @​1 ms delivered @​0 ms
AB-C: recall never settles memory absent; recall aborted at dispatch; dispatch latency absent, dispatch @​100 ms, abortedAtDispatch=false absent, dispatch @​0 ms
AB-D: parent abort @​20 ms during wait memory absent; recall aborted; dispatch < budget absent, dispatch @​21 ms absent, dispatch @​0 ms (abort bridge pre-existing)

Witnesses: 02-delivery-ab-head-bounded-wait.png, 03-delivery-ab-base-zero-wait-miss.png.
The AB-A row is the load-bearing flip — same harness, same environment, only
client.ts differs, and delivery goes absent → present. AB-C shows the budget is real
(dispatch at exactly the 100 ms timer, never early) and that a deadline miss does not
abort the recall, preserving the ToolResult path. One nuance: sampling
recallSignal.aborted at stream end reads true on both arms whenever the turn
produced no tool call — that is the pre-existing no_safe_delivery_point cleanup, not
a deadline abort; the assertion therefore samples at the dispatch seam.

Cron and ToolResult consume points pass waitMs = 0 (gate is
messageType === UserQuery ? 100 : 0 at the single consume site) — the claimed
zero-wait paths hold by construction; the prefetch itself is only created when managed
memory is available and enabled, so the wait cannot fire when the feature is off.

PR's own tests as A/B control

The HEAD test files were run verbatim against base source: 23 failed | 339 passed
(362)
on base vs 362/362 on head (04-pr-tests-on-base-23-red.png). The red set
is exactly the new behavior: 22 recall tests (every CJK/NFKC/gating/window case) plus
should inject auto-memory when recall settles inside the initial wait budget, whose
failure quotes the missing ## Relevant memory prompt in the first request — the
intended assertion, not an import/compile break. The other 339 (all pre-existing
behavior) are green on both arms — no collateral movement on the covered surface.

Scorer fallback A/B (secondary claim 1)

scorer-ab.mjs imports selectRelevantAutoMemoryDocuments from both dist builds and
runs 37 cells: the PR's 31 labeled cases plus six verifier-added siblings of the same
root cause — half-width Katakana (NFKC), a Kangxi radical (NFKC), an astral
Extension-B Han pair (code-point iteration), CJK punctuation splitting, a Latin
ligature inside a doc body, and an uppercase-ASCII regression guard.
Head 37/37; base wrong on 21 cells (witness 01-scorer-ab-37-cells-flip.png):
pure-CJK queries return [] on base (zero tokens), and no-match queries select up to 5
arbitrary non-empty-body docs on base (expected [] → got 5 docs), the exact
"selected because the body is non-empty" defect the design doc names. All sibling
shapes flip clean; no cell that base handled correctly regressed on head.

Timing ladder (200 docs = scanner cap, ~0.5 KB bodies, per rung):

query head base
2 k ASCII distinct tokens 5.3 ms 6.0 ms
5 k 3.3 ms 11.0 ms
20 k 3.6 ms 42.5 ms
20 k CJK 2.7 ms 0.1 ms (zero tokens, early exit)

Head is flat (the 64-token bound), base grows linearly with query token count — the
"bounded work" claim measured, not read. Query here is the local user's own prompt and
memory docs are user/project files, so this is a robustness bound rather than an
attacker-facing surface; the bound holds either way.

Vacuity and mutation matrix

Reverting is unnecessary as a separate step — the base-source run above is the
whole-hunk revert, and it fails the intended assertions (quoted above). Per-guard
mutations on head (mutation-matrix.sh, junit failure counts of the 42-test suite;
witness 05-mutation-matrix-6-of-6-killed.png):

mutation guard failures/42 verdict
unmutated control 0 green
M1 remove lexicalScore === 0 gate no-match gating 1 killed
M2 remove body .slice(0, 1200) window surfaced-window scoring 1 killed
M3 remove .normalize('NFKC') NFKC 1 killed
M4 disable bigram emission CJK bigrams 15 killed
M5 unbounded tokens (edgeSize = ∞) token bound 2 killed
M6 title weight 4→1 (positive control) field weighting 4 killed

No survivors; the positive control proves the suite can go red. The client-side wait
block is likewise load-bearing (its revert = base arm of the delivery A/B, where the
inject test and AB-A fail). The cancel-during-wait test passes on base too — it pins
cancel semantics that pre-date this PR and cannot discriminate the wait itself; the
delivery A/B cells AB-C/AB-D cover that axis instead. Noted for completeness, not a
defect.

Targeted gates (head)

  • vitest run src/core/client.test.ts src/memory/recall.test.ts: 362/362 (320 + 42).
  • npm run typecheck -w @qwen-code/qwen-code-core: clean. Liveness proven in both
    directions: the same gate reported 14 real errors when my scratch harness had unused
    imports, and exited 0 once they were removed.
  • eslint on the four changed files: clean; liveness proven with a planted
    no-unused-vars violation that was reported, then removed.

Reviewer Test Plan walkthrough

step status evidence
1. recall settles ≤100 ms → in first request verified AB-A (40 ms → delivered), PR inject test
2. pending >100 ms → proceeds, not aborted, ToolResult consumes once verified AB-C (dispatch @​100 ms, abortedAtDispatch=false), PR ToolResult-delivery test green
3. cancel during wait → wait ends, aborted, no stale delivery verified AB-D (dispatch @​21 ms, recall aborted, memory absent)
4. labeled multilingual fallback corpus verified scorer harness 37/37 incl. bounded work + edge preservation
5. model selector + active-tool filtering unchanged verified those tests green on both arms (unchanged code paths)

Findings

None. No blocking or advisory defects found. Specifically checked and not present:
wait firing when managed memory is disabled; waits on Cron/ToolResult paths; deadlock in
the wait's abort/settle race (worst case resolves via the promise's .then(finish));
listener leak (finish removes itself; the promise handler is bounded by recall
settling); scoring/window inconsistency (both the surfaced body window and the scoring
window are the same raw 1200-char prefix, NFKC applied after slicing on both sides);
regressions on previously-correct ASCII behavior (all English corpus cells green on
both arms).

Not covered

  • Per-commit attribution: checkout is depth 2; only the head commit ec0c746 is
    reachable, aa0bc54 is behind the shallow boundary (verified, not assumed:
    rev-list HEAD^1..HEAD^2 returns 1 commit vs 2 in the metadata snapshot). The
    aggregate HEAD^1..HEAD diff is what was verified. The two commit subjects map
    cleanly onto the two changes each A/B isolates (client.ts delivery vs recall.ts
    scoring), so the isolation loss is small.
  • End-to-end run against a real model selector endpoint (the model-primary path is
    unchanged by this PR; the heuristic fallback was exercised directly).
  • The PR's local-bundle E2E claim (MEMORY_PRESENT with a mock endpoint) was not
    replayed — superseded by the wire-seam delivery A/B above, which observes the same
    injection point.
  • Windows/macOS behavior (pure JS, no platform branches in the diff).
  • The 200-document candidate cap, explicitly out of scope per the PR description and
    design doc.
  • Per-commit vacuity of the second commit's hunks in isolation (same reason as
    attribution); the mutation matrix covers each guard individually instead.

Methodology

Environment: CI verify container (node v22.23.2, Linux), merge-ref checkout of
refs/pull/8716/merge at depth 2; npm ci + npm run build pre-run at HEAD. The
base control was a git worktree at HEAD^1 with packages/core recompiled via the
root tsc; compiled entry points were realpath-asserted into their own tree and
code-identity-grepped before use. Delivery harness: a verifier-authored vitest file
(byte-identical in both trees, scaffold copied from client.test.ts lines 1–706)
driving the real GeminiClient.sendMessageStream with a mocked Config/transport
environment — the unit under test (consume/wait wiring) runs unstubbed; oracles sample
the turn.run dispatch seam (request parts, latency, recall-signal state). Scorer
harness: direct import of the compiled selectRelevantAutoMemoryDocuments from both
trees. Mutation matrix: perl-applied single-point mutants, suite re-run, file restored
(diff-verified) after each. Raw logs in logs/ (scorer-ab.log, delivery-head.log,
delivery-base.log, prtests-on-base.log, mutation-matrix.log); harness scripts in
this directory; terminal witnesses in evidence/ captured via scripts/verify-capture.mjs.

Evidence images

01-scorer-ab-37-cells-flip

02-delivery-ab-head-bounded-wait

03-delivery-ab-base-zero-wait-miss

04-pr-tests-on-base-23-red

05-mutation-matrix-6-of-6-killed

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

Qwen Code · sandboxed verification

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

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

LGTM, looks ready to ship. ✅

@yiliang114 yiliang114 left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

The implementation paths look correct. I found one non-blocking test gap inline; it does not block merge.

Comment thread packages/core/src/core/client.test.ts Outdated
Rewrite the slow-recall test to assert with fake timers that the main
request is still held 1 ms inside the 100 ms initial budget and proceeds
without memory at expiry, so budget changes can no longer pass unnoticed.

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

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Reviewed. Suggestions are inline. 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.7)

Comment thread docs/design/2026-08-08-native-memory-recall-reliability.md Outdated
Comment thread packages/core/src/memory/recall.ts Outdated
Comment thread packages/core/src/core/client.test.ts Outdated
Comment thread packages/core/src/memory/recall.test.ts Outdated
Comment thread packages/core/src/core/client.ts
Comment thread packages/core/src/memory/recall.test.ts
Comment thread packages/core/src/core/client.ts Outdated
Comment thread packages/core/src/core/client.ts
Address review findings with mutation-verified pins:
- settle-early: bounded wait ends when recall settles, not at full budget
- Cron and ToolResult consume points stay zero-wait
- post-wait replacement guard refuses stale handles
- type boost flips the winner (tie-break no longer masks its removal)
- hiragana-only coverage for the CJK tokenizer
- design doc: RFC #7040 sets no numeric overhead target; fix attribution
@yiliang114

Copy link
Copy Markdown
Collaborator Author

Closeout for the automated review findings (addressed in 7a079d1):

Fixed (7) — each pin verified by mutation check (the corresponding regression turns the new test red):

  • bounded wait ends early when recall settles, not at the full budget (fake timers)
  • Cron consume point stays zero-wait
  • ToolResult consume point stays zero-wait
  • post-wait replacement guard refuses a handle swapped mid-wait
  • type-boost test rewritten so dropping the boost flips the winner (tie-break no longer masks it)
  • hiragana-only coverage added for the CJK tokenizer
  • design doc: RFC RFC: Reliable auto-memory recall — timing, quality, and telemetry #7040 sets no numeric overhead target; attribution corrected

Deferred (1) — tokenizer dedup against packages/channels/base: cross-package extraction is out of this PR's scope; replied in-thread, tracked as follow-up.

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

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Reviewed. Suggestions are inline. 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.7)

Comment thread packages/core/src/memory/recall.ts Outdated
Comment thread packages/core/src/memory/recall.ts
Comment thread packages/core/src/memory/recall.ts
@wenshao

wenshao commented Aug 8, 2026

Copy link
Copy Markdown
Collaborator

@qwen-code /triage

@qwen-code-ci-bot

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

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

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

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

Verification report

PR 8716 Deep Verification (round 2) — fix(memory): improve recall delivery and multilingual fallback

Verdict: merge-ready — 813 scripted assertions passed, 0 failed.
Verified head: 7a079d1fe598f54894f566022f646ec079ace157 (merge commit 5c84729d7c, base tip d91c66119b).

Assertion breakdown (all executed, none projected): head vitest gate 366; scorer A/B
corpus at head + base class checks 45; delivery A/B 8 (4 head cells + 4 base cells with
per-arm encoded expectations); PR test files against base source 366 (A/B control: the
observed red set of 25 is exactly the predicted new-behavior set, so every test matched
its encoded expectation); mutation matrix 16 (2 unmutated-green controls + 14 mutants
killed); gates 12 (typecheck clean, typecheck liveness, eslint clean, eslint liveness,
base-dist and head-dist code identity ×4, realpath isolation ×2, lockfile-untouched,
dist parity with the generated-file delta accounted).

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

本轮为跟进轮(上一轮在 head ec0c746 判定 merge-ready、零 findings;此后新增两个测试提交,base 也已前进),因此所有测量在新 head 7a079d1 上全部重跑,未沿用旧数据。

  • 结论merge-ready。813 项脚本化断言全部通过,0 失败。
  • A/B 结论(核心主张):同一 harness 下,head 的 100 ms 有界等待把「30 ms 内完成的 recall」从 base 的遗漏(dispatch @​8 ms 时无 memory)翻转为投递(dispatch @​32 ms 时首个模型请求携带 memory);永不 settle 的 recall 在 head 上等待 100 ms 后放行且不被中止abortedAtDispatch=false);等待期间父级 abort 使等待在 20 ms 提前结束且无过期投递。见 02-delivery-ab-head-bounded-wait.png / 03-delivery-ab-base-zero-wait-miss.png
  • A/B 结论(fallback 评分器):38 格标注语料(PR 的 32 格 + 验证器追加 6 个同根因兄弟形状)head 38/38 通过;base 错 22 格,且两个「有 token 但无词面匹配」查询在 base 上仍因「正文非空 +1」选中 5 个无关文档;无 base-正确格在 head 上回归。长查询计时阶梯 head 恒定 3.2–8.4 ms(64-token 上限),base 随 token 数超线性增长 78→839 ms。见 01-scorer-ab-corpus-flip.png
  • 增量提交的新 pin 全部突变验证:预算常数(100→50 与 100→150 双向杀灭)、settle-early 监听、等待后陈旧句柄守卫、Cron 零等待三元门、waitMs 默认 0、等待中的 abort 监听,以及 recall 侧词面门槛/窗口/NFKC/bigram/token 上限/type boost/平假名类别,共 14/14 突变体全部杀灭,0 存活,每个突变体恰好杀灭其归属测试。见 05-mutation-matrix-scripted-run.png
  • 测试非空洞:PR 测试文件在 base 源码上 25 红 | 341 绿,红集与预测的新行为集完全一致(2 个 client 等待测试 + 18 格语料 + 5 个 recall 单测),失败信息为行为性期望值不符;与 scorer 的 base OBSERVE 集合逐项吻合。见 04-pr-tests-on-base-red-set.png
  • 未覆盖:逐 commit 归因(浅克隆仅 1 个 PR commit 可达,快照为 4 个);真实模型 selector 端到端(未改动面);Windows/macOS(纯 JS 无平台分支);200 文档候选上限(PR 声明范围外);PR 自述的本地 bundle MEMORY_PRESENT E2E(已被线缝 A/B 取代)。

沙箱验证仅作为评审证据,不构成评审、批准或 CI 检查

Previous-round finding status (follow-up round)

The previous round (head ec0c746, merge 86311c7, base ee2e5be) shipped
merge-ready with zero findings, so there are no findings to carry forward. Its
measurements are carried forward not at all — head gained two commits (143a372
fake-timers budget pin; 7a079d1 mutation-verified pins + design-doc attribution fix)
and the base moved (ee2e5bed91c66119b), so the input closure changed and every
measurement below was re-run at the new head/base:

# previous-round measurement @​ ec0c746 status at 7a079d1
1 Delivery A/B: 40 ms settle delivered @​42 ms; never-settle held 100 ms, not aborted; abort ends wait @​21 ms stands — re-measured: 30 ms settle delivered @​32 ms; never-settle held 100 ms, not aborted; abort ends wait @​20 ms
2 Scorer corpus: head 37/37; base wrong on 21; bounded timing ladder stands — re-measured on a corpus grown to 38 cells (hiragana doc added by the PR itself): head 38/38; base wrong on 22; ladder flat on head (3.2–8.4 ms), superlinear on base (78→839 ms)
3 PR tests on base: 23 red = exact predicted new-behavior set stands — re-measured: 25 red = exact predicted set (+2 client wait tests added by the delta commits)
4 Mutation matrix: 6/6 killed, 0 survivors stands — re-measured and extended: 14/14 killed, 0 survivors (delta pins now included)
5 Gates: typecheck/eslint clean, liveness proven stands — re-measured clean with fresh liveness probes
6 Findings: none stands — none found this round either (see Findings)

Central claim and A/B proof

Central claim: the UserQuery initial request now waits up to 100 ms for an
in-flight managed-memory recall; a result settling inside the budget is injected into
the first model request; a deadline miss leaves the recall running (not aborted) for
the existing ToolResult delivery point. Secondary claims: (1) the selector-failure
fallback scorer handles CJK/mixed/NFKC queries and stops selecting lexically
non-matching documents; (2) cancellation during the bounded wait ends it early with no
stale delivery.

Control construction: git worktree add tmp/base-tree HEAD^1 (merge-ref checkout, so
HEAD^1 = base tip d91c66119b), packages/core rebuilt there with the repo's own
tsc (node_modules/typescript/lib/tsc.js --build), plus the gitignored
generated/git-commit.ts artifact regenerated with base-HEAD values. The PR touches no
package.json/lockfile (verified with git diff --exit-code), and the base tree
reuses the head's nested packages/core/node_modules (identical versions), so sharing
the root node_modules is a clean control. packages/core has no @qwen-code/*
dependencies; readlink -f on both dist entry points resolved inside their own trees,
so no workspace symlink could leak head code into the control. Emitted code identity
was asserted directly: base dist carries the old split(/[^a-z0-9]+/) tokenizer and no
INITIAL_MEMORY_RECALL_WAIT_MS/RECALL_TOKEN_RUN; head dist the inverse. The only
dist file-list delta was src/generated/git-commit.js (untracked codegen artifact,
display constants only).

Delivery A/B (verifier-authored cells, byte-identical file in both trees, run via the repo's vitest)

cell observable oracle head base
AB-A: recall settles after 30 ms memory prompt in first turn.run request; dispatch latency delivered, dispatch @​32 ms missed, dispatch @​8 ms
AB-B: recall settles synchronously (positive control, both arms) memory prompt present delivered @​0 ms delivered @​0 ms
AB-C: recall never settles memory absent; recall aborted at dispatch; dispatch latency absent, dispatch @​100 ms, abortedAtDispatch=false absent, dispatch @​0 ms
AB-D: parent abort @​20 ms during wait memory absent; recall aborted; dispatch < budget absent, dispatch @​20 ms, abortedAtDispatch=true absent, dispatch @​0 ms

Witnesses: 02-delivery-ab-head-bounded-wait.png, 03-delivery-ab-base-zero-wait-miss.png.
AB-A is the load-bearing flip — same harness, same environment, only client.ts
differs, delivery goes absent → present, and dispatch lands ~2 ms after settle (the
wait ends early, it does not run out the budget). AB-C shows the budget is real
(dispatch at the 100 ms timer, not earlier) and that a deadline miss does not abort
the recall, preserving the ToolResult path. AB-D bounds the abort path.

Cron and ToolResult consume points are zero-wait by construction and now pinned by
tests: the initial consume site sits inside the UserQuery || Cron branch and passes
messageType === UserQuery ? 100 : 0 (mutant C4 → Cron test red), the ToolResult site
relies on the waitMs = 0 default (mutant C6 → ToolResult test red) and is on a
branch the initial site never reaches.

PR's own tests as A/B control

The HEAD test files were run verbatim against base source: 25 failed | 341 passed
(366)
on base vs 366/366 on head (04-pr-tests-on-base-red-set.png). The red
set is exactly the new behavior, adjudicated by scripted membership checks: 2 client
tests (the fake-timers budget test — fails with expected "spy" to not be called at all, but actually been called 1 times, i.e. base dispatched inside the 99 ms hold;
and the settle-early test — fails quoting the missing ## Relevant memory prompt) +
18 corpus cases + 5 recall unit tests. The other 341 (all pre-existing behavior) are
green on both arms. The 18 red corpus cases match cell-for-cell the scorer's
independent base OBSERVE set — two instruments, one set. The remaining 4 new client
tests pass on base (cancel semantics and zero-wait paths pre-date the PR; their value
is mutation-pinning at head, verified below), which the red-set adjudication encodes
rather than assuming.

Scorer fallback A/B (secondary claim 1)

scorer-ab.mjs imports selectRelevantAutoMemoryDocuments from both dist builds and
runs 38 cells: the PR's 32 labeled cases plus six verifier-added siblings of the same
root cause (half-width Katakana via NFKC, a Kangxi radical via NFKC, an astral
Extension-B Han pair probing code-point iteration, CJK punctuation splitting, a Latin
ligature inside a doc body, and an uppercase-ASCII regression guard).
Head 38/38; base wrong on 22 cells (witness 01-scorer-ab-corpus-flip.png):
pure-CJK/hiragana/NFKC queries return [] on base (zero tokens), and the two
token-bearing no-match queries select 5 arbitrary non-empty-body docs on base
(No lexical match → body-only.md n=5, Unrelated English terms → body-only.md n=5)
— the exact "selected because the body is non-empty" defect. The four token-less
no-match queries return [] on both arms (base via a zero-token early exit, head via
the lexical gate — same outcome, different cause; both encoded). A scripted regression
guard confirms no base-correct cell regressed on head.

Harness note, for honesty: the first scorer run showed 2 FAILs, both adjudicated as
harness defects, not PR defects — one sibling fixture was ambiguous (a decoy doc
legitimately outscored the intended winner under the PR's own field weighting), and
the no-match class was over-encoded (expected all six to be non-empty on base when
only token-bearing queries exhibit the defect). Fixtures/encoding corrected, re-run
green; the pre-fix log is not the one cited.

Timing ladder (200 docs = scanner cap, ~0.5 KB bodies, min of 3):

query head base
2 k ASCII distinct tokens 3.2 ms 77.9 ms
5 k 3.9 ms 196.6 ms
20 k 8.4 ms 838.9 ms
20 k CJK 4.0 ms 0.05 ms (zero tokens, early exit)

Head is flat (the 64-token bound); base grows superlinearly in unique token count.
Input provenance is unchanged from the previous round: the query is the local user's
own prompt and memory docs are user/project files, so this is a robustness bound
rather than an attacker-facing surface; the bound holds either way.

Vacuity and mutation matrix

Whole-hunk revert is unnecessary as a separate step — the base-source run above is
the whole-hunk revert, and it fails the intended behavioral assertions (quoted above).
Per-guard single-point mutants on head, each with its own vitest run and
restore-verified (git diff --quiet after every mutant; witness
05-mutation-matrix-scripted-run.png; C6/C7 were run with the identical discipline):

mutation guard failures killed by
unmutated control (client, filtered) 0/323 green
unmutated control (recall) 0/43 green
C1 INITIAL_MEMORY_RECALL_WAIT_MS 100→50 budget constant 1 budget fake-timers test
C7 budget 100→150 budget constant (upward) 1 same test — the pin catches both directions
C2 drop handle.promise.then(finish, finish) settle-early wait exit 1 settle-early test
C3 drop pendingMemoryPrefetch !== handle re-check post-wait stale-handle guard 1 replaced-during-wait test
C4 ternary → always 100 Cron zero-wait gate 1 Cron test
C5 drop abort listener in wait cancel ends wait 1 cancel-during-wait test
C6 waitMs default 0→100 ToolResult zero-wait default 1 ToolResult zero-wait test
R1 drop lexicalScore === 0 gate no-match gating 1 type-boost test's "keyword alone ⇒ []" assertion
R2 drop body .slice(0, 1200) surfaced-window scoring 1 window test
R3 drop .normalize('NFKC') NFKC 1 NFKC full-width API case
R4 disable bigram emission CJK bigrams 16 all pure-CJK/hiragana cases + bounds
R5 unbounded edgeSize token bound 2 bounds + tail-refresh
R6 drop typeBoost type boost flips winner 1 type-boost flip test
R7 drop \p{Script=Hiragana} class hiragana coverage 1 hiragana-only case

14/14 killed, 0 survivors, positive controls green. Every delta-commit pin claim
("settle-early", "Cron and ToolResult stay zero-wait", "post-wait replacement guard",
"type boost flips the winner", "hiragana-only coverage", "budget changes can no longer
pass unnoticed") is independently mutation-verified — including the four new client
tests that pass on base: each is pinned against a head-only mutant, which is exactly
the shape a regression pin should have. Attribution check: each mutant killed exactly
its named test (R4/R5 the cases that exercise the removed mechanism); no mutant killed
an unrelated test, and no shared-name pre-existing test went red under any mutant.

Targeted gates (head)

  • vitest run src/core/client.test.ts src/memory/recall.test.ts: 366/366
    (323 + 43).
  • tsc --noEmit (packages/core): clean. Liveness proven twice: it reported the real
    TS6133/TS6192 diagnostics of my scratch harness (exit 2) before the harness was
    removed, and a planted number = 'string' probe file produced its diagnostic and
    was removed; the post-removal run is exit 0.
  • eslint on the four changed files: clean; liveness proven with a planted unused-var
    that was reported, then removed.
  • Base-control hygiene gates (counted above): lockfile untouched, dist code identity
    on both arms, realpath isolation, file-list parity modulo the generated artifact.

Reviewer Test Plan walkthrough

step status evidence
1. recall settles ≤100 ms → in first request verified AB-A (30 ms → delivered @​32 ms), PR inject tests green
2. pending >100 ms → proceeds, not aborted, ToolResult consumes once verified AB-C (dispatch @​100 ms, abortedAtDispatch=false), PR ToolResult-delivery test green incl. the new recallSignal.aborted === false assertion
3. cancel during wait → wait ends, aborted, no stale delivery verified AB-D (dispatch @​20 ms, recall aborted, memory absent) + cancel-during-wait test (kills C5)
4. labeled multilingual fallback corpus incl. bounded work, edges, empty for unrelated/single-char verified scorer 38/38 + ladder + bounds/refresh/window unit tests
5. model selector + active-tool filtering unchanged verified those shared-name tests green on both arms; the diff touches only the wait block and the heuristic scorer

Findings

None. No blocking or advisory defects found. Specifically checked and not present:
wait firing when managed memory is disabled (prefetch only created when available +
enabled); waits on Cron/ToolResult paths (ternary + branch structure + mutants C4/C6);
stale handle consumed after a mid-wait replacement (guard + C3); deadlock in the
wait's abort/settle race (worst case resolves through the promise's .then(finish));
listener leak (finish removes itself; the promise handler is bounded by recall
settling); scoring/window inconsistency (surfaced window and scoring window are the
same raw 1200-char prefix, NFKC applied after slicing on both sides); regressions on
previously-correct ASCII behavior (scripted no-regression guard over the corpus);
upward budget drift (C7).

Not covered

  • Per-commit attribution: checkout is depth 2; git rev-list HEAD^1..HEAD^2
    returns 1 commit locally vs 4 in the metadata snapshot (verified with
    rev-parse --is-shallow-repository = true, not assumed). The aggregate
    HEAD^1..HEAD diff is what was verified. The delta commits' subjects map cleanly
    onto the pins the mutation matrix now verifies individually, so the isolation loss
    is small.
  • End-to-end run against a real model selector endpoint (the model-primary path is
    unchanged by this PR; the heuristic fallback was exercised directly).
  • The PR's local-bundle E2E claim (MEMORY_PRESENT with a mock endpoint) was not
    replayed — superseded by the wire-seam delivery A/B, which observes the same
    injection point.
  • Windows/macOS behavior (pure JS, no platform branches in the diff).
  • The 200-document candidate cap, explicitly out of scope per the PR description and
    design doc.
  • Harness incident, fully recovered: the first mutation-matrix run was invalid
    its git checkout restore used a cwd-relative path, so restores silently failed and
    mutations accumulated (visible in the monotone failure counts). Detected via the
    script's own restore checks, the log was quarantined
    (mutation-matrix-v1-INVALID-accumulated.log), the tree restored and verified
    clean, and the matrix re-run with a hard-abort restore guard. No v1 number is cited
    anywhere in this report. This is a verifier-harness defect, not a PR issue.
  • Environmental note: a direct tsc --build of packages/core reports one TS7016
    declaration error in the untouched shellExecutionService.ts (@lydell/node-pty
    exports resolution in the shared root node_modules); emission was unaffected and
    the repo's own tsc --noEmit gate is clean at head, so this is recorded as an
    environment artifact, not a PR regression.

Methodology

Environment: CI verify container (node v22.23.2, Linux), merge-ref checkout of
refs/pull/8716/merge at depth 2; npm ci + npm run build pre-run at HEAD. The
base control was a git worktree at HEAD^1 with packages/core recompiled via the
repo's own tsc and the gitignored generated/git-commit.ts regenerated with base
values; compiled entry points were realpath-asserted into their own tree and
code-identity-grepped before use. Delivery harness: a verifier-authored vitest file
(byte-identical in both trees; scaffold = client.test.ts lines 1–706 plus
verifier cells with runtime arm detection) driving the real
GeminiClient.sendMessageStream with the scaffold's mocked Config/transport
environment — the unit under test (consume/wait wiring) runs unstubbed; oracles sample
the turn.run dispatch seam (request parts, latency, recall-signal state) and write
per-cell JSONL records. Scorer harness: direct import of the compiled
selectRelevantAutoMemoryDocuments from both trees. Mutation matrix: perl-applied
single-point mutants, vitest junit parsed by parse-junit.mjs, file restored and
git diff --quiet-verified after each (hard abort otherwise). All logs were then
cross-checked by adjudicate.mjs (56 scripted checks: red-set membership, encoded
totals, required-red presence, matrix kill/total invariants, delivery cell ranges) —
56/56 pass. Raw logs in logs/ (delivery jsonl + vitest logs, scorer-ab.log,
prtests-on-base.log, mutation-matrix.log + quarantined v1, adjudication.log,
gate logs, test-name lists); harness scripts in this directory; terminal witnesses in
evidence/ captured via scripts/verify-capture.mjs.

Evidence images

01-scorer-ab-corpus-flip

02-delivery-ab-head-bounded-wait

03-delivery-ab-base-zero-wait-miss

04-pr-tests-on-base-red-set

05-mutation-matrix-scripted-run

06-adjudication-cross-checks

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

Qwen Code · sandboxed verification

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

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

LGTM, looks ready to ship. ✅

@wenshao

wenshao commented Aug 8, 2026

Copy link
Copy Markdown
Collaborator

Local verification on a real stack

I built both sides and ran the real CLI against a recording OpenAI-compatible provider, rather than relying on the unit suite alone.

Setup — base 7b7ff19 (merge-base) and head 7a079d1, each npm ci + npm run build + npm run bundle in its own worktree; every run uses that tree's own dist/cli.js (a bundle-integrity gate asserts the shipped constant, the settle listener and the tokenizer regex before any scenario runs — I had one contaminated bundle early on and this catches it). Each run gets a throwaway project with QWEN_CODE_MEMORY_LOCAL=1, an isolated HOME/QWEN_HOME, and a mock provider that classifies each /chat/completions call as the recall selector or the agent's own turn, delays or fails the selector on demand, and records arrival timestamps plus whether the payload carried a ## Relevant memory block. 3 runs per cell.

1. Delivery behaviour

e2e

scenario base 7b7ff19 head (this PR)
A · recall settles in 30 ms, tool-free turn never delivered (0/3, and 0/7 on a 7× repeat) delivered in the first request (7/7 on the repeat)
B · recall settles in 400 ms, turn has a tool call first request no, ToolResult turn yes (3/3) identical (3/3) — late-delivery semantics unchanged
C · selector fails, Chinese query never delivered correct memory delivered, first request (3/3)
D · selector fails, query with no lexical match injects all three unrelated memories injects nothing (3/3)
E · recall settles instantly never delivered delivered in the first request (3/3)
F · project has no memories no selector call, no delivery identical

A and E are the bug this PR is about: on base, a recall that resolves a few tens of ms after the turn starts is simply dropped when the turn has no tool call, and it stayed dropped in 0/10 attempts. D is the fallback's other defect — every non-empty document scored, so an unrelated query pulled three memories into the prompt.

2. The deterministic fallback, side by side

Compiled recall.js from each tree, same corpus, same queries:

fallback

Base returns nothing for any CJK query (the ASCII tokenizer produces zero tokens) and returns the entire corpus for queries that match nothing. Head returns the expected document in every case, and an empty list for the negative cases including single-character CJK.

3. Latency cost

Measured as the gap between the recall side-query hitting the provider and the turn's first request hitting it (median of 3):

case base head added
recall settles instantly (E) −3 ms +36 ms ~39 ms — the wait ends on settle, not at the budget
recall settles in 30 ms (A) −8 ms +69 ms ~77 ms
recall never settles in time (B) −10 ms +79 ms ~89 ms — budget expiry
project has no memories (F) no recall call at all same 0

So the early-exit path is real: a fast recall costs roughly its own latency, not the full budget, and the worst case stays inside the advertised 100 ms. Projects with no memories pay nothing.

4. Tests and mutation checks

tests

recall.test.ts 43/43 and client.test.ts 323/323 pass on head. To check the new tests actually pin the behaviour rather than just executing it, I applied five deliberate regressions to the PR source and re-ran: dropping the budget to 0 fails 2 tests, removing the settle listener fails 1, removing the post-wait stale-handle guard fails 1, restoring the pre-PR "non-empty body scores" rule fails 3, and reverting the tokenizer to ASCII-only fails 16. Nothing silently survived.

Notes for the merge decision

  • The fallback is only reached when the selector fails quickly. My first attempt injected HTTP 500 and the fallback never ran — the provider client treats 5xx as retryable and retried ~460 ms later, outliving a short turn. With a 400 the fallback runs immediately. This is pre-existing behaviour, not something this PR changes, but it does mean the "selector failure" fallback is less reachable in practice than the tests suggest.
  • A deadline miss on a tool-free turn is still a total miss. That is the documented design, and it is strictly better than base, but under machine load one of ten A-runs missed the 100 ms budget and — with no tool call to provide a later delivery point — delivered nothing. The budget buys a large improvement, not a guarantee.
  • Not covered here: cancellation during the bounded wait (unit tests only), Windows/Linux, and the 200-document candidate cap, which the PR explicitly leaves out of scope.

Behaviour matches what the description claims, the regression surface I probed is clean, and both defects reproduce on base and are fixed on head. No blocking findings from my side.

中文版本

本地真实环境验证

我没有只跑单测,而是把两侧都完整构建出来,用真实 CLI 打一个会记录请求的 OpenAI 兼容 mock provider。

环境 — base 7b7ff19(merge-base)与 head 7a079d1,各自独立 worktree 里 npm ci + npm run build + npm run bundle,每次运行都用该树自己的 dist/cli.js;跑任何场景前有一道 bundle 完整性校验,断言产物里确实带着本 PR 的常量、settle 监听和分词正则(我中途确实拿到过一个被污染的 bundle,就是靠这道闸发现的)。每次运行都是一次性的项目目录,QWEN_CODE_MEMORY_LOCAL=1,隔离的 HOME/QWEN_HOME;mock provider 会区分 recall selector 请求和主回合请求,按需延迟或让 selector 失败,并记录到达时间以及请求体里是否带 ## Relevant memory。每格 3 次运行。

1. 投递行为

场景 base 7b7ff19 head(本 PR)
A · recall 30 ms 返回,回合内无工具调用 从未投递(0/3,7 次重复也是 0/7) 首个请求即投递(重复 7/7)
B · recall 400 ms 返回,回合有工具调用 首个请求无,ToolResult 回合有(3/3) 完全一致(3/3),后续投递语义未变
C · selector 失败,中文 query 从未投递 首个请求投递正确 memory(3/3)
D · selector 失败,无词面匹配 注入全部三条无关 memory 不注入任何内容(3/3)
E · recall 立即返回 从未投递 首个请求即投递(3/3)
F · 项目没有任何 memory 不发 selector 请求,也无投递 一致

A 和 E 就是本 PR 要修的问题:base 上只要 recall 比回合起步晚几十毫秒,而该回合又没有工具调用,结果就被直接丢掉,10 次尝试全丢。D 则是 fallback 的另一个缺陷 —— 只要文档正文非空就有分数,于是完全无关的 query 也会把三条 memory 塞进 prompt。

2. 确定性 fallback 对比

用两棵树编译产物里的 recall.js,同一份语料、同一批 query:base 对任何 CJK query 都返回空(ASCII 分词器切不出 token),对无匹配 query 则返回整个语料;head 每个用例都返回预期文档,负例(含单字 CJK)返回空。

3. 延迟代价

以「recall side-query 到达 provider」到「本回合首个请求到达 provider」的间隔衡量(3 次中位数):

情况 base head 增量
recall 立即返回(E) −3 ms +36 ms 约 39 ms —— 等待在 settle 时结束,不是等满预算
recall 30 ms 返回(A) −8 ms +69 ms 约 77 ms
recall 超时未返回(B) −10 ms +79 ms 约 89 ms —— 预算到期
项目无 memory(F) 根本不发起 recall 一致 0

也就是说提前退出这条路是真的生效的:快 recall 只花它自己的耗时,不会等满预算,最坏情况仍在承诺的 100 ms 以内;没有 memory 的项目零代价。

4. 测试与变异验证

head 上 recall.test.ts 43/43、client.test.ts 323/323 通过。为确认新测试是真的「钉住」行为而不只是走一遍代码,我对 PR 源码注入了五处故意的回归再重跑:预算改 0 挂 2 条,去掉 settle 监听挂 1 条,去掉等待后的 stale-handle 守卫挂 1 条,恢复改前「正文非空即得分」挂 3 条,分词器退回纯 ASCII 挂 16 条。没有一处被静默放过。

合并前需要知道的几点

  • fallback 只有在 selector 快速失败时才走得到。 我最初注入 HTTP 500,结果 fallback 根本没跑 —— provider 客户端把 5xx 当可重试,约 460 ms 后重试,直接活过了整个短回合。换成 400 才会立刻进 fallback。这是既有行为、不是本 PR 引入的,但意味着「selector 失败」这条路在实际中比测试看上去更难触发。
  • 无工具调用回合上的预算 miss 仍然是彻底 miss。 这是设计上写明的,且明显优于 base;但在机器有负载时,A 场景 10 次里有 1 次没赶上 100 ms 预算,而该回合没有工具调用可作为后续投递点,于是什么都没投递。预算带来的是大幅改善,不是保证。
  • 本次未覆盖: 有界等待期间的取消(仅有单测)、Windows/Linux,以及 PR 明确排除在范围外的 200 文档候选上限。

行为与描述一致,我探到的回归面是干净的,两个缺陷在 base 上都能复现、在 head 上都已修复。我这边没有阻塞性发现。

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

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

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

Test Plan (not a blocker): src/memory/recall-eval.test.tsno such file or directory; src/memory/recall-delivery-eval.test.tsno such file or directory; src/memory/recall.test.tsno such file or directory; src/memory/relevanceSelector.test.tsno such file or directory; src/memory/memoryLifecycle.integration.test.tsno such file or directory; and 1 more.

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

  • packages/core/src/memory/recall-delivery-eval.test.ts:227 — [review] anyDeliveryRate docstring claims relevant-doc delivery; the metric counts any delivery
  • packages/core/src/telemetry/types.ts:1607 — [review] phase docstring says when a result reached the model; discard events hardcode phase:'refined' and strategy:'none' is unenumerated
  • packages/core/src/memory/recall-delivery-eval.test.ts:353 — [review] expect(p50).toBeLessThanOrEqual(p95) is a tautology; probe-confirmed defect variants keep it green
中文说明

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

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

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

Test Plan(非阻断):src/memory/recall-eval.test.tsno such file or directory; src/memory/recall-delivery-eval.test.tsno such file or directory; src/memory/recall.test.tsno such file or directory; src/memory/relevanceSelector.test.tsno such file or directory; src/memory/memoryLifecycle.integration.test.tsno such file or directory; and 1 more。

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

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

@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 — ran all 5 rounds (cap) without two consecutive dry rounds; rounds 1-4 kept reporting candidates that verification confirmed or dropped as re-reports of existing threads.

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 on Linux only.

Test Plan (not a blocker): src/memory/recall-eval.test.tsno such file or directory; src/memory/recall-delivery-eval.test.tsno such file or directory; src/memory/recall.test.tsno such file or directory; src/memory/relevanceSelector.test.tsno such file or directory; src/memory/memoryLifecycle.integration.test.tsno such file or directory; and 1 more.

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

  • packages/core/src/core/client.ts:929 — [probe] Cron turns can synchronously inject the deterministic fast memory result
  • packages/core/src/memory/recall-delivery-eval.test.ts:45 — [probe] RECALL_AT hand-mirrors unexported MAX_RELEVANT_DOCS with no comment or import
  • packages/core/src/memory/__fixtures__/auto-memory-recall-eval.json:377 — [probe] NFKC halfwidth-katakana composition axis pinned by no test
  • packages/core/src/memory/__fixtures__/auto-memory-recall-eval.json:63 — [probe] Placeholder-body strip (_No entries yet._) pinned by no eval case
  • packages/core/src/memory/recall-delivery-eval.test.ts:276 — [probe] Delivery table prints two structurally identical first-turn rows as distinct metrics
  • packages/core/src/memory/recall-eval.test.ts:350 — [probe] maxSelectedDocs floor cannot pin the production selection cap
  • packages/core/src/memory/__fixtures__/auto-memory-recall-eval.json:363 — [probe] Pure-ASCII query categorized 'mixed' dilutes the mixed-script slice
  • packages/core/src/memory/recall-delivery-eval.test.ts:227 — [probe] anyDeliveryRate docstring claims 'relevant document' but the metric counts any delivered doc
中文说明

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

未审查:reverse audit — ran all 5 rounds (cap) without two consecutive dry rounds; rounds 1-4 kept reporting candidates that verification confirmed or dropped as re-reports of existing threads。

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

Test Plan(非阻断):src/memory/recall-eval.test.tsno such file or directory; src/memory/recall-delivery-eval.test.tsno such file or directory; src/memory/recall.test.tsno such file or directory; src/memory/relevanceSelector.test.tsno such file or directory; src/memory/memoryLifecycle.integration.test.tsno such file or directory; and 1 more。

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

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

@yiliang114

Copy link
Copy Markdown
Collaborator Author

Follow-up issues filed for the deferred items from the review rounds, so nothing is silently dropped:

The remaining round-9 deferred items are test-harness polish (docstring wording, tautological assertion, hand-mirrored constants) recorded in the review ledger above and intentionally not blocking per the convergence posture.

Three review follow-ups on the recall reliability change.

Tie-break: `selectRelevantAutoMemoryDocuments` broke score ties with
`type.localeCompare`, which orders feedback < project < reference < user.
That was tolerable while the result was five documents wide; the fast path
takes only MAX_FAST_RECALL_DOCS = 2, so a tied user-typed document was
dropped every time — the exact memory a tool-free turn exists to surface.
Ties now fall to recency, then to input order, which keeps the
project-before-user precedence the concatenation already establishes.

Corpus: the case labeled `semantic-no-lexical` had no relevant documents,
so it was a no-result case wearing the wrong label and nothing measured the
cost of "no lexical match, no score". Relabel it and add three genuine
answerable-but-lexically-disjoint cases. Both scorers return nothing for
them, so the slice sits outside the quality floor and is asserted
separately: the fast path closes the timing gap, not the matching gap.
Tool-free delivery is 92.3%, not 100%, and the residual is that slice.

Telemetry: a tool-free turn logs its terminal event from the discard path,
which did not apply the fast-phase exclusion. A turn whose every selected
document had already been fast-delivered was recorded as
`no_safe_delivery_point`, inflating the "memory never reached the model"
bucket with turns that got it. Apply the same rule the ToolResult consume
point uses; a partial overlap still reports the cancellation reason.
… count

Two review follow-ups, documentation only. No behaviour change.

"Removes the 200-document cap" oversold the candidate change. What it does
is swap a per-scope, query-blind recency truncation for a global,
query-aware one, and the effect is not a uniform widening: at or under 200
documents nothing was excluded by count under either design, but the new
25,000-byte manifest budget is a ceiling the old path lacked; between 200
and 400 with neither scope over 200 the old path sent every document and
the new one sends at most 200, so fewer reach the model; only a scope over
200 is the case the change is actually for. Record all three, plus the fact
that the manifest budget packs rather than prefixes.

MAX_RELEVANT_DOCS = 5 bounds one prompt, not one turn. A fast delivery of
two plus a refined delivery of five disjoint documents puts seven in front
of the model; dedupe removes repeats, not the sum. This follows from
dropping combined fast/refined budget accounting, which was a deliberate
choice, but the number was never written down next to the constant that
reads like a hard cap.
…kenization

The 100 ms initial budget was a fixed cost, and the evidence for it measured
the wrong thing. Deterministic *scoring* is microseconds, but the fast result
is only published once recall has enumerated, read, and parsed the memory
tree — and this branch removed the 200-document cap for recall, so that scan
grows with the tree. recall-scan-latency.test.ts adds that measurement
against a real temporary tree: ~29 ms at 200 topics, ~70 ms at 500, ~130 ms
at 1000.

So for any tree small enough to scan in time — the ordinary case — the fast
result was in hand tens of milliseconds before the budget expired, and the
rest of the budget was spent waiting on a model selector this design already
assumes will miss it. The wait now ends on whichever comes first: recall
settling, the fast result being published, cancellation, or the ceiling. The
preference order is unchanged, because the code after the wait still prefers
a settled recall. Past roughly a thousand topics the scan alone exceeds the
ceiling and the turn pays the full budget for nothing; that is recorded as a
known limitation rather than fixed, since the fix is a persistent catalog.

Tokenization kept only [a-z0-9]{3,} runs, so Cyrillic, Greek, Arabic, and
accented Latin produced no tokens at all and the deterministic path was
unconditionally silent for them. Keep whole runs of non-CJK letters, marks,
and digits instead. CJK is excluded per character rather than by alternation
order: \p{L} also matches Han, so a Latin-initial run would otherwise swallow
the CJK after it and turn abc漢字 into one token. Scripts without word
separators outside the CJK set still collapse to one run, which is recorded
rather than claimed as segmentation.

Two smaller follow-ups. The active-tool alias set is now derived once per
recall instead of once per scanned document, which mattered little under the
old 200-document cap and more without it. And the eval prints the Recall@5 a
query-blind random scorer would score on this corpus (20%), with a test
holding that floor at or below 25%, because a small corpus flatters every
design and the headline was unreadable without it.
@yiliang114

Copy link
Copy Markdown
Collaborator Author

Summary: what this solves, how, and what it touches

Posting a roll-up now that the review follow-ups have landed (8a5a524, d2598bd, 01ef7d7).

The problem

Two independent failures, both of which made managed memory unreliable rather than merely imperfect.

Selected memory did not reach the model. Recall starts asynchronously on UserQuery, and the initial request consumed it with a zero-wait poll — so memory made it into the first prompt only when the timing happened to work out. When it didn't, delivery fell through to the ToolResult point, which a turn that makes no tool call never reaches; the result was discarded as no_safe_delivery_point. Tool-free turns are the short, context-answered questions where user-level memory matters most, so the failure was concentrated exactly where the feature was supposed to pay off.

Selection itself was broken outside ASCII, and too permissive inside it. The deterministic scorer tokenized only [a-z0-9]{3,}, so an ordinary Chinese query produced no tokens at all. It also gave every non-empty document a positive score, so with no lexical match whatsoever it would still return documents. Separately, topics were truncated to the 200 most recent per scope before relevance was considered, so an old but relevant document was permanently invisible.

The solution

Delivery. One recall lifecycle and model-primary selection, with a single deterministic stage in front of it — deliberately not RFC #7040's original two-result shared-scan architecture, whose cross-phase bookkeeping is the source of the duplicate-injection bug class the RFC itself warned about. selectModelCandidateDocuments already computes lexically ranked candidates to build the model manifest, so the fast result reuses them at no extra scan or I/O and is capped at two documents. Recall stays alive afterwards, so the model-selected result still lands at ToolResult with the fast-delivered documents excluded and the prompt rebuilt from the remainder.

The initial wait is a ceiling, not a fixed cost — it ends on whichever comes first: recall settling, the deterministic result being published, cancellation, or 100 ms. That detail turned out to matter more than expected; see the measurement below.

Selection. NFKC normalization; whole-run tokens for non-CJK letters (\p{L}-based, so Cyrillic, Greek, Arabic, and accented Latin work); code-point bigrams for CJK runs; no score without a lexical match; title and description weighted above body; ties broken by recency rather than by document type. The per-scope 200-document recency truncation is replaced, for recall only, by a global query-aware candidate set with a recency reserve and a bounded manifest.

What the measurements changed about the design

The original evidence cited deterministic scoring latency (~0.03 ms) as proof the budget was cheap. That measured the wrong thing. The fast result is only published once recall has enumerated, read, and parsed the memory tree — and this PR removed the 200-document cap for recall, so that scan grows with the tree. recall-scan-latency.test.ts measures it against a real temporary tree:

topics median time to fast result share of the 100 ms ceiling
200 ~29 ms ~29%
500 ~70 ms ~70%
1000 ~130 ms ~130%

At 1000 topics the split is ~140 ms scan against ~8 ms ranking, so the scan is the whole story. Two conclusions followed. For an ordinary tree the fast result was in hand tens of milliseconds before the ceiling and the rest of the budget was spent waiting on a selector this design already assumes will miss it — which is why the wait now ends on the fast result. Past roughly a thousand topics the scan alone exceeds the ceiling, so the turn pays the full budget and delivers nothing; that is recorded as a known limitation rather than fixed, since the real fix is a persistent catalog and that stays out of scope.

Impact assessment

Who is affected. Only sessions with managed auto-memory enabled and at least one memory topic. With memory off or the tree empty there is no pending prefetch and no wait, so the path is inert.

What is deliberately not affected. The scan.ts change is purely additive — scanAutoMemoryTopicDocuments and scanUserAutoMemoryTopicDocuments keep their 200-document cap, so Forget, Indexer, Status, Extraction, DREAM, and Team memory are untouched. relevanceSelector.ts is recall-only. In client.ts the wait applies to SendMessageType.UserQuery alone; Cron, Retry, Notification, Teammate, and ToolResult all pass a zero budget.

Latency. Previously zero added latency. As originally written this PR added up to a fixed 100 ms to every UserQuery turn with memory enabled. As it stands now it adds the scan time — single-digit milliseconds for a typical tree of tens of topics, ~29 ms at 200 — bounded at 100 ms.

User-visible behaviour changes.

  • Memory now reaches the first prompt on tool-free turns. This is the point of the change, and it means the model sees user memory on turns where it previously saw none.
  • A turn can now surface up to seven documents (two fast plus five refined) where the constant MAX_RELEVANT_DOCS = 5 suggests five. Dedupe removes repeats, not the sum; this follows from dropping combined budget accounting and is documented next to the constant.
  • CJK, Cyrillic, Greek, Arabic, and accented-Latin queries now match where they previously could not.
  • Fewer irrelevant memories. Requiring a lexical match means vague queries that previously pulled in arbitrary non-empty documents now return nothing. This is a correctness fix, but it is a reduction in injected memory and will be visible as such.
  • Old-but-relevant documents beyond the per-scope 200 are now reachable. Note the converse: for a pool between 200 and 400 documents with neither scope over 200, fewer candidates reach the selector than before, since the union is re-bounded at 200.

Observability. MemoryRecallDiscardReason gains already_delivered, recorded on every discard path — not only at ToolResult — whenever the fast phase already delivered every selected document, so the no_safe_delivery_point bucket stops counting turns that did get their memory. phase (fast/refined) and strategy (none/heuristic/model) remain orthogonal.

Known limitations, stated rather than hidden. The fast result carries no model judgement. Queries sharing no token with their document produce nothing on the deterministic path, so a tool-free turn asking one still gets nothing — the semantic-no-lexical slice measures this at 0% for both the shipped and the pre-change scorer, which is why the headline delivery figure is 92.9% rather than 100%. Scoring is substring-based (owner matches inside ownership). Past ~1000 topics the scan exceeds the ceiling. Thai, Khmer, and Lao now produce a token where they produced none, but the token is the whole run, which is not segmentation.

Rollback. No migration, no persisted state, no new dependency, no new public setting. A revert is clean.

Verification

packages/core src/memory/ plus src/core/client.test.ts: 928 passed on Linux. The one failure, team-memory-sync.test.ts > unstages the team path when the commit fails, reproduces on the untouched branch head and is a sandbox git-hook environment issue. eslint clean; tsc --noEmit -p packages/core reports only the pre-existing sharp SharpConstructor error in src/utils/image-view.ts.

@wenshao

wenshao commented Aug 18, 2026

Copy link
Copy Markdown
Collaborator

Local verification on a real stack — head 01ef7d7dc4

I rebuilt both sides and drove the shipped CLI bundle against a recording OpenAI-compatible provider with a real .qwen/memory tree on disk, rather than reading the unit suite alone. This re-verifies the PR after the commits that landed since my previous run on 6085ef08a5a524 (recency tie-break, already_delivered on every discard path) and 01ef7d7d (end the initial wait on the fast result, widen tokenization).

Setup. base 9a5b07c0b1 (merge-base) and head 01ef7d7dc4, each npm install + npm run build + npm run bundle in its own worktree; every run uses that tree's own dist/cli.js. A bundle-integrity gate runs first: head carries onFastResult / fastDeliveredPaths / already_delivered / the Script=Hiragana token class, base carries none of them. Each run gets a throwaway project with QWEN_CODE_MEMORY_LOCAL=1, an isolated HOME and QWEN_CODE_MEMORY_BASE_DIR, and a fixture corpus written as real topic files with controlled mtimes. The provider identifies the recall side query by its Available memories: marker and can delay or fail it independently of the main loop; the main-loop reply echoes back which ## Relevant memory documents that very request carried, so the transcript states the delivery outcome itself. Three judgement surfaces per run: the provider request ledger (what the model actually received, with arrival timestamps), qwen-code.memory.recall{,.delivery} from the local-file telemetry exporter, and the TUI.

1. Delivery

delivery matrix

Same query, same memory tree, same provider, tool-free first turn — base leaves the first prompt empty, head delivers:

TUI A/B, English

The Chinese case is the one the pre-change tokenizer could not produce a token for at all:

TUI A/B, Chinese

Point by point, from the ledger and telemetry:

  • Tool-free turn, selector above the budget. base: nothing on the initial request, recall settles with 3 model-selected documents, discarded no_safe_delivery_point. head: phase=fast, delivery_point=initial, strategy=heuristic, docs_selected=2, latency_ms=32, and the two documents are in the first request body.
  • Dedupe. On a tool-using turn head's second request carries two memory blocks — the fast pair, then a refined block containing only release-checklist.md, the one document not already delivered (refined / tool_result / model / docs_selected=1). No document appears twice. base delivers all three in one block at tool_result.
  • already_delivered accounting. When the selector re-picks exactly the fast documents, head records already_delivered where base records no_safe_delivery_point. On a partial overlap (3 selected, 2 fast-delivered) head correctly keeps the cancellation reason.
  • Scorer precision. Selector failed, query sharing no token with anything: base delivered 5 irrelevant documents; head delivered nothing (no_relevant_results).
  • Scorer tokenization. Selector failed, Chinese query: base strategy=none, docs_selected=0 — the query produced zero tokens; head selected cjk-deploy.md.
  • Candidate coverage. 251 documents in one scope with the only lexical match the oldest: base's manifest is 200 lines and the target is absent; head's manifest is 96 lines and the target is line 1, then delivered.

2. Cost, and two single-line mutations of the shipped bundle

latency and mutations

n = 5 runs per arm, medians. Measuring the gap between the selector request and the main request at the provider cancels CLI start-up noise, which is ~1.2 s and would otherwise swallow a 100 ms budget.

arm main req − selector req fast-delivery latency_ms end-to-end vs base
base, query matches −4 ms n/a
head, query matches +1 ms 31 ms +39 ms
head, no lexical match +79 ms n/a +82 ms
head with the early exit removed +78 ms 124 ms +76 ms
empty memory tree n/a no measurable cost

Both mutations are one-line edits to head's own bundle, so nothing else moves:

  • handle.fastResultRef.onArrive = finish= void 0 (the behaviour before 01ef7d7d): the wait runs to the ceiling, fast delivery latency goes 31 ms → 124 ms. The early exit is doing exactly what the commit message claims.
  • b.doc.mtimeMs - a.doc.mtimeMsa.doc.type.localeCompare(b.doc.type): with three documents tied on score the fast result flips from tie-user.md, tie-reference.md to tie-project.md, tie-reference.md — the user document is dropped, which is the failure the tie-break comment describes.

3. Observations for the reviewer

None of these are defects; they are consequences worth having on the record before merge.

  1. On a tool-free turn the selector's judgement effectively never reaches the first prompt once the deterministic scorer matches anything. onFastResult fires immediately before the selector request is issued, so handle.settledAt is still null when the wait ends and the "prefer a settled recall over the fast result" branch below it is unreachable. Measured with the selector settling in 15 ms — comfortably inside the budget — head still injects the heuristic pair and discards the model's two picks as no_safe_delivery_point; the same bundle with the early exit removed injects refined / model instead. The PR body lists "the fast result carries no model judgment" as the main risk; this measurement shows the trade is not limited to slow selectors. It is still strictly better than base, which delivered nothing in that same run.
  2. Per-turn document total reaches 7, confirmed end-to-end (2 fast + 5 disjoint refined in one turn, against 5 on base) — exactly as the PR body documents.
  3. Candidate count drops in the under-cap case, also as documented: 150 project + 150 user documents, neither scope over 200 → base sends 300 manifest lines to the selector, head sends 94 (the 25 KB manifest budget binds well before the 200-document cap). Fewer, but query-ranked, and in the over-cap case that is the difference between the matching document being first and being absent.
  4. The scan gate is ~3× faster here than the PR body's Linux numbers: 200 topics 9.1 ms, 500 topics 21.4 ms, 1000 topics 46.4 ms — all inside the 100 ms ceiling. The stated "past roughly a thousand topics the scan exceeds the ceiling" did not reproduce on this machine, so that limitation is machine-dependent and the PR body states the conservative case.

4. Gates on macOS (the row the PR body marks as not rerun)

Head worktree, macOS 26.6 / arm64 / Node 24.18.1:

  • packages/core src/memory + src/core/client.test.ts37 files, 929 passed, 0 failed. team-memory-sync.test.ts > unstages the team path when the commit fails, which the PR body reports as an unrelated pre-existing failure on Linux, passes here.
  • The two eval files reproduce the PR body's tables exactly (overall Recall@5 45.2% → 92.9%, top-1 46.2% → 97.4%, cjk 0% → 100%, delivery 0% → 92.9% at every latency scenario above the budget, duplicate delivery 0%).
  • tsc --noEmit -p packages/core — clean, no output (the sharp error the PR body mentions is not present on this checkout).
  • eslint on the five changed source files — clean.

5. Not covered

Cancellation inside the initial window (Ctrl-C / Esc) was not driven; Windows was not run; selector latency is injected on loopback rather than a real network round trip; the ordinary-corpus scenarios use 7 documents, with scale exercised only in the 251- and 300-document runs; single machine, so the absolute timings are indicative, not portable.

Assessment. Every behavioural claim in the PR body that I could drive end-to-end reproduces on a real stack, and the two mutation checks show the newest commit's two lines are load-bearing. The documented trade-offs are real and I measured both directions of each. Observation 1 is the only item I would want a deliberate answer on before merge — it is a design choice the PR already names, just broader in scope than "slow selectors". From my side this is merge-ready.

中文说明

本地真实环境验证 —— head 01ef7d7dc4

我重新构建了两侧,用真实的 CLI bundle 打到一个会记账的 OpenAI 兼容 provider 上,磁盘上放真实的 .qwen/memory 树,而不是只看单测。这次是在我上一轮验证(当时 head 是 6085ef0)之后新增的两个 commit 上重新验证:8a5a524(按 mtime 的同分排序、所有丢弃路径都记 already_delivered)和 01ef7d7d(初始等待在 fast 结果处结束、扩大分词覆盖)。

环境。 base 用 merge-base 9a5b07c0b1,head 用 01ef7d7dc4,各自独立 worktree 里 npm install + npm run build + npm run bundle,每次运行都用该树自己的 dist/cli.js。先跑 bundle 完整性闸门:head 里有 onFastResult / fastDeliveredPaths / already_delivered / Script=Hiragana token 类,base 一个都没有。每次运行都用一次性项目目录 + QWEN_CODE_MEMORY_LOCAL=1,隔离的 HOMEQWEN_CODE_MEMORY_BASE_DIR,语料写成真实 topic 文件并控制 mtime。provider 按报文里的 Available memories: 标记识别 recall 侧查询,可以独立地延迟或让它失败;主模型的回复直接回显「这次请求里带了哪些 ## Relevant memory 文档」,所以对话记录本身就说明了投递结果。每次运行三个判据面:provider 请求台账(模型真正收到了什么,带到达时间戳)、本地文件 exporter 导出的 qwen-code.memory.recall{,.delivery} 遥测、以及 TUI。

1. 交付

同一个 query、同一棵 memory 树、同一个 provider、无工具的首轮 —— base 的首个 prompt 是空的,head 投递成功(见上方英文部分的截图;第二张是 CJK 场景,改动前的 tokenizer 对它根本产生不了 token)。

逐条来自台账和遥测:

  • 无工具回合、selector 超预算。 base:初始请求里没有 memory,recall 之后带着 3 篇模型选中的文档 settle,最终以 no_safe_delivery_point 丢弃。head:phase=fast, delivery_point=initial, strategy=heuristic, docs_selected=2, latency_ms=32,两篇文档确实在第一个请求体里。
  • 去重。 有工具的回合里,head 的第二个请求带了两个 memory 块 —— fast 的两篇,加上只含 release-checklist.md 的 refined 块,即唯一一篇没被 fast 投过的文档(refined / tool_result / model / docs_selected=1)。没有任何文档出现两次。base 则在 tool_result 一次性投三篇。
  • already_delivered 记账。 selector 恰好重选了 fast 那两篇时,head 记 already_delivered,base 记 no_safe_delivery_point。部分重叠时(选中 3 篇、fast 投过 2 篇)head 正确保留了原取消原因。
  • Scorer 精度。 selector 失败、query 与任何文档都没有词面重叠:base 投了 5 篇完全不相关的文档;head 什么都没投(no_relevant_results)。
  • Scorer 分词。 selector 失败、中文 query:base 是 strategy=none, docs_selected=0 —— query 产生了零个 token;head 选中了 cjk-deploy.md
  • 候选覆盖。 单个 scope 251 篇、唯一词面命中的那篇最旧:base 的 manifest 是 200 行且目标不在里面;head 的 manifest 是 96 行且目标是第 1 行,随后被投递。

2. 开销,以及对 head bundle 的两处单行变异

每个 arm 跑 5 次取中位数。在 provider 侧量「selector 请求」到「主请求」的间隔,可以把 CLI 约 1.2 s 的启动噪声抵消掉——否则 100 ms 的预算会被完全淹没。

arm 主请求 − selector 请求 fast 交付 latency_ms 相对 base 的端到端
base,query 命中 −4 ms 不适用
head,query 命中 +1 ms 31 ms +39 ms
head,无词面命中 +79 ms 不适用 +82 ms
head 去掉提前退出 +78 ms 124 ms +76 ms
空 memory 树 不适用 无可测开销

两处变异都只改 head 自己 bundle 里的一行,其它一切不变:

  • handle.fastResultRef.onArrive = finish= void 0(即 01ef7d7d 之前的行为):等待跑满上限,fast 交付延迟从 31 ms 变成 124 ms。这一行确实在做 commit 说明里声称的事。
  • b.doc.mtimeMs - a.doc.mtimeMsa.doc.type.localeCompare(b.doc.type):三篇同分文档时,fast 结果从 tie-user.md, tie-reference.md 翻成 tie-project.md, tie-reference.md —— user 文档被挤掉,正是 tie-break 注释里描述的那种失败。

3. 给 reviewer 的观察

以下都不是缺陷,但合入前值得留档。

  1. 无工具回合里,只要确定性 scorer 有命中,selector 的判断实际上永远进不了第一个 prompt。 onFastResult 是在 selector 请求发出之前紧挨着触发的,所以等待结束时 handle.settledAt 必然还是 null,下面那段「优先用已 settle 的 recall 而不是 fast 结果」的分支不可达。实测让 selector 在 15 ms 内返回(远在预算之内),head 仍然注入 heuristic 的那两篇,把模型选的两篇按 no_safe_delivery_point 丢掉;同一个 bundle 去掉提前退出那一行后,注入的是 refined / model。PR 正文把「fast 结果没有模型判断」列为主要风险;这次测量说明这个取舍并不只发生在 selector 慢的时候。不过它仍然严格优于 base —— 同一次运行里 base 什么都没投。
  2. 单回合文档总量会到 7 篇,端到端确认(一轮里 2 篇 fast + 5 篇不重叠的 refined,base 是 5 篇)—— 与 PR 正文写的完全一致。
  3. 未超旧上限的场景里候选数确实变少,也与正文一致:150 篇 project + 150 篇 user、两个 scope 都不超 200 时,base 给 selector 送 300 行 manifest,head 送 94 行(25 KB 的 manifest 预算比 200 篇的数量上限先生效)。变少了,但是按 query 排过序的;而在超上限的场景里,这个差别就是「命中文档排第一」和「命中文档根本不在」的区别。
  4. 本机的扫描闸门比 PR 正文的 Linux 数字快约 3 倍:200 篇 9.1 ms、500 篇 21.4 ms、1000 篇 46.4 ms —— 全部在 100 ms 上限之内。正文里「超过约 1000 篇时扫描本身就超上限」在本机没有复现,所以这个限制与机器相关,正文取的是保守的那一侧。

4. macOS 门禁(正文里标为「本轮未重跑」的那一行)

head worktree,macOS 26.6 / arm64 / Node 24.18.1:

  • packages/coresrc/memory + src/core/client.test.ts —— 37 个文件,929 passed,0 failed。正文里报为「无关的既有失败」的 team-memory-sync.test.ts > unstages the team path when the commit fails在这里是通过的
  • 两个 eval 文件的表格与正文完全一致(overall Recall@5 45.2% → 92.9%,top-1 46.2% → 97.4%,cjk 0% → 100%,超预算的每个 latency 场景交付 0% → 92.9%,重复交付 0%)。
  • tsc --noEmit -p packages/core —— 干净,无输出(正文提到的 sharp 类型报错在这个 checkout 上不存在)。
  • 对 5 个改动源文件跑 eslint —— 干净。

5. 未覆盖

初始窗口内的取消(Ctrl-C / Esc)没有驱动;Windows 没跑;selector 的延迟是在 loopback 上注入的,不是真实网络往返;普通语料场景只有 7 篇文档,规模只在 251 篇和 300 篇那两组里验证;单机结果,绝对耗时只作参考。

结论。 PR 正文里所有我能端到端驱动的行为性主张,在真实链路上都复现了;两处变异检查也证明最新那个 commit 的两行是起作用的。文中记录的取舍都是真的,我把每一项的两个方向都量了。第 3 节第 1 条是我合入前希望有个明确态度的唯一一项 —— 它是 PR 已经点名的设计取舍,只是覆盖面比「selector 慢的时候」更广。就我这边而言,可以合入。

…a test

Local end-to-end verification on #8716 found the claim added in 01ef7d7 —
"the preference order is unchanged: whatever ends the wait, a settled recall
is still delivered in preference to the fast result" — to be false in the
case that matters. `onFastResult` is published before recall issues the
selector request at all, so the recall promise cannot be settled when the
wait ends on the fast result. Measured against a selector settling in 15 ms,
comfortably inside the ceiling, the initial turn still delivers the
deterministic pair and discards the model's picks.

The behaviour is right and stays: a model side query does not return inside a
100 ms ceiling in production, so arbitrating would spend the rest of the
budget on every turn to win a race that does not happen, and the selector's
judgement still lands at ToolResult with the fast documents excluded. What
was wrong was the description. State it directly instead — on the initial
turn, once the deterministic scorer matches, the fast result wins regardless
of selector latency — and pin it with a test that fails when the early exit
is removed, so it reads as a decision rather than an accident.

Two measurements corrected while here. The scan crossover is machine-
dependent, not a fixed topic count: the same three sizes measure 9/21/46 ms
on faster hardware against 29/70/130 ms on the machine the tables were
written from, so the ceiling is not reached there at all. And
MAX_MODEL_CANDIDATE_DOCS = 200 is rarely the binding constraint —
MAX_MODEL_MANIFEST_BYTES is, at roughly 90-150 documents once absolute paths
and timestamps are counted. Measured runs sent 94 and 96 manifest lines where
the document cap would have allowed 200, which also explains why the recency
reserve has to be interleaved rather than appended.
@yiliang114

Copy link
Copy Markdown
Collaborator Author

Thanks — the two single-line bundle mutations are the part I want to call out. Asserting that a line is load-bearing is cheap; showing that flipping it reproduces the exact failure the comment describes is not, and both of them landed on commits from the last day.

Answering Observation 1 directly, since you asked for a deliberate one, and then two corrections your numbers force.

Observation 1 — you are right, and the code said otherwise

You are correct, and the claim I wrote in 01ef7d7d was wrong:

client.ts:938   // The preference order is unchanged: whatever ends the wait, the code
                // below still prefers a settled recall over the fast result.

onFastResult fires at recall.ts:467, synchronously, before selectRelevantAutoMemoryDocumentsByModel is called at :473. So when the wait ends on the fast result, the selector request has not been issued yet and handle.settledAt cannot be anything but null. I reasoned about that branch in isolation and never checked when the callback that wakes it actually fires.

One refinement to the framing: the branch is not unreachable, it is reachable only where no fast result exists — no Config, or nothing matched lexically — plus the narrow case where the whole recall finishes before the consume point is reached. Your characterisation of the measured behaviour holds; I want the precise condition on the record because it is what the replacement comment has to say.

The decision: the behaviour stays, the description was the defect.

The trade you measured is real but its cost is bounded by something your harness deliberately removes. Selector latency is injected on loopback; in production this is a model side query with a 30 s abort ceiling, and it does not return inside 100 ms. So the case where arbitrating would win is one that essentially does not occur, while the cost of preserving the option is the remainder of the budget on every turn — your own table prices that at +39 ms versus +76 ms end-to-end. Paying ~37 ms per turn to win a race that does not start is the wrong side of that trade, and the selector's judgement is not lost either way: it lands at ToolResult with the fast documents excluded.

What was missing is that this reads as an accident. Fixed in db006f8b:

  • The false comment is replaced by a direct statement of the actual rule — on the initial turn, once the deterministic scorer matches, the fast result wins regardless of selector latency — with the condition under which the settled-recall branch is still reached.
  • Same correction in 2026-08-08-native-memory-recall-reliability.md, including your 15 ms measurement and the fact that the pre-change build delivered nothing on that same turn.
  • The PR body's main-risk bullet no longer says "on a tool-free turn where the selector never lands". It now says "whenever the deterministic scorer matches — not only when the selector is slow", which is your sentence.
  • New test, delivers the fast result even when the selector settles inside the budget: scan at 10 ms, selector at 15 ms, asserts the initial request carries the fast prompt and not the refined one. I ran your mutation against it — with handle.fastResultRef.onArrive = finish removed it fails, so it pins the decision rather than restating the implementation.

Observation 3 — the document cap is not the binding constraint, and my docs said it was

Your 300 → 94 measurement is the more interesting number, and it does not follow from anything I documented. I had written the reduction as "at most 200 in total", implying MAX_MODEL_CANDIDATE_DOCS binds. It usually does not: each manifest line carries an absolute path and an ISO-8601 timestamp before the description, so the fixed overhead is roughly 150–250 bytes, and against MAX_MODEL_MANIFEST_BYTES = 25_000 that binds somewhere around 90–150 documents. Your 94 and your 96 both land there, which is the confirmation.

Two consequences now written into 2026-08-09-bounded-memory-recall-candidates.md, with your measurements: operators should read the byte budget rather than the document cap as the real candidate ceiling; and the recency reserve only survives a cut in the nineties because it is interleaved with the lexical candidates rather than appended after them. Appended, it would be discarded in full — that property was designed in, but it was justified against the wrong number.

Observation 4 — crossover is machine-dependent, corrected

9.1 / 21.4 / 46.4 ms against my 29 / 70 / 130 ms is a 3× spread, so "past roughly a thousand topics the scan exceeds the ceiling" was never a topic count. It is now stated as a machine-dependent crossover — roughly a thousand topics on the slower of the two machines, not reached at all on the faster one — in the design doc, the limitations list, and the PR body, with the table labelled as the conservative side.

The two environment failures

Both of the caveats in my "Tested on" row turn out to be my machine, and your macOS run is what settles it: team-memory-sync.test.ts > unstages the team path when the commit fails passes there, and tsc --noEmit -p packages/core is clean with no sharp error. The PR body now says so and links this comment. The macOS row is yours.

On section 5

Cancellation inside the initial window is covered by unit tests rather than driven end-to-end — delivers no fast result when the turn is cancelled inside the initial window in client.test.ts, which had to be rewritten in 01ef7d7d precisely because the early exit changed when the window exists. Not a substitute for driving Ctrl-C through the TUI, but the path is not unexercised. Windows remains unverified from my side too.

Head is now db006f8b. Everything above is documentation, one comment, and one test; no behaviour changed since the build you verified, so your ledger still describes the shipped code.

@yiliang114

Copy link
Copy Markdown
Collaborator Author

@qwen-code /triage

@qwen-code-ci-bot

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

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

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

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

Verification report

PR 8716 verification — fix(memory): improve recall delivery and multilingual fallback

Verdict: merge-ready — 1034/1034 scripted assertions passed (94 harness A/B cells, 930 targeted-gate tests, 10 mutation-matrix rows), 0 unexpected failures, no blocking findings. Verified head: db006f8b253b294efbb7d097daf641999c173ef0 (merge-ref checkout cc53842238, base tip 72ae65d78f).

中文摘要
  • 结论: merge-ready。1034 条脚本化断言全部通过,无阻塞性发现。
  • A/B 结论(head vs base,真实编译产物 + 真实 recall + 假模型 peer):
    • 核心声明成立:无工具首轮在 ~7 ms 内注入确定性 fast 结果(base 在 100 ms 预算内什么都拿不到,只能等 ~530 ms 的 selector settle,且无工具轮没有投递点);见 01-ab-client-delivery-head-vs-base.png03-ab-recall-seam-fast-publication.png
    • 去重、取消、Cron/ToolResult 零等待、already_delivered 遥测语义均按描述工作;8 个单点突变中 7 个被套件杀死,1 个(fast 上限常量)套件因自引用常量而存活,但 harness 证明该 guard 行为上是活的(覆盖缺口,非死代码)。
    • 多语言 scorer 成立:CJK/西里尔/希腊/阿拉伯/重音拉丁/全角 NFKC/泰文整串/孤立 CJK 拒绝/同分按 mtime 等 16 个 cell 全部按声明翻转;eval 表与 PR 声称数字逐格复现(overall Recall@​5 45.2%→92.9% 等),见 05-eval-tables-reproduce.png
    • 扫描上限变更成立:250 篇树中 recency 排名 250 的文档在 head 可召回、base 永久不可见;manifest 25 KB 字节上限、continue-not-break、fail-closed 校验均经 wire oracle 验证。
  • Findings(均非阻塞):① MAX_FAST_RECALL_DOCS 的数值 2 没有被任何测试以硬编码方式钉住(测试自引用该常量),建议补一个硬编码 ≤2 的 fixture;② recall-eval 的 CJK 分片对 bigram 粒度不敏感(查询是逐字 run),粒度由 recall.test.ts 钉住;③ Cron 轮若在 consume 前已有 fast 结果会被顺带注入(与 base 零等待消费已 settle 结果同构,非回归,仅提示)。
  • 未覆盖:逐 commit 归因(shallow checkout,23 个 commit 仅 1 个可达)、对当前 main 的 trial merge(无网络)、真实网络 selector 延迟(以假 peer 建模)、tokenizer 的 ReDoS 阶梯(查询是会话用户自己的文本,非外部攻击面;文档正文不参与 tokenize)。

Central claim + A/B

Central claim: on a tool-free first turn, selected memory actually reaches the model — a bounded ≤100 ms wait ends on the deterministic fast result, which is injected when the selector is still in flight; the refined result lands later with fast-delivered docs excluded.

Harness h2-client-inject-ab.mjs drives the real compiled tryConsumeMemoryPrefetch against a real recall over a temp memory tree, with a fake model peer that answers {selected_memories} after a 500 ms round trip (the upstream contract; the unit under test is not stubbed). Witness: 01-ab-client-delivery-head-vs-base.png.

cell (selector 500 ms in flight) head base
initial consume (tool-free turn) fast prompt injected, 2 docs, elapsed 7 ms null — nothing delivered
wait duration ends on fast arrival (7 ms), not full budget zero-wait poll, unsettled → null
refined at ToolResult after settle deduped to 0 remaining (all fast-delivered), logged already_delivered full result — but only reachable on a tool-using turn
refined with 1 extra doc delivers ONLY the new doc, fast bodies excluded n/a
cancelled turn nothing delivered, no fast flag nothing
ToolResult / Cron consume zero-wait (0.0 ms), no wait applied zero-wait (0.0 ms)

Recall-seam A/B (h1, witness 03-ab-recall-seam-fast-publication.png): head publishes the deterministic result at 4.5 ms (≤2 docs, lexical, strategy heuristic) while the selector settles at 526 ms; base has nothing available inside the 100 ms budget (settle 530 ms), sends every scanned doc (incl. non-matching) to the selector, and its selector-failure fallback leaks the non-matching doc (3 docs) where head keeps only the 2 lexical matches.

Secondary claim — multilingual selection (h3, witness 02-ab-scorer-multilingual-head-vs-base.png), 16 cells per arm, all flipping as claimed: CJK bigrams, Cyrillic/Greek/Arabic/naïve whole-runs, fullwidth deploy NFKC, Thai whole-run, isolated-CJK rejection, abc漢字 mixed-run split, lexical gate (base scores every non-empty doc positive), true-tie recency break (base breaks ties by type, dropping user), field weighting, 64-token bound, ownerownership substring hazard (documented limitation, asserted as such).

Secondary claim — bounded candidates (h5): 250-topic tree; head's uncapped scan returns 250 and recall retrieves the doc at recency rank 250; base's 200-cap scan drops it and recall can never see it. Shared scanner stays capped at 200 on both arms (non-recall flows unchanged).

Manifest wire oracle (h4): head's selector request carries 44 of 60 doc lines at 26,283 bytes (manifest ≤25,000); base sends all 60 at 35,387 bytes. A line missing the remaining budget is skipped while a later small line is still admitted (continue, not break); a pick of an unmanifested path is rejected fail-closed (Recall selector returned unknown file path), as is any hallucinated path; the 512-char description slice leaves no lone surrogate.

PR's own eval tables reproduce exactly on this container (witness 05-eval-tables-reproduce.png): overall Recall@​5 45.2%→92.9%, top-1 46.2%→97.4%, cjk 0→100%, semantic-no-lexical 0→0; delivery eval tool-free first-turn 0%→92.9% above budget, duplicate delivery 0%. Scan-latency on this runner: 200/500/1000 topics → 12.7 / 34.1 / 64.9 ms medians (all inside the 100 ms ceiling here; the PR's slower-hardware crossover is machine-dependent and did not trigger).

Findings (non-blocking)

F1 — MAX_FAST_RECALL_DOCS value is unpinned by the suite (coverage gap, not dead code). Mutation M3 (2→5) survives recall.test.ts + recall-delivery-eval.test.ts (58 passed) because both files import the constant and compute expectations from it. Patching the compiled dist to 5 makes my harness fail 3 checks (fast injection of 3 docs, downstream dedupe cells) — the guard is behaviorally live; only the value pin is missing. Suggested fixture: a test that hard-codes expect(fast.selectedDocs.length).toBeLessThanOrEqual(2) with three lexical-matching docs. Not a merge condition.

F2 — the eval's CJK slice is insensitive to bigram granularity. Mutation M5 (Han/Hiragana/Katakana removed) survives recall-eval.test.ts (8 passed) because the corpus's CJK queries are verbatim runs, which whole-run tokens still match; recall.test.ts kills it (3 failed: partial-run and mixed-run cases). The granularity is pinned, just not by the eval. Completeness note only.

F3 — a Cron turn can opportunistically receive an already-published fast result. The fast-injection branch does not check waitMs, so a Cron consume that runs after the fast box is populated injects it. This mirrors base, which consumed an already-settled recall at the zero-wait Cron point; the pinned property ("Cron never waits") holds (M4-style fake-timer test + my zero-wait cells). Awareness note, not a regression.

Not covered

  • Per-commit attribution: shallow depth-2 checkout; the snapshot lists 23 commits but only db006f8b25 is locally reachable (git rev-list HEAD^1..HEAD^2 returns the shallow-boundary 1). The aggregate HEAD^1..HEAD diff is what was verified.
  • Trial merge into current main: no network and no main ref in this container; the snapshot's baseRefOid (9a5b07c0) postdates the merge base used here, so main has moved — conflict-freeness at landing was not re-measured.
  • Real-network selector latency: modeled by the fake peer (40/250/600 ms scenarios in the PR's own eval; 500 ms in my A/B).
  • ReDoS ladder on RECALL_TOKEN_RUN: deliberately not run — the tokenized input is the session user's own query text (not outsider-authored), and document bodies are never tokenized (only substring-matched), so the untrusted-writer premise does not hold here.
  • The author-reported team-memory-sync Linux failure does not reproduce in this container (green at head, 10/10); nothing to attribute on either arm.
  • 7-docs-per-turn tradeoff (fast 2 + refined 5 disjoint): author-acknowledged in the description; accepted, not re-litigated.
  • Full sendMessageStream integration of the fast path is covered by the suite (mocked recall), not by my harness, which drives the compiled consume path + real recall instead.

Methodology

Environment: node:22-bookworm CI container, merge-ref checkout (HEAD cc53842238 = merge of db006f8b25 into 72ae65d78f). Control: scratch worktree tmp/base-tree at HEAD^1, rebuilt with npm run build -w @qwen-code/qwen-code-core after symlinking the root node_modules (and the package-local one) into the worktree — the lone base build error (@lydell/node-pty TS7016) was proven a worktree-layout artifact via --traceResolution (tsconfig paths resolves ../../node_modules/... relative to the package), not a base-code difference; the rebuilt control compiles with 0 errors and its dist verifiably lacks onFastResult/INITIAL_MEMORY_RECALL_WAIT_MS. Realpath assertions: the code under test loads from each arm's own dist/; packages/core has no internal @qwen-code deps, so no workspace-link confound. Harnesses (h1h5, lib.mjs) import compiled dist, use a recording fake model peer for the selector (the peer, not the unit under test), and write per-run *.assertions.json. Gates: npx vitest run src/memory src/core/client.test.ts at head (37 files / 930 tests, log gate-head.log). Mutation matrix: mutation-matrix.sh, captured as printed in 04-mutation-matrix.png; every mutant restored (git status clean). Raw logs and harness sources live in this artifact directory.

Evidence images

01-ab-client-delivery-head-vs-base

02-ab-scorer-multilingual-head-vs-base

03-ab-recall-seam-fast-publication

04-mutation-matrix

05-eval-tables-reproduce

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

Qwen Code · sandboxed verification

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

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

LGTM, looks ready to ship. ✅

@yiliang114
yiliang114 added this pull request to the merge queue Aug 18, 2026
Merged via the queue into main with commit 179c8f8 Aug 18, 2026
57 of 58 checks passed
@qwen-code-ci-bot

Copy link
Copy Markdown
Collaborator

Released in v0.21.14.

pull Bot pushed a commit to Stars1233/qwen-code that referenced this pull request Aug 24, 2026
)

* fix(memory): scan uncapped when selecting forget candidates

Recall moved to the uncapped scanner in QwenLM#8716; forget did not. A document
ranked past the 200-document cap could be recalled and injected into the
prompt but never forgotten.

Forget now scans uncapped, so its candidate universe matches recall's. The
model-selection prompt renders every candidate, so it gets its own bound of
400: literal query matches first, then the most recently modified remainder.
The heuristic fallback keeps scanning the full uncapped list.

Indexer, status, and extraction stay capped on purpose, and the two design
docs that recorded forget as capped now say otherwise.

Refs: QwenLM#9378

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* fix(memory): give each scope its own share of the forget prompt

Review round 1. The 400-candidate bound ranked both scopes into one recency
budget, so a store whose project entries are all newer than its user entries
seated no user memory at all. The capped scanners this replaced ran per scope,
so each scope always had seats. That made an old user entry unselectable by the
model while recall could still inject it, which is the same asymmetry the PR
set out to close.

Each scope now keeps a 200-candidate quota and whatever a smaller scope leaves
is handed to the other. Within a scope, literal query matches rank first and
both groups are ordered newest first, so truncation is deterministic instead of
scan-order, and the bound logs when it drops candidates.

Also from review: the query normalisation and match predicate are now shared
with selectByHeuristic so the two cannot drift; the user scan gets the
best-effort guard recall.ts and extractionAgentPlanner.ts already carry; and
the docstring and design docs no longer claim an unconditional guarantee the
bound does not provide.

Three tests, each verified against the mutation it is meant to catch: global
ranking drops the user ids, an ascending sort drops the newest filler, and
handing the fallback the bounded list returns 400 of 450 matches.

Refs: QwenLM#9378

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* fix(memory): bound the unconfirmed forget path and drop the silent scan guard

Review round 2, all suggestions.

MemoryManager.forget passed limit: MAX_SAFE_INTEGER and deletes without
confirmation. With an uncapped scan and a heuristic fallback that substring
matches the whole store, a one-character query matched nearly every entry in
both scopes, where the capped scanners had held that same failure to one scan's
worth of candidates. The limit is now the prompt bound, restoring the old
ceiling.

Round 1 added a best-effort catch on the user scan. That was wrong on two
counts: scan.ts caps after reading and ordering the whole tree, so uncapping
adds no read exposure to justify it, and swallowing the failure made forget
report "no entries matched" for a scope it never read, then act on that answer
by deleting. Reverted, with a comment saying why forget differs from recall
here: a missed injection is recoverable, a missed deletion is not.

normalizeForgetQuery now delegates to normalizeSummary so query matching and
the post-selection re-match cannot drift apart, and one design-doc sentence no
longer implies only semantic matches fall off the bound.

Two tests, each verified against its mutation: the quota split is now exercised
with both scopes over quota, where dropping it to 150 seats 250 project entries
instead of 200; and the delete ceiling fails at 401 removals if the unbounded
limit comes back.

Refs: QwenLM#9378

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* fix(memory): split forget's deletion seats per scope, and decouple the ceiling

Review round 3.

The deletion ceiling added last round truncated the heuristic fallback in
candidate order, and listIndexedForgetCandidates pushes every user entry ahead
of every project entry. With 450 matching user entries and 50 matching project
ones and the side query down, forget deleted 400 user entries, zero project
ones, and reported success. That is the reachability asymmetry this PR exists
to remove, moved into the delete path. The per-scope allocation the model
prompt already used is now shared with the heuristic, so each scope keeps its
share of the limit and a smaller scope's unused seats go to the other.

The ceiling is also its own constant now rather than an alias of the prompt
bound. Resizing the model prompt is a cost decision and resizing this is a
blast-radius decision; sharing one constant let the first silently widen the
second.

Two tests, each checked against its mutation: the 450-user/50-project shape
returns zero project matches under a plain slice, and oldest-first ranking
inside a scope drops that scope's newest entry from the prompt.

Refs: QwenLM#9378

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* test(memory): pin the forget split at a small limit and the heuristic's own order

Cross-review found both new tests mutation-survivable. Every case used a
400 limit, so hard-coding a 200 per-scope quota instead of deriving it from
the budget still passed, and the recency case let the side query succeed, so
it pinned the model prompt's ranking rather than selectByHeuristic's own
comparator.

One case at limit 5 with the side query failing covers both: it asserts the
3/2 split, which only holds if the quota comes from the budget, and that each
scope contributes its newest entry, which fails if the comparator is reversed.
Both mutants verified failing.

Refs: QwenLM#9378

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* refactor(memory): share the forget recency comparator and log a bound deletion

Review round 4, both suggestions.

The mtime comparator was the last thing the model path and the heuristic path
each typed for themselves, after this branch had already hoisted the query
normaliser, the match predicate and the per-scope allocator so the two could
not drift. Each site has its own test, so a one-sided ordering change would
have updated its own test, passed CI, and left the sibling stale. Now one
definition.

The deletion cap also bound silently. The prompt bound warns when it truncates;
the path that actually deletes did not, so a forget that removed 400 of 500
matches reported success and left no record of why recall kept injecting the
rest. It now says so.

No test for the new warning: it is a debug log line, and asserting on it would
pin the wording rather than the behaviour.

Refs: QwenLM#9378

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
Co-authored-by: Shaojin Wen <shaojin.wensj@alibaba-inc.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants