Skip to content

feat(review): carry the incremental anchor sha in the posted ledger marker - #9067

Merged
wenshao merged 4 commits into
mainfrom
feat/review-ledger-sha
Aug 13, 2026
Merged

feat(review): carry the incremental anchor sha in the posted ledger marker#9067
wenshao merged 4 commits into
mainfrom
feat/review-ledger-sha

Conversation

@wenshao

@wenshao wenshao commented Aug 13, 2026

Copy link
Copy Markdown
Collaborator

What this PR does

Carries the incremental anchor in the posted review itself: the machine ledger marker compose-review embeds in every posted /review round now includes sha, the head commit that round reviewed. The next round — in any environment — recovers it through pr-context's prev-ledger side file and, after validating it against the fetched head, scopes its incremental diff from it exactly as it would from the local cache's lastCommitSha. The anchor is withheld on a fail-closed round (unreviewed dimensions, undecided blockers, uncoverable chunks, context unavailable) — the findings still ride; the round just never certifies a range. A malformed sha in a posted body is dropped at field level: the next round keeps its work list and never hands garbage to git.

Why it's needed

The machine ledger solved half of cross-environment incremental review: a fresh environment (CI, another clone) recovers the previous round's findings from the posted body, but "last reviewed at" lived only in one clone's .qwen/review-cache/, so the incremental diff range silently degraded to the full diff every time — exactly the token cost incremental review exists to avoid, and the core scenario of #8946 (CI re-reviews on every push, always from a fresh checkout). The posted review is the one artifact every environment can see; the anchor belongs on it, under the same fail-closed discipline Step 8 already applies to the cache.

Reviewer Test Plan

How to verify

  • cd packages/cli && npx vitest run src/commands/review/lib/ledger.test.ts src/commands/review/compose-review.test.ts src/commands/review/pr-context.test.ts — the new coverage: sha round-trips through a posted body; a forged "sha":"$(rm -rf /)" is dropped while the ledger survives, and the serializer refuses non-hex on the write side; a clean composeReview run carries the plan's fetchedSha into the posted marker; each of the four fail-closed conditions withholds the sha while the findings still ride; the rendered ledger section names reviewed at `<sha>` when present and stays silent when absent.
  • cd packages/core && npx vitest run src/skills/bundled/review/SKILL.test.ts — structural checks over the edited SKILL.md.
  • Read SKILL.md's two edits: Step 1's new "When the cache has no anchor, the PR itself carries one" bullet (validation via git cat-file -e + merge-base --is-ancestor, full-diff fallback, the side-file-round-beats-stale-cache edge), and Step 8's updated marker paragraph (the sha's second job and the withholding conditions).

Evidence (Before & After)

N/A — no UI. Before: parseLedger on any posted round returned {v, round, findings} and a CI re-review had no anchor, so its "incremental" range was the full diff. After: a clean round's marker carries sha (asserted end-to-end through composeReviewparseLedger in compose-review.test.ts), and a fail-closed round's marker verifiably does not.

Tested on

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

Environment (optional)

Unit tests only (npx vitest run in packages/cli and packages/core). Full src/commands/review suite: 2432/2433 green — the one failure is stale-bundle.test.ts, which fails on a clean checkout of this machine (stale local build), unrelated.

Risk & Scope

  • Main risk or tradeoff: an anchor recovered from a posted body scopes the next round's diff, so the failure to guard against is a wrong anchor narrowing a review. Three layers hold that line: only clean rounds write the sha; the parser accepts only plausible hex; Step 1 validates ancestry inside the worktree before scoping and falls back to the full diff otherwise — a tampered anchor costs a full-range review, never a mis-scoped one.
  • Not validated / out of scope: no live multi-round PR exercise in this PR (the flow is asserted at the unit seam composeReviewparseLedgerrenderLedgerSection). The larger Incremental (delta) review: review only new commits since the last reviewed SHA instead of restarting full passes #8946 items — CLI-computed delta diffs (fetch-pr --since), consumer-union scoping, re-verification depth tiers — are follow-ups; this PR is deliberately the smallest change that unlocks the CI scenario.
  • Breaking changes / migration notes: none. sha is optional in the marker; older markers parse unchanged, and older readers ignore the new field.

Linked Issues

Refs #8946 (incremental/delta review: review only new commits since the last reviewed SHA).

中文说明

What this PR does(本 PR 做什么)

把增量锚点带进发布的 review 本身:compose-review 在每轮发布的 /review 中嵌入的机器 ledger marker 现在包含 sha——该轮 review 的 head commit。下一轮(在任何环境)通过 pr-context 的 prev-ledger side file 恢复它,经与 fetched head 的验证后,像使用本地 cache 的 lastCommitSha 一样以它收窄增量 diff 范围。fail-closed 的轮次(存在未审 dimension、未决 blocker、uncoverable chunk、context 不可用)会扣留锚点——findings 照常携带,只是该轮不认证范围。发布正文里的畸形 sha 在字段级被丢弃:下一轮保住工作清单,垃圾也绝不会传给 git

Why it's needed(为什么需要)

机器 ledger 解决了跨环境增量 review 的一半:新环境(CI、另一台机器的 clone)能从发布正文恢复上一轮的 findings,但"上次审到哪"只存在于单个 clone 的 .qwen/review-cache/ 里,增量 diff 范围每次都静默退化为全量——这正是增量 review 要省的 token 成本,也是 #8946 的核心场景(CI 在每次 push 时从全新 checkout 重审)。发布的 review 是所有环境都能看到的唯一 artifact;锚点应该放在它上面,并沿用 Step 8 已对 cache 施加的 fail-closed 纪律。

Reviewer Test Plan(评审验证计划)

How to verify(如何验证)

  • cd packages/cli && npx vitest run src/commands/review/lib/ledger.test.ts src/commands/review/compose-review.test.ts src/commands/review/pr-context.test.ts——新增覆盖:sha 经发布正文 round-trip;伪造的 "sha":"$(rm -rf /)" 被丢弃而账本存活,序列化端拒绝非 hex;干净的 composeReview 运行把 plan 的 fetchedSha 带进发布 marker;四种 fail-closed 条件各自扣留 sha 且 findings 保留;渲染段有 sha 时标出 reviewed at `<sha>` 、无 sha 时沉默。
  • cd packages/core && npx vitest run src/skills/bundled/review/SKILL.test.ts——改动后 SKILL.md 的结构检查。
  • 阅读 SKILL.md 的两处改动:Step 1 新增的 "When the cache has no anchor, the PR itself carries one" 段(git cat-file -e + merge-base --is-ancestor 验证、全量回退、side file round 高于陈旧 cache 的边界),以及 Step 8 更新的 marker 段(sha 的第二职责与扣留条件)。

Evidence (Before & After)(前后证据)

N/A——无 UI。之前:对任何发布轮 parseLedger 只返回 {v, round, findings},CI 重审没有锚点,"增量"范围实为全量。之后:干净轮的 marker 携带 sha(在 compose-review.test.ts 中经 composeReviewparseLedger 端到端断言),fail-closed 轮的 marker 可验证地不携带。

Tested on(测试平台)

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

Environment(环境,可选)

仅单元测试(在 packages/clipackages/corenpx vitest run)。src/commands/review 全套件:2432/2433 通过——唯一失败是 stale-bundle.test.ts,在本机干净检出上同样失败(本地陈旧构建),与本次无关。

Risk & Scope(风险与范围)

  • 主要风险/权衡:从发布正文恢复的锚点会收窄下一轮的 diff 范围,需防的失败是错误锚点导致审查范围缩窄。三层防线:只有干净轮写 sha;解析端只接受合理 hex;Step 1 在 worktree 内验证祖先关系后才收窄、否则回退全量——被篡改的锚点最多花费一次全量审查,绝不造成错误收窄。
  • 未验证/超出范围:本 PR 未做真实多轮 PR 演练(流程在 composeReviewparseLedgerrenderLedgerSection 的单元接缝处断言)。Incremental (delta) review: review only new commits since the last reviewed SHA instead of restarting full passes #8946 的更大项——CLI 计算 delta diff(fetch-pr --since)、消费方并集入范围、复验深度分档——留作后续;本 PR 刻意做成解锁 CI 场景的最小改动。
  • 破坏性变更/迁移说明:无。marker 的 sha 为可选字段;旧 marker 解析不变,旧读取方忽略新字段。

Linked Issues(关联 issue)

Refs #8946(增量/delta review:只审上次已审 SHA 之后的新 commit)。

…arker

The machine ledger solved half of cross-environment incremental review:
a fresh environment (CI, another clone) recovers the previous round's
findings from the posted body, but 'last reviewed at' lived only in one
clone's .qwen/review-cache/, so the incremental diff range silently
degraded to the full diff every time — exactly the cost incremental
review exists to avoid (issue 8946's core scenario).

The marker now carries sha, the head the round reviewed:

- ledger.ts: optional sha on Ledger; the serializer embeds only a valid
  hex anchor, and the parser drops a malformed field without dropping
  the ledger — a garbage anchor must not cost the next round its work
  list, and must not survive to be handed to git either
- compose-review.ts: ledgerMarkerFor reads fetchedSha from the plan and
  withholds it under exactly the conditions Step 8 forbids advancing
  the cache's lastCommitSha (unreviewedDimensions, cannotTellCriticals,
  uncoverableChunks, context-unavailable) — an anchor written past
  unreviewed scope would let the next round's incremental range skip it
  forever; the findings still ride
- pr-context.ts: the rendered ledger section names 'reviewed at <sha>';
  the prev-ledger side file carries it through
- SKILL.md Step 1: the recovered-anchor check — when the cache is
  absent or rebased away, read the side file's sha, validate it with
  git cat-file -e and merge-base --is-ancestor inside the worktree, and
  treat it exactly as lastCommitSha; a sha that fails either check
  falls back to the full diff. Step 8 documents the marker's second job
  and the fail-closed withholding
@qwen-code-ci-bot

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

Copy link
Copy Markdown
Collaborator

Qwen Triage finished — CI landed green on 2fa20e5 and the deferred approval was posted. finalize run

Qwen Triage 已完成 —— 2fa20e5 的 CI 全绿,延迟审批已提交。查看 finalize 运行

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

Thanks for the PR, @wenshao!

The PR body doesn't follow the PR template — all the required headings are missing: What this PR does, Why it's needed, Reviewer Test Plan (with How to verify / Evidence (Before & After) / Tested on), Risk & Scope, and Linked Issues. The body uses Summary / Design / Changes / Test plan instead.

The content itself largely covers what the template asks for, so this should be a quick reshape:

  • Summary → split into What this PR does + Why it's needed
  • Test planReviewer Test Plan, with a How to verify section and the Tested on matrix (which OSes did the review suite run on?)
  • Add a short Risk & Scope section (the fail-closed/fail-quiet design notes in Design are a good source)
  • Move the 8946 and 9065 references into Linked Issues

Your sibling PR #9065 already follows the template if you want a reference. Once the body is updated, re-trigger with @qwen-code /triage and the gate will pick it up from Stage 1.

中文说明

感谢贡献,@wenshao

PR 正文没有遵循 PR 模板——必需的标题均缺失:What this PR doesWhy it's neededReviewer Test Plan(含 How to verify / Evidence (Before & After) / Tested on)、Risk & ScopeLinked Issues。正文使用的是 Summary / Design / Changes / Test plan

内容本身已经基本覆盖模板要求,改起来应该很快:

  • Summary 拆成 What this PR does + Why it's needed
  • Test plan 对应 Reviewer Test Plan,补上 How to verifyTested on 表格(review 套件在哪些 OS 上跑过?)
  • 加一段 Risk & ScopeDesign 里 fail-closed/fail-quiet 的说明就是很好的素材)
  • 89469065 的引用移到 Linked Issues

姊妹 PR #9065 已经遵循模板,可以参考。正文更新后用 @qwen-code /triage 重新触发,gate 会从 Stage 1 继续。

Qwen Code · qwen3.8-max

@github-actions

github-actions Bot commented Aug 13, 2026

Copy link
Copy Markdown
Contributor

Code Coverage Summary

