fix(acp-bridge): bound live journal replay chunks - #8801
Conversation
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
🩺 serve daemon A/BBuilt the PR base vs this PR head ✅ No response changes against the PR base across 4 scenario(s). — Qwen Code · serve A/B |
yiliang114
left a comment
There was a problem hiding this comment.
NEEDS-CHANGES on one item — the engine itself is solid. The merge predicate checks every boundary I could ask for (parentToolCallId, sourceRecordIds, promptId, originatorClientId, sessionId, explicit-empty vs absent provenance, non-timestamp envelope _meta, discrete and unmodeled update meta), the 256-cap and byte-cap split arithmetic is correct, text is never silently dropped (every source event is merged, kept as its own entry, or evicted into the truncated count), ordering and last-source-id semantics are monotonic and consumer-tolerant, and the unfinished/completed gate is sound — all pinned across the 92-test suite.
Blocker: the entry-vs-event semantic change breaks two integration tests that were not updated, and that only escaped detection because Integration Tests (CLI, No Sandbox) is skipped for this PR's CI:
- integration-tests/cli/qwen-serve-live-journal-recovery.test.ts:46-82 and integration-tests/cli/qwen-serve-webui-live-journal-recovery.test.ts:124-183 both start the daemon with --max-journal-events 3 and have the mock child emit 20 bare compatible agent_message_chunk events (the fixture emits {sessionUpdate, content} with no _meta). Pre-change that is 20+ raw entries > 3 → marker; now all 20 merge into one entry, the journal stays under the cap, history_truncated never appears, the first test's expect(duringTurn).toBeDefined() fails and the second's waitFor('visible live journal marker') times out. Suggested fix: rework both to force truncation with non-mergeable events (or a tiny --max-journal-bytes to force a segment split), and ideally add an assertion that a long compatible stream now stays marker-free.
Non-blocking notes:
- mergeLiveJournalTextEvent spread-merges the open-typed update ({...existing, ...incoming, content}), unlike the canonical reconstruction on the completed path. Verified unreachable today — MessageEmitter only emits sessionUpdate/content/_meta on chunks and every _meta variant it uses is blocked by hasUnmodeledTextMeta and pinned — but requiring the exact key set {sessionUpdate, content, _meta?} or reconstructing canonically would make that structural rather than contingent.
- The live marker sentence mixes units: 'kept the latest N events and dropped M older replay events (limits: X replay entries / Y bytes)' — N/M count source events while X counts entries. Documented, but easy for an operator to misread.
- Thought-chunk _meta now propagates on the live path too (parity fix, pinned by the new SDK test) — a user-visible SDK behavior change beyond replay, worth a release note.
CI note: Test (ubuntu-latest) on this head is red on the known backgroundShellRegistry retention-cap flake that #8797 deflakes (not in this branch yet); 19,563 tests including every PR-related suite pass, so it is unrelated to this change.
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
…ay-chunks # Conflicts: # packages/core/src/services/backgroundShellRegistry.test.ts
|
Addressed the integration-test blocker in
已在
|
doudouOUC
left a comment
There was a problem hiding this comment.
APPROVE (C=0) at baf5dedb653f9cee770308451e4af1ed5cc51b16.
Reviewed the full 15-file diff and traced the changed live-journal semantics through the bridge, CLI configuration/status surface, load snapshot consumers, SDK normalization/transcript reduction, and WebUI truncation repair. The merge predicate preserves type, tool, attribution, provenance, discrete-message, and semantic-metadata boundaries; the 256-source-event segment cap, conservative source-byte accounting, oldest-first eviction, source-event diagnostics, latest event ID, and turn-boundary reset behavior are consistent.
The earlier integration blocker is fixed on the current head: the compatible 20-chunk case now proves the complete live replay stays marker-free under the entry cap, while the truncation-recovery cases use the byte cap to exercise eviction. I verified the built bundle locally: both integration files passed (3/3), ACP compaction passed (92/92), SDK daemon UI passed (285/285), and build, bundle, full typecheck, ESLint on changed TypeScript, Prettier, and git diff --check all passed.
The remaining red Linux check is not a product-test failure: all 19,622 core tests passed, and the job exited only because Vitest reported a worker RPC timeout while calling onTaskUpdate. This is unrelated to the PR diff.
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
|
Follow-up for the Ubuntu CI failure on The log confirms the same fixed-sidecar collision pattern: ordinary status writes took ~351/702ms and the four retention tests took 23.2–23.9s each. The upstream 120s per-test timeout prevented assertion timeouts but did not remove the shared Commit 补充说明 日志再次确认是固定 sidecar 路径冲突:普通状态写入稳定耗时约 351/702ms,四个 retention tests 分别耗时 23.2–23.9 秒。上游增加 120 秒 test timeout 只能避免 assertion timeout,无法消除共享
|
|
@qwen-code /triage |
|
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: 97 passed · 0 failed · 97 total 中文 — 判定:✅ 通过 · 可合入(agent 判定)沙箱验证在隔离、无凭证的容器中执行了该 PR 的代码(与 base 构建 A/B 对照、无 mock harness 断言、定向门禁)。仅作为评审证据,不构成评审、批准或 CI 检查。 脚本断言:97 通过 · 0 失败 · 97 总计 Verification reportPR 8801 verification — fix(acp-bridge): bound live journal replay chunksVerdict: 中文摘要
Central claim + A/BCentral claim: during an unfinished turn, consecutive compatible assistant text/thought chunks share bounded replay entries (≤256 source events each), so the Harness:
Totals: base arm 20/20 (all base failures occurred exactly as predicted), head arm 25/25. The flip is the load-bearing proof: the same stream that base truncates survives head with byte-identical text, and the realtime subscriber path is unchanged on both arms. Secondary claims
FindingsNone blocking. Two non-defect observations, recorded for the reviewer:
Mutation matrix (vacuity)All mutants are single-point edits to the changed source, run against the unmodified head test file; every kill failed with a behavioral assertion (quoted in
7/7 mutants killed, no survivors; both restore controls green. Targeted gates (all green)
The mutation matrix doubles as the gate-liveness proof: the same vitest harnesses that report green were shown to go red on planted single-line changes. Not covered
MethodologyEnvironment: Evidence imagesHarness scripts and raw logs are in the workflow run artifacts (7-day retention). — Qwen Code · sandboxed verification |
|
Re-run at the new head ( Template looks good ✓ Problem: observed, not theoretical — a live turn streaming hundreds of thousands of fine-grained thought/message chunks deterministically exhausts the 10,000-entry live journal cap and surfaces a Direction: aligned — a direct continuation of the live-journal truncation-recovery work, scoped to the unfinished-turn replay snapshot. Real-time SSE delivery and completed-turn compaction semantics are untouched; the live merge predicate is strictly more conservative than the completed path's (exact equality where the completed path does last-wins), so the two replay surfaces agree. Size: cross-package (acp-bridge, cli, sdk-typescript) — 354 production logic lines vs 743 test lines and 21 doc lines, under the 500-line awareness threshold. The author is a collaborator with write access. Approach: scope remains right, and the single new commit is exactly the outstanding Critical, nothing more — +11/−4 engine lines adding the content-sub-key gate to Risk: no high-risk path matches. One standing review-depth consequence: Moving on to code review. 🔍 中文说明在新 head( 模板完整 ✓ 问题:已观测到的问题,非理论性加固——长时间运行的 live turn 若流式输出数十万个细粒度 thought/message chunk,会确定性地耗尽 live journal 的 10,000 条回放 entry 上限,在实际文本量还很小时就显示 方向:对齐——这是 live-journal 截断恢复工作的直接延续,范围限定在未完成 turn 的回放快照;实时 SSE 投递与已完成 turn 的压缩语义均未改动。live 合并判定比 completed 路径更保守(completed 路径采用 last-wins 的地方这里要求精确相等),因此两个回放面保持一致。 规模:跨包改动(acp-bridge、cli、sdk-typescript)——生产逻辑 354 行、测试 743 行、文档 21 行,低于 500 行关注阈值;作者为有写权限的 collaborator。 方案:范围仍然合理,且唯一的新 commit 恰好就是那个待处理的 Critical、别无其他——引擎 +11/−4 行,为 风险:未命中高风险路径。一个持续影响 review 深度的点:fork PR 的 CI 会跳过 进入代码审查 🔍 — Qwen Code · qwen3.8-max Reviewed at |
Code reviewThe mechanics are unchanged from the previous pass and still hold: What this head adds is exactly @doudouOUC's verified Critical — legal ACP One observation, pre-existing and out of scope: the completed-turn path ( Everything else verified on the prior head remains addressed here (@yiliang114's integration-test blocker and three non-blocking notes; @wenshao's seven findings — exact-key gating, discrete/meta-shaped boundaries including the thought path, empty-string Files changed (15)
Test evidence — the PR's own CI (the gate never builds or runs PR code)Same structural gap as before:
One row per check name (latest run); skipped checks omitted; failures sort first. / 每个检查名一行(取最新一次运行),省略 skipped,失败项排在最前。 The integration-level claim is not gate-verified by the PR's own CI on this head (the lane is skipped for forks), and the metadata-fix behavior itself is not observable from fork CI at all. Sandboxed verification would settle this: Real-scenario testing: N/A for this run — the gate never executes PR-derived code (no checkout of the fork branch, no applying the diff to the working tree), and a tmux before/after arm would require building this PR. Live-behavior evidence is delegated to the isolated sandboxed lane above. Not verified locally: daemon-level behavior on this head — reason: static-gate rule; the sandboxed lane is in flight. 中文说明代码审查机制与上一轮一致且仍然成立: 当前 head 新增的恰好就是 @doudouOUC 已验证的 Critical——合法 ACP 一点观察,属于既有行为、不在本 PR 范围内:completed-turn 路径( 上一个 head 上已验证的其他各项在当前 head 仍然成立(@yiliang114 的集成测试 blocker 与三条非阻塞意见;@wenshao 的七条意见——精确 key 门禁、离散/meta 形状边界(含 thought 路径)、空字符串 测试证据 —— 本 PR 自身的 CI(门禁从不构建或运行 PR 代码)结构性缺口与之前相同:fork PR 的 CI 跳过 集成层面的结论尚未由本 PR 自身的 CI 在当前 head 上门禁验证(该通道对 fork 跳过),且 metadata 修复的行为本身完全无法从 fork CI 观测。沙箱验证用于补上这个缺口: 真实场景测试:本轮为 N/A——门禁从不执行 PR 衍生的代码(不 checkout fork 分支、不把 diff 应用到工作树),而 tmux before/after 需要构建本 PR。live 行为证据委托给上述隔离沙箱通道。未在本地验证:当前 head 上的 daemon 级行为——原因:静态门禁规则;沙箱通道正在进行中。 — Qwen Code · qwen3.8-max Reviewed at |
|
Confidence: 4/5 — the verified Critical is resolved by the reviewer's own proposed fix, pinned by a regression test on his exact wire shape; what remains is process (a re-review and an in-flight verify round), not code. Stepping back: the approach still matches what I would have proposed independently — merge at ingest (the only placement that actually bounds the journal), a predicate that refuses on any doubt, source-event byte accounting so the memory cap keeps its meaning, and the unit change spelled out on every doc/help/SDK surface. What decides this round is how the Critical landed: +11/−4 engine lines doing exactly what @doudouOUC suggested (admit only content objects whose own keys are Three honest reservations, none blocking. First, the behavioral proof on this exact head is still in flight: Verdict: approve — every 中文说明置信度:4/5 —— 已验证的 Critical 由 reviewer 自己提议的方案修复,并有锁定其确切 wire 形状的回归测试;剩余的是流程事项(re-review 与进行中的 verify 轮次),而非代码。 整体来看:方案仍然与我独立提出的做法一致——在 ingest 时合并(唯一能真正约束 journal 的位置)、拿不准即拒绝合并的判定、按源事件计字节以保持内存上限语义不变、单位变化在文档/帮助/SDK 各面逐一写明。决定本轮结论的是 Critical 的落地方式:引擎 +11/−4 行,恰好是 @doudouOUC 建议的做法(只允许 content 键集恰为 三点保留意见,均不阻塞。其一,当前 head 上的行为证明仍在进行中: 结论:批准——被审查 commit 上所有 — Qwen Code · qwen3.8-max Reviewed at |
qwen-code-ci-bot
left a comment
There was a problem hiding this comment.
LGTM, looks ready to ship. ✅
|
@qwen-code /takeover |
|
🤝 Takeover engaged: the autofix loop now manages this PR — it will address new review feedback and resolve base conflicts until the label is removed or the round cap is reached. This is a fork PR, so the first round comes from the next scheduled scan (usually within minutes). Remove the 中文说明🤝 已接管:autofix 循环现在管理此 PR —— 将持续处理新的评审反馈与 base 冲突,直到移除标签或达到轮次上限。本 PR 来自 fork,首轮处理将由下一次定时扫描执行(通常几分钟内)。移除 |
wenshao
left a comment
There was a problem hiding this comment.
Reviewed. Suggestions are inline. Not reviewed: build-and-test — Integration Tests (CLI, No Sandbox) was skipped in CI and its suite (qwen-serve-live-journal-recovery, qwen-serve-webui-live-journal-recovery) did not run in this review; the diff's two changed integration tests are only exercised by that skipped job. Not explored to full depth (tool budget reached): This PR (fix(acp-bridge): bound live journal replay chunk...: I did not run the two integration tests ( qwen-serve-live-journal-recovery , qwen-serve-webui-live-journal-recovery ) — they spawn daemons and need a build; I …; This PR (fix(acp-bridge): bound live journal replay chunk...: integration tests ( qwen-serve-live-journal-recovery , qwen-serve-webui-live-journal-recovery ) were not executed (they spawn real daemons); the backgroundShe…. Test Plan (not a blocker): src/compactionEngine.test.ts — no such file or directory; test/unit/daemonUi.test.ts — no such file or directory; src/commands/serve.test.ts — no such file or directory; src/serve/fast-path.test.ts — no such file or directory; 92 passed — this review observed 1140 passed; and 2 more.
中文说明
已审查。 建议见行内评论。 未审查:build-and-test — Integration Tests (CLI, No Sandbox) was skipped in CI and its suite (qwen-serve-live-journal-recovery, qwen-serve-webui-live-journal-recovery) did not run in this review; the diff's two changed integration tests are only exercised by that skipped job。 未探索到全部深度(达到工具调用预算):This PR (fix(acp-bridge): bound live journal replay chunk...:I did not run the two integration tests ( qwen-serve-live-journal-recovery , qwen-serve-webui-live-journal-recovery ) — they spawn daemons and need a build; I …;This PR (fix(acp-bridge): bound live journal replay chunk...:integration tests ( qwen-serve-live-journal-recovery , qwen-serve-webui-live-journal-recovery ) were not executed (they spawn real daemons); the backgroundShe…。 Test Plan(非阻断):src/compactionEngine.test.ts — no such file or directory; test/unit/daemonUi.test.ts — no such file or directory; src/commands/serve.test.ts — no such file or directory; src/serve/fast-path.test.ts — no such file or directory; 92 passed — this review observed 1140 passed; and 2 more。
— DeepSeek/deepseek-v4-flash via Qwen Code /review (v0.21.8)
The merged live-journal entry is rebuilt by spread-merging the first and
last source events, which was only safe because producers happen to emit
exactly {sessionUpdate, content, _meta?} on mergeable chunks. Gate the
merge on that key set so unmodeled data/update fields keep entries
discrete instead of leaking into the aggregate. Also clarify the
live-journal truncation marker: its retained/truncated counts describe
source events, while the limits count replay entries.
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
|
🤖 Addressed the latest review feedback (round 1/100). What changed, and what I pushed back on: · 已处理最新评审反馈(第 1/100 轮)。改动内容与我反驳保留之处如下: Autofix review round — PR #8801Commit: Feedback dispositions1. Blocker (CHANGES_REQUESTED): entry-vs-event semantic change breaks the two live-journal integration tests — VERIFIED ALREADY FIXED, re-proven by execution.
2. Note 1: 3. Note 2: live truncation marker mixes units — IMPLEMENTED. 4. Note 3: thought-chunk 5. CI note: red Test (ubuntu-latest) from the Changed files this round
VerificationAll commands actually run this round against the committed tree (
中文说明Autofix 审查轮次 — PR #8801提交: 反馈处理结果1. 阻塞项(CHANGES_REQUESTED):entry 与 event 语义变更破坏了两个 live-journal 集成测试 — 确认已在先前提交修复,并通过实际运行再次验证。
2. 注记 1: 3. 注记 2:live 截断 marker 混用单位 — 已实现。 4. 注记 3:thought-chunk 5. CI 注记:Test (ubuntu-latest) 因 本轮修改的文件
验证以下命令均为本轮针对已提交代码树(
Base-conflict check · 基分支冲突检查: no conflict with main. · 与 main 无冲突。 Re-review when you have a moment. After round 100 this bot stops and leaves the PR for a human. · 有空请复审;第 100 轮后本 bot 停止并将 PR 交给人工。 🧠 Handled by Qwen Code · model/模型 |
|
🤖 Addressed the latest review feedback (round 2/100). What changed, and what I pushed back on: · 已处理最新评审反馈(第 2/100 轮)。改动内容与我反驳保留之处如下: Review feedback addressed — PR #8801 (round 2)All seven inline suggestions were verified against the code and addressed in one commit ( Findings and dispositions
Review-level notes: the two integration suites flagged as not run ( Verification
中文说明已处理的审查反馈 — PR #8801(第 2 轮)七条行内建议均已对照代码核实,并在一个提交中处理完毕( 各条反馈及处理
审查级备注:本轮在 验证
Base-conflict check · 基分支冲突检查: no conflict with main. · 与 main 无冲突。 Re-review when you have a moment. After round 100 this bot stops and leaves the PR for a human. · 有空请复审;第 100 轮后本 bot 停止并将 PR 交给人工。 🧠 Handled by Qwen Code · model/模型 |
qwen-code-ci-bot
left a comment
There was a problem hiding this comment.
Reviewed — no blockers. Suggestions are inline. Test Plan (not a blocker): src/compactionEngine.test.ts — no such file or directory; test/unit/daemonUi.test.ts — no such file or directory; src/commands/serve.test.ts — no such file or directory; src/serve/fast-path.test.ts — no such file or directory; 92 passed — this review observed 1150, 18673, 19547, 1482, 481, 2941, 454 passed; and 2 more.
中文说明
已审查——无阻断问题。 建议见行内评论。 Test Plan(非阻断):src/compactionEngine.test.ts — no such file or directory; test/unit/daemonUi.test.ts — no such file or directory; src/commands/serve.test.ts — no such file or directory; src/serve/fast-path.test.ts — no such file or directory; 92 passed — this review observed 1150, 18673, 19547, 1482, 481, 2941, 454 passed; and 2 more。
— qwen3.8-max via Qwen Code /review (v0.21.8)
SubAgentTracker stamps every streamed subagent fragment with
{ parentToolCallId, subagentType }, but the live-journal merge gate
only modeled parentToolCallId, so subagent chunks stayed discrete and
a high-fragment subagent stream could still trip history_truncated.
Model subagentType as a carried label (like the completed-turn path,
which merges by parentToolCallId alone) and cover the producer wire
shape in the merge tests.
|
🤖 Addressed the latest review feedback (round 3/100). What changed, and what I pushed back on: · 已处理最新评审反馈(第 3/100 轮)。改动内容与我反驳保留之处如下: Review feedback addressed — PR #8801Findings[Suggestion] R1-1 (rc:3745939288) — Subagent-streamed chunks never merge in the live journal → AddressedThe finding was verified against the code before changing anything:
Fix chosen: the suggestion's second option — explicitly model Test updates:
Load-bearing proof: with the source change temporarily reverted, exactly the two paired-shape tests fail ( Review-level Test Plan note — No action requiredThe review body's Test Plan (marked "not a blocker") listed paths like Changes
Commit: VerificationCommands actually run this round, all from the repository checkout:
No conflict resolution was needed ( 中文说明已处理的评审反馈 — PR #8801各项发现[建议] R1-1(rc:3745939288)— subagent 流式 chunk 在 live journal 中从不合并 → 已处理修改前已对照代码核实该发现:
所选修复: 采用建议中的第二个方案 —— 把 测试更新:
承重性证明:临时还原源码修改后,恰好是这两个成对形状用例失败( 评审正文的 Test Plan 备注 — 无需处理评审正文的 Test Plan(已标注"非阻断")把 变更内容
提交: 验证本轮在仓库检出目录中实际执行的命令:
无需解决冲突( Base-conflict check · 基分支冲突检查: no conflict with main. · 与 main 无冲突。 Re-review when you have a moment. After round 100 this bot stops and leaves the PR for a human. · 有空请复审;第 100 轮后本 bot 停止并将 PR 交给人工。 🧠 Handled by Qwen Code · model/模型 |
…ay-chunks # Conflicts: # packages/core/src/services/backgroundShellRegistry.test.ts
|
🤖 Addressed the latest review feedback (round 4/100). What changed, and what I pushed back on: · 已处理最新评审反馈(第 4/100 轮)。改动内容与我反驳保留之处如下: Autofix review round — base-conflict resolution for PR #8801Feedback triageThe workflow-prepared feedback contained no actionable items this round: no reviews, no inline comments, no issue-level comments, no failed checks, and no still-red checks. The only work was resolving the reported conflict against Changes madeMerged Conflict resolution — Auto-merged files audited (both sides changed them, in disjoint regions): journal-cap doc wording in No feedback findings existed to resolve, decline, or escalate; VerificationCommands actually run against the merged tree (before committing the merge):
No settings source changed, so 中文说明Autofix 审查轮次 — PR #8801 的基分支冲突解决反馈分类本轮工作流准备的反馈中没有可处理项:没有审查意见、没有行内评论、没有 issue 级评论、没有失败的检查,也没有持续失败的检查。唯一的工作是解决针对 所做更改在合并提交 冲突解决 — 已审查的自动合并文件(双方都修改了它们,但区域互不重叠): 不存在需要解决、拒绝或升级的反馈发现;因此相应地省略了 验证在合并后的代码树上(提交合并之前)实际运行的命令:
未修改任何 settings 源,因此无需运行 Base-conflict check · 基分支冲突检查: conflicted with main — resolved in this push. · 与 main 有冲突——已在本次推送中解决。 Re-review when you have a moment. After round 100 this bot stops and leaves the PR for a human. · 有空请复审;第 100 轮后本 bot 停止并将 PR 交给人工。 🧠 Handled by Qwen Code · model/模型 |
|
@qwen-code /triage |
|
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: 140 passed · 0 failed · 140 total 中文 — 判定:✅ 通过 · 可合入(agent 判定)沙箱验证在隔离、无凭证的容器中执行了该 PR 的代码(与 base 构建 A/B 对照、无 mock harness 断言、定向门禁)。仅作为评审证据,不构成评审、批准或 CI 检查。 脚本断言:140 通过 · 0 失败 · 140 总计 Verification reportPR 8801 verification (round 2) — fix(acp-bridge): bound live journal replay chunksVerdict: 中文摘要
Previous-finding status (round 1 → round 2)Round 1 reported no blocking findings; two observations. Status at the new head:
Round-1 verified claims, re-measured (not diffed) at the new head/base: central A/B cells re-run (table below); boundary behavior re-pinned by the head suite's Central claim + A/BCentral claim: during an unfinished turn, consecutive compatible assistant text/thought chunks share bounded replay entries (≤256 source events each); Harness:
Totals: base arm 50/50, head arm 71/71 — every base failure occurred exactly as predicted (encoded as passing assertions); the flips are the load-bearing proof. CorrectionsNone needed this round. FindingsNone blocking. Observations for the reviewer, each with its repro:
Mutation matrix (vacuity)Single-point mutants of the head source, run against the unmodified head test file (
7/7 mutants killed, 0 survivors. Attribution contrast: M2 (turn-compaction guard) leaves all live-journal discrete tests green and vice versa — the two layers are pinned independently, so a future regression in either gate is caught by its own tests. Targeted gates (all green)
Gate liveness: the mutation matrix above is the proof — the same vitest harnesses reporting green here went red on planted single-line changes. Witness: Not covered
MethodologyEnvironment: Evidence imagesHarness scripts and raw logs are in the workflow run artifacts (7-day retention). — Qwen Code · sandboxed verification |
qwen-code-ci-bot
left a comment
There was a problem hiding this comment.
LGTM, looks ready to ship. ✅
|
🤖 Reviewed the latest feedback — no changes needed. Why, point by point: · 已审阅最新反馈——无需改动。逐点说明原因如下: Autofix review round for PR #8801 — no action neededThe workflow delivered only feedback newer than the last evaluation (2026-08-10T01:09:56Z):
All earlier review and inline-comment findings predate the last evaluation and were already handled in previous rounds; the current branch head ( No code changes were made and no commit was created this round. If the pending sandbox verification report raises findings, they will be triaged in a later round. 中文说明PR #8801 的 Autofix 审查轮次 —— 无需处理工作流仅提供了上次评估(2026-08-10T01:09:56Z)之后的新反馈:
此前的所有审查和行内评论发现均早于上次评估,已在之前的轮次中处理完毕;当前分支头( 本轮未做任何代码变更,也未创建任何提交。如果待完成的沙箱验证报告提出了问题,将在后续轮次中进行分类处理。 Base-conflict check · 基分支冲突检查: no conflict with main. · 与 main 无冲突。 🧠 Handled by Qwen Code · model/模型 |
doudouOUC
left a comment
There was a problem hiding this comment.
Requesting changes for one verified Critical. The previous integration-test blocker and all currently visible review-thread findings are fixed on this head, and the targeted compaction and SDK suites pass. The remaining inline issue causes legal ACP content metadata to disappear from load/recovery snapshots.
|
🤖 Addressed the latest review feedback (round 5/100). What changed, and what I pushed back on: · 已处理最新评审反馈(第 5/100 轮)。改动内容与我反驳保留之处如下: Review feedback addressed — PR #8801Feedback points[Critical] Preserve ACP TextContent metadata in live replay (
|
qwen-code-ci-bot
left a comment
There was a problem hiding this comment.
Reviewed. Suggestions are inline. 1 Suggestion-level finding(s) could not be anchored to a changed line and were dropped; nothing further to act on here. Not reviewed: build-and-test — Integration Tests (CLI, No Sandbox) was skipped in CI and its suite (qwen-serve-live-journal-recovery, qwen-serve-webui-live-journal-recovery) did not run locally; the diff's two changed integration tests are only exercised by that skipped job. Test Plan (not a blocker): src/compactionEngine.test.ts — no such file or directory; test/unit/daemonUi.test.ts — no such file or directory; src/commands/serve.test.ts — no such file or directory; src/serve/fast-path.test.ts — no such file or directory; 92 passed — this review observed 1200, 18740, 1502, 481, 2983, 459 passed; and 2 more.
中文说明
已审查。 建议见行内评论。 1 条建议级发现无法锚定到改动行,已丢弃;此处无需进一步处理。 未审查:build-and-test — Integration Tests (CLI, No Sandbox) was skipped in CI and its suite (qwen-serve-live-journal-recovery, qwen-serve-webui-live-journal-recovery) did not run locally; the diff's two changed integration tests are only exercised by that skipped job。 Test Plan(非阻断):src/compactionEngine.test.ts — no such file or directory; test/unit/daemonUi.test.ts — no such file or directory; src/commands/serve.test.ts — no such file or directory; src/serve/fast-path.test.ts — no such file or directory; 92 passed — this review observed 1200, 18740, 1502, 481, 2983, 459 passed; and 2 more。
— qwen3.8-max via Qwen Code /review (v0.21.8)
|
🤖 Reviewed the latest feedback — no changes needed. Why, point by point: · 已审阅最新反馈——无需改动。逐点说明原因如下: Autofix review round: no action taken No actionable feedback was found for this round:
The PR is in Critical-only mode after five change-producing rounds. The listed deferred non-Critical findings are an audit record kept open for human follow-up; per the mode's rules this round makes no code changes, resolves no threads, and posts no replies for them. No commits were made; the branch remains at its previous verified head. 中文说明Autofix 审查轮次:未采取任何操作 本轮未发现可处理的反馈:
该 PR 在经历五个产生改动的轮次后已进入仅处理 Critical 的模式。列出的已延后非 Critical 发现仅作为审计记录保留,供人工后续跟进;按照该模式的规则,本轮不修改代码、不解决任何讨论串,也不针对这些条目发布回复。 本轮未产生任何提交;分支保持在之前已验证的 head 上。 Deferred non-Critical feedbackCritical-only mode is active after 5 change-producing rounds. The workflow excluded the non-Critical feedback below from this round's actionable sections; the items remain open for human follow-up. Maintainer feedback is deferred only after its author has used 2 regular feedback batches in this window's Critical-only tail; authors at that budget, if any, are named below. (
中文说明完成 5 个产生改动的轮次后进入仅处理 Critical 的模式。本轮可执行区域已排除下方非 Critical 反馈;这些条目保持开放,留待人工跟进。维护者反馈仅在其本人于本窗口 Critical-only 阶段已使用 2 批常规反馈预算后才会延后;达到预算的作者(如有)在下方点名。(评论 Base-conflict check · 基分支冲突检查: no conflict with main. · 与 main 无冲突。 🧠 Handled by Qwen Code · model/模型 |
|
@qwen-code /triage |
|
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: 153 passed · 0 failed · 153 total 中文 — 判定:✅ 通过 · 可合入(agent 判定)沙箱验证在隔离、无凭证的容器中执行了该 PR 的代码(与 base 构建 A/B 对照、无 mock harness 断言、定向门禁)。仅作为评审证据,不构成评审、批准或 CI 检查。 脚本断言:153 通过 · 0 失败 · 153 总计 Verification reportPR 8801 verification (round 3) — fix(acp-bridge): bound live journal replay chunksVerdict: 中文摘要
Previous-finding status (round 2 → round 3)Round 2 reported no blocking findings; three observations. Status at the new head (each re-measured, not diffed):
Round-2's verified central cells were re-run as the C1/C2/C8/C10/C13 rows of the table below (all hold); round-2's boundary matrix ( Central claim + A/BCentral claim: during an unfinished turn, consecutive compatible assistant text/thought chunks share bounded replay entries (≤256 source events each); Three-build design: besides base and head, a delta-revert build was compiled — head source with ONLY the content-keyset clause of
Arm totals: base 31/31, delta-revert 40/40, head 56/56 — every predicted base/revert failure reproduced exactly as encoded (predicted breakage counts as a passing assertion); the C3–C7/C11 flips are the load-bearing proof of the delta hunk. Re-measured interleaved-subagent observation: CorrectionsNone needed this round. One attribution note for readers of earlier rounds: the SDK normalizer change carrying update FindingsNone blocking. Observations for the reviewer, each with its repro:
Mutation matrix (vacuity)Single-point mutants applied by exact string replacement (
4/4 mutants killed, 0 survivors. Attribution is exact: M1 and M2 each red exactly one test (the one the delta commit added); M3 reds exactly the three tests pinning the keyset gate. M1 doubles as the vacuity check for the delta's new test — reverting the source hunk fails the intended behavioral assertion, so the test pins the change and the change is load-bearing. Adjudicated by Targeted gates (all green)
Gate liveness: the mutation matrix above is the proof for the engine and SDK suites — the same vitest harnesses reporting green here went red on planted single-clause changes. The integration no-truncation test is itself an end-to-end A/B witness: at Not covered
MethodologyEnvironment: Evidence imagesHarness scripts and raw logs are in the workflow run artifacts (7-day retention). — Qwen Code · sandboxed verification |
qwen-code-ci-bot
left a comment
There was a problem hiding this comment.
LGTM, looks ready to ship. ✅
|
🤖 Reviewed the latest feedback — no changes needed. Why, point by point: · 已审阅最新反馈——无需改动。逐点说明原因如下: Autofix review round: no action neededThis round found no actionable feedback for PR #8801:
Critical-only mode is active after 5 change-producing rounds. The one non-Critical item listed in the deferred feedback section (a PR comment from the CI bot) is an audit record left open for human follow-up; per the workflow rules it was not addressed in this round. No code changes were made and no commit was created. The branch head remains unchanged. 中文说明Autofix 评审轮次:无需处理本轮未发现针对 PR #8801 的可处理反馈:
在完成 5 个产生改动的轮次后,已进入仅处理 Critical 的模式。延后反馈区域中列出的唯一一条非 Critical 条目(来自 CI 机器人的一条 PR 评论)属于审计记录,保持开放以留待人工跟进;按照工作流规则,本轮不予处理。 未做任何代码改动,也未创建提交。分支 head 保持不变。 Deferred non-Critical feedbackCritical-only mode is active after 5 change-producing rounds. The workflow excluded the non-Critical feedback below from this round's actionable sections; the items remain open for human follow-up. Maintainer feedback is deferred only after its author has used 2 regular feedback batches in this window's Critical-only tail; authors at that budget, if any, are named below. ( 中文说明完成 5 个产生改动的轮次后进入仅处理 Critical 的模式。本轮可执行区域已排除下方非 Critical 反馈;这些条目保持开放,留待人工跟进。维护者反馈仅在其本人于本窗口 Critical-only 阶段已使用 2 批常规反馈预算后才会延后;达到预算的作者(如有)在下方点名。(评论 Base-conflict check · 基分支冲突检查: no conflict with main. · 与 main 无冲突。 🧠 Handled by Qwen Code · model/模型 |
doudouOUC
left a comment
There was a problem hiding this comment.
APPROVE (C=0) at 6c2dad8e0b96bcbade164b18fe174af390841467.
Reviewed the complete 15-file diff and traced the per-session live-journal change through EventBus snapshot construction, ACP/REST replay delivery, SDK normalization and transcript reduction, WebUI recovery, CLI configuration, and protocol documentation. The previous ACP TextContent metadata Critical is fixed: rich annotations and content _meta remain raw and survive load replay unchanged.
Independent verification passed: compactionEngine.test.ts 104/104, both live-journal daemon integration files 3/3, build, and bundle. Current reported checks have no failures.
One non-blocking Suggestion remains inline: a hypothetical chunk carrying both qwenDiscreteMessage and parentToolCallId can reorder a later same-parent chunk during completed-turn compaction. No in-repo producer emits that metadata combination, so it does not block this PR and can be handled as a focused follow-up.
|
Released in v0.21.9. |












What this PR does
This PR compacts consecutive compatible assistant text and thought chunks in the bounded replay snapshot for an unfinished turn. Each replay entry represents at most 256 source events, while tool, attribution, provenance, discrete-message, and semantic metadata boundaries remain intact. Real-time EventBus/SSE delivery remains unchanged and still emits every source chunk.
The live journal event cap now applies to bounded replay entries. Byte accounting and truncation diagnostics continue to use the serialized source events, so the configured memory protection and source-event counts retain their existing meaning. CLI help, SDK types, status text, and protocol documentation are updated to describe those units explicitly.
Why it's needed
Long-running Web Shell sessions can receive hundreds of thousands of very small thought or message chunks during one unfinished turn. The previous live journal retained each chunk as a separate replay event, reached the 10,000-event limit quickly, and displayed a live-turn history truncation warning even though the retained text itself was relatively small. Compacting only the replay snapshot keeps the unfinished turn recoverable without changing real-time streaming or completed-turn compaction.
Reviewer Test Plan
How to verify
Start
qwen servewith a small--max-journal-eventsvalue and use an ACP fixture that emits at least 20 consecutive compatible assistant chunks before completing the turn. While the turn is still active, load the session and confirm that the live journal contains the complete concatenated text without ahistory_truncatedmarker, and that the merged replay event uses the latest source event ID. Confirm that real-time SSE still exposes each original chunk. After the turn completes, load the session again and confirm that the normal completed replay still contains the full text.Also verify that tool boundaries, different prompt/client/session attribution, transcript source record IDs, parent tool call IDs, generic discrete message/thought updates, update metadata, and non-timestamp envelope metadata prevent live-journal aggregation. A stream large enough to cross the byte cap should start a new bounded segment and report discarded/retained source-event counts correctly.
Automated verification completed locally:
packages/acp-bridge:npx vitest run src/compactionEngine.test.ts— 92 passedpackages/sdk-typescript:npx vitest run test/unit/daemonUi.test.ts— 284 passedpackages/cli:npx vitest run src/commands/serve.test.ts src/serve/fast-path.test.ts— 132 passednpm run buildnpm run typechecknpm run bundlegit diff --checkEvidence (Before & After)
Before: a live turn with a high-volume fine-grained stream reached the 10,000 raw-event journal cap and displayed a truncation warning despite the turn still running.
After: compatible source chunks share bounded replay entries, so the same live stream remains complete in the load snapshot without changing real-time chunk delivery. Completed-turn replay remains unchanged.
Tested on
Environment (optional)
macOS, Node.js 22-compatible repository toolchain, sandbox disabled for local daemon E2E verification.
Risk & Scope
Linked Issues
N/A
中文说明
本 PR 做了什么
本 PR 对未完成 turn 的有界回放快照中连续且兼容的 assistant 文本和思考 chunk 进行聚合。每个回放 entry 最多代表 256 个源事件,同时保留工具、归属、来源、离散消息以及语义 metadata 边界。实时 EventBus/SSE 投递保持不变,仍然逐个发送所有源 chunk。
live journal 的事件上限现在作用于有界回放 entry。字节记账与截断诊断仍按序列化后的源事件计算,因此配置的内存保护和源事件计数保持原有含义。CLI 帮助、SDK 类型、状态文案和协议文档也同步明确了这些单位。
为什么需要
长时间运行的 Web Shell 会话可能在一个未完成 turn 中收到数十万个非常细粒度的 thought 或 message chunk。此前 live journal 会将每个 chunk 作为独立回放事件保留,很快达到 10,000 事件上限,并在 turn 仍运行时显示历史截断警告,即使实际文本量并不大。仅压缩回放快照可以保持未完成 turn 可恢复,同时不改变实时流式输出或完成 turn 的压缩逻辑。
Reviewer Test Plan
How to verify
使用较小的
--max-journal-events启动qwen serve,并让 ACP fixture 在完成 turn 前连续发送至少 20 个兼容的 assistant chunk。在 turn 仍活跃时加载会话,确认 live journal 包含完整拼接文本、没有history_truncatedmarker,且合并回放事件使用最新源事件 ID。确认实时 SSE 仍暴露每一个原始 chunk。turn 完成后再次加载会话,确认正常的 completed replay 仍包含完整文本。还应验证工具边界、不同 prompt/client/session 归属、transcript source record IDs、parent tool call IDs、通用离散 message/thought update、update metadata 和非时间戳 envelope metadata 都会阻止 live-journal 聚合。足以跨越字节上限的流应开启新的有界 segment,并正确报告丢弃和保留的源事件数量。
本地已完成以下自动验证:
packages/acp-bridge:npx vitest run src/compactionEngine.test.ts— 92 passedpackages/sdk-typescript:npx vitest run test/unit/daemonUi.test.ts— 284 passedpackages/cli:npx vitest run src/commands/serve.test.ts src/serve/fast-path.test.ts— 132 passednpm run buildnpm run typechecknpm run bundlegit diff --checkEvidence (Before & After)
Before:高频细粒度流的 live turn 会达到 10,000 个原始事件的 journal 上限,并在会话仍运行时显示截断警告。
After:兼容源 chunk 共享有界回放 entry,因此相同 live stream 可在 load snapshot 中保持完整,同时不改变实时 chunk 投递。completed-turn replay 保持不变。
Tested on
Environment (optional)
macOS,兼容 Node.js 22 的仓库工具链,本地 daemon E2E 验证关闭 sandbox。
Risk & Scope
Linked Issues
N/A