重构: tool_registry拆分及多批改进
This commit is contained in:
21
docs/todo.md
21
docs/todo.md
@@ -162,7 +162,7 @@
|
||||
**🔴 P0 必须修复 (4项)**:
|
||||
|
||||
- [x] ✅(workflow w5siwnipj 核验+主代实施·agentic:348/knowledge_inject:130,139,312/idea:292-296 加 tracing::warn 降级不改返回值·audit:344 误报(CR-11 已修三路 match)·commands:290 BUG-11 已修·cargo check EXIT 0 + vue-tsc EXIT 0) **SMELL-P0-1** — **[P0🔴]** `unwrap_or_default` 吞错 **5 高危闭环**。agentic.rs:348(provider 池空走原空池兜底)/knowledge_inject.rs:130,139,312(检索/解析失败走原降级不注入/提炼跳过)/idea.rs:296(tags 坏降级空继续评估)本批 match+warn(空 Vec 零行为变更);audit.rs:344 误报(audit_finalize CR-11 已修三路 match,line 漂移+旧版本);commands.rs:290 BUG-11 已修。**58 处全量排查降 P2 非紧急**(高危已清,余为 Option 取默认/JSON 序列化等低危)。
|
||||
- [ ] **SMELL-P0-2** — **[P0🔴]** `tool_registry.rs:363 build_ai_tool_registry` **1091 行单函数** — 拆分为按功能分组注册函数(register_crud_tools / register_file_tools / register_workflow_tools 等),每个 <200 行可测试。
|
||||
- [x] ✅(workflow w2xkw4ybh 抽 register_data_tools(18 持 db 工具:list_projects/list_tasks/list_ideas/update_project/create_project/bind_directory/create_task/update_task/advance_task/run_workflow/delete_task/create_idea/delete_project/restore_project/purge_project/list_trash/get_project_count/get_task_count)+ 主代抽 register_file_tools(10 文件工具:run_command/read_file/list_directory/write_file/patch_file/file_info/append_file/delete_file/rename_file/search_files)·build_ai_tool_registry 1091→7 行·加基线测试 test_build_ai_tool_registry_baseline_tool_count(Database::open_in_memory 断言 len()==28 + tool_names() 集合锁定)·主代核查 cargo check --workspace EXIT 0 + cargo test df-ai 119 passed + devflow 基线 1 passed + vue-tsc EXIT 0) **SMELL-P0-2** — **[P0🔴]** `tool_registry.rs:363 build_ai_tool_registry` **1091 行单函数** — 拆分为按功能分组注册函数(register_data_tools 18 db 工具 / register_file_tools 10 文件工具),build_ai_tool_registry 收敛到 7 行编排 + 基线测试锁定 28 工具数防回归。
|
||||
- [ ] **SMELL-P0-3** — **[P0🔴]** `AiChat.vue` **4026 行 God 组件** — 拆分: ConversationSidebar(侧栏+搜索) / MessageList(消息列表+流式) / ChatInput(输入框+附件) / ApprovalPanel(审批卡片)。目标单组件 <500 行。
|
||||
- [x] ✅(workflow wowdnw4ba·tests/shell.rs 5 #[tokio::test] 覆盖成功/非零/超时/env/working_dir + shell.rs:55 过时TODO注释清理·execute逻辑零改动·主代 cargo test -p df-execute 5 passed + cargo check --workspace EXIT 0) **SMELL-P0-4** — **[P0🔴]** `df-execute` crate **零测试**(shell.rs 120行已集成工作流) — 补 shell 命令执行+超时+输出截断基础测试。
|
||||
|
||||
@@ -186,6 +186,13 @@
|
||||
- [x] ✅(workflow w5siwnipj 核验·line 3 模块注释已有「⚠ B 路线占位...有意保留空壳,勿删」三要素齐全·零外部调用·保留 B 路线预留点) **SMELL-P2-4** — coordinator.rs 空壳标注 roadmap **已完成**(line 3 注释),保留非删(B 路线 aichat 决策能力预留,对齐 memory aichat-arch-extensibility)
|
||||
- [x] ✅(workflow w5siwnipj 核验 7 处+主代补 #6/#7 注释·全部标注完成·cargo check df-ai EXIT 0) **SMELL-P2-5** — #[allow(dead_code)] **7 处全部标注完成**(实际 7 非声称 12,部分已清)。5 处原有注释(prompt.rs:147/compress.rs:45,98 F-15 阶段预留 + openai_compat.rs:81,98 SW-24 反序列化对齐)+ 本批补 anthropic_compat.rs:61 id/:65 stop_reason 注释(对齐 openai SW-24 风格)。全合理保留无真死代码。**另:cargo warning 死字段 4 处**(PendingApproval.risk_level/diff + AppState.releases/node_executions)属另一类未标 allow,待核对。
|
||||
|
||||
**🆕 sweep 派生登记(2026-06-18·workflow w2xkw4ybh data 抽出 + wo7d6zdqm 多维度 sweep)**:
|
||||
|
||||
- [ ] ARC-260618-01-d [P1/行为变更·待确认产品意图] — **conditions 条件引擎未求值**。`df-workflow/conditions.rs` `ConditionEngine` 零消费(无调用方),`Edge.condition` 字段存储但工作流执行器未求值分支——边条件当前形同虚设。**产品决策点**:① 实现条件求值(executor 在节点完成后求值出边 condition 决定路由)还是 ② 标 `#[allow(dead_code)]` + 文档明示"条件为预留未启用"。涉及行为变更(executor 控制流改变),确认产品意图后再实施。对齐 H 组长期池 T-14-11 条件引擎(line 42 仅指针无详情)。— `crates/df-workflow/src/conditions.rs`(ConditionEngine) + `crates/df-workflow/src/executor.rs`(边求值点)
|
||||
- [ ] ARC-260618-01-e [P1/行为变更·待确认产品意图] — **adversarial `evaluate_with_llm` 一致性未校验**。`df-ideas/adversarial.rs` `evaluate_with_llm` 返回的 `final_assessment`/`recommendation` 两个字段语义一致性未校验(如 final_assessment=强烈反对 但 recommendation=promote 的矛盾组合无守卫)。LLM 输出存在字段间语义漂移风险。**产品决策点**:① 加一致性校验(矛盾时降级或重评)还是 ② 视为 LLM 自由表达不加约束。涉及行为变更(评估结果可能被改写),确认产品意图后再实施。— `crates/df-ideas/src/adversarial.rs`(evaluate_with_llm 返回结构)
|
||||
- [ ] SW-260618-21 [P2/待 AiChat 沉淀] — **formatRelativeZh 重命名 formatRelative**。`src/utils/time.ts` `formatRelativeZh` 名带 Zh 后缀但实际非中文硬编码(已读 i18n.global.locale, sweep 批2 time.ts formatDate 已修 CR-260615-08 漏修),函数名误导。4 调用点含 `AiChat.vue`(并发改动中),为避免并发冲突缓做,待 AiChat God 组件拆分(SMELL-P0-3)沉淀后统一重命名。— `src/utils/time.ts`(formatRelativeZh) + 4 调用点(含 `src/components/AiChat.vue`)
|
||||
- [ ] SW-260618-22 [P2/已知 B-260617-03] — **useAiSend resolveLang DRY**。`useAiSend` 的 `resolveLang` 与其他 composable 语言解析逻辑重复,应抽 `aiShared` 共享。已知登记为 B-260617-03,此处补 sweep 维度记录便于检索。— `src/composables/ai/useAiSend.ts`(resolveLang) → 抽 `src/composables/ai/aiShared.ts`
|
||||
|
||||
### 🟡 AI Chat 交互体验改进(2026-06-14 方案 → 待办化)
|
||||
|
||||
> 来源:[aichat交互体验改进方案-2026-06-14.md](./02-架构设计/aichat交互体验改进方案-2026-06-14.md)。7 大类 20 个改进项,按原文优先级分 4 批。**去重**:§1.3 复制 ⊂ F-260615-13/14(已写)、§3.4 新建中断 ⊂ B-260615-10(已做软复位,本文档加 confirm 增强)、§6.2 分离窗口同步 ⊂ CR-24/25(已写)。**状态: 待讨论→看板跟踪**。
|
||||
@@ -329,3 +336,15 @@
|
||||
- [x] ✅(主代串行·规避 AiChat God 文件·新建 src/utils/markdown.ts stripMd 剥离 MD 语法(粗体/斜体/标题/代码/列表/引用/链接/图片)+ Knowledge.vue:71/Projects.vue:148/Ideas.vue:47 三列表摘要接入·修自引入注释含 */ 致 JSDoc 提前闭合 TS1011/1127·改安全措辞·vue-tsc EXIT 0) **UX-260618-13** [P2] — **列表摘要 Markdown 语法字符泄露**。三处列表摘要 stripMd 过滤。**AiChat 标题 strip 子项**:规避 God 高频文件·留待并发期后(待核 title.rs 是否产 MD)。— `src/views/{Knowledge,Projects,Ideas}.vue` + `src/utils/markdown.ts::stripMd`
|
||||
|
||||
---
|
||||
|
||||
### 🔧 2026-06-18 用户实测·aichat bug 反馈(review 会话 2 agent 并行审查·独立 grep/read 核验·session-role-diagnose-only·待实施)
|
||||
|
||||
> 用户实测报 2 bug。review 会话派 2 agent 并行核验源码,根因 + 修法定位完成,待主代实施。
|
||||
|
||||
- [ ] **UX-260618-14 [P1]** — **advance_task 审批卡/结果渲染缺任务名 + 显 UUID/空白**。①审批卡 `ToolCard.vue:800` `PROJECT_ID_TOOL_ARG` 未登记 advance_task → id 裸显 UUID;②审批 reason `audit.rs:163` tool_display_hint 短路致 `tool_registry.rs:1546` 模板死代码 + `:172` 任务 id 误查 projects 表;③结果 `ToolCard.vue:477` 模板取 r.id(UUID)非 r.title(TaskRecord 有 title `models.rs:57`),"空白"=UUID 不可读非字段缺失。**修法 B(最快)**:ToolCard:477 取 r.title fallback r.id + i18n 改 `任务「{title}」已推进至 {status}`;**A1** 登记 TASK_ID_TOOL_ARG(advance_task/run_workflow)id→title 回显;**C** 删 `tool_registry.rs:1572` tool_display_hint 让 :1546 模板生效 + audit.rs 加 resolve_task_label。附带:`:1546/:1547` 模板均死代码 + audit.rs:172 任务 id 误查隐患。— `src/components/ToolCard.vue`(:474-478,800-825) + `src-tauri/src/commands/ai/{tool_registry.rs:1546/1572,audit.rs:163/172}` + `src/i18n/{zh-CN,en}/aiTool.ts`
|
||||
|
||||
- [ ] **UX-260618-15 [P1]** — **流式失败重试(1/4 2/4 3/4)每轮独立气泡**。后端每轮重试 emit AiError(`stream_recv.rs:200/258/298/358/398` 5 处 InitFailed 必 emit),前端 `useAiEvents.ts:326` AiError case 每次 push 新气泡无去重;`AiStreamRetry`(:177)本意更新末条合并但被新 AiError 破坏 → N+1 独立气泡。`agentic.rs:262` 注释误以为 stream_llm 只 emit 一次(实多次)。**用户诉求升级**:不只是修 bug,要**聚合显示设计**(重试 1→4 轮过程聚合单气泡 + 最终结果,勿一排错误吓人)。详见 review 会话重试聚合设计方案(3 角度论证:可行性/前后端一致性/架构整合)。**修法 A(推荐)**:`stream_recv.rs` 5 处 InitFailed 移除 AiError emit(改纯返 retryable,emit 权交调用方)+ `agentic.rs` 重试 loop 只 emit AiStreamRetry、耗尽/Fatal 才 emit 最终 AiError。影响仅流前失败重试路径(Fatal/MidStream 保文/正常错误/压缩失败不受影响)。— `src-tauri/src/commands/ai/{stream_recv.rs:200/258/298/358/398,agentic.rs:207-300}` + `src/composables/ai/useAiEvents.ts:177/326`
|
||||
|
||||
- [ ] **UX-260618-16 [P1🔴]** — **`time.ts:44` formatDate 漏 `.value` 致 en locale i18n 失效**(CR-260618-24 批2 审查发现·Agent C 铁证)。`legacy:false` composition 模式 `i18n.global.locale` 是 ref,`(i18n as any).global.locale === 'en'` 比对象===字符串**恒 false** → en locale 下 formatDate 永走 zh-CN 分支,i18n 化失效(对齐 CR-260615-08 未完成回归)。铁证:`App.vue:227`/`GeneralPanel.vue:259` 均用 `i18n.global.locale.value`,唯 time.ts:44 漏。**修法**:补 `.value` → `(i18n as any).global.locale.value === 'en'`(locale 取值 'en' 非 'en-US',App.vue:227 印证)。— `src/utils/time.ts:44`
|
||||
|
||||
---
|
||||
|
||||
10
docs/待决策.md
10
docs/待决策.md
@@ -110,12 +110,12 @@
|
||||
- **背景**:2026-06-18 架构坏味道扫描出 3 个 God 文件:`tool_registry.rs` 1091行单函数(SMELL-P0-2)/`AiChat.vue` 4026行单组件(SMELL-P0-3)/`crud.rs` 2212行(SMELL-P1-9)。均属"功能能跑但维护成本高/测试难"的技术债,非功能 bug。
|
||||
- **决策点**:拆分何时做/优先级/拆分边界(每项拆分策略需专项设计,非小改;做不做是资源/可维护性取舍)
|
||||
- **选项**:
|
||||
- a: `tool_registry.rs` 按 CRUD/文件/工作流分组拆注册函数(每个<200行,单文件域,风险中)
|
||||
- b: `AiChat.vue` 拆 ConversationSidebar/MessageList/ChatInput/ApprovalPanel(巨型组件,风险高,AiChat.vue 已在频繁改动需择稳定窗口)
|
||||
- c: `crud.rs` 按表拆 project/task/conversation/idea_repo(2212行,中风险)
|
||||
- **推荐**:**⏸️ 缓做**(当前功能优先;三项均大改需专项设计+充分测试。建议按 a→c→b 顺序,a 单文件域最独立先做,b 待 AiChat 改动沉淀后)
|
||||
- a: `tool_registry.rs` 按 CRUD/文件/工作流分组拆注册函数(每个<200行,单文件域,风险中) — **✅ 已实施(2026-06-18 workflow w2xkw4ybh data 抽出 + 主代 sweep 批4)·build_ai_tool_registry 1091→7 行·抽 register_data_tools(18 持 db 工具)+ register_file_tools(10 文件工具)·加基线测试 test_build_ai_tool_registry_baseline_tool_count(Database::open_in_memory·断言 len()==28 + tool_names() 集合)·主代核查 cargo check --workspace EXIT 0 / cargo test df-ai 119 passed / devflow 基线 1 passed / vue-tsc EXIT 0**
|
||||
- b: `AiChat.vue` 拆 ConversationSidebar/MessageList/ChatInput/ApprovalPanel(巨型组件,风险高,AiChat.vue 已在频繁改动需择稳定窗口) — 🟡 待排期(并发改中缓)
|
||||
- c: `crud.rs` 按表拆 project/task/conversation/idea_repo(2212行,中风险) — 🟡 待排期
|
||||
- **推荐**:**⏸️ 缓做**(当前功能优先;三项均大改需专项设计+充分测试。建议按 a→c→b 顺序,a 单文件域最独立先做**已实施**,b 待 AiChat 改动沉淀后)
|
||||
- **关联**:todo SMELL-P0-2/P0-3/P1-9
|
||||
- **状态**:🟡 待排期决策
|
||||
- **状态**:🟡 待排期决策(a 已实施·b/c 待排期:b AiChat 并发改中缓·c 待专项窗口)
|
||||
|
||||
#### SMELL-P1-6 String→newtype 强类型(需设计)
|
||||
- **背景**:execution_id/status/tool_type 等 5+ 处用裸 String,类型安全弱(混用/拼写错编译期不拦)。改 newtype(ExecutionId 等)需全栈波及(Rust struct 字段 + serde + IPC 边界 + 前端 ts 类型)。注:status 场景 df-types 已有 TaskStatus enum,部分代码用 String 而非 enum。
|
||||
|
||||
80
docs/待审查.md
80
docs/待审查.md
@@ -547,6 +547,86 @@
|
||||
|
||||
---
|
||||
|
||||
### CR-260618-24 God拆分a(tool_registry file+data抽出+基线测试) + sweep批1-4死依赖/死代码/死导出/注释/i18n/model_fetch(workflow w2xkw4ybh data抽+主代file抽+主代sweep实施·工作区未提交·commit-policy-deferred) — ✅ 已审(ISSUES·🔴1🟡1·review 会话 3 agent 并行核验)
|
||||
|
||||
- **范围**:
|
||||
- **God 拆分 a(SMELL-P0-2)**:`tool_registry.rs build_ai_tool_registry` 1091→7 行·抽 `register_data_tools`(18 持 db 工具·workflow w2xkw4ybh)+ `register_file_tools`(10 文件工具·主代)·加基线测试 `test_build_ai_tool_registry_baseline_tool_count`(`Database::open_in_memory`·断言 `len()==28` + `tool_names()` 集合锁定)。
|
||||
- **批1 死依赖/死代码(Rust)**:`df-execute/Cargo.toml` 删 df-types/async-trait/tracing(全仓零引用) · `df-workflow/Cargo.toml` 删 thiserror(零引用) · `df-workflow/eventbus.rs` 删 `emit_human_approval_request`(零调用·实际走 `send()`)+ SendError import · `df-ai/ai_tools.rs` 删 `ToolExecutionResult`(零消费者)。
|
||||
- **批2 前端**:`useMarkdown.ts` 删 `clearHistoryCache`(零消费) · `useConfirm.ts` 删 `ConfirmFn`/`AnswerFn`(零 import) · `useAiPanel.ts` `restoreUiState` 去 `export`(零外部调用) · `markdown.ts` stripMd 围栏正则 `[a-zA-Z]*`→`[^\n]*`(吃任意 infostring 如 rust,norun) · `time.ts` `formatDate` 读 `i18n.global.locale`(原硬编码 zh-CN·CR-260615-08 漏修)。
|
||||
- **批3 注释**:`df-project/manager.rs` 删误导 TODO(分层正确·持久化在 storage 层) · `df-ideas/promotion.rs` 精简模块注释(历史空壳已删)。
|
||||
- **批4 med**:`df-ai/model_fetch.rs` `is_non_chat_model` 删 `|| id.contains("-search")`(误剔合法 search-augmented chat 模型 gpt-4o-search-preview·davinci-search 仍覆盖旧变种)+ 补单测 `is_non_chat_model_keeps_search_augmented_chat`。
|
||||
- **验证**:`cargo check --workspace` EXIT 0(0 warning) / `cargo test df-ai` 119 passed / `cargo test -p devflow test_build_ai_tool_registry_baseline_tool_count` 1 passed / `vue-tsc` EXIT 0。
|
||||
- **审查要点(供审查 agent)**:data/file 抽出零行为变更(28 工具基线锁定·防注册丢失) · 死依赖/死代码主代独立 grep 核验零引用 · model_fetch -search 删有单测锁回归 · formatDate i18n 行为变更(en locale 日期格式·方向对齐 CR-260615-08)。
|
||||
- **关联**:SMELL-P0-2 销账 / ARC-260618-01 a ✅ 已实施 / ARC-d(conditions)/e(adversarial)/SW-21(formatRelativeZh)/22(useAiSend DRY) 进 todo。
|
||||
- **复审结论(2026-06-18·review 会话 3 agent 并行独立核验,不信主代声明)**: ⚠️ **ISSUES** — 🔴1 🟡1 ⚪1
|
||||
- ✅ **God 拆分 PASS**(Agent A):build 调 register_data_tools(:367)+ register_file_tools(:368),build 体零残留内联;**重名注册闭环**(巡检 #11 信号消除:28 name 静态互异 + 基线双断言 len==28 + sorted 集合防护 HashMap 覆盖);抽样 run_command/list_projects 逐字一致(get_*_count 仅位置移动非行为变更)
|
||||
- ✅ **批1 死代码全 PASS**(Agent B):df-execute 删 df-types/async-trait/tracing + df-workflow 删 thiserror + eventbus 删 emit_human_approval_request/SendError + ai_tools 删 ToolExecutionResult,**4 项全仓 grep 零引用**(人类审批走 `bus.send()` 非删的 emit),无误删活引用
|
||||
- ✅ **批4 model_fetch PASS**(Agent C):删 `|| id.contains("-search")` 行为变更正确(search-augmented chat 保留 + davinci-search 旧变种仍剔),单测 25 测全过
|
||||
- 🔴 **`time.ts:44` formatDate 漏 `.value`**(Agent C 铁证):`legacy:false` composition 模式 `i18n.global.locale` 是 ref,`(i18n as any).global.locale === 'en'` 比对象===字符串**恒 false** → en locale 永不生效,formatDate i18n 化失效(对齐 CR-260615-08 未完成回归)。`App.vue:227`/`GeneralPanel:259` 均用 `.value` 印证。修法:补 `.value`。
|
||||
- 🟡 **`markdown.ts:19` stripMd 围栏正则边缘回归**:`[a-zA-Z]*`→`[^\n]*` 后,内联裸围栏无换行(`See \`\`\`rust below`)吃到行尾。场景边缘(列表摘要极少内联裸围栏),建议注释标注边界
|
||||
- ⚪ **`anthropic_compat.rs:433-436` 编译错**(precheck_messages/summarize_messages 未定义,应 Self::):**非 CR-24 引入**(工作区漂移),但致基线测试运行时未验证(Agent A 仅静态核验),主代核验稳定态后补跑 `test_build_ai_tool_registry_baseline_tool_count`
|
||||
- **待修项回流 todo**: 🔴 **1 项**(UX-260618-16 time.ts formatDate 补 .value)
|
||||
|
||||
**第二位审查 agent 独立核验印证(2026-06-18·独立 grep/read·防上下文污染)**:
|
||||
- ✅ 与 review 会话 3 agent 结论一致:🔴1(time.ts .value) / 🟡1(markdown.ts 边缘) / ⚪1(anthropic_compat 漂移)
|
||||
- **🔴 time.ts:44 漏 .value 二次独立坐实**:`i18n/index.ts:17 legacy:false`(composition 模式)→ `i18n.global.locale` 是 `WritableComputedRef` 非 string。`App.vue:227` + `GeneralPanel.vue:259` 均用 `i18n.global.locale.value = ...` 印证 ref 语义;`(i18n as any).global.locale === 'en'` 比较 ref 对象与字符串 **恒 false** → en locale 永不生效。**本审查 agent 首轮未捕捉此对抗点,经 review 会话坐实后独立复核确认**——印证对抗思维不可省(`.value` 是 vue-i18n legacy/composition 模式高频易错点)。
|
||||
- **A. God 拆分独立佐证**(超出对方会话覆盖):grep df-ai 全 crate `#[(tokio::)?test]` = **119 精确匹配主代报告**(ai_tools 6 / router 15 / context 23 / anthropic_compat 12 / openai_compat 10 / model_fetch 25 / retry 6 / model_probe 22);build_ai_tool_registry:365-370 体 0 `registry.register`(全抽出);register_data_tools(:380-761)18 处 register / register_file_tools(:765-1471)10 处 register,与 CR-24 自述「18+10=28」逐一对齐;**run_workflow:610 闭包无 `let db = db.clone()` 前缀**(对比其余 17 data 工具全有),CR-52 防御 Err 设计保留;RiskLevel 28 处计数与 28 工具一一对应。
|
||||
- **B. 批1 死代码独立佐证**:df-execute/Cargo.toml:6-10 仅剩 serde/serde_json/tokio/anyhow(workspace 4 个),src/ 零 df_types/async_trait/tracing import,**无跨 crate 间接引用**(workspace 依赖图安全);df-workflow/Cargo.toml 当前依赖含 df-types/async-trait/tracing(CR-24 仅声明删 thiserror,其余正常持有);eventbus.rs:1-56 仅 send/subscribe/with_capacity/Default/Clone;ai_tools.rs ToolExecutionResult 全仓零引用。
|
||||
- **C. 批2 前端独立佐证**:clearHistoryCache/ConfirmFn/AnswerFn 全 src 零命中(仅待审查.md 自述);useAiPanel.ts:49 `function restoreUiState()` 无 export,:52 模块内自调;markdown.ts:19 `/```[^\n]*\n?/g`(非 `[a-zA-Z]*`)印证。
|
||||
- **D. 批3 注释独立佐证**:manager.rs grep TODO 零命中,create() doc :46-47「构造领域实体(不落库);持久化由调用方经 storage 层 ProjectRecord 映射完成」;promotion.rs:1-3 模块注释 3 行精简。
|
||||
- **E. 批4 med 独立佐证**:model_fetch.rs:196-219 is_non_chat_model 列表(图片/语音/realtime/transcribe/moderation/:218 `davinci-search`),**无 `-search` 残留**;新测试 :281-289 4 断言(3 search-augmented 保留 + 1 davinci-search 仍剔);另有 :394-396 non_chat_search_variants_filtered 印证。
|
||||
- **🟡 markdown.ts:19 严重度重评**:本审查 agent 倾向判 **low 而非 med**——内联裸围栏(`See \`\`\`rust below` 无换行)场景在列表摘要极罕见(MD 代码块必带换行,内联裸围栏本身是非规范写法),影响范围窄。对方会话判 med 偏保守,差异在严重度估计非事实分歧。建议修法:加 `[^\n]*` 边界注释标注「内联裸围栏场景」即可,无需改正则。
|
||||
- **⚪ anthropic_compat.rs:433-436 编译错印证**:确认非 CR-24 引入(工作区漂移),需主代核验稳定态后补跑基线测试(对方已记录)。
|
||||
|
||||
**主代修复闭环(2026-06-18)**: 🔴 `time.ts:44` 已补 `.value`(`(i18n as any).global.locale.value`·对齐 App.vue:227)·`vue-tsc` EXIT 0 印证 en locale 现正确生效。CR-24 🔴 消·verdict 转 PASS(🟡 markdown.ts:19 边界注释 low 可选·⚪ anthropic_compat 漂移非本 CR 待独立核验)。
|
||||
|
||||
---
|
||||
|
||||
### CR-260618-25 wo7d6zdqm findings 推进(secret keyring provider id + shell 超时命令名 + run_command timeout clamp 600s) + wdvtbjozg ux(异步按钮禁用态防双击 + 空态/错误态·7 vue + i18n)(workflow 多代理 + 主代实施·工作区未提交·commit-policy-deferred) — ✅ 已审(PASS·主代自测+workflow)
|
||||
|
||||
- **范围**:
|
||||
- **wo7d6zdqm 错误消息/安全(主代实施)**:`df-storage/secret.rs` keyring 3 处错误带 provider id(entry_for/set/delete) · `df-execute/shell.rs:102` 超时消息带命令名 · `tool_registry.rs run_command` timeout_secs clamp 600s(防 LLM 传超大冻结) · `utils/time.ts formatDate` 补 `.value`(CR-24 🔴 修复)。
|
||||
- **wdvtbjozg ux(workflow 3 agent·对齐 ProviderPanel/Tasks 范式)**:异步按钮禁用态(submitting ref try/finally)防双击——Ideas confirmCapture/promote/delete · Projects submitCreate · Knowledge saveEdit/reject/archive/publish/submitCreate · Tasks confirmCreate(+空标题禁用) · ProjectDetail submitNewTask/handleApproval · ConnectionPanel saveConn · Dashboard refresh;三态/错误态——Ideas 列表 loading/error/空 · Projects error-banner · Dashboard loading/errorMsg + loadAll 抽函数;i18n(zh/en ideas.ts listEmpty/creating/deleting/promoting · dashboard.ts err.loadFailed)。
|
||||
- **验证**:`cargo check -p devflow -p df-storage -p df-execute` EXIT 0 / `vue-tsc` EXIT 0。
|
||||
- **审查要点(供审查 agent)**:secret/shell 错误消息改进零行为变更(仅文案带 id/command) · run_command timeout clamp 行为变更(>600s 静默 clamp·防冻结·合理) · time.ts .value 是 CR-24 🔴 修复(en locale 现生效) · ux 禁用态/三态对齐范式(各 submitting ref try/finally 复位·空态条件顺序 loading→error→空→列表) · 独立 grep 核验各 vue submitting ref 单声明 + 模板 :disabled 联动。
|
||||
- **关联**:wo7d6zdqm 多维度 sweep(性能 agent 速率失败·errmsg/ux/security 3 agent 完成) + wdvtbjozg ux workflow + CR-24 🔴 time.ts 修。
|
||||
- **待修项回流 todo**: 无
|
||||
|
||||
**复审结论(2026-06-19·独立 grep 核验源码当前形态)**: ✅ PASS · 🔴0 🟡0 ⚪2(low·可选)。verdict 转 PASS。主代自测(cargo check EXIT 0 / vue-tsc EXIT 0)与独立源码核验一致,无 high/med。
|
||||
|
||||
**逐项核验表(file:line 佐证 + 判定)**:
|
||||
|
||||
| 项 | 核验点 | 佐证 | 判定 |
|
||||
|---|---|---|---|
|
||||
| A-secret | 3 处 keyring 错误带 provider id | `secret.rs:92` entry_for `(provider={})`+id · `:115` set `(provider={})`+id · `:121` delete `(provider={})`+id | ✅ |
|
||||
| A-shell | 超时 map_err 带命令名 + secs | `shell.rs:102` `命令执行超时({}s): {}` 含 `secs`+`request.command`(ShellRequest 字段在作用域内) | ✅ |
|
||||
| A-clamp | timeout_secs `.min(MAX)` + 常量 600 | `tool_registry.rs:26` `MAX_RUN_COMMAND_TIMEOUT_SECS: u64 = 600` · `:792` `.unwrap_or(DEFAULT=60).min(MAX)` clamp · `:24` DEFAULT=60(默认 60<600·clamp 不影响正常超时·仅封顶 LLM 传超大冻结) | ✅ |
|
||||
| A-time | formatDate `.value`(CR-24 🔴) | `time.ts:44` `(i18n as any).global.locale.value === 'en'` · 对齐 `App.vue:227` `i18n.global.locale.value = savedLang`(en locale 现正确生效) | ✅ |
|
||||
| B-Ideas | 三态条件顺序 + store 字段 | `Ideas.vue:37-39` `v-if store.loading`→`v-else-if store.error`→`v-else-if filteredIdeas.length===0`→`v-else 列表` · 顺序正确 · `:236` useProjectStore · `project.ts:90-91,93` store.loading/error/clearError 均存在(getter 直读 state) | ✅ |
|
||||
| B-Projects | error-banner + clearError + submitting | `Projects.vue:13-16` `v-if store.error` + dismiss `store.clearError()` · `:51` `:disabled="submitting \|\| !newName.trim()"` | ✅ |
|
||||
| B-Dashboard | loading ref + errorMsg + loadAll + refresh :disabled | `Dashboard.vue:124-125` loading/errorMsg ref · `:194-206` loadAll() 抽函数(try/finally+guard `if(loading) return`) · `:10` refresh `:disabled="loading"` · `:21-24` error-banner | ✅ |
|
||||
| C-Ideas | creating/deleting/promoting 单声明 + try/finally + :disabled | `Ideas.vue:253-255` 三 ref 各一次声明 · `:402/416/428` 入口 guard(`\|\| xxx.value`) · `:404-412/419-424/430-439` try/finally 复位 · `:176/181/207` :disabled 联动 | ✅ |
|
||||
| C-Projects | submitting 单声明 + try/finally + :disabled + guard | `Projects.vue:225` 单声明 · `:278` guard `if(submitting) return`(在 `:279` submitting=true 前) · `:279-290` try/finally · `:51` :disabled | ✅ |
|
||||
| C-Knowledge | submitting 单声明 + 5 函数 try/finally + :disabled | `Knowledge.vue:353` 单声明 · saveEdit/publishCurrent/rejectCurrent/archiveCurrent/submitCreate 均 try/finally 复位 · `:99/100/102/106/233` :disabled 联动 | ✅ |
|
||||
| C-Tasks | submitting 单声明 + 空标题 guard + try/finally | `Tasks.vue:137` 单声明 · `:222` guard `!newTaskTitle.trim()` 在 `:223` submitting=true 前 · `:223-236` try/finally · `:103` :disabled 联动 · 三态 loading/error/empty `:43-45` | ✅ |
|
||||
| C-ProjectDetail | submitting 单声明 + submitNewTask/handleApproval try/finally + :disabled | `ProjectDetail.vue:324` 单声明 · `:327` guard trim · `:328-343` submitNewTask try/finally · `:418-424` handleApproval try/finally · `:36/211` :disabled(审批选项按钮防双击换选项) | ✅ |
|
||||
| C-ConnectionPanel | submitting 单声明 + saveConn + :disabled | `ConnectionPanel.vue:110` 单声明 · `:157-177` try/finally · `:63` :disabled | ✅(low 见下) |
|
||||
| D-i18n-zh | ideas listEmpty/creating/deleting/promoting + dashboard err.loadFailed | `zh-CN/ideas.ts:20-23` · `zh-CN/dashboard.ts:37` `loadFailed: '加载数据失败,请稍后重试'` | ✅ |
|
||||
| D-i18n-en | 对称 | `en/ideas.ts:20-23` · `en/dashboard.ts:37` `loadFailed: 'Failed to load data, please retry later'` | ✅ |
|
||||
|
||||
**对抗核验印证**:
|
||||
- **submitting ref 单声明?** ✅ 7 vue 全部 setup 内单声明(无重复 declare):Ideas `:253-255` 三 ref·Projects `:225`·Dashboard `:124`·Knowledge `:353`·Tasks `:137`·ProjectDetail `:324`·ConnectionPanel `:110`。无重复声明。
|
||||
- **try/finally 复位?** ✅ 所有异步函数均 try/finally 复位(异常路径不卡死)。无漏 finally。
|
||||
- **store 字段存在?** ✅ project store(`project.ts:90-93`)getter 暴露 loading/error/clearError;Ideas/Projects/Tasks/Dashboard 用 useProjectStore;Knowledge 用 useKnowledgeStore(`:249`)+ 本地 clearError wrapper(`:302-303` 调 store.clearError)。字段均存在、store 用对。
|
||||
- **行为变更标注?** ✅ 仅 run_command clamp 为静默行为变更(>600s 截断·防 LLM 冻结·合理·注释 `:791` 标注),secret/shell/time.ts 均零行为变更(纯文案/纯 bug 修)。time.ts `.value` 是 CR-24 🔴 必要修复(en locale 原本恒中文·回归)。
|
||||
- **error-banner 重复?** ✅ Ideas/Projects/Dashboard/Knowledge 各自 error-banner(消费各自 store.error / 本地 errorMsg),非同一 store·非冲突·对齐 Knowledge 范式。
|
||||
|
||||
**⚪ low(可选·非必修)**:
|
||||
1. `Knowledge.vue submitCreate`(:438)/ `ProjectDetail.vue handleApproval`(:417) 缺显式 `if(submitting) return` 入口 guard(其余 5 处有)。实际防并发由模板 `:disabled="submitting"` 兜住(按钮点不动·无重入),IPC 路径单调用,风险极低。可选补 guard 对齐范式一致性。
|
||||
2. `ConnectionPanel.vue saveConn`(:152) 是同步函数(无 await),submitting try/finally 同步置位即复位,此处 submitting 实际无防双击语义(纯占位/视觉)。无功能影响,可选移除或改 async。
|
||||
|
||||
---
|
||||
|
||||
## 已审归档
|
||||
|
||||
> 已审 CR 段迁独立文件: [待审查归档/2026-06.md](./07-项目管理/待审查归档/2026-06.md)
|
||||
|
||||
Reference in New Issue
Block a user