Package Lines Statements Functions Branches
CLI 84.13% 84.13% 89.99% 83.34%
Core 87.9% 87.9% 89.45% 86.45%
CLI Package - Full Text Report
-------------------|---------|----------|---------|---------|-------------------
File               | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
-------------------|---------|----------|---------|---------|-------------------
All files          |   84.13 |    83.34 |   89.99 |   84.13 |                   
 src               |   85.27 |    81.44 |   87.61 |   85.27 |                   
  cli.ts           |   95.68 |    84.11 |     100 |   95.68 | ...60-561,565-566 
  gemini.tsx       |   73.75 |    79.33 |   80.76 |   73.75 | ...1319-1323,1450 
  ...ractiveCli.ts |   87.19 |    81.33 |   88.13 |   87.19 | ...2972,2978,3043 
  ...liCommands.ts |   88.64 |    82.83 |      80 |   88.64 | ...77-579,593,692 
  ...ActiveAuth.ts |     100 |     87.5 |     100 |     100 | 66-80             
 ...cp-integration |   71.65 |    73.85 |   91.22 |   71.65 |                   
  acpAgent.ts      |   71.02 |    73.64 |   90.74 |   71.02 | ...20,12325-12327 
  ...k-reporter.ts |     100 |    80.95 |     100 |     100 | 77,80,115,135     
  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.23 |    86.48 |   96.48 |   91.23 |                   
  Session.ts       |   90.35 |    84.88 |   95.79 |   90.35 | ...81,11408-11412 
  ...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 |   93.38 |    91.74 |     100 |   93.38 | 74,85-88,115-125  
  ...y-replayer.ts |   98.22 |    98.14 |     100 |   98.22 | 195-197           
  index.ts         |       0 |        0 |       0 |       0 | 1-40              
  ...ssionUtils.ts |   89.76 |    87.32 |     100 |   89.76 | ...54-270,326-328 
  ...lure-guard.ts |   98.32 |    97.75 |     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 |   96.04 |    93.93 |   96.87 |   96.04 |                   
  ...ageEmitter.ts |   96.03 |    95.08 |     100 |   96.03 | 71,108-115        
  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      |   90.81 |    79.61 |   66.66 |   90.81 |                   
  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.66 |      100 |      50 |   98.66 | 86                
  serve.ts         |   89.84 |    77.32 |     100 |   89.84 | ...52,855-858,870 
  sessions.ts      |     100 |      100 |      50 |     100 |                   
  update.ts        |   98.13 |    94.44 |   66.66 |   98.13 | 82-83             
 ...mmands/channel |   88.95 |    88.56 |   90.59 |   88.95 |                   
  channel-cwd.ts   |     100 |      100 |     100 |     100 |                   
  ...l-registry.ts |   94.11 |    95.45 |   88.88 |   94.11 | ...54-257,302-305 
  ...entry-path.ts |      75 |       50 |     100 |      75 | 8-9               
  config-utils.ts  |   95.87 |    96.35 |     100 |   95.87 | ...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.73 |   87.09 |   88.85 |                   
  consent.ts       |   72.53 |    90.32 |   42.85 |   72.53 | ...86-142,157-163 
  disable.ts       |     100 |       90 |     100 |     100 | 30                
  enable.ts        |     100 |    91.66 |     100 |     100 | 38                
  install.ts       |   82.95 |    81.57 |      75 |   82.95 | ...96-199,202-211 
  link.ts          |     100 |      100 |     100 |     100 |                   
  list.ts          |     100 |     87.5 |     100 |     100 | 18                
  new.ts           |     100 |      100 |     100 |     100 |                   
  settings.ts      |   99.15 |      100 |   83.33 |   99.15 | 151               
  sources.ts       |   93.42 |    87.09 |   92.85 |   93.42 | ...4-66,96-98,167 
  uninstall.ts     |   74.57 |       40 |   66.66 |   74.57 | 45-47,60-67,70-73 
  update.ts        |   96.71 |    97.05 |     100 |   96.71 | 114-118           
  utils.ts         |   75.63 |    55.55 |     100 |   75.63 | ...30-134,136-140 
 ...les/mcp-server |       0 |        0 |       0 |       0 |                   
  example.ts       |       0 |        0 |       0 |       0 | 1-60              
 ...amples/starter |       0 |        0 |       0 |       0 |                   
  example.ts       |       0 |        0 |       0 |       0 | 1-64              
 src/commands/mcp  |   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 |   87.65 |    88.33 |   88.45 |   87.65 |                   
  agent-prompt.ts  |   93.73 |     92.4 |   97.22 |   93.73 | ...2524,2649-2729 
  base-tree.ts     |   76.16 |    80.76 |   77.77 |   76.16 | ...50-371,373-386 
  capture-local.ts |   68.57 |     90.9 |      75 |   68.57 | 107-111,158-189   
  ...k-coverage.ts |   50.71 |       35 |   66.66 |   50.71 | ...40-245,279-289 
  cleanup.ts       |   89.12 |    82.22 |   83.33 |   89.12 | ...99-504,506-507 
  ...ent-status.ts |   93.03 |    83.87 |   83.33 |   93.03 | 291,531-551       
  ...ose-review.ts |   97.01 |    93.27 |   96.66 |   97.01 | ...2230,2258-2280 
  cost-ledger.ts   |   94.67 |    95.86 |   78.57 |   94.67 | ...04-505,545-555 
  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-pr.ts      |    76.7 |    68.75 |   63.63 |    76.7 | ...95,417,450-455 
  findings.ts      |   89.35 |    89.13 |   95.45 |   89.35 | ...15-918,927-928 
  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     
  mock-provider.ts |   95.44 |    90.25 |   89.47 |   95.44 | 145,690-709       
  parse-args.ts    |   99.66 |    96.55 |     100 |   99.66 | 404               
  plan-diff.ts     |   64.04 |      100 |   66.66 |   64.04 | 127-163           
  pr-context.ts    |   81.77 |    81.32 |   92.85 |   81.77 | ...1043,1072-1074 
  presubmit.ts     |   83.75 |    92.72 |   88.88 |   83.75 | ...77-578,655-685 
  ...ish-assets.ts |   77.18 |    82.14 |   71.42 |   77.18 | ...85-531,533-544 
  repo-context.ts  |   94.92 |    90.82 |     100 |   94.92 | ...67-368,376-377 
  ...ve-anchors.ts |   77.77 |    88.88 |      75 |   77.77 | ...77-182,194-211 
  run.ts           |   82.16 |    87.12 |   91.66 |   82.16 | ...52,468-516,529 
  save-artifact.ts |    89.9 |    81.81 |   94.11 |    89.9 | ...08-311,404-407 
  script-lint.ts   |   81.14 |    79.23 |   88.88 |   81.14 | ...59-773,775-797 
  submit.ts        |   83.77 |    83.95 |      90 |   83.77 | ...55,544,571-607 
  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.46 |    95.06 |   98.32 |   97.46 |                   
  agent-briefs.ts  |   98.98 |      100 |      50 |   98.98 | 735-736           
  anchors.ts       |     100 |    94.79 |     100 |     100 | ...33,169,178,225 
  assets.ts        |     100 |      100 |     100 |     100 |                   
  audit-layers.ts  |   99.04 |    97.36 |     100 |   99.04 | 223-224           
  authorization.ts |    92.4 |    92.59 |     100 |    92.4 | 127-133           
  budget.ts        |     100 |    97.14 |     100 |     100 | 513,553           
  coverage.ts      |   96.81 |    94.42 |     100 |   96.81 | ...85-486,526-537 
  deadline.ts      |   98.33 |    93.61 |     100 |   98.33 | ...88,237,629,661 
  diff-flags.ts    |     100 |        0 |     100 |     100 | 63                
  diff-plan.ts     |   98.73 |    93.01 |     100 |   98.73 | ...41,264,290-291 
  disk.ts          |     100 |      100 |     100 |     100 |                   
  effort.ts        |     100 |      100 |     100 |     100 |                   
  gh.ts            |   87.07 |    92.45 |   76.47 |   87.07 | ...72,309-310,337 
  git.ts           |   97.64 |    95.65 |     100 |   97.64 | 180-181           
  heavy.ts         |     100 |      100 |     100 |     100 |                   
  inline-counts.ts |     100 |      100 |     100 |     100 |                   
  ...audit-gate.ts |     100 |    96.15 |     100 |     100 | 107               
  ledger.ts        |     100 |      100 |     100 |     100 |                   
  local-diff.ts    |    84.4 |    88.46 |     100 |    84.4 | ...63-473,475-483 
  ...ry-context.ts |   96.19 |    94.93 |     100 |   96.19 | ...90-491,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         |     100 |     87.5 |     100 |     100 | 92                
  prompt-record.ts |   97.88 |    93.87 |     100 |   97.88 | 260-261,267       
  receipt.ts       |     100 |      100 |     100 |     100 |                   
  remote-match.ts  |   97.26 |    91.42 |     100 |   97.26 | 49-50             
  report.ts        |   94.68 |    93.75 |     100 |   94.68 | 189-193           
  ...ry-context.ts |     100 |    98.66 |     100 |     100 | 184               
  retirement.ts    |     100 |    92.39 |     100 |     100 | ...28,308-309,449 
  review-footer.ts |     100 |      100 |     100 |     100 |                   
  roster.ts        |     100 |    95.71 |     100 |     100 | 145,163,208       
  shell-quote.ts   |     100 |      100 |     100 |     100 |                   
  stale-bundle.ts  |   98.11 |    94.04 |     100 |   98.11 | 416,457,497-498   
  test-utils.ts    |     100 |      100 |     100 |     100 |                   
  toolchain.ts     |     100 |      100 |     100 |     100 |                   
  transcripts.ts   |   96.59 |    94.56 |     100 |   96.59 | ...08,297-298,323 
  ...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 |                   
 ...mands/sessions |   91.56 |    86.95 |   83.33 |   91.56 |                   
  common.ts        |     100 |      100 |     100 |     100 |                   
  list.ts          |   90.96 |    86.66 |   81.81 |   90.96 | 208-219,221-222   
 src/config        |    94.9 |    89.84 |   96.27 |    94.9 |                   
  ...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        |   88.93 |    88.59 |   83.33 |   88.93 | ...2451,2453-2461 
  ...cy-monitor.ts |   88.75 |    76.19 |     100 |   88.75 | ...3,90-92,98,101 
  ...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.47 |      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 |    77.77 |   83.33 |   95.23 |                   
  index.ts         |   95.65 |     87.5 |     100 |   95.65 | 117-118           
  scheduler.ts     |   96.55 |    77.77 |     100 |   96.55 | 19-20             
  types.ts         |       0 |        0 |       0 |       0 | 1                 
 ...ation/versions |   94.91 |      100 |     100 |   94.91 |                   
  ...-v2-shared.ts |     100 |      100 |     100 |     100 |                   
  v1-to-v2.ts      |   81.75 |      100 |     100 |   81.75 | ...28-229,231-247 
  v2-to-v3.ts      |     100 |      100 |     100 |     100 |                   
  v3-to-v4.ts      |     100 |      100 |     100 |     100 |                   
  v5-to-v4.ts      |      96 |      100 |     100 |      96 | 94-95,99          
 src/core          |     100 |      100 |     100 |     100 |                   
  auth.ts          |     100 |      100 |     100 |     100 |                   
  initializer.ts   |     100 |      100 |     100 |     100 |                   
  theme.ts         |     100 |      100 |     100 |     100 |                   
 src/dualOutput    |   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.2 |   95.29 |   98.12 |                   
  ...putAdapter.ts |   97.98 |    93.26 |   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         |   87.58 |    83.86 |   90.51 |   87.58 |                   
  ...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 | 685               
  ...cp-command.ts |     100 |      100 |     100 |     100 |                   
  ...horization.ts |   92.79 |    93.33 |    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 |   88.59 |    93.65 |   96.29 |   88.59 | ...95-207,451-454 
  ...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 
  daemon-logger.ts |    82.2 |    77.42 |   91.76 |    82.2 | ...1720,1747-1753 
  ...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.57 |     90.8 |     100 |   98.57 | ...1411,1413-1414 
  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 |    86.95 |     100 |   92.06 | ...72,287-293,316 
  ...-path-argv.ts |     100 |      100 |     100 |     100 |                   
  ...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-144             
  ...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.06 |    80.14 |   75.43 |   84.06 | ...7481,7487-7488 
  ...tup-errors.ts |     100 |      100 |     100 |     100 |                   
  ...-keepalive.ts |   94.22 |    88.99 |     100 |   94.22 | ...27,531-532,572 
  ...-lifecycle.ts |     100 |      100 |     100 |     100 |                   
  server.ts        |   90.67 |    91.22 |   71.81 |   90.67 | ...2744,2758-2762 
  ...-admission.ts |   98.24 |    94.73 |     100 |   98.24 | 79-80,303-304     
  ...on-helpers.ts |     100 |      100 |     100 |     100 |                   
  ...t-event-id.ts |     100 |    95.23 |     100 |     100 | 12                
  ...-admission.ts |   98.71 |    89.65 |     100 |   98.71 | 68                
  types.ts         |     100 |      100 |     100 |     100 |                   
  ...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 |   93.89 |     87.5 |     100 |   93.89 | ...18-519,525-526 
  ...e-remember.ts |   98.23 |    92.51 |     100 |   98.23 | ...36,340-345,386 
  ...te-runtime.ts |   83.98 |    90.29 |     100 |   83.98 | ...48-156,216-237 
  ...me-storage.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.26 |     100 |   91.63 | ...71-273,306-307 
 ...serve/acp-http |   78.26 |    80.03 |    93.1 |   78.26 |                   
  ...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 |    98.2 |    88.55 |     100 |    98.2 | 1015,1041-1052    
  dispatch.ts      |   73.87 |    77.71 |   94.23 |   73.87 | ...5240,5288-5294 
  index.ts         |   82.23 |    80.11 |   91.07 |   82.23 | ...2341,2425-2426 
  json-rpc.ts      |     100 |    96.96 |     100 |     100 | 92                
  safe-ws-send.ts  |   52.94 |    71.42 |     100 |   52.94 | 33-42,47-55       
  sse-stream.ts    |   93.96 |    88.88 |   84.61 |   93.96 | ...57-159,161-163 
  ...ort-stream.ts |       0 |        0 |       0 |       0 | 1                 
  ws-stream.ts     |   91.86 |       80 |     100 |   91.86 | 45,50,96,100-103  
 src/serve/auth    |   86.86 |     79.7 |   93.87 |   86.86 |                   
  device-flow.ts   |   96.35 |    80.57 |   97.61 |   96.35 | ...1358,1453,1519 
  ...w-provider.ts |   44.24 |    74.07 |   71.42 |   44.24 | ...23-284,297,301 
 ...rve/cdp-tunnel |   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             
 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    |   78.01 |    69.54 |   90.61 |   78.01 |                   
  ...en-context.ts |   95.74 |    81.25 |     100 |   95.74 | ...0,66-67,99-100 
  ...-workspace.ts |   88.63 |    82.53 |     100 |   88.63 | ...40-241,253-254 
  discovery.ts     |   85.77 |    76.92 |      90 |   85.77 | ...49-250,255-256 
  ...structions.ts |     100 |      100 |     100 |     100 |                   
  ...oordinator.ts |   82.67 |     76.8 |   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.3 |    59.78 |   93.33 |    86.3 | ...1160,1184-1191 
  ...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.83 |    77.58 |     100 |   94.83 | ...18,327-330,350 
  ...ion-source.ts |     100 |      100 |     100 |     100 |                   
  types.ts         |     100 |      100 |     100 |     100 |                   
 src/serve/routes  |   85.78 |    80.36 |    94.9 |   85.78 |                   
  a2ui-action.ts   |   96.84 |     88.5 |    87.5 |   96.84 | ...70-272,309-311 
  capabilities.ts  |   98.63 |    95.65 |     100 |   98.63 | 76                
  ...nel-notify.ts |   86.45 |       88 |     100 |   86.45 | ...,83-87,103-104 
  ...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          |    82.4 |    71.42 |     100 |    82.4 | ...-94,96-101,121 
  permission.ts    |     100 |     92.3 |     100 |     100 | 50,98             
  ...uled-tasks.ts |   87.29 |    82.94 |   92.59 |   87.29 | ...1275,1318-1319 
  ...on-runtime.ts |     100 |    90.47 |     100 |     100 | 58,94             
  session.ts       |   85.84 |    82.35 |   91.54 |   85.84 | ...4938,4940-4941 
  sse-events.ts    |   86.82 |    85.71 |   94.11 |   86.82 | ...16-927,930,937 
  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.92 |    79.69 |     100 |   90.92 | ...81-482,501-502 
  ...d-contacts.ts |     100 |      100 |     100 |     100 |                   
  ...controller.ts |   83.11 |    79.31 |      90 |   83.11 | ...1033,1039,1042 
  ...extensions.ts |   88.15 |    74.95 |   92.98 |   88.15 | ...2027,2072-2073 
  ...-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.41 |    84.13 |     100 |   87.41 | ...1660,1680-1685 
  ...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 |   78.92 |    66.21 |      80 |   78.92 | ...38-343,351-352 
  ...pace-voice.ts |   91.33 |    80.92 |     100 |   91.33 | ...70-673,676-678 
 src/serve/server  |   91.75 |    89.37 |   96.95 |   91.75 |                   
  access-log.ts    |   98.68 |     97.1 |     100 |   98.68 | 115,186           
  ...er-helpers.ts |   63.82 |    77.96 |   81.81 |   63.82 | ...16,330,332-347 
  ...w-registry.ts |    98.8 |    81.81 |     100 |    98.8 | 107               
  ...r-handlers.ts |   97.29 |       75 |     100 |   97.29 | 17                
  ...r-response.ts |   86.54 |    72.48 |     100 |   86.54 | ...49,766,829-838 
  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 |    73.33 |   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.55 |    87.72 |   97.14 |   89.55 | ...32-836,888-889 
  ...ion-export.ts |     100 |    94.44 |     100 |     100 | 64                
  session-list.ts  |   95.86 |    93.37 |     100 |   95.86 | ...-848,1026-1030 
  telemetry.ts     |   99.04 |    97.45 |     100 |   99.04 | ...37,652,794-796 
 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.65 |    87.73 |   91.11 |   90.65 |                   
  index.ts         |   90.13 |    87.04 |   89.74 |   90.13 | ...1464-1468,1471 
  types.ts         |     100 |      100 |     100 |     100 |                   
 src/services      |   92.49 |    89.25 |      98 |   92.49 |                   
  ...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 |   88.23 |    86.48 |     100 |   88.23 | ...94-199,232-233 
  ...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.24 |    75.55 |   67.03 |   73.24 |                   
  App.tsx          |   33.33 |       75 |   33.33 |   33.33 | 32-86             
  AppContainer.tsx |   74.45 |    72.09 |   68.57 |   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 |   70.51 |       74 |    62.5 |   70.51 | ...12,339,392-397 
  ...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.6 |   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 |    81.25 |     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 |   71.96 |    79.54 |   79.56 |   71.96 |                   
  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 |       0 |        0 |       0 |       0 | 1-598             
  DiffDialog.tsx   |    53.5 |     37.5 |   69.23 |    53.5 | ...32-737,747-760 
  ...ngsDialog.tsx |       0 |        0 |       0 |       0 | 1-195             
  EffortDialog.tsx |   97.36 |      100 |     100 |   97.36 | 55-56             
  ExitWarning.tsx  |     100 |      100 |     100 |     100 |                   
  ...hProgress.tsx |    87.8 |    33.33 |     100 |    87.8 | 28-31,56          
  ...ustDialog.tsx |     100 |      100 |     100 |     100 |                   
  Footer.tsx       |   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 |       0 |        0 |       0 |       0 | 1-56              
  ...onsDialog.tsx |       0 |        0 |       0 |       0 | 1-1004            
  ...ryDisplay.tsx |     100 |      100 |     100 |     100 |                   
  ...icePrompt.tsx |   92.64 |    85.71 |     100 |   92.64 | 102-106,134-139   
  PrepareLabel.tsx |   91.66 |    77.27 |     100 |   91.66 | 73-75,77-79,110   
  ...atePrompt.tsx |       0 |        0 |       0 |       0 | 1-134             
  ...geDisplay.tsx |     100 |      100 |     100 |     100 |                   
  ...ngDisplay.tsx |       0 |        0 |       0 |       0 | 1-39              
  ...hProgress.tsx |   85.25 |    88.46 |     100 |   85.25 | 121-147           
  ...dSelector.tsx |   92.79 |    82.65 |     100 |   92.79 | ...19-323,354-370 
  ...ionPicker.tsx |   83.66 |    72.13 |     100 |   83.66 | ...96,402,444-466 
  ...onPreview.tsx |   93.58 |    83.78 |     100 |   93.58 | ...,70-71,195-197 
  ...ryDisplay.tsx |     100 |      100 |     100 |     100 |                   
  ...putPrompt.tsx |   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 |       0 |        0 |       0 |       0 | 1-40              
  ...iewDialog.tsx |   97.77 |    87.67 |     100 |   97.77 | ...97,305-307,324 
  ...tsDisplay.tsx |   95.86 |       75 |     100 |   95.86 | 67-71             
  ...ionPicker.tsx |       0 |        0 |       0 |       0 | 1-172             
  ...tivityTab.tsx |    3.94 |      100 |       0 |    3.94 | 27-275            
  StatsDialog.tsx  |    8.64 |      100 |       0 |    8.64 | ...76-111,130-322 
  StatsDisplay.tsx |     100 |      100 |     100 |     100 |                   
  ...ciencyTab.tsx |    78.9 |    56.52 |     100 |    78.9 | ...26,213,262-288 
  ...atmapView.tsx |    8.98 |      100 |       0 |    8.98 | 20-107            
  ...essionTab.tsx |      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 |       0 |        0 |       0 |       0 | 1-134             
  ...xitDialog.tsx |   80.36 |    43.47 |      60 |   80.36 | ...24-238,248-251 
  ...odeVisuals.ts |   97.22 |    85.71 |     100 |   97.22 | 25                
  ...s-helpers.tsx |   66.25 |    81.25 |      50 |   66.25 | 25-32,46-53,62-72 
 ...nts/agent-view |   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 |    42.3 |    68.69 |   73.68 |    42.3 |                   
  ArenaCards.tsx   |   73.06 |    71.79 |   85.71 |   73.06 | ...83-185,321-326 
  ...ectDialog.tsx |   83.48 |    69.86 |   88.88 |   83.48 | ...88-392,409-410 
  ...artDialog.tsx |       0 |        0 |       0 |       0 | 1-166             
  ...tusDialog.tsx |       0 |        0 |       0 |       0 | 1-288             
  ...topDialog.tsx |       0 |        0 |       0 |       0 | 1-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 |       0 |        0 |       0 |       0 |                   
  ...gerDialog.tsx |       0 |        0 |       0 |       0 | 1-681             
 ...ents/subagents |       0 |        0 |       0 |       0 |                   
  constants.ts     |       0 |        0 |       0 |       0 | 1-71              
  index.ts         |       0 |        0 |       0 |       0 | 1-11              
  reducers.tsx     |       0 |        0 |       0 |       0 | 1-190             
  types.ts         |       0 |        0 |       0 |       0 | 1-125             
  utils.ts         |       0 |        0 |       0 |       0 | 1-102             
 ...bagents/create |       0 |        0 |       0 |       0 |                   
  ...ionWizard.tsx |       0 |        0 |       0 |       0 | 1-299             
  ...rSelector.tsx |       0 |        0 |       0 |       0 | 1-85              
  ...onSummary.tsx |       0 |        0 |       0 |       0 | 1-331             
  ...tionInput.tsx |       0 |        0 |       0 |       0 | 1-177             
  ...dSelector.tsx |       0 |        0 |       0 |       0 | 1-63              
  ...nSelector.tsx |       0 |        0 |       0 |       0 | 1-58              
  ...EntryStep.tsx |       0 |        0 |       0 |       0 | 1-78              
  ToolSelector.tsx |       0 |        0 |       0 |       0 | 1-253             
 ...bagents/manage |   14.14 |    53.19 |    37.5 |   14.14 |                   
  ...ctionStep.tsx |       0 |        0 |       0 |       0 | 1-103             
  ...eleteStep.tsx |       0 |        0 |       0 |       0 | 1-62              
  ...tEditStep.tsx |       0 |        0 |       0 |       0 | 1-124             
  ...ctionStep.tsx |   35.61 |    59.52 |     100 |   35.61 | ...21-433,438-440 
  ...iewerStep.tsx |       0 |        0 |       0 |       0 | 1-73              
  ...gerDialog.tsx |       0 |        0 |       0 |       0 | 1-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    |       0 |        0 |       0 |       0 |                   
  ...ngsManager.ts |       0 |        0 |       0 |       0 | 1-67              
 src/ui/hooks      |   85.64 |    83.19 |   87.86 |   85.64 |                   
  ...dProcessor.ts |   85.53 |    85.13 |     100 |   85.53 | ...-970,1017-1018 
  ...ention-ref.ts |   97.72 |       84 |     100 |   97.72 | 65                
  keyToAnsi.ts     |    3.92 |      100 |       0 |    3.92 | 19-77             
  ...esourceRef.ts |     100 |      100 |     100 |     100 |                   
  ...completion.ts |     100 |    95.45 |     100 |     100 | 95                
  ...ention-ref.ts |     100 |      100 |     100 |     100 |                   
  ...dProcessor.ts |   94.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 |      52 |    63.63 |     100 |      52 | ...59,67-70,76-87 
  ...odeCommand.ts |   58.82 |      100 |     100 |   58.82 | 28,33-48          
  ...enaCommand.ts |      85 |      100 |     100 |      85 | 23-24,29          
  ...aInProcess.ts |   27.92 |       80 |      25 |   27.92 | ...69-170,173-175 
  ...Completion.ts |   86.44 |    88.48 |     100 |   86.44 | ...14-515,525-541 
  ...ifications.ts |   87.82 |    96.77 |     100 |   87.82 | 138-152           
  ...tIndicator.ts |   88.28 |    81.57 |     100 |   88.28 | ...66,175,179-187 
  ...waySummary.ts |   96.26 |       75 |     100 |   96.26 | 126-128,170       
  ...ndTaskView.ts |   94.89 |    77.55 |     100 |   94.89 | 164-168,257,263   
  ...chedScroll.ts |     100 |      100 |     100 |     100 |                   
  ...ketedPaste.ts |    23.8 |      100 |       0 |    23.8 | 19-37             
  ...nchCommand.ts |   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   |       0 |        0 |       0 |       0 | 1-87              
  ...oublePress.ts |   53.12 |       75 |     100 |   53.12 | 33-35,41-54       
  ...orSettings.ts |     100 |      100 |     100 |     100 |                   
  ...Completion.ts |   99.12 |    97.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 |   86.08 |    81.23 |   76.92 |   86.08 | ...5198-5200,5202 
  ...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.48 |    88.88 |     100 |   89.48 | ...54-456,489-499 
  ...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.26 |     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.19 |     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.54 |     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.57 |    85.61 |   95.76 |   87.57 |                   
  ...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       
  ...ow-keyword.ts |     100 |      100 |     100 |     100 |                   
 ...i/utils/export |   75.03 |     60.3 |   94.59 |   75.03 |                   
  collect.ts       |   71.27 |    66.38 |      96 |   71.27 | ...90-633,655-656 
  index.ts         |     100 |      100 |     100 |     100 |                   
  normalize.ts     |   80.42 |    50.68 |     100 |   80.42 | ...59-364,376-378 
  types.ts         |       0 |        0 |       0 |       0 | 1                 
  utils.ts         |     100 |      100 |     100 |     100 |                   
 ...ort/formatters |   52.92 |    47.22 |   71.42 |   52.92 |                   
  html.ts          |   84.61 |       50 |     100 |   84.61 | ...53,57-58,62-63 
  json.ts          |     100 |      100 |     100 |     100 |                   
  jsonl.ts         |   82.45 |     37.5 |     100 |   82.45 | ...48,50-51,65-66 
  markdown.ts      |   36.32 |    47.05 |      50 |   36.32 | ...16-219,233-295 
 src/ui/voice      |   81.27 |    79.92 |   81.94 |   81.27 |                   
  ...d-recorder.ts |     6.2 |      100 |       0 |     6.2 | ...33-159,162-163 
  ...o-recorder.ts |   84.61 |    93.33 |   57.14 |   84.61 | ...16-117,131-136 
  ...me-session.ts |   91.09 |     92.1 |     100 |   91.09 | ...99,305,316-319 
  sox-recorder.ts  |    92.7 |    71.87 |     100 |    92.7 | ...34-135,153-154 
  ...ailability.ts |     100 |      100 |     100 |     100 |                   
  ...e-keyterms.ts |     100 |      100 |     100 |     100 |                   
  voice-model.ts   |     100 |      100 |     100 |     100 |                   
  ...e-recorder.ts |   88.29 |    67.74 |   81.81 |   88.29 | ...,98-99,112,115 
  voice-refine.ts  |     100 |    93.33 |     100 |     100 | 92                
  ...ream-retry.ts |   86.79 |       70 |     100 |   86.79 | 16-18,48-49,59-60 
  ...am-session.ts |   88.02 |    66.66 |   84.61 |   88.02 | ...26,343-345,363 
  ...ranscriber.ts |     100 |      100 |     100 |     100 |                   
 src/utils         |   81.63 |    87.34 |   92.75 |   81.63 |                   
  ...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.05 |     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.85 |     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 |                   
  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.12 |    90.27 |     100 |   95.12 | ...54-255,260-264 
  ...InfoFields.ts |    87.5 |    65.85 |     100 |    87.5 | ...24-125,146-147 
  ...alSequence.ts |     100 |    97.61 |     100 |     100 | 60                
  ...iffPreview.ts |   76.47 |       25 |     100 |   76.47 | 13,17,23-24       
  ...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 |                   
  windowTitle.ts   |   96.55 |    94.73 |     100 |   96.55 | 56-57             
  ...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          |    87.9 |    86.45 |   89.45 |    87.9 |                   
 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.38 |    84.54 |   94.85 |   90.38 |                   
  ...transcript.ts |   87.63 |    83.52 |     100 |   87.63 | ...80,588,594-598 
  ...ent-resume.ts |   85.59 |    77.55 |   83.33 |   85.59 | ...1793-1797,1800 
  ...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.32 |    67.71 |   78.94 |   76.32 |                   
  ...gentClient.ts |   79.47 |    88.88 |   81.81 |   79.47 | ...68-183,189-204 
  ArenaManager.ts  |   75.11 |    64.51 |   78.57 |   75.11 | ...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.11 |    86.68 |   89.23 |   91.11 |                   
  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.4 |       90 |   83.78 |    92.4 | ...1862,1911-1914 
  ...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.72 |    84.65 |   89.05 |   82.72 |                   
  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   |   92.02 |    94.91 |   95.23 |   92.02 | ...31-332,368-378 
  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.81 |    87.18 |   75.53 |   84.81 |                   
  approval-mode.ts |     100 |      100 |     100 |     100 |                   
  ...xtDefaults.ts |     100 |      100 |     100 |     100 |                   
  config.ts        |   84.13 |    86.91 |   73.98 |   84.13 | ...8535,8539-8540 
  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.37 |    88.08 |   93.29 |   92.37 |                   
  baseLlmClient.ts |    88.4 |     83.8 |   81.81 |    88.4 | ...59,672,678-680 
  client.ts        |   92.05 |     87.4 |   91.66 |   92.05 | ...3987,4085-4086 
  ...tGenerator.ts |   86.34 |    87.34 |   84.61 |   86.34 | ...96-497,542-548 
  ...lScheduler.ts |   90.04 |    84.67 |   96.15 |   90.04 | ...6216,6244-6260 
  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 | 68-72             
  ...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          |   98.67 |    93.12 |     100 |   98.67 | ...79,707-708,755 
  ...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 |   95.88 |    90.34 |    92.3 |   95.88 |                   
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...tGenerator.ts |   95.81 |    89.63 |   91.89 |   95.81 | ...1221-1222,1250 
  ...tDetection.ts |     100 |      100 |     100 |     100 |                   
 ...ntentGenerator |   91.71 |    90.53 |   95.61 |   91.71 |                   
  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         |   60.31 |       75 |      50 |   60.31 | ...71,74-78,90-94 
  ...tGenerator.ts |    66.4 |    70.58 |   88.88 |    66.4 | ...51-157,168-169 
  pipeline.ts      |   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.36 |    92.19 |    98.5 |   97.36 |                   
  dashscope.ts     |   98.33 |    94.97 |   96.42 |   98.33 | ...91-692,834-835 
  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.9 |    78.92 |    90.9 |    79.9 |                   
  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.76 |    64.76 |   71.42 |   71.76 | ...53-654,661-662 
  ...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         |   93.25 |    88.99 |   93.68 |   93.25 |                   
  ...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.79 |     88.5 |   96.42 |   88.79 | ...04-805,828-831 
  ...projection.ts |   66.66 |    72.97 |   33.33 |   66.66 | ...87,190,194-196 
  ...ersistence.ts |   87.73 |    84.84 |      80 |   87.73 | ...-94,97,101-106 
  goal-protocol.ts |      92 |    93.33 |      80 |      92 | 102-103,167-168   
  goal-reducer.ts  |    93.4 |    90.65 |   96.96 |    93.4 | ...27,501,519-520 
  goal-runtime.ts  |   97.44 |    89.68 |   97.67 |   97.44 | ...1216-1217,1338 
  goal-tools.ts    |   98.22 |    93.02 |      95 |   98.22 | ...46-147,248-249 
  ...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.36 |   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.12 |   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        |   87.83 |    83.82 |   90.47 |   87.83 |                   
  ...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 |       80 |     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 |    87.03 |     100 |   97.26 | ...10-218,222,225 
  recall.ts        |   82.06 |       75 |    90.9 |   82.06 | ...59-364,395-406 
  refresh.ts       |   93.58 |    89.58 |     100 |   93.58 | ...75-176,183-184 
  ...ceSelector.ts |    93.1 |    81.81 |     100 |    93.1 | ...25,127-128,136 
  remember.ts      |   98.89 |    90.19 |     100 |   98.89 | 50,70             
  scan.ts          |   93.12 |    77.41 |     100 |   93.12 | ...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 |     82.6 |     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.97 |   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 |    47.82 |   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.17 |   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 |    89.01 |      80 |   86.63 | ...1111,1217-1221 
  rule-parser.ts   |   94.49 |     92.7 |     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      |   89.83 |    84.84 |   96.92 |   89.83 |                   
  ...ionTrailer.ts |     100 |      100 |     100 |     100 |                   
  ...llRegistry.ts |   98.46 |    87.17 |     100 |   98.46 | 81-82,105,468-469 
  ...ionService.ts |   97.51 |    96.15 |     100 |   97.51 | ...,929,1072-1080 
  ...ingService.ts |    91.6 |    85.47 |   95.77 |    91.6 | ...2155,2182-2183 
  ...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.76 |     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.85 |     100 |   97.74 | 298-308,646       
  ...ersistence.ts |   90.95 |    78.75 |     100 |   90.95 | ...78,963-964,992 
  ...on-service.ts |   94.49 |    92.26 |   97.14 |   94.49 | ...98-600,656-664 
  ...ce-service.ts |    98.5 |    94.11 |    90.9 |    98.5 | 64-65             
  ...ipt-reader.ts |   94.55 |    89.78 |   96.66 |   94.55 | ...1353-1354,1422 
  ...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.26 |    85.35 |   97.22 |   89.26 | ...2537,2613-2633 
  sessionTitle.ts  |   95.75 |    77.41 |     100 |   95.75 | ...53-256,287-288 
  ...ionService.ts |    84.4 |    78.45 |   97.18 |    84.4 | ...2493,2499-2504 
  ...pInhibitor.ts |   97.42 |    92.77 |     100 |   97.42 | ...30,169,369-370 
  ...Estimation.ts |     100 |    88.23 |     100 |     100 | 118-119           
  ...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.8 |     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.89 |   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.5 |     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     |   81.83 |    84.11 |   84.92 |   81.83 |                   
  ...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.31 |    74.62 |   73.68 |   76.31 | ...80,387-389,405 
  ...attributes.ts |   95.15 |    87.27 |     100 |   95.15 | ...97-198,216-217 
  ...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.1 |    95.72 |      95 |    99.1 | 145,369-370       
  ...t.circular.ts |       0 |        0 |       0 |       0 | 1-128             
  loggers.ts       |   60.25 |    77.03 |   66.66 |   60.25 | ...1492,1509-1529 
  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      |   91.06 |    87.15 |   68.75 |   91.06 | ...32,482-483,499 
  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.1 |    88.68 |   96.77 |    91.1 | ...1737,1768-1771 
  ...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.27 |    85.09 |   88.72 |   86.27 |                   
  ...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.81 |    84.22 |   91.91 |   78.81 | ...5036,5099-5100 
  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   |   87.02 |    87.31 |   88.69 |   87.02 |                   
  agent.ts         |   85.64 |    86.19 |   86.31 |   85.64 | ...4366,4400-4410 
  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.91 |    89.65 |   96.89 |   92.91 |                   
  LruCache.ts      |     100 |      100 |     100 |     100 |                   
  ...Controller.ts |     100 |      100 |     100 |     100 |                   
  ...ssageQueue.ts |     100 |      100 |     100 |     100 |                   
  ...cFileWrite.ts |   94.94 |    92.47 |     100 |   94.94 | ...43-544,651-655 
  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        |   83.39 |    95.17 |    61.9 |   83.39 | ...81-397,401-407 
  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.95 |   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.02 |    81.25 |   85.71 |   78.02 | ...22-123,147-198 
  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.54 |     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         |   93.61 |    92.42 |     100 |   93.61 | ...62-563,565-567 
  pdf.ts           |   92.17 |    85.81 |     100 |   92.17 | ...64-565,606-611 
  projectPath.ts   |     100 |      100 |     100 |     100 |                   
  projectRoot.ts   |   71.73 |    78.57 |     100 |   71.73 | 54-66             
  ...ectSummary.ts |   89.62 |    72.41 |     100 |   89.62 | ...40-145,196-199 
  ...tIdContext.ts |     100 |      100 |     100 |     100 |                   
  proxyUtils.ts    |     100 |      100 |     100 |     100 |                   
  ...rDetection.ts |   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.11 |     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 |   95.98 |    83.96 |     100 |   95.98 | ...70,386,466,485 
  ...-pager-env.ts |     100 |      100 |     100 |     100 |                   
  ...fety-rules.ts |     100 |     89.7 |     100 |     100 | ...01,304,309-311 
  shell-utils.ts   |   86.07 |    88.34 |     100 |   86.07 | ...2269,2276-2280 
  ...lAstParser.ts |   98.27 |    91.38 |     100 |   98.27 | ...1321-1323,1333 
  ...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 |       64 |      75 |   54.62 | ...03-105,108-134 
  ...Compaction.ts |   96.13 |    96.42 |     100 |   96.13 | ...34-339,341-346 
  ...pt-records.ts |    87.5 |    86.13 |     100 |    87.5 | ...76-480,510-525 
  truncation.ts    |   90.61 |    90.43 |     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.

