Repository navigation
Conversation
In-range lock refresh closing all 4 open Dependabot alerts (4 high): - undici 7.29.1 -> 7.30.1 via wrangler 4.150.0 -> 4.156.1 -> miniflare 5.20261006.2-beta -> 5.20261101.0-beta in root, web/, and telemetry-ingest/: closes GHSA-xjj6-f33q-929c / CVE-2026-109869 (alerts Pinvou#139, Pinvou#142, Pinvou#145; fetch DoS via unhandled error on excessive content-encodings). This closes the follow-up PR Pinvou#120 left open: wrangler 4.156.1 (latest stable) exact-pins miniflare 5.20261101.0-beta (2026-11-01), which exact-pins undici 7.30.1, so a plain `npm update wrangler` per directory lands there. Collateral, all npm-canonical: workerd 1.20261006.1 -> 1.20261101.1 (+ its five platform binaries), tslib 2.8.1 -> 2.9.1 in root and telemetry-ingest, `libc` metadata added to the existing @img/sharp-* entries in root and telemetry-ingest, wrangler's @cloudflare/workers-types peer range following to ^5.20261101.1, web's nested miniflare ws 8.21.0 hoisting to the top level (content-identical), and the nested miniflare/node_modules/undici copies in web/ and telemetry-ingest/ moving to a single top-level 7.30.1 entry (root's undici was already top-level). No other package versions change. - @azure/msal-node 6.0.1 -> 7.1.2 in extensions/vscode/: closes GHSA-xcx6-jx8p-x3h5 / CVE-2026-109461 (alert Pinvou#136; auth-code flow origin validation; first patched 7.1.0) via the native in-range path: @azure/identity 4.14.1 (2026-10-29) requires @azure/msal-node ^7.1.0 and satisfies @vscode/vsce's declared ^4.13.2, so `npm update @azure/identity` moves identity 4.14.0 -> 4.14.1 and msal-node -> 7.1.2 with no manifest change. msal-common follows upstream's native shape (top-level 16.14.2 for msal-browser 5.25.1, nested 16.15.0 under msal-node; both exact pins). msal-node 7.x keeps the confidential-client surface identity uses (jsonwebtoken ^9, node >= 20); the path is dev-only (vsce). Verified: - npm ci green in root, web/, telemetry-ingest/, extensions/vscode/ - telemetry-ingest: npm run typecheck, npm run check (wrangler 4.156.1 deploy --dry-run), npm test (171 passed) - web: npx wrangler --version -> 4.156.1, npm run cf-typegen, npm test (408 passed in 47 files) - extensions/vscode: npm run check (tsc), vsce package --no-dependencies (valid 13-file vsix), and an identity -> msal-node 7 live smoke: ClientSecretCredential.getToken() builds and parses a real AAD protocol response through msal-node 7.1.2 - npm audit: root and telemetry-ingest report 0 vulnerabilities; web reports 20 moderate advisories (glob via @opennextjs/cloudflare 1.20.9, minimatch via the eslint toolchain) ingested after this branch's initial verification; all devDependencies, none open GitHub alerts, left for a separate decision. No HIGH findings remain in any of the four refreshed manifests: the base audits carried 1 HIGH for undici in root, web/, and telemetry-ingest/, and 2 HIGH for msal-node in extensions/vscode (the advisory this bump closes) Out of scope, unchanged: npm audit reports follow-redirects (high) in integrations/{feishu,wecom}-bridge and qs + minimatch (moderate) in extensions/vscode; none of these are open GitHub Dependabot alerts, so they are left for a separate decision. Signed-off-by: asto <asto18089@126.com>
将模型与本地运行时错误的来源随最终选中错误一起传递,保留重试清空、本地覆盖与取消语义。 内部 TurnComplete 增加来源字段,同步仓内构造和消费方,现有线协议保持不变。 Signed-off-by: zhuowp <zwp-1989@qq.com>
a4fc2e9 to
e8d00aa
Compare
asto18089
left a comment
There was a problem hiding this comment.
从零复审:REQUEST_CHANGES — 唯一阻断 = 测试目标 E0063 编译断(实跑亲证)
本轮从零复审:9 个分片并行(失败出口清单 / turn_error 生命周期等价 / TurnComplete 全仓构造点 / 线协议泄漏 / 消费方适配 / 夹带审计 / 主线耦合间隙 / 覆盖与变异设计 / 宿主耦合核对)+ 本地门禁实跑 + 变异负控与正控。codewhale-hq#2383 评审发现的同类阻断在本 PR 上独立复现,文件清单逐位吻合。
已完成的 rebase(已推送)
已 rebase 到最新主线 11cba403dc 并推送(443 直推失败,改走 GitData API:树 d70da5f50663... 与本地 rebase 结果程序化断言全等;作者/提交信息/Signed-off-by 原样保留;新 head e8d00aa0b0)。冲突仅一处:turn_loop.rs 顶部 main #124 的 fresh_fallback_tool_id 与本 PR 的 TurnFailure 同位相邻,双方语义完整保全。rebase 保真双重验证:range-diff 仅 2 处冲突区上下文差异;排序后增删行多重集与原提交字节级一致(134/134 行)。
P0 阻断:cargo test 目标编译断 E0063(原 head ×20,rebase 后 ×22)
- 原提交
a4fc2e91(树db5b9d4b13)测试侧Event::TurnComplete构造漏补error_source共 20 处:runtime_api/tests.rs7 +runtime_threads/tests.rs13 —— 与 codewhale-hq#2383 评审公布清单逐位吻合。 - rebase 后主线 #131 在
runtime_threads/tests.rs新增 2 处构造,合计 22 处(15+7,rustc 实跑输出确认)。cargo check --workspace --all-targetsrc=101,cargo test -p codewhale-tui无法编译。 - CW CI 无 cargo-test 门禁(原 head 仅 CodeQL/intake/analyze/credentials 绿),正文"配套底座树已通过 v3 完整审核"未覆盖测试目标编译层;正文虽披露"不是单独运行全部 CodeWhale 测试",但实际后果是测试目标从未编译。
- 修复处方已实跑验证:22 处机械插入
error_source: None,(status:行后,与本 PR 自身 36 处插入同型)后:cargo check --workspace --all-targets绿、cargo fmt --check --all绿、clippy 与 main 基线完全一致(8 项too_many_arguments/collapsible_if均为本 PR 未触碰函数、11cba403dc 基线同款,属本地工具链与 CI 的 lint 漂移)。请作者补齐该 22 处并按正文惯例重锚固定提交/树声明。
核心语义评审:全部通过
- 分类正确:
run_turn全部 Failed 出口(预算/max-steps/上下文恢复耗尽/请求派发/终止 stop-reason/benchmark/REPL init+refresh/空流尾返回)逐一核对 Model/Runtime 无误;request_error_source每次派发尝试按prepare_stream_call(本地载荷构建,无网络)结果重算,prepare 失败=Runtime、provider 传输=Model,与契约一致;未知不猜测(Interrupted/合成失败/panic 恢复均 None)。 - 行为等价:
turn_error旧 24 处 token 1:1 映射;重试清空(stream-retry/reasoning-only)消息+来源一并丢弃;首错 wins(or→or_else等价);取消优先于尾错误消费;TurnContext每回合新建(唯一生产构造点 engine.rs:5964),terminal_error_source仅finish()写入且finish()必然立即返回——stale 泄漏结构性不可能;两处expect可证不可达。 - 线协议零泄漏:
crates/protocol/全目录零error_source;protocol_parity穷举解构显式丢弃(亦是未来字段守卫);SSE/REST/remote bridge/journal/telemetry/hooks 全不携带;Event无 serde。 - 无夹带:68 hunks 全分类为字段适配/分类逻辑/文档;零行为漂移、零格式噪音;无 Cargo.lock/CI/文档改动。
- 主线耦合无洞:#123/#124/#129/#131/#133-135 在爆炸半径内无新增未分类失败路径(唯 #131 的 2 处测试构造,已计入上述阻断)。
P2(不阻断)
- 新行为零仓内断言覆盖:全仓无任何测试绑定
error_source值(grep 证实仅生产代码 4 处触点)。变异实跑:M1(Model→Runtime 翻转)3 个失败回合测试全绿存活、M2(Runtime→Model 翻转)2 个测试全绿存活、M5(engine.rs:6494 传播改 None)2 个测试全绿存活——分类值可静默翻转而全绿;纯字段删除(M4 形态)会被编译器 dead_code 拦截,但传播截断(M5)不会。正控实证:在既有测试injected_chat_content_filter_never_becomes_a_completed_answer(engine/tests.rs ~9263)解构处加error_source绑定 +assert_eq!(Some(TurnErrorSource::Model))后,M1 立即转红。处方:该测试与max_steps_exhaustion_fails_as_budget_never_completed(~8908)各加 2-4 行断言(Model/Runtime 各一钉)。 - "线协议不变"缺负向钉:若未来 wire
TurnComplete误加error_source,现无测试可拦;建议在protocol_covers_engine_events补assert!(terminal.get("error_source").is_none())。
P3 / 备注
- "远控桥接适配"实为纯测试构造:生产桥
observe_engine_event上传turn.completed{status,usage},不透传 error/error_source;远端宿主目前只能经 in-process 事件消费本字段(与 codewhale-hq#2383 实际消费方式一致,不构成缺陷)。 - engine 级合成失败点(5119/6139/6656/6692/6884 等)按字段文档刻意保留 None;宿主若要区分预检类失败需逐点补分类。
exec_agent.rs:975-982仍以文本启发式归类终态错误(如 REPL 失败文本含 connection → 误判 Network → retryable exit);本 PR 已提供权威来源,建议另行小 PR 接线。- 风格 nit:
turn_loop.rs六处全限定crate::core::events::TurnErrorSource可提为 import。
与 codewhale-hq#2383 的耦合(核对无误)
codewhale-hq#2383 经 in-process Event::TurnComplete.error_source 消费(forwarder.rs 比对 TurnErrorSource::Model),字段名/类型/语义与本 PR 完全一致;其 gitlink 现钉原 head a4fc2e91(即 E0063×20 之树,且落后主线 7 提交)。修复路径:本 PR 补齐 22 处 → 作者更新正文锚定 → codewhale-hq#2383 重钉新 gitlink 并同步登记/指纹/EXPECTED_HEAD,其 RC 唯一阻断即解除。
本地验证环境说明(诚实披露)
- 最终全量证据:
cargo test -p codewhale-tui(串行--test-threads=1,RUST_MIN_STACK=16MB)= 12,656 passed / 0 failed(lib 12,407 + 集成 13 + 236,13+8 ignored),含本 PR 全部 touched 区域与 22 处补字段的 runtime_* 测试。 - 环境坑(均与本 PR 无关,已在干净树/单独运行复核):默认栈下
runtime_api两个测试栈溢出 SIGABRT(RUST_MIN_STACK=16MB即消,属 debug 深帧环境问题);多线程并行套件在 ~2550 处于共享 engine 状态交互整组停滞(cwd 级.codewhale/state/subagents.v1.lock,单独运行 0.15s 即绿),PR diff 零锁/状态代码且 patch 字节级等价,判定上游既有。
结论
方向正确、实现干净、根因到位、无夹带、线协议守住;唯一阻断是测试目标 22 处机械补字段(处方已验证)。请作者补齐并重锚正文后,本 PR 可转入可合并状态,并解锁 codewhale-hq#2383。
No-Issue: Issues are disabled in this repository.
Signed-off-by: zhuowp <zwp-1989@qq.com>
asto18089
left a comment
There was a problem hiding this comment.
全新复审(2026-11-08,fresh 8 分片 + 3 突变实跑)
头 c8e05f61e 恰平 pinvou3-clean tip 11cba403dc(merge-base = base tip,零 rebase)。按四条标准独立复审:claim 完备性/根因、工程优雅、夹带、feature+performance 缺陷。
结论:可合并(APPROVE),以下均为非阻塞 MINOR/NIT
1. Claim 真实且完备,根因到位。 审计了 run_turn 全部失败路径(10 个终态 + 8 个 stream_error 生产点):TurnOutcomeStatus::Failed 在 turn_loop.rs 中只剩 TurnFailure::finish 一处字面量,即每个 Failed 终态必然携带 source,无分类洞。根因处理正确:普通路由本地准备失败之所以此前会被误判为 provider 错误,是因为字符串分类无从分辨——deferred preparation + DeferredStreamPreparationError 哨兵 downcast 是让 engine 知晓真实来源的最小机制(新测试 ordinary_route_preparation_failure_is_runtime_without_sending_http 实证了零 HTTP 请求 + Runtime)。首错选择、重试清除(2788/3510 处 turn_error = None)、取消路径均确认未变;error_source 无任何 serde 泄漏面(Event 不派生 Serialize,wire 侧 error_source: _ 且有 parity 测试钉死)。
2. 不属重复造轮。 error_taxonomy 分类的是展示内容(severity/可恢复性),TurnErrorSource 是选中终态错误的生产者溯源,二者关注点不同且后者刻意不上 wire;首错胜出机制要求 source 随 message 一起穿越重试,事后查表不可行。TurnFailure 让 10 个返回点删掉手工元组,过 rung-2。~60 处测试构造更新是本仓既有惯例(当年 base_url 字段同样方式落地,commit cef1632)。
3. 零夹带。 12 个文件全部在 crates/tui 内;无 protocol/persistence/CHANGELOG/CI/Cargo.lock 改动。commit 2 除 22 处测试构造(数目与正文一致)外含 3 处生产改动(client.rs 重构、哨兵类型、split_stream_open_error),但其 commit message("区分本地请求错误")已声明且都在 claim 内,client.rs 重构经逐步比对确认行为保持(同序 permit → 同一 prepare_outbound_request(request, true) → 同一 finish_prepared_stream,零双重准备)。commit 1 的 committer 是评审代 rebase 身份,作者与 DCO trailer 保留。
4. 无缺陷。 fmt 干净;clippy 8 个 deny 全部为既有问题(逐条比对不在本 PR hunk 内);engine 模块实测 test result: ok. 714 passed; 0 failed; 4 ignored,6 个定向 filter 全绿;3/3 突变全红(去哨兵 → ordinary-route 测试红;content-cap runtime→model → 红;max-steps runtime→model → 红);happy path 零新增开销(准备次数、permit 顺序、clone 数与 base 一致,TurnErrorSource 为 Copy)。
非阻塞发现
- [MINOR·测试强度] Model 侧分类基本未钉。 突变实跑:把 stream-open 错误默认翻成 Runtime,全仓没有任何测试变红——
TurnErrorSource::Model断言只覆盖了 in-stream content-filter 一条路径。中心 claim(传输类失败 = Model)只有 Runtime 半边有回归保护。建议补一个小测试:dead endpoint 打开流失败,断言error_source == Model。同理 "Context remains above model limit" 恢复耗尽的 Runtime 分类也无测试钉(M4 突变无消费方)。 - [MINOR] 三处可零成本带
Some(Runtime)却传了 None:reject_unstarted_submission(engine.rs:5119)、no-model-client 拒绝(engine.rs:6139,"API client not configured" 明显是本地)、panic catch 路径(engine.rs:~6422,catch_unwind 伪造成 Failed)。按字段契约 None 合法,但与本 PR 自己建立的本地区分精神不一致。另:route-mismatch 等内部不变量错误会落到 Model 默认(实践中不可达,仅记录)。 - [NIT] turn_loop.rs:2127/2479 的
turn_error = Some(..); return turn_error.expect("failure was assigned").finish(turn)可直接 return(该变量此后无人读),2127/3534 各有一处可避免的 clone;DeferredStreamPreparationError的哨兵契约只写在 DeepSeekClient 侧,trait default 文档未提示未来 impl 需包本地准备错误才能获得 Runtime 分类。
证据声明
以上测试/突变数字均为本机 /tmp/cw-pr142-review(CARGO_TARGET_DIR 共享缓存)实际运行输出,非转述。Windows 全量跑停在与本 PR 无关的 /tmp/codewhale-primary 路径校验用例与正文说明一致(该测试与校验代码在本 PR diff 外)。
No-Issue: Issues are disabled in this repository. This is the foundation dependency of Pinvou/pinvou3#2383.
做什么
给内部
TurnComplete保留实际错误来源。模型传输、模型响应和 provider 等待超时归为Model,本地请求准备、执行及流式时长和内容上限归为Runtime。普通路由在获得准入后准备请求,也保留本地错误来源。重试、取消、首错选择和公开线协议沿用原有行为。固定版本和验证
c8e05f61ef6b58640695e65fe7b217abd47fdf69,树efcc3fff03b5c61a36f0acb910df917cfaf29781,目标基线11cba403dc6bd6ca5c4dca55042785b03449ac8e。在评审者已解决冲突的e8d00aa0b上补齐了测试目标的 22 处构造。codewhale-app-server后停止,105 项通过,1 项失败。失败用例使用/tmp/codewhale-primary,路径校验器在 Windows 拒绝该路径。测试和校验代码与目标基线相同。Linux CI 正在验证最终提交。宿主依赖
Pinvou/pinvou3#2383 仍固定在早期 CodeWhale 提交。之前的 121 项宿主定向测试对应旧组合。底座合入
pinvou3-clean后,宿主需要对齐真实公开 gitlink、更新登记和指纹,并运行最终组合的门禁。