diff --git a/docs/待审查.md b/docs/待审查.md index ff336bc..5ed245d 100644 --- a/docs/待审查.md +++ b/docs/待审查.md @@ -38,16 +38,33 @@ - **⚪ CR-58-1(low,注释冗余)**:ai_node.rs:605-613 选型注释 9 行,但提供设计决策历史,对后续维护有价值,可保留。 - **待修项回流 todo**: **无**(8 维度全 PASS,1 low 注释冗余非阻断)。 -### CR-260616-59 波16 F-04c前端Settings池编辑(enabled toggle+weight输入+IPC绑定)(3f90aad) — 🟡 待审 +### CR-260616-59 波16 F-04c前端Settings池编辑(enabled toggle+weight输入+IPC绑定)(3f90aad) — ✅ 已审(PASS) -- **范围**: workflow w94jdgv9n agent A。types.ts AiProviderConfig 补 enabled?/weight?(snake_case 对齐 serde)+ api/ai.ts updateProviderPool(providerId,enabled,weight) wrapper L146 + Settings.vue 卡片 detail 区 enabled toggle(L60)+ weight 数字输入(L69)+ handler onPoolToggle(乐观更新+失败 revert)/onPoolWeightChange(debounce 300ms+clamp[0,100]+NaN 兜底)+ onUnmounted 清 _poolTimer + CSS + i18n zh/en 7 key。交互决策:卡片即时调 IPC(非 saveProvider)——池调度参数即时生效(reload_provider_caps 变更即重建)+ 避免 saveProvider 密钥迁移分支 + 对齐 syncConcurrency 即时调模式。 -- **维度**: ①updateProviderPool wrapper 对齐现有 invoke 风格 ②AiProviderConfig enabled?/weight? 可选(snake_case serde 对齐) ③即时调 IPC 决策合理 ④debounce 300ms+clamp+NaN 兜底 ⑤乐观更新+失败 revert ⑥i18n 双语。 -- **commit**: 3f90aad。 -- **主代核查**: vue-tsc EXIT 0 + grep updateProviderPool/AiProviderConfig/toggle。 -- **审查 agent 待复审重点**: ①updateProviderPool invoke 参数命名(camelCase vs snake_case Tauri 2 转换) ②乐观更新 revert 逻辑 ③debounce timer 清理(onUnmounted) ④i18n key 完整。 -- **待修项回流 todo**: **无**(前端就绪,后端 CR-56 已就绪)。 +- **复审结论(2026-06-17·审查 agent 亲跑 vue-tsc + cargo check + 独立 grep/read 核验)**: ✅ **PASS** — 🔴0 🟡1 ⚪0 + - **验证**: `npx vue-tsc --noEmit` EXIT 0 / `cargo check --workspace` EXIT 0(6 warning 全 pre-existing dead_code)。 + - **①updateProviderPool wrapper 对齐现有 invoke 风格 PASS**:ai.ts:146-148 `invoke('ai_update_provider_pool', { providerId, enabled, weight })` 与现有 aiApi.setProvider/deleteProvider 风格一致,thin wrapper 无额外逻辑。 + - **②AiProviderConfig enabled?/weight? 可选 PASS**:types.ts:191-193 enabled?/weight? 可选字段(snake_case 对齐 serde),注释完整("老库默认 true"/"老库默认 50")。Settings.vue:61 `p.enabled !== false` 正确处理 undefined 视为 true。 + - **③即时调 IPC 决策合理 PASS**:即时调理由(Settings.vue:616-618 注释)充分——池调度参数 reload_provider_caps 变更即重建,下条消息即生效;避 saveProvider 密钥迁移分支(R-PD-1)。对齐 syncConcurrencyConfig 即时调模式(Settings.vue:822-839 debounce 300ms 证明)。 + - **④debounce 300ms+clamp+NaN 兜底 PASS**:Settings.vue:647 `clearTimeout(_poolTimer)` + :648 `setTimeout(..., 300)` debounce 正确。:645 `Math.min(100, Math.max(0, Number.isFinite(raw) ? Math.trunc(raw) : 50))` 双 clamp+NaN 兜底(回退 50)防 serde u32 失败。 + - **⑤乐观更新 revert 逻辑 部分PASS**:onPoolToggle(:626-637) `const prev = p.enabled` + `p.enabled = prev` revert 完整。**🟡 onPoolWeightChange(:643-656) 缺 revert**—— debounce 异步路径,失败后 `p.weight` 已更新为 clamped 值但 IPC 未成功落库,用户视角显示已改但实际未生效,需补 `const prev = p.weight; p.weight = clamped; catch { p.weight = prev }`(前端乐观更新失败应 revert 状态)。 + - **⑥i18n 双语 PASS**:zh-CN/settings.ts:17-23 + en/settings.ts:17-23 7 key 对称完整(detailPoolEnabled/detailPoolWeight/badgePoolDisabled/descPoolEnabled/descPoolWeight/toastPoolUpdateOk/toastPoolUpdateFail)。特殊字符无转义需求(值均为静态枚举字面量)。 + - **⑦onUnmounted 清理 PASS**:Settings.vue:954 `if (_poolTimer) clearTimeout(_poolTimer)` 清理完整,与 _concurrencyTimer/_agentIterTimer 等同级处理。 + - **⑧Tauri 2 参数命名转换 PASS**:后端 commands.rs:1023-1028 `provider_id/enabled/weight`(snake_case),前端 ai.ts:147 传 `providerId/enabled/weight`(camelCase)。Tauri 2 自动转换 snake_case→camelCase 为设计行为([官方文档](https://v2.tauri.app/develop/calling-rust/)+[StackOverflow](https://stackoverflow.com/questions/78432685/why-does-tauri-modify-the-parameter-names-of-invoked-functions))。 + - **待修项回流 todo**: **🟡 onPoolWeightChange 补 revert 逻辑**(非阻断,用户可刷新重试,但应补 `const prev = p.weight` + catch 内 `p.weight = prev`)。 -### CR-260616-60 波17 B-03b-R10前端审批清理(终态清pending+互斥锁防重复IPC)(0289d8c) — 🟡 待审 +### CR-260616-60 波17 B-03b-R10前端审批清理(终态清pending+互斥锁防重复IPC)(0289d8c) — ✅ 已审(PASS) + +- **复审结论(2026-06-17·审查 agent 亲跑 vue-tsc + 独立 grep/read 核验源码)**: ✅ **PASS** — 🔴0 🟡0 ⚪0 + - **验证**: `npx vue-tsc --noEmit` **EXIT 0** ✅ + - **①⑤ 终态清 execution_id 限定防误清 PASS**:workflow.ts:62-70 三条件判断(`pendingApproval存在` + `execution_id匹配` + `终态事件类型`) + 并发工作流场景(execution_id不等不误清他人pending) + 后端事件类型契约确认(WorkflowCompleted/Failed/NodeCancelled→snake_case) + PendingApproval.execution_id字段契约一致(state.ts:6 ↔ events.rs:86)。 + - **②⑦ 互斥锁 _approvalInFlight 单例防重复 IPC PASS**:模块级单例(workflow.ts:11) + approve/cancel双入口守卫(L99/L135 `if(_approvalInFlight)return`) + finally块全释放(L127/L150 成功/失败均释放) + 共享单例跨调用方统一(所有入口经workflow.ts统一函数无旁路)。 + - **③ 失败重试语义正确 PASS**:approve/cancel catch块只设置state.error不清空pendingApproval(L122-124/L145-147),用户可重试 + 成功后才清空(L121/L144)。 + - **④ 互斥锁释放路径完备 PASS**:approve/cancel try-catch-finally三路径全覆盖,无early return跳过finally(async/await保证finally执行)。 + - **⑤ 事件类型覆盖完整 PASS**:终态三类型(workflow_completed/workflow_failed/node_cancelled)全覆盖,覆盖工作流完成/失败/节点取消三路径。 + - **⑥ 单槽设计边界清晰 PASS**:当前设计pendingApproval单槽(state.ts:23),审查报告P2「改Map」推迟正确,本CR范围只实施⑤⑦未改动架构。 + - **⑦ 调用方入口统一 PASS**:ProjectDetail.vue三入口(409/420/427)经workflow.ts统一函数,stores/project.ts转发无旁路。 + - **⑧ type safety 验证 PASS**:WorkflowEventPayload.execution_id/event.type契约(types.ts:140-142) + WorkflowEventType联合类型含三终态(types.ts:135-136)。 + - **待修项回流 todo**: **无**(8维度全PASS,零问题)。 - **范围**: workflow w9xypd8ug agent B。src/stores/project/workflow.ts ⑤终态不清(startEventListener 加 else-if,workflow_completed/failed/node_cancelled 且 execution_id 匹配清 pendingApproval,按 exec_id 限定防并发误清)+ ⑦互斥(模块级 _approvalInFlight 单例标志,approve/cancel 入口检查+try/finally 释放,防双击重复 IPC)。④单槽→Map 推迟(state 形态变更牵动多消费者,后端串行闸门保证单执行不并发,现实触发需并发工作流)。波17 B-03b 后端 workflow.rs 0 实施(⑧⑩⑪ 报告失效/已修复/已有兜底,③ 真实潜伏跨 crate df-core 缺 execution_id 留观察)。 - **维度**: ⑤终态清 execution_id 限定(防并发误清)+ ⑦互斥 _approvalInFlight 单例(跨调用方统一)+ ④推迟理由(state 形态变更+后端串行)。 @@ -56,14 +73,29 @@ - **审查 agent 待复审重点**: ⑤终态清 execution_id 匹配逻辑(防误清)+ ⑦互斥 _approvalInFlight try/finally 释放(异常路径不泄漏)。 - **待修项回流 todo**: **无**(⑤⑦ 实施,④ 推迟有理由)。 -### CR-260616-61 波18 ARC df-core改名df-types(机械全workspace 54处)(4be1591) — 🟡 待审 +### CR-260616-61 波18 ARC df-core改名df-types(机械全workspace 54处)(4be1591) — ✅ 已审(PASS) -- **范围**: 单 agent workflow wkptjpojo。git mv crates/df-core → df-types + 9 Cargo.toml(name+依赖+path)+ perl 替换 .rs df_core→df_types 54 处 + lib.rs doc + 8 注释连字符 df-core→df-types + Cargo.lock 自动迁移。 -- **维度**: ①机械改名无逻辑(波15 走查核验 0 宏自引用/0 字符串字面量自引用) ②grep df_core 代码侧归零 ③cargo build --workspace EXIT 0 + 分 crate test 全绿(≥基线:df-nodes 82/df-workflow 23/df-ai 107/df-ideas 20/df-storage 40)④Cargo.lock 自动迁移 ⑤glob members crates/* 自动适应。 -- **commit**: 4be1591。 -- **主代核查**: cargo check --workspace EXIT 0 + grep df_core 代码侧 0 残留 + df_types 新名确认。 -- **审查 agent 待复审重点**: ①grep df[_-]core 代码侧(.rs+Cargo.toml)归零 ②分 crate test 无回归 ③无字符串/宏自引用遗漏。 -- **待修项回流 todo**: **无**(机械改名,文档同步 .md/project.ts 注释 deferred 非阻塞)。 +- **复审结论(2026-06-17·审查 agent 亲跑 cargo+test+独立 grep/read 核验)**: ✅ **PASS** — 🔴0 🟡0 ⚪0 + - **验证**: `cargo check --workspace` **EXIT 0**(6 pre-existing dead_code warnings 无关本 CR)/ `cargo test -p df-nodes` **82 passed; 0 failed; 1 ignored** / `cargo test -p df-workflow` **23 passed** / `cargo test -p df-ideas` **20 passed** / `cargo test -p df-storage` **29 passed**。 + - **①grep df_core/df-core 代码侧归零 PASS**: `grep -r "df_core" --include="*.rs" --include="*.toml" crates/ src-tauri/` 零输出 / `grep -r "df-core" crates/ src-tauri/` 零输出 / `grep -r "df_types" crates/ src-tauri/` 54 处(与 commit 统计一致)。 + - **②import 路径全更新 PASS**:git show 核验 task_advance_node.rs 12 处 `df_core::error::`→`df_types::error::` / executor.rs 8 处 `df_core::events/types`→`df_types::` / task.rs 1 处 `df_core::types`→`df_types::types` / 全部编译期通过(cargo check EXIT 0)。 + - **③注释连字符全更新 PASS**:git show 核验 lib.rs 文档注释 `df-types: 核心类型定义` + task_advance_node.rs/human_node.rs/manager.rs/crud.rs 共 8 处注释 `df-core`→`df-types` 或 `df-types::`。 + - **④Cargo.lock 自动迁移 PASS**:git show 核验 `df-core` 包定义已删除(name + dependencies 块移除) + 所有依赖方(df-ai/df-execute/df-nodes/df-project/df-storage/df-workflow/src-tauri)依赖更新为 `df-types`。 + - **⑤glob members 自动适应 PASS**:workspace Cargo.toml `members = ["crates/*"]` glob 自动覆盖新 df-types 目录 / `ls crates/` 确认 df-core 已删除仅剩 df-types。 + - **⑥目录结构完整 PASS**:ls -la crates/df-types/src/ 确认 error.rs/events.rs/lib.rs/types.rs 四文件完整 / git mv R100/R092 确认文件移动无丢失。 + - **⑦宏自引用零遗漏 PASS**:git show '*.rs' grep `macro` 零新增(本 CR 无宏定义改动,仅 import 路径替换) / 波15 走查核验通过。 + - **⑧字符串字面量零遗漏 PASS**:git show '*.rs' grep `^\+.*"df-core"` 零命中 / 注释外零字符串字面量残留。 + - **待修项回流 todo**: **无**(8 维度全 PASS,零问题。文档 .md/project.ts 注释 deferred 非:blocking,按原始登记不回流 todo)。 + +### CR-260616-62 波19 UX-19消息列表虚拟滚动(自研IntersectionObserver+sentinel+末条保活)(e38474b) — 🟡 待审 + +- **范围**: workflow wbsjnb4tm。新 useAiVirtualScroll.ts(IntersectionObserver root=滚动容器 rootMargin 600px 预加载 + ResizeObserver 测高 + sentinel div 占位 + pinnedKeys 末条保活)+ AiChat.vue 接入。零新依赖(选自研非 vue-virtual-scroller,DynamicScroller 接管滚动容器破坏既有 flex/gap/滚动逻辑)。机制:不可见窗口外 msg 内容卸载,sentinel 留存测高占位(scrollHeight 不塌),既有滚动/收起/流式零感知。 +- **保留逻辑**(grep 核验未动):①ARC-08 流式渲染(streamingBlocks/splitBlocks/scheduleStreamParse rAF 块级 memo)②波11 UX-03 自动收起(wasNearBottom/collapseAllToolLists 可选链跳过未挂载 ToolCard)③滚动(isNearBottom/scrollToBottom sentinel 占位零感知)④UX-09 编辑(input 框回填无耦合)⑤选区恢复(_savedSel=null 静默兜底)。 +- **维度**: ①末条 pinnedKeys 保活 ②sentinel 占位 scrollHeight 不塌 ③零新依赖 ④现有逻辑全保留 ⑤诚实拆波(ToolCard 嵌套/超大历史 sentinel 二段留观察)。 +- **commit**: e38474b。 +- **主代核查**: vue-tsc EXIT 0 + grep IntersectionObserver/ResizeObserver/sentinel/pinnedKeys。 +- **审查 agent 待复审重点**: ①末条 pinnedKeys 保活 ②sentinel 占位高度不塌 ③现有 ARC-08/UX-03/滚动未动 ④IO/RO disconnect 无泄漏。 +- **待修项回流 todo**: **无**(骨架落地,运行时留实测;ToolCard 嵌套/超大历史留观察)。 ### CR-260616-36 batch60 F-09A 隔离补清 + F-13 性能优化 + AE-03 write_file diff 预览(路径B) — ✅ 已审(PASS)