@wenshao

wenshao commented Aug 13, 2026

Copy link
Copy Markdown
Collaborator Author

@qwen-code /triage

@qwen-code-ci-bot

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

Copy link
Copy Markdown
Collaborator

Re-run after the fourth commit (2fa20e5) — gate re-checked on the new head.

  • Template: still complete ✓ — the body is unchanged and carries every required heading.
  • Problem: unchanged — real and structural: the incremental anchor lived only in one clone's .qwen/review-cache/, so every fresh checkout (CI re-review, Incremental (delta) review: review only new commits since the last reviewed SHA instead of restarting full passes #8946's core scenario) recovered the previous round's findings but not "last reviewed at", and the incremental range silently degraded to the full diff.
  • Direction: aligned — the review skill's own cross-environment story, inside Incremental (delta) review: review only new commits since the last reviewed SHA instead of restarting full passes #8946, no public contract touched.
  • Size: 113 production lines (compose-review.ts +32/−5, ledger.ts +63/−11, pr-context.ts +1/−1), 216 test lines, 6 lines of SKILL.md. Well under any threshold; the only core-path contact is the SKILL.md documentation, which carries the Tier-2 bar and is structurally checked by SKILL.test.ts (confirmed this round that the test does not pin the edited Step 8 paragraph).
  • Approach: still minimal — 2fa20e5 answers exactly the two items open since the last pass: the verifier's §4.1 (the parser's own count-cap truncation could read as complete and keep a live anchor — now counted into dropped, so the anchor is forfeited) and the last human review round's pair (fail-closed predicate collapsed onto the module's verdict; Step 8's cache net aligned with the marker net). Nothing unrelated.
  • Risk: no high-risk-path matches; no elevated risk signals.

Moving on to code review. 🔍

中文说明

第四个 commit(2fa20e5)后的 re-run——gate 在新 head 上重新检查。

  • 模板:仍然完整 ✓——正文未变,所有必需标题齐全。
  • 问题:不变——真实且结构性:增量锚点只存在于单个 clone 的 .qwen/review-cache/,每个全新检出(CI 重审,Incremental (delta) review: review only new commits since the last reviewed SHA instead of restarting full passes #8946 的核心场景)能恢复上一轮的 findings,却恢复不了"上次审到哪",增量范围每次都静默退化为全量 diff。
  • 方向:对齐——review skill 自身的跨环境能力,在 Incremental (delta) review: review only new commits since the last reviewed SHA instead of restarting full passes #8946 范围内,不触及任何公共契约。
  • 规模:113 行生产代码(compose-review.ts +32/−5、ledger.ts +63/−11、pr-context.ts +1/−1),216 行测试,6 行 SKILL.md。远低于任何阈值;唯一的核心路径接触是 SKILL.md 文档,按 Tier-2 标准评估,且有 SKILL.test.ts 的结构检查兜底(本轮已确认该测试不钉住被改动的 Step 8 段落)。
  • 方案:仍然最小化——2fa20e5 恰好回应上次通过后遗留的两项:验证报告 §4.1(解析端自身的数量上限截断会被读成完整清单并携带活锚点——现计入 dropped,锚点随之扣留)以及最后一轮人工 review 的两点(fail-closed 谓词收敛到模块自己的判定;Step 8 的 cache 判定网与 marker 判定网对齐)。无无关改动。
  • 风险:未命中高风险路径;无升级风险信号。

进入代码审查。🔍

Qwen Code · qwen3.8-max

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

@qwen-code-ci-bot

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

Copy link
Copy Markdown
Collaborator

Code review of 2fa20e5, verified against the source at the pinned head — not just the diff.

Independent proposal first: for the verifier's §4.1 I would count the parser's own slice as truncation — dropped = declared + overflow — so the existing !dropped anchor gate forfeits it with no new machinery; for the fail-closed predicate I would fold it onto cappedBy and keep exactly the one raw check the cap list cannot express. The commit does both, and then pins both.

What I verified in the source:

  • The parser's count cap binds on READ — §4.1 closed. parseLedger now computes dropped = declared + (valid.length − findings.length) || undefined: a hand-edited 51-entry marker parses as 50 findings with dropped: 1, and the anchor is forfeited through the same !dropped gate the serializer obeys — the marker both renders PARTIAL and loses its anchor, one step further than the minimal gate the verification suggested. I checked the edges in the code: only VALID entries count toward the overflow (invalid ones never were findings), exactly-at-cap stays clean (dropped undefined, sha rides), and dropped: 0/-2 still read as no-truncation. The new fixture pins the exact probe-measured shape (51 → 50 kept, dropped = 1, sha gone).
  • The fail-closed collapse is behaviorally sound. The predicate is now (cannotTellCriticals?.length ?? 0) > 0 || cappedBy.length > 0. I confirmed at the cap-construction site that every folded input still pushes its own cap — unreviewed-dimension (named input plus coverage entries), uncoverable-chunk, context-unavailable (strict toBool) — so nothing the old five-condition form caught can slip through, and the collapse removes duplication, not coverage. The one surviving raw check is load-bearing, not vestigial: the cap side trim-filters cannotTellCriticals (confirmed the .filter(e => e.trim() !== '') at its derivation), so a whitespace-only entry pushes no cap while Step 8's contract is "any entry". The new loop case [' '] asserts cappedBy is EMPTY while the sha is withheld — delete the raw check and exactly that case fails.
  • Cache and marker now share one net. Step 8's cache-skip enumeration names "any cap in the composed verdict", and the Ledger.sha doc restates the same net — the two anchors can no longer disagree about what a clean round is, which closes the leak the last review round's failure scenario described.
  • The verifier's §4.2/§4.3 completeness tier is unchanged and was explicitly non-blocking: the write-side truncation guard stays pinned by round-trip composition, and the render escaper still has no non-hex fixture.

No new concerns; the diff carries nothing beyond these fixes.

Testing evidence — the PR's own CI on the reviewed commit, quoted from the API (per policy I do not build or run PR code):

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

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

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

The Linux unit suite is still running on this commit at review time — it takes ~30 minutes, and the finalize job rewrites the table above in place once CI settles; macOS/Windows unit tests and CLI integration tests are skipped for this branch. A fresh sandboxed verification on this head was triggered alongside this triage run and posts its own report. Not verified: a live multi-round /review exercise — Step 1's agent-side consumption in SKILL.md (ancestry validation, same-SHA stop) is model behavior neither unit tests nor the sandbox pin. Sandboxed verification would settle the mechanical remainder: @qwen-code /tmux — a real two-round /review on a scratch PR, confirming round 2 scopes to the recovered anchor instead of the full diff.

中文说明

2fa20e5 的代码审查——对照钉住 head 的源码验证,而不只是看 diff。

先说独立方案:对验证报告 §4.1,我会把解析端自身的切片计为截断——dropped = declared + overflow——让既有的 !dropped 锚点门直接扣留它,不引入任何新机制;对 fail-closed 谓词,我会把它收敛到 cappedBy 上,只保留 cap 清单无法表达的那一条原始检查。这个 commit 两样都做了,而且都钉住了。

我在源码里验证了什么:

  • 解析端的数量上限在读侧也生效——§4.1 闭环。 parseLedger 现在计算 dropped = declared + (valid.length − findings.length) || undefined:手工编辑的 51 条 marker 解析为 50 条 findings 且 dropped: 1,锚点经与序列化端相同的 !dropped 门被扣留——marker 既渲染 PARTIAL 又失去锚点,比验证建议的最小门控多走了一步。我在代码里核过边界:只有 VALID 条目计入溢出(非法条目本就不是 findings),恰好压线仍算完整(dropped 为 undefined,sha 随行),dropped: 0/-2 依旧不算截断。新 fixture 钉住的正是探测实测的形状(51 → 保留 50,dropped = 1,sha 消失)。
  • fail-closed 收敛在行为上是可靠的。 谓词现在是 (cannotTellCriticals?.length ?? 0) > 0 || cappedBy.length > 0。我在 cap 构造点确认每一个被折叠的输入仍然推入自己的 cap——unreviewed-dimension(具名输入加 coverage 条目)、uncoverable-chunkcontext-unavailable(严格 toBool)——所以旧五条件形式能拦住的任何一种情况都漏不过去,收敛去掉的是重复,不是覆盖。唯一保留的原始检查是承重墙而非残留:cap 一侧对 cannotTellCriticals 做了 trim 过滤(已确认其推导处的 .filter(e => e.trim() !== '')),纯空白条目不会推入任何 cap,而 Step 8 的契约是"任一条目"。新增的循环用例 [' '] 断言 cappedBy 为空而 sha 被扣留——删掉原始检查,恰好只有这一例失败。
  • cache 与 marker 现在共用同一张判定网。 Step 8 的 cache 跳过枚举写明了"合成判定中的任何 cap",Ledger.sha 的文档注释复述同一张网——两个锚点不再可能对"什么是干净轮"产生分歧,关掉了上一轮 review 失败场景里描述的那个泄漏。
  • 验证报告的 §4.2/§4.3 完整档未变、本就明确不阻塞:写侧截断门仍由 round-trip 组合钉住,渲染转义器仍无非 hex fixture。

无新问题;diff 里没有超出这些修复的任何东西。

测试证据——被审 commit 上 PR 自己的 CI,经 API 原文引用(按规则不构建、不运行 PR 代码):Linux 单测在审查时仍在运行(约 30 分钟,落定后 finalize 任务会就地更新上方表格);macOS/Windows 单测与 CLI 集成测试在此分支 skipped。针对该 head 的新一轮沙箱验证已随本次 triage 触发,会单独发布报告。未验证:真实多轮 /review 演练——SKILL.md Step 1 中 agent 侧的消费(祖先校验、same-SHA 停止)是模型行为,单测与沙盒都钉不住。沙盒验证可以补上剩余的机械环节:@qwen-code /tmux——在临时 PR 上真实跑两轮 /review,确认第二轮收窄到恢复出的锚点而非全量 diff。

Qwen Code · qwen3.8-max

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

@qwen-code-ci-bot

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

Copy link
Copy Markdown
Collaborator

Confidence: 4/5 — every open finding is closed with source-verified fixes; the one standing reservation is unchanged and non-blocking.

Stepping back: the last pass left two open items — the verifier's §4.1 and the final human review round's pair — and 2fa20e5 closes both with exactly the shapes I proposed independently before reading the diff. The count-cap fix folds the parser's own slice into dropped so the anchor forfeits through the gate that already existed, edges checked one by one; the fail-closed collapse removes duplication without removing coverage — each folded input provably pushes its own cap, and the surviving raw check has a fixture that fails exactly when it is deleted. Six months from now this reads as the way the marker should have worked from day one.

The one reservation is unchanged and was always a follow-up, not a fix demand: the live multi-round exercise stays deferred — Step 1's agent-side consumption (ancestry validation, same-SHA stop) is model behavior neither the unit seam nor the sandbox pins.

Housekeeping: the two stale change-requests this bot left on the original head — the template gate and the first findings round — were dismissed with this re-run; both were resolved by later commits (body rewrite; 39c85d0/9ee7413 re-verified in source) and were only holding the queue.

Verdict: approve. CI is still running on the reviewed commit, so approval is deferred to green rather than posted now. The approval guardrail does not apply (same-repo branch, feat type).

中文说明

置信度:4/5 —— 所有未决 findings 均已由经源码验证的修复闭环;唯一保留意见不变、不阻塞。

退一步看:上次通过留下两项未决——验证报告 §4.1 与最后一轮人工 review 的两点——2fa20e5 以我在读 diff 之前独立提出的形状全部闭环。数量上限修复把解析端自身的切片计入 dropped,锚点经由既有的门被扣留,边界逐一核过;fail-closed 收敛去掉了重复而没有去掉覆盖——每个被折叠的输入都可证地推入自己的 cap,保留下来的原始检查有一个"删掉它就恰好失败"的 fixture。六个月后再看,这就像 marker 从第一天起就该有的样子。

唯一保留意见不变、且从来就是后续跟进项而非修改要求:真实多轮演练仍留作后续——Step 1 中 agent 侧的消费(祖先校验、same-SHA 停止)是模型行为,单元接缝与沙盒都钉不住。

例行清理:本机器人在最初 head 上留下的两个过期 change-request——模板门禁与第一轮 findings——已随本次 re-run 解散;两者均已被后续 commit 解决(正文重写;39c85d0/9ee7413 并经源码复核),此前只是卡在队列里。

结论:approve。被审 commit 的 CI 仍在运行,因此批准推迟到全绿时执行,而不是现在发出。approve 护栏不适用(同仓库分支、feat 类型)。

Qwen Code · qwen3.8-max

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

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

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

LGTM, looks ready to ship. ✅

@qwen-code-ci-bot

Copy link
Copy Markdown
Collaborator

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

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

Scripted assertions: 2815 passed · 3 failed · 2818 total

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

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

脚本断言:2815 通过 · 3 失败 · 2818 总计

Verification report

PR 9067 deep verification — feat(review): carry the incremental anchor sha in the posted ledger marker

Verdict: findings — assertions 2815 pass / 3 fail / 2818 total. Verified head: 027b3546f262a1e97e65d91578f3b46521a891aa (merge-ref checkout, base 52cfb18). The central claim is proven load-bearing by A/B, the security posture of the new field holds every probe, and all four new guards are pinned by their intended tests. The 3 failing assertions are the finding in §4.1: a round that compose-review itself deterministically caps still certifies the anchor — violating the PR's own stated invariant ("only clean rounds write the sha").

中文摘要
  • 结论findings(2815 通过 / 3 失败)。核心功能经 A/B 证实有效且必要;新字段的安全处理通过了全部 28 项伪造/畸形探测;4 个新守卫均被其对应测试钉死(4/4 突变体被杀)。
  • A/B 结论:同一段"已发布评审正文",head 构建的 parseLedger 恢复出 "sha":"deadbeef00112233",base 构建恢复出同构但无 sha 字段的 ledger(见 01-ab-head-vs-base-anchor-recovery.png)。干净的 compose 运行把 plan.fetchedSha 写入 marker;四类 fail-closed 输入均 withheld findings 但保留 anchor withheld。
  • Findingscompose-review 的正文自身有 7 个确定性封顶条件(cappedBy),但 marker 的 failClosed 只读模型上报的 4 个字段。实测:一个被模块自己判定为 "⚠️ could not certify that any of this diff was reviewed" 的轮次,marker 仍携带 "sha":"deadbeef00112233"02-capped-round-still-carries-anchor.png)。后果:下一轮(尤其 CI 新环境)可能据此缩小增量 diff 范围、甚至触发 same-SHA 快捷跳过,正好落入该 PR 注释声称要防止的"缺口永不复审"失败模式。已实测修复:把 cappedBy 并入 failClosed 后探针由红转绿,套件影响恰为 1 个测试变红——即 PR 自己的"clean run"测试,因为它的 fixture 本来就是一个被封顶的轮次(缺 diffPathAbsolute)。
  • 未覆盖:SKILL.md 中 agent 侧对 anchor 的消费(git cat-file -e / merge-base --is-ancestor 校验、same-SHA 停止、side-file 与 cache 的轮次优先级)为模型行为而非可执行代码,未端到端演练;真实 GitHub 发布→恢复回路无 token,未走真实 API(用合成已发布正文复现了 wire 形状,非触发链路)。

1. Central claim and A/B proof

Central claim: the posted review's machine-ledger marker now carries sha (the head commit the round reviewed), so a fresh environment recovers "last reviewed at" from the posted body and scopes its incremental diff from it — withheld on fail-closed rounds, field-level-dropped when malformed.

The diff is 7 files, +129/−5: Ledger.sha + SHA_RE (/^[0-9a-f]{7,64}$/) in lib/ledger.ts (serialize validates on write, parse validates on read), ledgerMarkerFor computes a 4-condition failClosed and reads plan.fetchedSha in compose-review.ts, renderLedgerSection names the anchor in pr-context.ts, plus SKILL.md instructions and tests. Write/read-site trace: fetchedSha is written into the plan by fetch-pr.ts (git rev-parse of the PR ref — production field, not test-only); the side file writer (pr-context.ts:981) is JSON.stringify(prevLedger) of the parsed ledger, so sha rides automatically; latestOwnLedger passes the parsed ledger through untouched; submit.ts:232 and the CLI handler both go through composeReview, the single chokepoint where the marker is appended.

A/B: identical scenarios driven through the compiled dist/ of head and of a base worktree (HEAD^1, packages/cli rebuilt with tsc --build; log: logs/base-build.log). Expectations are encoded per arm, so both arms print all-PASS only if head has the anchor behavior and base lacks it; a wrong control (base accidentally loading head code) would fail cells 1/2/3/5b/6. The flip cells, as observed:

cell observable head base
parse an already-posted body parseLedger(body) {v:1,round:3,findings:[…],sha:"deadbeef00112233"} {v:1,round:3,findings:[…]} — same ledger, no anchor
clean composeReview marker in returned body sha = plan.fetchedSha no sha key
fail-closed ×4 (input fields) marker sha withheld, findings ride n/a (no field), findings ride
round carry-over via side file marker round 4→5, anchor = this round's head, not the side file's stale one round 4→5, no anchor
renderLedgerSection rendered section names reviewed at `abc1234def56789` ; silent without sha silent
truncation pressure (50 findings, 8 KiB cap) marker sha survives, dropped reported no anchor

22/22 assertions per arm; raw runs in logs/ab-head.log, logs/ab-base.log; witness 01-ab-head-vs-base-anchor-recovery.png.

Control purity note: the emitted base closure's only bare specifier is @qwen-code/qwen-code-core (realpath /__w/qwen-code/qwen-code/packages/core, i.e. the head tree), and the PR changes no core TypeScript — only the SKILL.md data file — so the link is not a confound for the code under test; ledger.js and compose-review.js have no bare specifiers at all. The base tsc --build reported type errors confined to unrelated UI test files (worktrees lack gitignored package-local node_modules and the generated git-commit.ts); emission completed and the harness's successful imports of the exact closure prove it.

2. Security probes (wire oracle, head build)

The posted body is another account's writable surface. 28/28 scripted probes passed (logs/forge-head.log, harness forge-probe.mjs):

  • The PR's own forged case, live against compiled dist: "sha":"$(rm -rf /)" → field dropped, ledger survives (round/findings intact).
  • Non-string shapes (number/object/null/array/boolean) dropped; boundaries: 6-hex dropped, 7-hex accepted, 64-hex accepted, 65-hex dropped; uppercase dropped (git rev-parse emits lowercase — the only legitimate producer); embedded newline/space dropped.
  • JSON-escape smuggling: "\\u002d\\u002d" unescapes to -- before the hex check and is rejected — the comment-termination hazard cannot ride the new field.
  • Serializer write-side guard refuses shell metachars, uppercase, too-short, too-long, empty.
  • Last-marker-wins preserved with two markers carrying different shas.
  • Timing ladder on hostile padding: sha-length 2k/20k/200k → 0.003/0.032/0.189 ms per parse; body padding 2k→200k flat at ~0.002 ms. Linear; the anchored character class has no backtracking regime. No rung near a cap.

3. Vacuity — mutation matrix

Four single-hunk mutants of the HEAD merge commit, each run against the suite that should catch it (unmutated control: 299/299 green). 4/4 killed, no survivors, each by its intended test with an expected-vs-actual message (witness 03-mutation-matrix-all-killed.png, raw logs logs/m1..m4-*.log):

mutant killed by failure message
M1 drop SHA_RE from parseLedger ledger.test.ts forged-sha test expected '$(rm -rf /)' to be undefined
M2 drop SHA_RE from serializeLedger same test, serializer half expected … not to contain 'sha' (received "sha":"not a sha")
M3 failClosed := false compose-review.test.ts fail-closed test deep-equal keyed by the fail-closed condition names its condition
M4 remove reviewed at clause from render pr-context.test.ts render test expected … to contain 'reviewed at abc1234def56789'

M1 is also the positive control for discrimination: it reds exactly one test while the round-trip test stays green, so the suite is distinguishing behaviors, not going globally red.

4. Findings

4.1 A round compose-review itself caps still certifies the anchor (the 3 failing assertions)

ledgerMarkerFor.failClosed reads four model-reported input fields (unreviewedDimensions, cannotTellCriticals, uncoverableChunks, contextUnavailable) — exactly the list Step 8 of SKILL.md names for the cache. But the body's verdict is capped by cappedBy, computed in the same module from seven conditions: the four above plus chunk-nobody-read (coverage-derived missingReceipts, which has no input channel at all), criticals-unverified, findings-unverified-at-compose, and deterministic enrichment of the named lists (scriptLintGate/layerAuditGate pushing into unreviewed, coverage recomputation pushing into uncoverable, plus coverageEntries counting toward unreviewed-dimension). The marker never sees any of the derived ones.

Live cells (harness cap-divergence.mjs against compiled dist; witness 02-capped-round-still-carries-anchor.png):

DIVERGES  drafted Critical, no transcripts (verification unclosed)
  cappedBy=["unreviewed-dimension"]  event=COMMENT
  marker sha="deadbeef00112233"
DIVERGES  findings file with surviving [unverified] tag
  cappedBy=["unreviewed-dimension","findings-unverified-at-compose"]  event=COMMENT
  marker sha="deadbeef00112233"

The sharpest form, printed by the module itself about the same round:

⚠️ This run could not certify that any of this diff was reviewed.
Not reviewed: coverage — the plan could not be used (… no diffPathAbsolute) …
Not reviewed: verification — could not check that Step 4 and Step 5 ran …
&lt;!\-\- qwen-review-ledger {"v":1,"round":1,"findings":[],"sha":"deadbeef00112233"} -->

Why it matters: the SKILL.md bullet this PR adds tells the next round to treat a recovered anchor exactly as lastCommitSha — "the same outcomes", which include the same-SHA stop. A fail-closed round that writes the anchor can make the next round (a) scope its incremental diff past scope this round never certified, or (b) stop early when the head is unchanged — precisely the "no later round ever re-covers the gap" failure the code comment above failClosed says it exists to prevent. The PR description's "only clean rounds write the sha" is the claim the module's own output falsifies.

Bounds (what it is not): findings always ride, so the work list survives; the cap is disclosed visibly in the posted body, so a human is not blind; a manually forced full review recovers; and the local cache has the same pre-existing blind spot (its advancement is agent-decided before the deterministic gates run). Attribution: the blind-spot class is pre-existing; this PR adds a new, cross-environment propagation path for it and overclaims the invariant.

Suggested fix (measured, not eyeballed) — fold the module's own verdict into the marker, in compose-review.ts:

const marker = ledgerMarkerFor(input, result.cappedBy);
// …
function ledgerMarkerFor(input: ComposeReviewInput, cappedBy: string[]): string | null {
  // …
  const failClosed =
    (input.unreviewedDimensions?.length ?? 0) > 0 ||
    (input.cannotTellCriticals?.length ?? 0) > 0 ||
    (input.uncoverableChunks?.length ?? 0) > 0 ||
    input.contextUnavailable === true ||
    cappedBy.length > 0;

Measured in a scratch copy (harness capfix-scratch.test.ts):

  • unpatched, the scratch test fails the intended assertion — AssertionError: expected 'deadbeef00112233' to be undefined; patched, green (3/3).
  • suite impact of the patch across the 3 affected files: 298 stay green, exactly one test goes red'carries the reviewed head sha as the incremental anchor on a clean run'. That is the fixture talking, not the fix: the describe-local plan() writes {prNumber: 8255, fetchedSha} with no diffPathAbsolute, which compose-review caps as "could not certify that any of this diff was reviewed". The test's name promises a clean run; the fixture is a maximally capped one (this is also why the PR's suite never noticed the divergence — its happy-path fixture already diverges and only asserts the anchor's presence). If the fix lands, that test should move onto the module-level plan()/coveredPlan() fixture infrastructure (diffPathAbsolute + Step 4/5 records + transcripts) that the unreviewed-dimension tests already use — that is the fixture that would pin a genuinely clean round carrying the anchor.

Reproduce: node tmp/pr9067-verify-20260813-090420/cap-divergence.mjs /__w/qwen-code/qwen-code (needs the built dist; the repo's build is prebuilt in this run).

4.2 (info) renderLedgerSection interpolates ledger.sha without the sanitization every sibling field gets

The same function documents that cell contents "come from a marker in a PR body — untrusted text" and runs |/newline/backtick through cell()/code() — but the new `reviewed at \`${ledger.sha}\ `` interpolation bypasses all of it. Safe today only because the sole production inlet (parseLedger) enforces hex one layer away; the render itself carries no defense. Not exploitable as shipped; noted so a future field or caller doesn't inherit the assumption. No action required.

5. Not covered

  • Agent-side consumption of the anchor is model behavior, not code: the SKILL.md Step 1 bullet (git cat-file -e <sha>^{commit} + merge-base --is-ancestor validation before scoping, same-SHA outcomes, side-file-vs-cache round precedence) was read and is internally consistent with the code's validation, but was not exercised end-to-end — there is no executable path to drive and no token to run a real review round.
  • Real GitHub post→recover round-trip: no network/token in this environment. The recovery cells replay the wire shape (synthetic posted bodies with the exact marker bytes pr-context will see), not the GitHub API trigger that produces them. latestOwnLedger's own-account filtering is pre-existing and unchanged.
  • Repo-wide gates (other packages' tests, lint, typecheck at root) — not touched by the diff beyond SKILL.md, whose structural suite ran (8/8).
  • Per-commit attribution: not applicable — the metadata's commits array has 1 entry and git rev-list HEAD^1..HEAD^2 agrees (1), so the aggregate diff is the whole PR.
  • A production-shaped clean round (real agent transcripts satisfying coverageFromTranscripts) could not be synthesized outside the suite's own fixtures; the full review suite (below) exercises those paths instead.
  • stale-bundle.test.ts passed in this container (fresh build), consistent with the author's note that their single red was a stale local build; no A/A on the author's machine was possible.

6. Gates (exact counts)

gate result
packages/cli — the 3 affected test files (unmutated control) 299/299 (ledger 14, pr-context 66, compose-review 219)
packages/coresrc/skills/bundled/review/SKILL.test.ts 8/8
packages/cli — full src/commands/review suite 68/68 files, 2429 passed, 4 skipped, 0 failed (2433) — verifies the PR's 2432/2433 claim with the author's one environmental failure green here

7. Methodology

Environment: the CI verify container (node:22-bookworm), working tree at refs/pull/9067/merge (depth 2), npm ci + npm run build pre-run. Harnesses (*.mjs in this directory) import the compiled dist of whichever tree they are pointed at and print one PASS/FAIL line per scripted assertion. Base control: git worktree add at HEAD^1, packages/cli rebuilt with tsc --build wired to the root node_modules; purity asserted per §1. Mutation matrix and fix measurement ran in a second scratch worktree at HEAD via vitest on source, each mutant reverted with git checkout -- between runs. Raw per-cell logs live in logs/; evidence captures in evidence/. Both worktrees were removed after capture; the verified tree's git status is clean.

Evidence images

01-ab-head-vs-base-anchor-recovery

02-capped-round-still-carries-anchor

03-mutation-matrix-all-killed

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

Qwen Code · sandboxed verification

@doudouOUC doudouOUC left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Reviewed. Suggestions are inline.

Not reviewed: verification and reverse audit — neither the verifier nor the reverse auditor was launched with a prompt this skill builds — the posted findings were ruled on, and the misses the rest of the review left were hunted, if at all, without the briefs this skill certifies against.

中文说明

已审查。 建议见行内评论。

未审查:验证与反向审计——验证 agent 与反向审计 agent 都没有用本 skill 构建的 prompt 启动——发布的发现即便被裁定过、评审其余部分遗漏的问题即便被搜寻过,也都缺失了本 skill 用以认证的 brief。

— deepseek-v4-flash via Qwen Code /review (v0.21.10)

* before scoping to it, so a tampered sha costs a full-range review, never a
* mis-scoped one.
*/
const SHA_RE = /^[0-9a-f]{7,64}$/;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

[Suggestion] SHA validation regex duplicated between ledger.ts and repo-context.ts — two patterns with different constraints, no shared helper

The review module now has two git SHA validation patterns. The new SHA_RE in ledger.ts (/^[0-9a-f]{7,64}$/) accepts 7–64 lowercase hex chars, while the pre-existing mergeBaseSha check in repo-context.ts (!/^(?:[0-9a-f]{40}|[0-9a-f]{64})$/i) requires exactly 40 or 64 hex chars (case-insensitive). The behavioural overlap is high enough that a reader who finds one and needs the other must search both files, and the two patterns could drift silently.

Suggested fix: Factor the patterns into shared helpers (e.g., isSha(s) for 7–64 lowercase hex, isFullSha(s) for exactly 40/64 hex case-insensitive) in a review/lib/ utility module, then import them in both ledger.ts and repo-context.ts.

Suggested change
const SHA_RE = /^[0-9a-f]{7,64}$/;
// In a shared utility module (e.g., review/lib/sha.ts):
export function isSha(s: string): boolean {
return /^[0-9a-f]{7,64}$/.test(s);
}
export function isFullSha(s: string): boolean {
return /^(?:[0-9a-f]{40}|[0-9a-f]{64})$/i.test(s);
}

— deepseek-v4-flash via Qwen Code /review (v0.21.10)

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.

Kept separate deliberately — the two checks make different claims at different trust boundaries: repo-context.ts validates a FULL 40/64-char object id from the trusted plan and hard-throws before resolving it via git; SHA_RE fail-quietly filters a possibly-abbreviated anchor out of an untrusted posted body. A shared helper would invite using the loose predicate where the strict one is meant. Addressed the discoverability half in 39c85d0: SHA_RE's comment now names the sibling check and why the constraints differ.(两个校验在不同信任边界上做不同断言,刻意不共享;39c85d0f9d 已在注释中交叉引用说明差异。)

Comment on lines +537 to +538
const failClosed =
(input.unreviewedDimensions?.length ?? 0) > 0 ||

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

[Suggestion] Fail-closed conditions in ledgerMarkerFor are a parallel implementation of Step 8's prompt-level logic — no enforcement link between them

The failClosed conditions in ledgerMarkerFor (compose-review.ts:531) mirror the same conditions described in SKILL.md Step 8's cache-write skip rule. The comment references Step 8, but there is no shared constant or function that both sides reference. If a future maintainer adds a new fail-closed condition to Step 8 but forgets to update ledgerMarkerFor, a fail-closed round would post a sha in the marker, and the next round's recovered-anchor check would scope past unreviewed content.

Suggested fix: Move the fail-closed condition into a shared function exported from ledger.ts that both compose-review.ts and the Step 8 prompt reference, or add a cross-reference comment in SKILL.md Step 8 that names the ledgerMarkerFor function as the authoritative source.

Suggested change
const failClosed =
(input.unreviewedDimensions?.length ?? 0) > 0 ||
// Export from ledger.ts:
export function isFailClosed(input: {
unreviewedDimensions?: unknown[];
cannotTellCriticals?: unknown[];
uncoverableChunks?: unknown[];
contextUnavailable?: boolean;
}): boolean {
return (
(input.unreviewedDimensions?.length ?? 0) > 0 ||
(input.cannotTellCriticals?.length ?? 0) > 0 ||
(input.uncoverableChunks?.length ?? 0) > 0 ||
input.contextUnavailable === true
);
}

— deepseek-v4-flash via Qwen Code /review (v0.21.10)

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.

Fixed in 39c85d0 with a stronger link than a shared constant: ledgerMarkerFor now receives result.cappedBy — the verdict this module just computed — and withholds the anchor whenever it is non-empty, on top of the four named inputs. That covers a future Step 8 condition someone forgets to mirror AND the caps that have no input channel at all (a chunk nobody read, findings still — [unverified], the gates' enrichments). SKILL.md Step 8 now names cappedBy in the withholding conditions, so prompt and code cite one source of truth.(已修:marker 直接接收模块自身算出的 cappedBy,非空即扣留;SKILL Step 8 同步点名。)

@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 explored to full depth (tool budget reached): "You are review agent reverse-audit — Reverse audit agent…": none — the walk above is complete within budget; I did not run probes/tests (source-walk only), and I did not deep-audit agent-prompt.ts / DESIGN.md interna…; "PR #9067 adds a sha field (the head commit the round…": could not verify GitHub's permission semantics for non-author edits of a review body (relevant only to the finding above's attacker capability, not to its mecha…; "You are review agent reverse-audit — Reverse audit agent…": none — the walk completed within budget.; "You are review agent reverse-audit — Reverse audit agent…": did not execute the new tests (verifier's job); did not fully resolve bestDelivery 's null-vs-non-ok return semantics in coverage.ts — not load-bearing, since ….

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

中文说明

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

未探索到全部深度(达到工具调用预算):"You are review agent reverse-audit — Reverse audit agent…"none — the walk above is complete within budget; I did not run probes/tests (source-walk only), and I did not deep-audit agent-prompt.ts / DESIGN.md interna…"PR #9067 adds a sha field (the head commit the round…"could not verify GitHub's permission semantics for non-author edits of a review body (relevant only to the finding above's attacker capability, not to its mecha…"You are review agent reverse-audit — Reverse audit agent…"none — the walk completed within budget."You are review agent reverse-audit — Reverse audit agent…"did not execute the new tests (verifier's job); did not fully resolve bestDelivery 's null-vs-non-ok return semantics in coverage.ts — not load-bearing, since …

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

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

Comment on lines +537 to +541
const failClosed =
(input.unreviewedDimensions?.length ?? 0) > 0 ||
(input.cannotTellCriticals?.length ?? 0) > 0 ||
(input.uncoverableChunks?.length ?? 0) > 0 ||
input.contextUnavailable === true;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

[Critical] The fail-closed gate reads only the four orchestrator-written input lists, but composeReviewBody deterministically computes further unreviewed-scope states that cap the verdict and never reach this predicate: scriptLintGate/layerAuditGate push into the local unreviewed copy, coverageFromTranscripts produces missingReceipts, coverage-derived uncoverable chunks and idle/blind/unopened-agent coverageEntries, and readBudgetStop adds a budget-stop entry. A round this function itself declares not fully reviewed can therefore still certify fetchedSha as the next round's incremental anchor — the verdict cap is relay-proof, but the anchor withholding is not. — Failure scenario: a high-effort run where a chunk is never receipted (or the script-lint report is missing, or an agent is idle) while all four input lists arrive empty → the verdict is capped to COMMENT via unreviewed-dimension, yet the posted marker still carries sha = fetchedSha; the next round in a fresh environment (CI — the exact scenario this field exists for) recovers the anchor from the prev-ledger side file, passes both git checks (it is a real ancestor), and scopes sha..HEAD — the never-reviewed chunk is permanently skipped by every later round. Confirmed by probe at this commit: a plan with a missing script-lint report and empty input lists produced cappedBy: ["unreviewed-dimension"] AND markerSha: "deadbeef00112233"; OR-ing cappedBy.length > 0 into this gate flipped it to markerSha: null. The comment above this block names exactly the invariant this violates.

Suggested fix — derive the gate from the same state that produces the verdict caps (result.cappedBy is already in scope one level up in composeReview; it covers all four input conditions plus the deterministic ones, so the raw-input checks stay as a redundant fail-closed floor):

// composeReview(): pass the computed caps down
const marker = ledgerMarkerFor(input, result.cappedBy);

// ledgerMarkerFor(): withhold the anchor whenever ANY cap fired
function ledgerMarkerFor(
  input: ComposeReviewInput,
  cappedBy: readonly string[] = [],
): string | null {
  // ...
  const failClosed =
    cappedBy.length > 0 ||
    (input.unreviewedDimensions?.length ?? 0) > 0 ||
    (input.cannotTellCriticals?.length ?? 0) > 0 ||
    (input.uncoverableChunks?.length ?? 0) > 0 ||
    input.contextUnavailable === true;

Plus a regression test where the only unreviewed-scope signal is coverage-derived (a chunk nobody receipted) with all four input lists empty.

中文说明

[Critical] fail-closed 判定只读取四个由编排器写入的输入列表,但 composeReviewBody 会确定性地计算出更多“未审范围”状态并对裁决加帽,而这些状态永远到不了这个判定:scriptLintGate/layerAuditGate 会向局部的 unreviewed 副本追加条目,coverageFromTranscripts 会产生 missingReceipts、覆盖推导出的 uncoverable 块和 idle/blind/unopened agent 的 coverageEntriesreadBudgetStop 会追加预算终止条目。因此,一个被本函数自己判定为“未完整审查”的轮次,仍然可以把 fetchedSha 认证为下一轮的增量锚点——裁决加帽对“编排器漏报”是免疫的,但锚点扣留并不免疫。— 失败场景:一次 high-effort 运行中,某个 chunk 从未被 receipt(或 script-lint 报告缺失、或某 agent idle),而四个输入列表全部为空 → 裁决被 unreviewed-dimension 加帽降为 COMMENT,但发布的 marker 仍携带 sha = fetchedSha;下一轮在全新环境(CI——正是这个字段存在的场景)从 prev-ledger side file 恢复锚点,两个 git 检查都通过(它确实是祖先),于是范围收窄为 sha..HEAD——那个从未被审查的 chunk 被之后所有轮次永久跳过。已在本 commit 上用 probe 确认:一个缺失 script-lint 报告且输入列表为空的 plan 产生了 cappedBy: ["unreviewed-dimension"]markerSha: "deadbeef00112233";把 cappedBy.length > 0 并入该判定后翻转为 markerSha: null。此代码块上方的注释恰好点明了被违反的不变量。

建议修复——从产生裁决加帽的同一状态推导该判定(result.cappedBy 在上层 composeReview 中已在作用域内;它涵盖全部四个输入条件及确定性加帽,因此原始输入检查可保留作为冗余的 fail-closed 底线),并补充一个回归测试:唯一的未审范围信号是覆盖推导的(无人 receipt 的 chunk)、四个输入列表全空。

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

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.

Confirmed — the sandboxed verification measured the same divergence, and it was fixed in 39c85d0 (pushed before this round posted, which reviewed 027b354): ledgerMarkerFor now takes result.cappedBy and withholds the anchor whenever the module itself capped the round. The clean-run test moved onto the covered-plan fixture (transcripts + Step 4/5 records) and additionally pins cappedBy: []; its old bare fixture — itself a maximally capped round, which is why the suite never saw this — became the test that the module's own cap withholds the anchor.(与沙箱验证同根因,39c85d0f9d 已修——本轮 review 跑在旧 head 上;clean-run 测试已迁到真覆盖 fixture 并额外钉住 cappedBy 为空。)

const render = (findings: LedgerFinding[], dropped: number): string => {
const payload: Ledger = { v: 1, round: ledger.round, findings };
if (dropped > 0) payload.dropped = dropped;
if (ledger.sha && SHA_RE.test(ledger.sha)) payload.sha = ledger.sha;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

[Suggestion] The anchor is attached regardless of whether the size caps dropped findings — a truncated work list still certifies the range. — Concrete cost: when a round's findings overflow the 50-count or 8 KiB cap, the marker carries dropped: K AND sha; the next round in a fresh environment recovers the anchor, validates it (a real ancestor), and scopes to sha..HEAD — the K dropped findings (possibly open Criticals) reference code at or before the anchored head, now out of the diff range, and Step 6 only re-asserts entries that are IN the work list, so they retire silently without ever receiving a ruling again. Pre-PR, that same fresh-environment round had no anchor and reviewed the full diff, so their code was at least re-read. The sha doc comment this PR adds forbids exactly this ("an anchor written past unreviewed scope"). Confirmed by probe: count-cap arm dropped: 5 with sha present, byte-cap arm dropped: 16 with sha present; guarding on dropped === 0 removed it. The trigger requires an overflow the module says 66 measured reviews never hit — hence Suggestion, not Critical.

Suggested change
if (ledger.sha && SHA_RE.test(ledger.sha)) payload.sha = ledger.sha;
if (dropped === 0 && ledger.sha && SHA_RE.test(ledger.sha)) payload.sha = ledger.sha;
中文说明

[Suggestion] 锚点的附加与 cap 是否丢弃了 findings 无关——被截断的工作清单仍然认证范围。— 具体代价:当某轮的 findings 超过 50 条上限或 8 KiB 字节上限时,marker 同时携带 dropped: Ksha;下一轮在全新环境恢复锚点、验证通过(确为祖先)后,范围收窄为 sha..HEAD——被丢弃的 K 条 findings(可能包含未关闭的 Critical)引用的代码位于锚点 head 或其之前、现已超出 diff 范围,而 Step 6 只重新断言工作清单内的条目,于是它们悄然退役、再也得不到裁决。本 PR 之前,同样的全新环境轮次没有锚点、会审查全量 diff,这些代码至少会被重新读到。本 PR 新增的 sha 文档注释恰好禁止了这种情况(“写过未审范围的锚点……”)。已用 probe 确认:条数上限分支 dropped: 5 且 sha 仍在,字节上限分支 dropped: 16 且 sha 仍在;加上 dropped === 0 守卫后 sha 消失。触发条件需要一次溢出,而模块注释说 66 次实测 review 从未触发——因此是 Suggestion 而非 Critical。

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

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.

Real gap, fixed in 9ee7413: the serializer now withholds the sha whenever it drops findings (a partial work list must not certify a range — the dropped entries would fall outside the next round's sha..HEAD scope and retire silently), and the parser strips a hand-edited marker carrying both dropped and sha. SKILL.md Step 1 names truncation among the no-anchor cases. Pinned by a new test covering both halves.(真缺口,9ee741366e 已修:截断即丢锚点,序列化/解析双侧把守,新测试钉住。)

).not.toContain('PARTIAL');
});

it('names the reviewed-at sha when the ledger carries one, and stays silent when not', () => {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

[Suggestion] No test pins that sha survives the recovery seam this PR's payoff depends on: posted marker → latestOwnLedger → the qwen-review-pr-<n>-prev-ledger.json side file. Every new test covers only the write half or parse/serialize in isolation; the existing latestOwnLedger tests build markers with no sha field, and no test references the side file's contents. — Concrete cost: a future refactor that projects fields at either seam (e.g. normalizing latestOwnLedger's return to known fields, or writing a subset to the side file) silently drops sha with every current test green — Step 1's recovered-anchor check then finds no anchor in any fresh environment (CI, another clone), and every round degrades to the full diff, the exact cost this PR exists to eliminate. Production carries it today (latestOwnLedger returns the whole parsed ledger; the side file is JSON.stringify(prevLedger)), so this is a test-only gap — add the seam test this file is already positioned for:

it('carries the sha through latestOwnLedger into the side file', () => {
  // marker body containing "sha":"abc1234def567890"
  // assert latestOwnLedger(...)?.sha === 'abc1234def567890'
  // and the written prev-ledger side file contains the sha
});
中文说明

[Suggestion] 没有测试钉住 sha 能存活本 PR 收益所依赖的恢复接缝:发布的 marker → latestOwnLedgerqwen-review-pr-<n>-prev-ledger.json side file。所有新增测试只覆盖写入端或孤立的 parse/serialize;既有的 latestOwnLedger 测试构造的 marker 不含 sha 字段,也没有测试引用 side file 的内容。— 具体代价:未来任何在任一接缝处做字段投影的重构(例如把 latestOwnLedger 的返回归一化为已知字段、或只向 side file 写入字段子集)都会悄然丢掉 sha,而现有所有测试仍然全绿——此后 Step 1 的恢复锚点检查在任何全新环境(CI、另一个 clone)都找不到锚点,每一轮都退化为全量 diff,正是本 PR 要消除的成本。当前生产代码是携带 sha 的(latestOwnLedger 返回完整的解析结果;side file 是 JSON.stringify(prevLedger)),所以这只是测试层面的缺口——补上本文件已经具备位置的接缝测试即可。

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

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.

Fair — fixed in 9ee7413: latestOwnLedger's return is now pinned anchor-included (toEqual on the whole recovered ledger built from a real serializeLedger body), so a projection refactor at that seam can no longer drop sha with the suite green. The side file is JSON.stringify of exactly that return, so the pin covers the seam the payoff depends on.(已补:latestOwnLedger 返回值整体断言含 sha,投影式重构无法再静默丢字段。)

Sandboxed verification of this PR measured the stated invariant ('only
clean rounds write the sha') false: ledgerMarkerFor's failClosed read
only the four model-reported input fields, while compose-review caps
the verdict from seven conditions — including caps with no input
channel at all (a chunk nobody read, findings still unverified, the
deterministic gates' enrichments). A round the module itself stamped
'could not certify that any of this diff was reviewed' still carried
the anchor.

failClosed now also trips on a non-empty cappedBy — the verdict this
module just computed. The clean-run test moves onto the covered-plan
fixture (transcripts + Step 4/5 records) and additionally pins
cappedBy=[]; its old bare fixture — itself a maximally capped round,
which is why the suite never saw the divergence — becomes the test
that the module's own cap withholds the anchor. The four named input
conditions keep their own test, now on the clean fixture so each
withholding is attributable to the input, not the cap.

Also from review: renderLedgerSection routes the sha through the
section's code() sanitizer like every sibling field, and SHA_RE's
comment names the deliberately-unshared sibling check in
repo-context.ts (full object id, hard-throw) so the two do not read
as accidental duplication.
…am is pinned

Two findings from the second review round:

- A marker whose size caps dropped findings still carried the sha. The
  dropped entries (possibly open Criticals) reference code at or before
  the anchored head; a next round scoped to sha..HEAD never re-sees it,
  and Step 6 rules only on entries that are IN the work list — they
  would retire silently. The serializer now withholds the sha whenever
  it drops findings, the parser strips a hand-edited marker carrying
  both, and SKILL.md Step 1 names truncation among the no-anchor cases.

- No test pinned sha across the recovery seam the feature depends on
  (posted marker -> latestOwnLedger -> side file); a projection refactor
  could drop the field with every test green. latestOwnLedger's return
  is now pinned anchor-included.
@wenshao

wenshao commented Aug 13, 2026

Copy link
Copy Markdown
Collaborator Author

@qwen-code /triage

@qwen-code-ci-bot

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

Copy link
Copy Markdown
Collaborator

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

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

Scripted assertions: 2872 passed · 0 failed · 2872 total

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

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

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

Verification report

PR 9067 deep verification (follow-up round) — feat(review): carry the incremental anchor sha in the posted ledger marker

Verdict: findings — assertions 2872 pass / 0 fail / 2872 total. Verified head: 9ee741366ee3f9c5cd70d321b6c41c668c578e0b (merge-ref checkout, base HEAD^1 = 344ce4d1af). Every executed assertion passed, including all re-measurements of the previous round's blocker; the findings verdict is carried by one NEW suggestion-level finding (§4.1) in the same invariant family this PR's third commit exists to hold, plus two completeness notes. None of them is blocking; the fix for §4.1 is measured in §4.1 if the author wants it in this PR.

中文 — 判定:❌ 不通过 · 报告了发现(agent 判定)
  • 结论findings(2872 通过 / 0 失败)。上一轮的唯一阻断项(§4.1:模块自身封顶的轮次仍携带锚点)已在新 head 上复测确认修复;上一轮 info 项(渲染未消毒)同样修复。本轮新发现一项建议级问题:解析端自己的 50 条计数上限截断不披露 dropped 且锚点照常携带——与该 PR 第 3 个 commit 刚为序列化端钉死的"部分清单不得认证范围"是同一不变量的读端兄弟形状(仅可通过手工编辑本账号发布的 review 触达,外部攻击者不可达)。两项钉住性缺口(序列化端截断守卫、渲染端消毒)经突变体判定为覆盖缺口而非死代码。
  • A/B 结论:同一套场景分别驱动 head 与 base 的编译产物——head 29/29(已发布正文恢复锚点、干净轮携带 fetchedSha、模块封顶轮扣留锚点、side file 轮次递进且锚点取本轮 head、渲染段命名锚点、截断失锚);base 27/27(同构 ledger、处处无锚点)。上一轮红转绿的关键 cell(C5):cappedBy=["unreviewed-dimension"]、marker 携带 findings、无 sha。
  • Findings:§4.1(建议级)解析端计数上限截断静默且锚点幸存——已实测单行修复(11/11:敌意 fixture 变干净、良性 round-trip 逐字节不变、套件两侧 302/302 即该轴无钉住);§4.2/§4.3(完整性报告)序列化端截断守卫与渲染端消毒各自只被组合行为或完全未被测试钉住,均附应钉住的 fixture。
  • 未覆盖:SKILL.md 中 agent 侧对锚点的消费为模型行为,未端到端演练;真实 GitHub 发布→恢复回路无 token,仅复现 wire 形状;per-commit 归属因浅克隆(depth 2,本地仅可达 head)不可达,验证的是聚合 diff。

0. Previous-finding status (follow-up round)

# previous finding severity status at new head
1 §4.1 a round compose-review itself caps still certifies the anchor (the 3 failing assertions of round 1) blocker fixed — re-measured live (A/B cell C5, witness 01-ab-head-arm-anchor-behavior.png): the bare-plan round is capped ["unreviewed-dimension"], the module stamps "could not certify that any of this diff was reviewed", and the marker now carries the finding with no sha. Deleting the cappedBy.length > 0 clause (mutant M1) turns exactly the new test withholds the sha when the module ITSELF caps the round red, so the clause is load-bearing, and the suite-side restructuring is exactly what round 1 recommended (clean-run test on the covered-plan fixture pinning cappedBy=[]; the old bare fixture became the capped-round test).
2 §4.2 renderLedgerSection interpolates ledger.sha without the code() sanitization every sibling field gets info fixed — the sha now rides through code(); crafted non-hex shas handed DIRECTLY to the render (backtick, pipe, newline) are neutralised (3/3 probes, logs/forge-head.log). Mutant M6 (removing code()) survives the suite — expected: every fixture sha is hex, so nothing pins the sanitization. Classified as a coverage gap, not dead code (§4.3).

All round-1 measurements were re-run at the new head rather than carried forward (the tree, the dist, and the suites all changed with the two fix commits); the only input closure unchanged is the base-side behavior, re-derived from a fresh base worktree build anyway.

1. Central claim and A/B proof

Central claim: the posted review's machine-ledger marker carries sha (the head the round reviewed), so a fresh environment recovers "last reviewed at" through parseLedgerlatestOwnLedger → the prev-ledger side file and scopes its incremental diff from it — withheld on fail-closed rounds (now including the module's own caps and size truncation), field-level-dropped when malformed.

The aggregate diff (HEAD^1..HEAD, 7 files, +259/−7) matches the three commits' messages; write/read-site trace re-verified: fetchedSha is written into the plan by fetch-pr.ts:212 (git rev-parse of the PR ref — production field), ledgerMarkerFor (the single chokepoint both submit and the CLI handler go through) validates it through SHA_RE inside serializeLedger, the side file at pr-context.ts:981 is JSON.stringify(prevLedger) so sha rides it, and renderLedgerSection names it.

A/B: identical scenarios driven through the compiled dist/ of head and of a base worktree (HEAD^1, tsc --build wired to the root node_modules; control purity in §6). Expectations encoded per arm — both arms print all-PASS only if head has the anchor behavior and base lacks it. Witness 01-ab-head-arm-anchor-behavior.png / 02-ab-base-arm-no-anchor.png; raw logs logs/ab-head.log, logs/ab-base.log.

cell observable head (29/29) base (27/27)
C1 parse an already-posted body with sha parseLedger sha:"deadbeef00112233" recovered same ledger, no anchor field
C2 old marker without sha parse unchanged (backward compat) unchanged
C3 clean composeReview (covered plan, transcripts, Step 4/5) marker cappedBy=[], sha = plan.fetchedSha, round 1 marker present, no sha key
C4 fail-closed inputs ×4 (on the clean plan) marker each withholds sha, finding rides no field; findings ride
C5 round the MODULE caps (bare plan, drafted Critical) cappedBy + marker ["unreviewed-dimension"], uncertified stamp, sha withheld, finding rides same cap, no field
C6 side file carries round 4 + stale sha marker round 5, anchor = THIS round's head, not the stale one round 5, no anchor
C7 renderLedgerSection rendered section names reviewed at `abc1234def56789` ; silent without silent both ways
C8 serialize 51 findings + sha parse of bytes dropped=1, sha forfeited dropped=1, no field
C9 latestOwnLedger seam recovered ledger anchor intact (toEqual) ledger without anchor

2. Security + truncation battery (wire oracle, head build)

50/50 scripted probes (forge-probe.mjs, witness 04-forge-battery-50-probes.png, log logs/forge-head.log): the PR's own forged case "sha":"$(rm -rf /)" dropped field-level with the ledger intact; non-string shapes dropped; boundaries exact (6-hex dropped / 7 accepted / 64 accepted / 65 dropped); uppercase, mixed-case, space, newline, and --upload-pack-shaped inputs dropped; \u002d\u002d escape smuggling unescapes before the hex check and is rejected; no live -- survives serialization and dashed titles round-trip verbatim; write-side guard refuses all non-hex; last-marker-wins preserved; truncation forfeits the anchor under BOTH caps (count: 51 findings → dropped=1, no sha; byte: 50 wide findings → marker 7,885 B ≤ 8,192, no sha) and the parser strips a hand-edited dropped+sha marker; dropped:0/-2 are not truncation; timing ladder linear (sha-length 2k/20k/200k → 0.002/0.013/0.215 ms per parse; 200k body padding 0.002 ms — no rung near any cap, anchored character class has no backtracking regime).

3. Mutation matrix (encoded, 13/13)

Unmutated control green (302/302). Six single-hunk mutants with encoded expectations; witness 03-mutation-matrix-encoded.png, raw logs logs/m<N>-*.log and logs/matrix-encoded.log. No mutant regressed anything: each red is exactly one test, its intended one.

mutant expectation result killed by / classification
M1 drop cappedBy.length > 0 from failClosed red red withholds the sha when the module ITSELF caps the round — the §4.1 fix is load-bearing (positive control for the whole matrix)
M2 serializer emits sha despite dropped green (masked) green survivor → adjudicated: wire oracle shows the mutant bytes DO carry "sha" while head bytes don't, so the guard is load-bearing on the wire and the suite's round-trip is masked by the parser's !dropped. Coverage gap, not dead code (§4.2)
M3 parser keeps sha when dropped>0 red red a truncated ledger loses its anchor (hand-edited half)
M4 remove the reviewed at naming clause red red names the reviewed-at sha…
M5 latestOwnLedger projection dropping sha red red carries the anchor sha through the recovery seam intact — commit 3's seam pin works
M6 render bypasses code() for sha green green survivor → adjudicated: all fixture shas are hex, behavior identical; coverage gap for the §4.2 defense-in-depth fix (§4.3)

4. Findings

4.1 (suggestion, new) The parser's OWN count-cap truncation is silent — and the anchor rides it

The module's invariant is explicit — Ledger.dropped exists because "the incomplete case has to say so rather than look identical to it", and commit 3 just enforced "a partial work list must not certify a range" on the serializer and on hand-edited dropped+sha markers. One sibling shape escapes: parseLedger slices findings to LEDGER_MAX_FINDINGS on READ without recording dropped, so a hand-edited marker with >50 findings and a sha parses as a COMPLETE list of 50 carrying a live anchor:

INFO sibling: parser count-cap on hand-edited 53-finding marker → findings=50 dropped=undefined sha=aaaaaaaaaaaaaaaa

Reproduce: node tmp/pr9067-verify-20260813-101208/forge-probe.mjs /__w/qwen-code/qwen-code (probe "8. Parser count-cap sibling probe").

Why it matters in this PR's terms: the dropped entries reference code at or before the anchored head; a next round scoped to sha..HEAD never re-sees them, and Step 6 rules only on entries IN the work list — exactly the silent retirement commit 3's message describes. Bounds (what it is not): the slice is pre-existing (measured on the base build: findings=50 dropped=undefined), so the attribution splits as pre-existing truncation shape + new anchor consequence; the serializer can never produce >50 findings, and only this account's posted reviews feed latestOwnLedger, so reaching this requires hand-editing the bot's own review — not an outside attacker, not code injection (the sha remains hex-only and is validated against the worktree before scoping). Disclosure survives only in git's edit history, which nothing reads.

Suggested fix (measured, not eyeballed) — count the parser's own slice as truncation, in parseLedger (lib/ledger.ts):

const over = Math.max(0, raw.findings.length - LEDGER_MAX_FINDINGS);
const dropped =
  Number.isInteger(raw.dropped) && (raw.dropped as number) > 0
    ? (raw.dropped as number) + over
    : over > 0
      ? over
      : undefined;

Applied in a scratch copy and driven through fixcheck.mjs (rerunnable, shipped in this directory): hostile fixture goes clean (dropped=3, sha forfeited, 50 kept), four benign round-trips byte-identical including the exactly-at-cap ledger (no dropped, sha rides), serializer-truncation shape unchanged (dropped stays exactly 1) — 11/11 patched, 9/11 unpatched (the two disclosure cells fail by design — that delta is the measurement). Affected suite 302/302 both with and without the patch, i.e. the suite pins nothing along this axis and the fix should ship with its fixture: a hand-edited marker with more findings than the cap loses its anchor and reports dropped.

4.2 (completeness, not blocking) The serializer's truncation guard is pinned only by composition

M2 showed it: the suite's a truncated ledger loses its anchor round-trips through parseLedger, which strips the sha the mutated serializer emitted — so the write-side else if could be removed with every test green. The wire oracle proves the guard is load-bearing on the bytes the post carries (mutant bytes contain "sha", head bytes don't, under both caps). The fixture that would pin it: expect(serializeLedger(overflowing)).not.toContain('"sha"'). Reported as completeness, not a merge condition — the composition the feature depends on IS pinned, and the read side holds the line independently.

4.3 (completeness, not blocking) The §4.2 render-sanitization fix is unpinned

M6 (replacing code(ledger.sha) with bare interpolation) survives the suite because every fixture sha is hex; the render's own defense is verified correct only by this round's direct probes (crafted backtick/pipe/newline shas neutralised). A fixture handing a non-hex crafted sha DIRECTLY to renderLedgerSection would pin the layer the fix added. Same completeness tier as §4.2.

5. Gates (exact counts)

gate result
packages/cli — 3 affected test files, unmutated control (scratch tree) 302/302 (ledger 15, compose-review 220, pr-context 67)
packages/coresrc/skills/bundled/review/SKILL.test.ts 8/8
packages/cli — full src/commands/review suite 68/68 files, 2432 passed, 4 skipped, 0 failed (2436)
npm run build at HEAD pre-run by the workflow; the compiled dist used by every harness contains both fix commits (checked by grep + mtime)

The PR body's "2432/2433 — the one failure is stale-bundle.test.ts" matches: that test is green here on a fresh build (consistent with the author's stale-local-build note), and the total delta 2433 → 2436 is exactly the three tests added by the two fix commits. The Reviewer Test Plan's three steps were all executable and held; per-claim results are the cells of §1–§3 (sha round-trip, forged-sha drop, write-side refuse, clean-run carry, four-input withholding, module-cap withholding, render naming/silence).

6. Not covered

  • Agent-side consumption of the anchor is model behavior, not code: SKILL.md Step 1's recovered-anchor bullet (git cat-file -e <sha>^{commit} + merge-base --is-ancestor before scoping, same-SHA outcomes, side-file-round-beats-stale-cache precedence, truncation named among the no-anchor cases) was read and is internally consistent with the code's validation; no executable path exists to drive it, and there is no token to run a real review round.
  • Real GitHub post→recover round-trip: no network/token in this environment. The recovery cells replay the wire shape (synthetic posted bodies with the exact marker bytes pr-context will see), not the API trigger that produces them — this reproduces the shape the issue reported, not a live multi-round exercise.
  • Per-commit attribution: the metadata lists 3 commits; the depth-2 checkout makes only the head reachable (git rev-list HEAD^1..HEAD^2 returns 1 at the shallow boundary, which is the known false-small). The aggregate HEAD^1..HEAD diff is what was verified; the commits' messages match the aggregate code state.
  • Repo-wide gates beyond the affected suites (root lint/typecheck as separate invocations) — the pre-run npm run build is a full typecheck; the diff touches no package beyond cli's review command and core's SKILL.md data file.
  • stale-bundle.test.ts A/A on the author's machine was impossible; green here on a fresh build.

7. Methodology

Environment: the CI verify container (node:22-bookworm), working tree at refs/pull/9067/merge (depth 2), npm ci + npm run build pre-run at HEAD; verified head 9ee741366e = HEAD^2. Harnesses (ab-harness.mjs, forge-probe.mjs, fixtures.mjs, matrix-encoded.mjs, mutation-driver.mjs/sh in this directory) import the compiled dist of whichever tree they are pointed at and print one PASS/FAIL line per scripted assertion; fixtures.mjs reproduces the suite's plan/transcript/Step-4-5 fixture infrastructure in plain node so composeReview runs end-to-end without vitest (the bilingual plan flag keeps the deterministic path, so no gh call fires — no token exists here). Base control: git worktree add at HEAD^1, tsc --build wired to the root node_modules (base type errors confined to unrelated UI test files missing package-local dev-deps; emission completed and the harnesses imported the closure successfully); purity asserted — ledger.js/compose-review.js have no bare specifiers, pr-context.js exactly one (@qwen-code/qwen-code-core, realpath the head tree; the PR's only core change is the SKILL.md data file, so the link is not a confound). Mutations and the measured fix ran in a second scratch worktree at HEAD via vitest/tsx on source, each mutant reverted with git checkout -- between runs; package-local node_modules (gitignored) were symlinked into both worktrees and contain no @qwen-code links. Raw per-cell logs live in logs/, evidence captures in evidence/. Both worktrees were removed after capture; the verified tree's git status is clean.

Evidence images

01-ab-head-arm-anchor-behavior

02-ab-base-arm-no-anchor

03-mutation-matrix-encoded

04-forge-battery-50-probes

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

Qwen Code · sandboxed verification

@qwen-code-ci-bot

Copy link
Copy Markdown
Collaborator

Triage re-run completed without a new review.

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

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

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

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

@qwen-code-ci-bot qwen-code-ci-bot 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. ✅

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

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Partially reviewed — gaps disclosed. Suggestions are inline.

Not explored to full depth (tool budget reached): "PR #9067 adds a sha field — the head commit that round…": none — all checks above completed within budget.; "PR #9067 adds a sha field — the head commit that round…": none — all planned checks completed (~12 of ~42 calls).; "PR #9067 adds a sha field — the head commit that round…": none — all checks completed within budget..

Not reviewed: reverse audit — stopped before round 4 by the review time budget.

中文说明

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

未探索到全部深度(达到工具调用预算):"PR #9067 adds a sha field — the head commit that round…"none — all checks above completed within budget."PR #9067 adds a sha field — the head commit that round…"none — all planned checks completed (~12 of ~42 calls)."PR #9067 adds a sha field — the head commit that round…"none — all checks completed within budget.

未审查:反向审计——评审时间预算不足,未能开始第 4 轮。

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

Comment on lines +546 to +551
const failClosed =
(input.unreviewedDimensions?.length ?? 0) > 0 ||
(input.cannotTellCriticals?.length ?? 0) > 0 ||
(input.uncoverableChunks?.length ?? 0) > 0 ||
input.contextUnavailable === true ||
cappedBy.length > 0;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

[Suggestion] The four input-field disjuncts re-derive a fail-closed state that result.cappedBy already aggregates — composeReviewBody pushes a cap entry for each named input (cannot-tell-existing-critical, uncoverable-chunk, unreviewed-dimension, context-unavailable) at ~1089–1097, so cappedBy.length > 0 alone subsumes them (probe-verified: cappedBy contained the input-derived cap in all four fail-closed runs). The comment above and the test narrative ("attributable to the named input, not to the module-computed cap") assert a division of labor the code does not have. — Concrete cost: a future fifth input-channel cap has to be added to two predicates the comment claims are disjoint; missing one re-opens the anchor leak this PR measured. The one reach the raw checks add is whitespace/footer-only cannotTellCriticals entries (the cap list filters them out at ~602) — that edge implements Step 8's literal "or any cannotTellCriticals entry" contract and must be kept or documented if the rest is collapsed.

Suggested change
const failClosed =
(input.unreviewedDimensions?.length ?? 0) > 0 ||
(input.cannotTellCriticals?.length ?? 0) > 0 ||
(input.uncoverableChunks?.length ?? 0) > 0 ||
input.contextUnavailable === true ||
cappedBy.length > 0;
const failClosed =
(input.cannotTellCriticals?.length ?? 0) > 0 || cappedBy.length > 0;
中文说明

[Suggestion] 四个输入字段判定项重复推导了 result.cappedBy 已经聚合的 fail-closed 状态——composeReviewBody 会为每个命名输入追加对应的 cap 条目(~1089–1097),因此仅 cappedBy.length > 0 即可覆盖它们(probe 已验证:四次 fail-closed 运行中 cappedBy 均包含输入派生的 cap)。上方注释与测试叙述("归因于命名输入,而非模块计算的 cap")断言了一种代码中并不存在的分工。— 具体代价:未来新增第五个输入通道 cap 时,必须同时修改注释声称互不相交的两个判定式;漏改其一就会重新打开本 PR 实测过的锚点泄漏。原始判定唯一的额外覆盖是纯空白/仅含 footer 的 cannotTellCriticals 条目(cap 列表在 ~602 处将其过滤)——该边界实现了 Step 8 的字面契约"或任何 cannotTellCriticals 条目",若收敛其余判定项,必须保留或注明这一边界。

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

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.

Collapsed in 2fa20e5, keeping exactly the one raw check your analysis carved out: failClosed = (input.cannotTellCriticals?.length ?? 0) > 0 || cappedBy.length > 0. The comment now explains the subsumption and why the raw check survives (a whitespace-only entry is filtered out of the rendered caps, but an undecided blocker whose text was lost is still an undecided blocker — Step 8's literal 'any entry' contract). The false division-of-labor narrative in the test comment is gone with it.(已收敛为 cappedBy + 一条刻意保留的原始检查,注释如实说明。)

Comment on lines +4276 to +4278
const ledger = parseLedger(r.body);
// Keyed by the fail-closed input so a regression names its condition.
expect({ ...failClosed, sha: ledger?.sha }).toEqual({ ...failClosed });

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

[Suggestion] This loop does not isolate the input-level disjuncts: every named input also fires a module-computed cappedBy cap, so the mutation "delete the four input checks from failClosed" survives the whole suite — run, not inferred: with const failClosed = cappedBy.length > 0; all 302 tests still pass, including 'withholds the sha on a fail-closed input', contrary to the attribution comment above. — Failure scenario: the mutant is observable, not equivalent — with cannotTellCriticals: [' '] no module cap fires (the entry is filtered out at ~602) while the raw check still withholds, so the mutant would let the anchor ride; a regression confined to the input-level path ships uncaught. Add one case the module caps don't reach (or, if the redundancy is deliberate, assert r.cappedBy per case and correct the comment):

// covered plan + cannotTellCriticals: [' ']
expect(r.cappedBy).toEqual([]);
expect(parseLedger(r.body)?.sha).toBeUndefined();
中文说明

[Suggestion] 该循环没有隔离输入层判定项:每个命名输入都会同时触发一个模块计算的 cappedBy cap,因此"从 failClosed 中删除四个输入检查"这一变异能在整个测试套件下存活——这是实际运行的结果,不是推断:换成 const failClosed = cappedBy.length > 0; 后全部 302 个测试仍然通过,包括 'withholds the sha on a fail-closed input',与上方的归因注释相矛盾。— 失败场景:该变异是可观测的、非等价变异——当 cannotTellCriticals: [' '] 时没有任何模块 cap 触发(该条目在 ~602 处被过滤),而原始检查仍会扣留锚点,因此变异体会让锚点随之发布;局限于输入层通道的回归将不被发现。补一个模块 cap 覆盖不到的用例(或者,如果这种冗余是刻意的,就在每个用例中断言 r.cappedBy 并修正注释)。

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

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.

Added in 2fa20e5 — your exact case: cannotTellCriticals: [' '] joins the loop and asserts r.cappedBy is EMPTY alongside the withheld sha, so the cappedBy-only mutant you ran now fails precisely one case, and that case documents why the raw check exists. The loop comment now states the real attribution (each named input reaches the predicate through its cap entry; the whitespace case is the raw check's own witness).(已补该用例并修正归因注释;你实测的变异体现在恰好败在这一例。)

Comment on lines +206 to +208
typeof raw.sha === 'string' && SHA_RE.test(raw.sha) && !dropped
? raw.sha
: undefined;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

[Suggestion] The read side does not mirror the serializer for the findings COUNT cap — parseLedger silently slices valid findings past LEDGER_MAX_FINDINGS without synthesizing dropped, so the !dropped sha gate never fires for a count-overflowed marker; "every cap binds both halves" holds on write but not on read. — Failure scenario (probe-proven at this commit): a hand-edited own-account marker {"v":1,"round":2,"findings":[51 valid entries],"sha":"abc1234def567890"} with no dropped field parses to 50 findings and KEEPS the anchor — exactly the shape the serializer's else if refuses to emit; the silently sliced 51st entry references code at or before the anchored head, now out of every future sha..HEAD scope, and retires without ever receiving a ruling. Trigger is tamper-only (the serializer can never produce this shape, and latestOwnLedger restricts markers to the reviewing account — whose body is the writable surface). Count the pre-slice valid entries and withhold the anchor when the slice truncated:

const valid = raw.findings.filter(/* existing validity checks */);
const findings = valid.slice(0, LEDGER_MAX_FINDINGS).map(/* … */);
// and in the sha gate: && valid.length <= findings.length

(probe-verified: the patch withheld the sha and all 302 tests stayed green)

中文说明

[Suggestion] 读取端在 findings 条数上限上没有与序列化端对齐——parseLedger 会把超过 LEDGER_MAX_FINDINGS 的有效 findings 静默切片而不合成 dropped,因此对条数溢出的 marker,!dropped 的 sha 判定永远不会触发;"每个上限同时约束两端"在写入端成立、在读取端不成立。— 失败场景(已在本 commit 上用 probe 确认):一个本账号 review 上手工编辑的 marker {"v":1,"round":2,"findings":[51 条有效条目],"sha":"abc1234def567890"}(无 dropped 字段)会被解析为 50 条 findings 且锚点被保留——这正是序列化端 else if 拒绝产出的形状;被静默切掉的第 51 条引用的代码位于锚点 head 或其之前,从此落在所有未来 sha..HEAD 范围之外,再也得不到裁决。触发条件仅限篡改(序列化端不可能产生该形状,且 latestOwnLedger 只接受审查账号自己的 marker——而该账号的正文正是可编辑表面)。统计切片前的有效条目数,当切片发生截断时扣留锚点(patch 已用 probe 验证:sha 被扣留,全部 302 个测试保持绿色)。

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

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.

Fixed in 2fa20e5, one step further than the minimal gate: sliced valid entries now count into dropped (declared + overflow), so a count-overflowed hand-edited marker both renders the PARTIAL warning in the recovered section AND loses the anchor through the existing !dropped gate — 'every cap binds both halves' now holds on read for the count cap too. Pinned by a test with your exact probe shape (51 valid entries + sha, no dropped → 50 findings, dropped: 1, sha undefined).(读侧截断并入 dropped,PARTIAL 警示与锚点扣留同时生效,已按你的 probe 形状钉住。)

Comment on lines +59 to +61
* Absent on a fail-closed round ON PURPOSE — a run that left scope
* unreviewed must not hand the next round an anchor that scopes past it
* (the same rule Step 8 applies to the cache's `lastCommitSha`). The

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

[Suggestion] The parenthetical claims parity with Step 8's cache rule, but the marker's withholding net is strictly WIDER — the four named inputs plus every module-computed cap (cappedBy), while Step 8's cache-write skip enumerates only the four inputs — and this PR's own Step 8 paragraph states the wider net, contradicting "the same rule". — Failure scenario: on a module-only-capped round (e.g. chunk-nobody-read with all four inputs empty — module caps have no input channel) the marker withholds sha, but Step 8's enumeration gives the orchestrator no condition to skip the cache write, so lastCommitSha=fetchedSha is written anyway; the next high-effort run on the same machine scopes lastCommitSha..HEAD past the unreviewed chunk forever — or, with no new commits, hits the same-SHA stop outright. Align the nets — extend Step 8's skip enumeration with "or compose-review reported a non-empty cappedBy" — or at minimum correct the docstring:

Suggested change
* Absent on a fail-closed round ON PURPOSE a run that left scope
* unreviewed must not hand the next round an anchor that scopes past it
* (the same rule Step 8 applies to the cache's `lastCommitSha`). The
* Absent on a fail-closed round ON PURPOSE a run that left scope
* unreviewed must not hand the next round an anchor that scopes past it
* (a WIDER rule than Step 8 applies to the cache's `lastCommitSha`, which skips only on the four named inputs). The
中文说明

[Suggestion] 括号内的说法声称与 Step 8 的 cache 规则等同,但 marker 的扣留范围严格更宽——四个命名输入加上所有模块计算的 cap(cappedBy),而 Step 8 的 cache 写入跳过清单只列了四个输入——且本 PR 自己的 Step 8 段落明确写出了更宽的范围,与"同一规则"自相矛盾。— 失败场景:在一次仅被模块 cap 加帽的轮次(例如四个输入全空时的 chunk-nobody-read——模块 cap 没有输入通道),marker 正确扣留 sha,但 Step 8 的清单没有给编排器任何跳过 cache 写入的条件,于是 lastCommitSha=fetchedSha 照常写入;同一台机器上的下一次 high-effort 运行会以 lastCommitSha..HEAD 收窄范围,永久跳过那个未被审查的 chunk——或者在没有新 commit 时直接命中 same-SHA 短路。建议对齐两张网——把"或 compose-review 报告了非空 cappedBy"补进 Step 8 的跳过清单——至少也应修正文档字符串。

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

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.

Took the alignment option in 2fa20e5: Step 8's cache-skip enumeration now includes 'any cap in the composed verdict' (non-empty cappedBy), with the rationale that the cache and the marker must not disagree about what a clean round is — which closes the real leak in your failure scenario (module-only-capped round advancing lastCommitSha past the unreviewed chunk). The sha docstring's parenthetical is rewritten to name the shared net instead of claiming parity with the old narrower one.(选择了对齐两张网:Step 8 缓存跳写条件补入 cappedBy 非空,docstring 同步改写。)

…as on write

Three findings from the second review round on this PR:

- ledgerMarkerFor's four input disjuncts re-derived what cappedBy
  already aggregates — every named input pushes its own cap entry
  (probe-verified by the review). The predicate now reads the module's
  own verdict plus one deliberate raw check: a whitespace-only
  cannotTellCriticals entry is filtered out of the rendered caps, but
  an undecided blocker whose text was lost is still an undecided
  blocker. The fail-closed loop gains that raw-check-only case,
  asserting cappedBy is EMPTY — the case a cappedBy-only mutant fails
  (the review measured that mutant surviving the whole suite).

- parseLedger sliced valid findings past the count cap without
  synthesizing dropped, so a hand-edited 51-entry marker parsed to 50
  findings and KEPT the anchor — the shape the serializer's own
  truncation path refuses to emit. Sliced entries now count into
  dropped, which both renders the PARTIAL warning and withholds the
  sha through the existing gate.

- The sha docstring claimed parity with a Step 8 cache rule that named
  a narrower net: on a module-only-capped round the marker withheld
  the anchor while the cache still advanced lastCommitSha past the
  unreviewed chunk. Step 8's cache-skip enumeration now includes any
  cap in the composed verdict, so the two anchors cannot disagree
  about what a clean round is.
@wenshao

wenshao commented Aug 13, 2026

Copy link
Copy Markdown
Collaborator Author

@qwen-code /triage

@qwen-code-ci-bot

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

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

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

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

Verification report

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

Sandboxed verification: ✅ passed (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: 2902 passed · 0 failed · 2902 total

中文 — 判定:✅ 通过(agent 判定)

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

  • 结论merge-ready(2902 通过 / 0 失败)。上一轮的唯一建议级发现(§4.1:解析端计数上限截断静默且锚点幸存)在新 head 上复测确认已按上轮实测修复的语义修复(declared + slice,53 条 → dropped=3、声明 2+切 3=5、恰好 50 条完整带锚);两项完整性缺口(写端截断守卫、渲染端消毒)复测后维持原状,均为纵深防御层且读端独立守线,不构成合并条件。
  • A/B 结论:head 50/50(干净轮携带 fetchedSha、四个具名输入各自推入自己的 cap 条目并扣留锚点、模块自封顶轮扣留、空白 cannotTell 条目经原始检查扣留且 cappedBy 为空、截断失锚并渲染 PARTIAL、side file 轮次递进且锚点取本轮 head);base 45/45(处处无锚点、读端切片静默——即上轮 §4.1 的对照形状)。
  • Findings:无新增。§5.1/§5.2 为复测维持的完整性报告(非阻断)。
  • 未覆盖:SKILL.md Step 1/Step 8 的 agent 侧消费为模型行为;真实 GitHub 发布→恢复回路无 token;per-commit 归属因浅克隆不可达(验证聚合 diff)。
Verification report

PR 9067 deep verification (follow-up round 3) — feat(review): carry the incremental anchor sha in the posted ledger marker

Verdict: merge-ready — assertions 2902 pass / 0 fail / 2902 total. Verified head: 2fa20e5b16111dd6ab2f38d56fc6435086bd7cf2 (merge-ref checkout, base HEAD^1 = 5a6452a2a5). Every executed assertion passed; no new finding of any severity. The two completeness notes carried from the previous round were re-measured and stand unchanged as non-blocking (they pin defense-in-depth layers whose failure the pinned read-side guard would catch).

中文 — 判定:✅ 通过 · 无新发现(agent 判定)
  • 结论merge-ready(2902 通过 / 0 失败)。新 commit("one fail-closed net for anchor and cache, bound on read as on write")的三项主张全部实测成立:failClosed 读模块自身 verdict + 一条刻意保留的原始检查(空白 cannotTell 条目被渲染过滤但仍扣留锚点,M4 删除该检查后恰有一条用例红);解析端计数上限切片计入 dropped(M3 还原后 expected undefined to be 1,恰为预期断言);SKILL.md Step 8 缓存跳过枚举与标记锚点同网(文本核对;该层为 agent 指令,非可执行代码)。
  • A/B 结论:head 50/50 vs base 45/45(见证 01-ab-head-arm-anchor-cells.png / 02-ab-base-arm-no-anchor.png);base 侧 N2 复现上轮 §4.1 的静默切片形状(dropped=undefined),head 侧披露且失锚——修复的承重性由此证明。
  • Findings:无新增;§5.1/§5.2 两项完整性缺口复测维持(写端守卫 M6 套件绿但 wire 字节承重;渲染消毒 M7 套件绿但直探承重),均非阻断。
  • 未覆盖:agent 侧锚点消费(模型行为)、真实发布回路(无 token)、per-commit 归属(浅克隆)。

0. Previous-finding status (follow-up round)

# previous finding severity status at new head 2fa20e5b
1 §4.1 parser's own count-cap truncation silent — anchor rides a hand-edited >50-finding marker suggestion fixed — re-measured live (A/B cells N2/N3/N4/N5, forge probes 08/09, mutant M3 killed by the intended assertion expected undefined to be 1 at ledger.test.ts:164, witness 03-mutation-matrix-encoded.png). The implemented semantics match the previous round's measured fix exactly: declared + sliced (53 valid + sha → dropped=3, no sha; declared 2 + 53 valid → dropped=5; exactly-at-cap stays complete and keeps the anchor; dropped:0/-2/2.5 are not truncation). The PARTIAL warning now renders on the read-side truncation too (renderLedgerSection shows "3 further finding(s)").
2 §4.2 serializer truncation guard pinned only by composition (M2 survivor) completeness stands — re-measured: M6 (the same mutant shape) is GREEN against the 302-test suite, and the wire oracle shows the mutant's serialized bytes DO carry "sha" while head bytes do not (adjudicate-m6.log). Non-blocking for the same reason as last round: the read-side !dropped clause (M2, killed) independently strips the anchor next round, so the unpinned layer is defense-in-depth. The pinning fixture (expect(serializeLedger(overflowing)).not.toContain('"sha"')) is still the one-line addition that would close it.
3 §4.3 render sanitization of sha unpinned (M6-of-round-2 survivor) completeness stands — re-measured: M7 GREEN against the suite; direct probe shows head neutralises a crafted ``a

Both round-1 blockers (module-cap round carrying the anchor; unsanitised render) remain fixed at the new head — re-measured as A/B cell C5 and the §0.3 probe, not carried forward. All round-2 measurements were re-run at the new head (the tree, dist, and suites all changed with commit 4); nothing was carried by input-closure shortcut.

1. Central claim and A/B proof

Central claim (unchanged, extended by commit 4): the posted review's machine-ledger marker carries sha (the head the round reviewed) so a fresh environment recovers "last reviewed at" through parseLedgerlatestOwnLedger → the prev-ledger side file and scopes its incremental diff from it — withheld under ONE fail-closed net (the module's own cappedBy verdict plus a single raw check for any cannotTellCriticals entry, including whitespace-only ones the cap list deliberately filters), forfeited by every truncation (write-side caps AND the read-side count cap), field-level-dropped when malformed.

Write/read-site trace re-verified at the new head: fetchedSha is written into the plan by fetch-pr.ts:212 (git rev-parse of the PR ref); ledgerMarkerFor(input, result.cappedBy) (the single chokepoint) computes failClosed = (cannotTellCriticals?.length ?? 0) > 0 || cappedBy.length > 0 and passes sha only when clean; serializeLedger re-validates through SHA_RE and refuses the sha whenever dropped > 0; parseLedger counts its own count-cap slice into dropped (declared + (valid.length - findings.length)) and strips sha whenever dropped is set; pr-context.ts:981 writes the side file as JSON.stringify(prevLedger) so sha rides it; renderLedgerSection names it through code().

The net's asymmetry is deliberate and verified: of the four named inputs, only cannotTellCriticals is whitespace-filtered before the cap computation (compose-review.ts:597-602 vs 603-609), so only it needs the raw check — a whitespace-only uncoverableChunks entry still fires uncoverable-chunk (cell N6 on both arms) and a whitespace-only unreviewedDimensions fires unreviewed-dimension. The raw check therefore closes exactly the one sliver the cap list drops, and nothing more.

A/B: identical scenarios driven through the compiled dist/ of head and of a base worktree (HEAD^1, tsc -b packages/cli wired to the root node_modules; base type errors confined to unrelated UI test files, emission completed; control purity asserted — base ledger.js contains zero of fetchedSha/SHA_RE/payload.sha, base compose-review.js the same (the one grep hit is payload.shape); pr-context.js's only bare cross-package specifier @qwen-code/qwen-code-core realpaths into the head tree, and the PR's only core change is the SKILL.md data file, so the link is not a confound). Expectations encoded per arm — both arms print all-PASS only if head has the anchor behavior and base lacks it. Witnesses 01-ab-head-arm-anchor-cells.png / 02-ab-base-arm-no-anchor.png; raw logs logs/ab-head.log, logs/ab-base.log.

cell observable head (50/50) base (45/45)
C1 parse identical posted bytes with sha parseLedger anchor recovered same ledger, no anchor field
C2 old marker without sha parse unchanged unchanged
C3 clean composeReview (covered plan, transcripts, Step 4/5) marker cappedBy=[], sha=fetchedSha, round 1 marker present, no sha key
C4 the four named fail-closed inputs marker + cappedBy each withholds sha AND pushes its own cap entry (unreviewed-dimension, cannot-tell-existing-critical, uncoverable-chunk, context-unavailable — commit 4's "every named input pushes its own cap entry" claim verified per input) findings ride, no field
C5 round the MODULE caps (bare plan, drafted Critical) cappedBy + stamp + marker ["chunk-nobody-read","unreviewed-dimension"], "could not certify" stamp, sha withheld, finding rides same caps, no field
C6 side file round 4 + stale sha marker round 5, anchor = THIS round's head round 5, no anchor
C7 renderLedgerSection rendered section names reviewed at `abc1234def56789` ; silent without silent both ways
C8 serialize 51 findings + sha bytes + parse dropped=1, no "sha" in bytes dropped=1, no field
C9 latestOwnLedger seam recovered ledger anchor intact (byte-equal) ledger without anchor
N1 whitespace-only cannotTellCriticals (' ', '') cappedBy + marker cappedBy=[], sha withheld by the raw check alone, finding rides no field
N2 read-side count cap (53 hand-edited + sha) parse + render 50 kept, dropped=3, no sha, PARTIAL rendered with the count 50 kept, dropped=undefined — the §4.1 shape, silent
N3 declared 2 + sliced 3 parse dropped=5, no sha dropped=2 (declared only)
N4 exactly-at-cap (50 + sha) parse complete, anchor rides no field
N5 52 valid + 10 schema-invalid + sha parse 50 kept, dropped=2, no sha no field, silent
N6 whitespace-only uncoverableChunks cappedBy + marker cap entry fires, sha withheld cap entry fires too (no filter on this path)
N7 dropped:0 / dropped:-2 parse not truncation, anchor rides not truncation

The base arm's N2/N3 cells are the load-bearing control: they reproduce the previous round's §4.1 finding on base (dropped=undefined on a parser-sliced marker) while head discloses and forfeits the anchor — the fix is proven by the pair, not by the head arm alone.

2. Security + truncation battery (wire oracle, head build)

51/51 scripted probes (forge-probe.mjs, witness 04-forge-battery-51-probes.png, log logs/forge-head.log): the PR's own forged case "sha":"$(rm -rf /)" dropped field-level with the ledger intact; non-string shapes (number/null/boolean/object/array) dropped; boundaries exact (6-hex dropped / 7 accepted / 64 accepted / 65 dropped); uppercase, mixed-case, spaces, newline, --upload-pack, leading dash, backtick, quote-break and trailing-g inputs dropped; \u002d\u002d escape smuggling unescapes before the hex check and is rejected; no live -- survives into the payload and dashed titles round-trip verbatim with the sha riding; write-side guard refuses non-hex and embeds valid hex; read-side count cap discloses and forfeits under 53-entry, declared+slice, and mixed-valid/invalid shapes while exactly-at-cap stays complete; hand-edited dropped+sha stripped, dropped:0/-2/2.5 not truncation; byte-cap path forfeits the anchor (probe 10: wide-finding marker fits the 8,192 cap with dropped>0 and no sha; adjudicate logs: the 51-short-finding marker is 2,810 B, sha-free on head, sha-carrying under M6); last-marker-wins preserved; malformed markers (truncated JSON, bad v, round 0, non-array findings, unterminated) still null. Timing ladder linear — 2k/20k/200k-char bodies parse at ~0.002/0.007/0.064 ms; the anchored [0-9a-f]{7,64}$ class has no backtracking regime.

3. Mutation matrix (encoded, 7/7 + control)

Unmutated control green (302/302). Witness 03-mutation-matrix-encoded.png; raw logs logs/m<N>.log. Every red is exactly the intended test(s); git status clean after the matrix.

mutant expectation result killed by / classification
M1 serializer sha emission removed (positive control) red red (3) round-trip, clean-run carry, recovery-seam pins
M2 parser keeps sha when dropped>0 red red (1) a truncated ledger loses its anchor
M3 parser ignores its own count-cap slice (pre-§4.1 shape) red red (1) same test, expected undefined to be 1 at ledger.test.ts:164 (logs/M3-verbose.log) — the §4.1 fix is load-bearing and pinned by the intended assertion; the revert fails on the behavioral mismatch, not on an import or compile break
M4 failClosed = cappedBy only (raw check deleted) red red (1) withholds the sha on a fail-closed input — and only its whitespace-only case: the diff shows "sha": "deadbeef00112233" leaking on cannotTellCriticals: [' '] while every other case and every other test stays green, exactly as the commit message claims
M5 failClosed = raw check only (cappedBy deleted) red red (2) withholds the sha when the module ITSELF caps the round + the loop test (first divergent case aborts it)
M6 serializer emits sha despite dropped green green (302) survivor → adjudicated: mutant bytes carry "sha", head bytes don't (adjudicate-m6.log). Load-bearing on the wire; masked in-suite because every round-trip parses through the pinned !dropped read-side clause. Coverage gap, not dead code (§5.1)
M7 render bypasses code() for sha green green (302) survivor → adjudicated: crafted ``a

4. Commit-4 claim verification

  1. "The predicate reads the module's own verdict plus one deliberate raw check" — verified in code (compose-review.ts:550-551) and behaviorally (C4, N1, N6, M4, M5). The raw-check-only case exists and is pinned: M4's single red is it, asserting cappedBy empty while the anchor leaks. The commit's parenthetical ("a mutant keeping only cappedBy.length > 0 survived every other test") is reproduced by M4's green-everywhere-else pattern.
  2. "Sliced entries count into dropped; PARTIAL renders; sha forfeited" — verified (N2-N5, M3, forge 08/09). The PARTIAL disclosure now fires on read-side truncation, closing the previous round's §4.1.
  3. "Step 8's cache-skip enumeration includes any cap in the composed verdict" — verified as text: SKILL.md Step 8 now names "any cannotTellCriticals entry, or any cap in the composed verdict" for the cache skip and mirrors the marker's withholding conditions including truncation; Step 1 names truncation among the no-anchor cases. This layer is agent instruction, not executable code — SKILL.test.ts (8/8) checks structure and does not pin the new wording; consistency was checked by reading both sides (the doc's net = any cannotTell entry + any cap = the code's net).

5. Completeness notes (non-blocking, carried)

5.1 The serializer's truncation guard remains pinned only by composition

Re-measured at the new head (M6 + wire oracle, §3). The composition the feature depends on IS pinned (M2 red), and the read side holds the line independently, so a write-side regression would be caught next round at parse. Closing fixture, unchanged from the previous round: expect(serializeLedger(overflowing)).not.toContain('"sha"').

5.2 The render's code() sanitization of sha remains unpinned

Re-measured (M7 + direct probe, §3). Defense-in-depth over hex-only production input. Closing fixture, unchanged: hand a non-hex crafted sha directly to renderLedgerSection and assert the neutralised output.

5.3 Probed siblings that are NOT findings

  • Schema-invalid entries in a hand-edited marker are filtered without counting into dropped (N5). They were never findings — the serializer cannot emit them — so their silent absence matches the module's semantics; pre-existing on base.
  • A clean round with zero findings posts {"findings":[],"sha":…} — an empty work list with a live anchor, which is the correct meaning ("nothing found up to this head").
  • dropped:2.5 (non-integer) is ignored and the anchor rides — consistent with the "declared must be a positive integer" contract.

6. Gates (exact counts)

gate result
packages/cli — the 3 affected test files (unmutated control) 302/302
packages/coresrc/skills/bundled/review/SKILL.test.ts 8/8
packages/cli — full src/commands/review suite at head 68/68 files, 2438 passed, 4 skipped, 0 failed (2442)
packages/cli — full src/commands/review suite at base (attribution control) 68/68 files, 2430 passed, 4 skipped, 0 failed (2434) — delta +8 passed, +0 failed, exactly the 8 new it blocks (12→15, 213→216, 65→67 per file). No pre-existing failures on either arm.

The PR body's "2432/2433, one failure stale-bundle.test.ts" is consistent with a stale local build on the author's machine; on fresh builds both arms are green, including stale-bundle.test.ts. The Reviewer Test Plan's three steps were all executable and held; per-claim results are the cells of §1-§3.

7. Not covered

  • Agent-side consumption of the anchor is model behavior, not code: SKILL.md Step 1's recovered-anchor bullet and Step 8's unified net were read and are internally consistent with the code's validation (git cat-file -e + merge-base --is-ancestor before scoping, full-diff fallback, side-file-round-beats-stale-cache, truncation named among no-anchor cases); no executable path exists to drive them, and there is no token to run a real review round.
  • Real GitHub post→recover round-trip: no network/token in this environment. The recovery cells replay the wire shape (synthetic posted bodies with the exact marker bytes pr-context will see), not the API trigger that produces them.
  • Per-commit attribution: the metadata lists 4 commits; the depth-2 checkout makes only the head reachable (git rev-parse HEAD^2^ fails; git rev-list HEAD^1..HEAD^2 returns the known false-small 1). The aggregate HEAD^1..HEAD diff (7 files, +316/−19) is what was verified; the four commit messages match the aggregate code state.
  • SKILL.md Step 8 wording is not test-pinned: SKILL.test.ts is structural; the new cache-skip enumeration was verified by reading, not by an executable assertion (§4.3).
  • Repo-wide gates beyond the affected suites — the pre-run npm run build at HEAD is a full typecheck; the diff touches no package beyond cli's review command and core's SKILL.md data file.

8. Methodology

Environment: the CI verify container (node:22-bookworm), working tree at refs/pull/9067/merge (depth 2), npm ci + npm run build pre-run at HEAD; verified head 2fa20e5b16 = HEAD^2; base tip HEAD^1 = 5a6452a2a5 (the metadata snapshot's baseRefOid had drifted to an older main; on a merge-ref checkout HEAD^1 is authoritative). Harnesses (ab-harness.mjs, forge-probe.mjs, fixtures.mjs, matrix.mjs, apply-mutant.mjs, adjudicate-probe.mjs, vacuity-m4.sh in this directory) import the compiled dist of whichever tree they are pointed at (base via a scratch worktree + tsc -b packages/cli; the worktree was removed after capture) and print one PASS/FAIL line per scripted assertion; fixtures.mjs reproduces the suite's plan/transcript/Step-4-5 fixture infrastructure in plain node, with each composeReview cell on a fresh fixture dir (a shared dir leaks earlier cells' transcripts into a later bare-plan cell and masked the module cap — measured while building the harness). The bilingual plan flag keeps the deterministic path, so no gh call fires. Mutations ran in the verified tree's source with git checkout -- restores between runs, asserted by a clean git status after the matrix; they never touched the dist the A/B consumed. M6/M7 adjudication ran under tsx against the source with the mutant applied, then reverted. One environmental note: the base full-suite run initially failed 34/68 files because the scratch worktree lacked package-local node_modules (vite could not resolve ajv from core's src); symlinking the head tree's package-local node_modules (verified to contain no @qwen-code links) fixed it — a harness-setup issue, identical in nature to the previous round's, not a PR property. Raw per-cell logs live in logs/, evidence captures in evidence/. The verified tree's git status is clean.

Evidence images

01-ab-head-arm-anchor-cells

02-ab-base-arm-no-anchor

03-mutation-matrix-encoded

04-forge-battery-51-probes

05-m4-vacuity-ws-only-case

Harness scripts and raw logs are in this directory (tmp/pr9067-verify-20260813-121840/).

Qwen Code · sandboxed verification

Evidence images

01-ab-head-arm-anchor-cells

02-ab-base-arm-no-anchor

03-mutation-matrix-encoded

04-forge-battery-51-probes

05-m4-vacuity-ws-only-case

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 dismissed stale reviews from themself August 13, 2026 12:20

Resolved: the PR body was rewritten with every required template heading (re-verified on head 2fa20e5). Dismissing this stale gate so it no longer holds the queue.

@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 yiliang114 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Approved after a source-level audit at head sha, focused on the dangerous direction (a spoofed/tampered anchor silently scoping the next round too narrow).

Anchor integrity — verified fail-closed:

  • Recovery is own-account only (latestOwnLedger filters by login); the side file qwen-review-pr-<n>-prev-ledger.json is keyed per PR and is a verbatim JSON.stringify of the parsed ledger (pr-context.ts:969–982), so the seam the new seam-test pins is the real one.
  • Field-level SHA_RE gates on BOTH halves: parseLedger drops a garbage/forged sha without losing the work list, serializeLedger never emits a non-hex one. That matters beyond format: Step 1 interpolates the sha into git cat-file/merge-base, so hex-only is also the injection fence (the $(rm -rf /) test pins it).
  • Ancestry validation is enforced where it counts — SKILL.md Step 1 requires git cat-file -e <sha>^{commit} + git merge-base --is-ancestor <sha> HEAD inside the worktree, with full-diff fallback + warning on failure. An attacker-controlled sha that passes both can only be an ancestor of head: older than the true anchor means a WIDER range (over-review), and the descendant direction is structurally impossible. Within the documented trust model (marker is data, not authority; same trust tier as the cache's lastCommitSha), no path to a wrong narrow diff.
  • Truncation/tamper: dropped strips the anchor on write AND read; the read side now synthesizes dropped from count-cap slicing (declared + (valid.length - findings.length)), closing the hand-edited count-overflow hole from round 2. Precedence on that + ... || undefined expression is correct as written, if a touch subtle.
  • Withholding net: verified in source that the round-2 subsumption is complete — toStringList copies without trim-filtering, so whitespace-only uncoverableChunks/unreviewedDimensions still fire their caps via cappedBy; only cannotTellCriticals is trim-filtered (compose-review.ts:597–600), which is exactly the one input keeping a raw check. The whitespace-only test case asserting cappedBy: [] kills the would-be mutant. plan.fetchedSha itself comes from fetch-pr's git rev-parse of the fetched ref (fetch-pr.ts:212,378), not from model-written input.

Compatibility: old markers parse with sha absent → silent section, full-range review; old readers ignore the new field; render names the anchor only when present.

Nits (non-blocking):

  • P3: the trust model relies on own-account authorship of the review body; worth keeping the ledger.ts header's "data, not authority" framing in mind if GitHub ever exposes cross-account review edits — the ancestry check remains the backstop.
  • P3: const dropped = declared + (valid.length - findings.length) || undefined; would read more obviously with explicit parens around the sum.

CI on head sha: all substantive checks green/skipped; only review-pr (this review) in progress and route (triage routing) cancelled — neither gates.

All round-1/round-2 findings (incl. the Critical on module-computed caps bypassing the gate) verified fixed in source, not just claimed in replies.

@wenshao
wenshao added this pull request to the merge queue Aug 13, 2026
Merged via the queue into main with commit fbfef1e Aug 13, 2026
151 of 155 checks passed
@wenshao
wenshao deleted the feat/review-ledger-sha branch August 13, 2026 13:20
@qwen-code-ci-bot

Copy link
Copy Markdown
Collaborator

Released in v0.21.12.

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.

4 participants