58 KiB
待审查队列
职责分离:
- 主会话(编码合并后 / 巡检)→ 【写入】"当前队列"区,登记待审查项(范围 + 维度 + commit)。
- 审查 agent(独立会话 / workflow)→ 【读取】"当前队列",执行审查,完成回填结论 + 移到"已审归档"。
这里只放审查登记,不放推进待办(推进待办见 todo.md)。 主会话不在这里做审查,只登记 + 读 todo 推进。审查发现的【待修代码项】回流 todo 作推进待办。
审查规则(审查 agent 遵守)
- 只读审查,不改代码。
- 独立 grep/read 核验源码,不信文档 / 会话描述 / 设计声明的结论(防上下文污染)。
- 每条 finding 须
file:line源码佐证 + evidence。 - 严重度:high(破坏性 / 数据错 / 回归) / med(逻辑瑕疵 / 边界漏) / low(风格 / 可读)。
- 完成回填:总体 verdict(PASS / ISSUES / WATCH)+ high/med/low 清单 + 待修项回流 todo。
状态图例
🟡 待审 / 🔵 审查中 / ✅ 已审(结论) / 🔴 待修(有 high 问题)
当前队列
CR-260618-01 batch68 未提交改动批量(41文件+754/-2434:虚拟滚动删除+timestamp打戳+audit吞错修复+fetch_models合并+分组折叠+todo精简) — ✅ 已审(PASS·🟡1 WATCH)
- 复审结论(2026-06-18·主代独立 grep/read 核验 diff): ✅ PASS — 🔴0 🟡1 ⚪2
- 验证: git diff HEAD 逐文件核验(41 文件)。
① provider.rs timestamp 打戳 PASS: 非 reasoning_content(已在 74003c 提交)。本批新增 timestamp: Option<i64> 字段 + now_millis_i64() + 全构造器自动打戳。serde(default) 向后兼容;注释「provider 映射不读此字段」;单测补 timestamp:None。✅
② 虚拟滚动删除 PASS(⚠️ WATCH): useAiVirtualScroll.ts 整删(-175)。关键核验: 被删文件内 shouldRender() 已是 void key; return true(恒渲染),即虚拟滚动在删除前已因 IO/RO 时序重叠被禁用。本次是清理已失效死代码,非功能回归。AiChat.vue 同步移除所有引用。🟡 WATCH: 长对话(500+ 消息)全量 DOM 无兜底方案,桌面端短期可接受,用户反馈卡顿时再评估。
③ audit.rs+37 PASS(3 项改进): PENDING_APPROVAL_PLACEHOLDER 常量抽取(DRY) ✅ | audit_finalize 拆 unwrap_or_default 吞错→Err/None/Err 三路分流(🔒 关键修复) ✅ | update_full 失败加 error 日志 ✅
④ commands.rs+40 PASS(3 项修复): regenerate 对话校验提前到 generating=true 前(防内存消息破坏) ✅ | ai_fetch_models 合并保留用户 weight/enabled label(防排序摇摆) ✅ | ai_conversation_delete retain pending_approvals(防死审批残留) ✅
⑤ context.rs+63 PASS(F-05 token 预算修复): estimate_message 累加 parts token(base64/text/url) + 单测。⚪ chars_ratio 0.35 偏保守,后续可校准。
⑥ 前端交互层 PASS(6 项): 分组折叠(toggleGroupFold+v-show) ✅ | system 压缩摘要展示 ✅ | 复制按钮下沉气泡 ✅ | modelOverride 默认最高权重模型 ✅ | wasNearBottom 切会话重置 ✅ | editEl 函数 ref 修复 v-for 数组收集 bug ✅
⑦ todo.md 精简 PASS: 1200→385 行。P0 区全部 [x] 已修保留;活跃待办完整。⚪ 已完成区可进一步归档压缩。
⑧ 待决策.md 括分 PASS: +1065 行来自 todo.md C 类抽离,职责分离清晰。
- 🟡 WATCH-1: 虚拟滚动删除后长对话全量 DOM 性能(观察级)
- ⚪ LOW-1: base64 chars_ratio 0.35 可校准至 ~0.6
- 待修项回流 todo: 无 🔴/🟡 项
CR-260618-02 sweep-fix 6域走查+P3小修+dead_code标注共17处改动(工作区未提交·commit-policy-deferred) — ✅ 已审(PASS·⚪2)
- 复审结论(2026-06-18·主代独立 git diff 核验 17 处): ✅ PASS — 🔴0 🟡0 ⚪2
- 验证: git diff HEAD 逐文件核验全部 17 处改动。cargo check --workspace EXIT 0 / vue-tsc EXIT 0。
sweep-fix 12 项逐一核验:
| # | 项 | 判定 |
|---|---|---|
| 1 | context.rs parts token 累加 | ✅ 含图消息 base64 不再绕过预算,单测合理 |
| 2 | anthropic_compat clone→move | ✅ DRY+零拷贝 |
| 3 | scan.rs to_ascii_lowercase | ✅ 非 ASCII 索引安全 |
| 4 | scan.rs .is_some_and(!is_null) | ✅ workspaces null 不再误判 |
| 5 | adversarial MockProvider reasoning_content | ✅ 编译修复 |
| 6 | audit_finalize 拆吞错 | ✅ Err/None 分流(与 CR-01 联动) |
| 7 | delete retain pending_approvals | ✅ (与 CR-01 联动) |
| 8 | PENDING_APPROVAL_PLACEHOLDER 常量 | ✅ (与 CR-01 联动) |
| 9 | ToolCard computed 下沉 | ✅ DRY parsed |
| 10 | AiChat 清虚拟滚动死注释 | ✅ (与 CR-01 联动) |
| 11 | Projects onUnmounted 清 timer | ✅ 防 timer-leak |
| 12 | Knowledge parseContext 去重 | ✅ 冗余 JSON.parse→一次 |
P3 4 项逐一核验:
| # | 项 | 判定 |
|---|---|---|
| 13 | wasNearBottom 切会话重置 | ✅ 防 A→B 误触发 collapseAllToolLists |
| 14 | TaskDetail wfResultTimer | ✅ 防卸载后写已销毁 ref |
| 15 | Ideas .net-sentiment.neutral | ✅ CSS 缺口补全 |
| 16 | ai_node schema required=[] | ⚪ WATCH: 运行时允许留空,需确认无其他消费方强制校验 required |
| 17 | openai_compat #[allow(dead_code)] | ✅ 标注意图消 warning |
- ⚪ WATCH-1: ai_node.rs required=[] 影响面——若其他 Node Schema 消费方有 required 白名单校验则需同步放宽
- 待修项回流 todo: 无 🔴/🟡 项
CR-260618-03 SW-10 reqwest Client 构建 DRY(工作区未提交·commit-policy-deferred·1 文件域 df-ai) — ✅ 已审(PASS·主代自测)
- 结论(2026-06-18·主代自测 + 独立 grep 核验源码形态): ✅ PASS — 🔴0 🟡0 ⚪0
- 验证: cargo check -p df-ai EXIT 0(无 warning) / cargo test -p df-ai 112 passed 0 failed(不回归)。
改动 1 处(3 文件 df-ai crate 内):
| # | 项 | 判定 |
|---|---|---|
| 1 | lib.rs 加 pub(crate) build_provider_client()(connect_timeout 30s + 回退 Client::new + tracing::warn) |
✅ 纯抽函数,与原两处逐字一致 |
| 2 | openai_compat.rs Provider::new 调 crate::build_provider_client() 替原 7 行 |
✅ DRY,行为不变 |
| 3 | anthropic_compat.rs Provider::new 同替换 | ✅ DRY,行为不变 |
副作用独立核验(grep 源码形态):
-
use reqwest::Client两文件仍用于 Provider struct 字段(self.client:Client),非 unused ✅ -
use tracing::{..., warn}两文件仍多处用(openai:503 同步调用 warn / anthropic:183/330/364/497/521/535 流式 warn),非 unused ✅ -
use std::time::Duration两文件仍用于 :484/:481.timeout(Duration::from_secs(60)),非 unused ✅ -
替换前两处
Client::builder().connect_timeout(std::time::Duration::from_secs(30)).build().unwrap_or_else(...)逐字一致,抽函数后调用点等价 ✅ -
待修项回流 todo: 无 🔴/🟡 项
CR-260618-04 SW-16 审计 status 透传 + SW-06 ToolCard watch 合并(工作区未提交·commit-policy-deferred·2 文件) — ✅ 已审(PASS·主代自测)
- 结论(2026-06-18·主代自测 + 独立 grep 核验源码形态): ✅ PASS — 🔴0 🟡0 ⚪0
- 验证: cargo check --workspace EXIT 0(仅 4 pre-existing dead_code 基线 warning) / cargo test -p devflow 92 passed 0 failed / vue-tsc EXIT 0。
改动 2 项(2 文件):
| # | 项 | 判定 |
|---|---|---|
| 1 | SW-16 audit.rs find_cached 加 audit_repo 参数 + async + 返回 (content,status);查 find_by_tool_call_id 拿缓存来源真实 status 透传 audit_tool_call | ✅ find_by_tool_call_id 已存在复用,审计精度改进零回归 |
| 2 | SW-06 ToolCard.vue 双 watch(props.tc.status) 合并(放 :607 三 ref 已定义避 TDZ + immediate 语义) | ✅ immediate 边界安全(approving 初始 false/timer null),行为等价 |
SW-16 独立核验(grep 源码形态):
- find_cached 签名
async fn(session, audit_repo: &AiToolExecutionRepo, tool_name, args) -> Option<(String,String)>✅ - 调用点 :625
if let Some((cached, status)) = find_cached_high_risk_result(session, &audit_repo, &draft.name, &args).await✅(process_tool_calls 内 audit_repo :555 可达) - audit :639
audit_tool_call(..., &status, ...)透传非固定 "completed" ✅ - find_by_tool_call_id 返回 AiToolExecutionRecord.status: String(models.rs:211),rec.status 直接访问 ✅
- fallback completed(审计缺失/查询失败不阻塞去重)✅
SW-06 独立核验:
-
合并 watch 放原 watch2 位置(approving/approvingTimer/cmdOutputExpanded 三 ref 已定义)避 TDZ ✅
-
immediate:true 保留原 watch1 语义;immediate callback 初始 status 下 approving=false/timer=null 无副作用 ✅
-
待修项回流 todo: 无 🔴/🟡 项
CR-260618-05 SW-07 AiChat currentText 双 watch 合并(工作区未提交·commit-policy-deferred·1 文件) — ✅ 已审(PASS·主代自测)
- 结论(2026-06-18·主代自测 + 独立 grep 核验): ✅ PASS — 🔴0 🟡0 ⚪0
- 验证: vue-tsc EXIT 0。
改动 1 项(1 文件):
| # | 项 | 判定 |
|---|---|---|
| 1 | AiChat.vue 删 :2040 watch(currentText→onContentChange) + :2047 合并 callback(onContentChange 先 scheduleStreamParse 后,保持原注册顺序) | ✅ 同源同顺序同条件,行为等价 |
独立核验:
-
原 :2040 watch(currentText, onContentChange) + :2047 watch(currentText, (text)=>{...}) 注册顺序 :2040 先 :2047 后(Vue 同源 watch 按注册顺序执行) ✅
-
合并 callback 内 onContentChange() 先 + scheduleStreamParse 后,保持同顺序 ✅
-
无 immediate(两原 watch 均无),无 TDZ(onContentChange :2032/scheduleStreamParse :912 均在前定义) ✅
-
:2039 watch(messages.length→onContentChange)不同源保留 ✅
-
待修项回流 todo: 无 🔴/🟡 项
CR-260618-06 SW-19 ToolCard combineOutputs 抽函数 + SW-20 Ideas parseTags 复用(工作区未提交·commit-policy-deferred·2 文件) — ✅ 已审(PASS·主代自测)
- 结论(2026-06-18·主代自测 + 独立 grep 核验源码形态): ✅ PASS — 🔴0 🟡0 ⚪0
- 验证: vue-tsc EXIT 0。
改动 2 项(2 文件):
| # | 项 | 判定 |
|---|---|---|
| 1 | SW-19 ToolCard.vue 抽 combineOutputs(stdout, stderr) 共享函数;combineAndTruncateLines + cmdOutput computed 都复用 |
✅ DRY 收敛,行为不变 |
| 2 | SW-20 Ideas.vue 删本地 parseTags(IdeaRecord),import stores/knowledge.ts parseTags;3 调用点改传 .tags | ✅ DRY 复用 store 版,签名收敛 |
独立核验(grep 源码形态):
-
ToolCard
combineOutputs定义 :463 + 调用 :472/:652 ✅ -
Ideas
parseTagsimport :214 + 调用 currentIdea.tags(:148/:149) / i.tags(:278) ✅ -
待修项回流 todo: 无 🔴/🟡 项
CR-260618-07 SW-08 AuditLog.vue i18n 化(工作区未提交·commit-policy-deferred·3 文件) — ✅ 已审(PASS·主代自测)
- 结论(2026-06-18·主代自测 + 独立 grep 核验 + i18n message 盲点检查): ✅ PASS — 🔴0 🟡0 ⚪0
- 验证: vue-tsc EXIT 0。
改动 3 项(3 文件):
| # | 项 | 判定 |
|---|---|---|
| 1 | 新建 src/i18n/en/auditLog.ts(auditLog 命名空间:title/refresh/desc/loading/empty + col×7 + pager×4 + risk×3 + status×6 + decided×2) | ✅ 对齐 ideas.ts 风格 |
| 2 | 新建 src/i18n/zh-CN/auditLog.ts(中文对应,index glob 自动聚合) | ✅ 中英对称 |
| 3 | AuditLog.vue 引入 useI18n + template 15 处文本 t() 化 + riskLabel/statusLabel/decidedLabel 改 t() | ✅ class 映射不国际化(保留),模式对齐 Dashboard/Knowledge/Ideas |
独立核验(vue-tsc + i18n message 盲点):
-
vue-tsc EXIT 0 ✅
-
useI18n 模式对齐项目现有(Dashboard/Knowledge/Ideas/ProjectDetail 同款
const { t } = useI18n())✅ -
message 值仅
{n}标准插值(page: '第 {n} 页'),无@//裸{}(避 prod runtime 报错盲点)✅ -
riskLabel/statusLabel/decidedLabel 未知值走 vue-i18n 默认 fallback,但 risk/status/decided 后端值固定不触发 ✅
-
待修项回流 todo: 无 🔴/🟡 项
CR-260618-08 SW-09 ai_node provider 三件套 DRY(工作区未提交·commit-policy-deferred·1 文件 df-nodes) — ✅ 已审(PASS·主代自测)
- 结论(2026-06-18·主代自测 + 独立 grep 核验源码形态): ✅ PASS — 🔴0 🟡0 ⚪0
- 验证: cargo check -p df-nodes EXIT 0(无 warning) / cargo test -p df-nodes 82 passed 0 failed 1 ignored(不回归)。
改动 4 处(1 文件 df-nodes/src/ai_node.rs):
| # | 项 | 判定 |
|---|---|---|
| 1 | 加 resolve_and_parse(db,config,inputs) 合并 resolve_provider+parse_params 两步 |
✅ AiNode/SelfReview 逐字重复消除 |
| 2 | 加 provider_from_params(&p) 封装 build_provider 5 行 |
✅ 同上 |
| 3 | AiNode execute :254-262(9 行)→ 2 行(resolve_and_parse + provider_from_params) | ✅ 行为零变化 |
| 4 | SelfReview execute parse(:465-466)+ build(:493-498)→ resolve_and_parse + provider_from_params(中间 task 读保留) | ✅ p 生命周期跨 task 读正确 |
独立核验(grep 源码形态 + 测试):
-
messages/temperature 差异不抽(AiNode 用 p.system_prompt/p.temperature;SelfReview 强约束 Some(0.0)+REVIEW_SYSTEM_PROMPT)✅
-
helper 仅收 provider 三件套,差异区各节点自有 ✅
-
原 resolve_provider/parse_params fn 保留(test 直接调用 :781+),helper 是上层封装非替代 ✅
-
待修项回流 todo: 无 🔴/🟡 项
CR-260618-09 UX-260618-04 前端删 cost/intel 标签(工作区未提交·commit-policy-deferred·4 文件) — ✅ 已审(PASS·主代自测)
- 结论(2026-06-18·主代自测 + 独立 grep 核验无残留): ✅ PASS — 🔴0 🟡0 ⚪0
- 验证: vue-tsc EXIT 0 / grep
tagCost|tagIntel全 src/ 无残留。
改动 4 处(4 文件):
| # | 项 | 判定 |
|---|---|---|
| 1 | ProviderPanel.vue 删 tag-cost/tag-intel 两 span(:114-115) | ✅ 模态/能力/探测源标签保留 |
| 2 | AiChat.vue modelOptionLabel 删 intel/cost 拼接,只返 label/model_id + 注释更新 | ✅ 下拉选项不再显示瞎猜档位 |
| 3 | i18n en/settings.ts 删 tagCost/tagIntel + 注释 4 维度→模态+能力 | ✅ |
| 4 | i18n zh-CN/settings.ts 同 | ✅ |
独立核验(自主裁决依据 + grep):
-
用户已全局决策去掉 cost/intel(B-260618-03 背景)→ 前端删标签是决策落地 ✅
-
grep 全 src/ 确认 tagCost/tagIntel 仅 ProviderPanel + AiChat 引用,删后无残留 ✅
-
ModelConfig.cost_tier/.intelligence 字段保留(后端 B-03 解耦后清),前端先删引用独立安全 ✅
-
i18n 删 key 非加,message 编译盲点不适用 ✅
-
待修项回流 todo: 无 🔴/🟡 项
CR-260618-10 6项编码批·router解耦cost/intel+model_probe去瞎填+executor TOCTOU+审批占位终态化+knowledge_events query+CostTier清理(workflow wexu1isx1·6 agent·主代修SW-02借用+核查·工作区未提交·commit-policy-deferred) — ✅ 已审(PASS·主代自测)
- 结论(2026-06-18·workflow wexu1isx1 + 主代 cargo/test/vue-tsc 全量验证 + 独立 grep 核验): ✅ PASS — 🔴0 🟡0 ⚪1
- 验证: cargo check --workspace EXIT 0(5 pre-existing dead_code warning,非本批) / cargo test df-ai 109 passed 0 failed / cargo test df-ai-core 24 passed / cargo test df-workflow 23 passed / cargo test df-storage 全 passed / vue-tsc EXIT 0。
6 项逐项核验:
| # | 项 | 判定 |
|---|---|---|
| 1 | B-03 router 解耦:TaskRequirements 删 min_intelligence/max_cost + select 删步骤4/5 filter + max_by_key 纯 weight 删 Reverse + 9 调用点删传参 + import 清理 + test 改写(删3用例 112→109 + all_dimensions 改 d 胜) | ✅ 主代 grep 核验 min_intelligence/max_cost 代码层 0 残留(仅注释 3 处) |
| 2 | B-04 model_probe 去瞎填:heuristic_infer cost/intel 中性默认 Medium/Standard + presets/models.json 17条删两字段 | ✅ 功能维度 modalities/capabilities 保留,中性默认对齐 Default impl |
| 3 | B-05 CostTier::Free 清理:删 Free 变体 + test 同步 + 主代补前端 types.ts 删 'free' 对齐 | ✅ grep CostTier::Free 代码 0 残留(仅 todo 任务条目) |
| 4 | SW-01 executor TOCTOU:Ok 分支 emit NodeCompleted 移入 !is_cancelled + 取消 emit NodeCancelled 对齐 Err + outputs.insert 保留(不中止后续) | ✅ cargo test df-workflow 23 passed(test_cancelled_node_skips/emits 不回归) |
| 5 | SW-02 审批占位终态化:finalize_pending_placeholders helper + 5 处 .clear() 前替换终态 | ✅ 主代修 agent E0502 借用冲突 + cargo check EXIT 0 |
| 6 | SW-04 knowledge_events query:KnowledgeEventsRepo::list_recent ORDER BY timestamp 兜底 | ✅ 新方法预防性(无活跃调用方),df-storage test passed |
主代核查·审查防污染印证:
-
workflow agent 全按铁律不跑 cargo(只 grep 自验)。SW-02 agent riskNote 第4点预判"disjoint field borrow 应无问题"错误 —— 主代 cargo check 捕 5 个 E0502(函数参数列表不做 disjoint 推断,只在函数体内合法)。主代修 helper 签名
&mut AiSession整体(函数体内 disjoint)+ 调用点&mut *session(DerefMut 解 guard)。印证:agent 不跑 cargo 的 riskNote 是猜测,主代 cargo 必验(同 Sprint 22 教训)。 -
B-03 agent 自验 grep 0 残留准确(主代独立 grep 印证)。
-
df-ai test 109 = 112 - 3(B-03 删 intelligence_below_min/max_cost_filters/max_cost_none 3 用例)对齐。
-
B-05 riskNote 标注前端 types.ts 'free' 未同步 → 主代补删对齐 Rust(防 DB "free" 值反序列化边界 + 类型宽松)。
-
⚪ WATCH-1: B-03 行为变更 —— title/compress 失去 max_cost 约束后纯 weight 选模型,同 weight 并列时 max_by_key 返回最后一个(rust Iterator 语义,池顺序决定)。需用户核对 Settings weight 配置合理(用户已全局决策接受,核对 weight 即可)。
-
待修项回流 todo: 无 🔴/🟡 项
CR-260618-11 batch69 全面走查(53文件+1373/-2890:6域全量·Workflow wf_8f2a96d3-dc7·5路并行+安全扫描+主代独立核验降级) — ✅ 已审(ISSUES·🔴1🟡4⚪4) → 🔴已修(主代闭环 2026-06-18)
- 结论(2026-06-18·Workflow 5路并行 + 主代独立 grep/read 核验 + High 项逐条源码佐证降级): ⚠️ ISSUES — 🔴1 🟡4 ⚪4
- 验证: git diff HEAD 53 文件 / cargo check --workspace EXIT 0 / vue-tsc EXIT 0 / DOMPurify 覆盖确认
🔴 必须修复 (1):
| # | file:line | 问题 | 修复 |
|---|---|---|---|
| 1 | commands.rs:289 |
ai_approve 幂等路径仍 unwrap_or_default 吞 DB 错 — audit.rs 已修(B-260617-17 同款 match 三路分流),但 commands.rs:290 find_by_tool_call_id(...).await.unwrap_or_default() 仍在。DB 故障时 Err→None→返回「未找到挂起审批」误导用户 |
对齐 audit_finalize 模式: match { Ok(Some)→rec, Ok(None)→return Err, Err(e)→error!+return Err } |
🟡 建议改进 (4):
| # | file:line | 问题 | 建议 |
|---|---|---|---|
| 2 | context.rs:57 |
base64 chars().count() × 0.35 显著高估图片 token(OpenAI 按像素非字节),含图消息被过度裁剪 | 加注释说明偏保守粗估,或降至 0.10~0.15 |
| 3 | types.ts:207 |
IntelligenceTier i18n 标签同删但无注释说明(CostTier 有注释 rationale) | 加注释对齐 UX-260618-04 决策记录 |
| 4 | types.ts:303 |
AiMessage.role 新增 'system',前端 .role === / switch 完备性待全量验证 |
grep 全 src/ 确认无路径将 system 当 user 可编辑/可发送 |
| 5 | audit.rs:478 |
find_cached_high_risk_result N 次串行 DB 查询在 session lock 内,High risk 工具多时锁持有线性增长 | 批量预取或文档标注瓶颈防后续加重量级 IO |
⚪ 可选优化 (4):
| # | file:line | 问题 |
|---|---|---|
| 6 | provider.rs:134 |
now_millis_i64 i64 截断理论可能(实际 i64::MAX=2920亿年不触发),unwrap_or(0) 兜底值语义不纯 |
| 7 | AiChat.vue:414 |
v-if/else-if 链未知 role 落入 AI 分支(后端可控,既有逻辑) |
| 8 | tool_registry.rs:111 |
Path Traversal Unicode/8.3/ADS 绕过盲区(Tauri 桌面+审批双防线,门槛高) |
| 9 | AiChat.vue:423 |
system 消息 v-html XSS 向量(已确认 useMarkdown.ts:192 _purify.sanitize() 覆盖,DOMPurify 默认配置防 script/iframe/object) |
主代核验印证(防污染):
-
H2 🔴 确认:
commands.rs:290grep 命中unwrap_or_default(),与 audit.rs 修复口径不一致 ✅ -
H4/H8 XSS 降级🟡:
useMarkdown.ts:192确认_purify.sanitize(_marked.parse(wrapped))覆盖所有角色(含 system) ✅ -
H1 截断 降级⚪: i64::MAX = 9.22×10¹⁸ ms ≈ 2920 亿年后,当前 1.7×10¹² ms 远在范围内 ✅
-
H9 Path Traversal 降级🟡: Tauri 桌面应用非网络服务 + High risk 审批双重防线 ✅
-
待修项回流 todo: 🔴 1 项 (commands.rs:289 ai_approve 吞错修复)
主代修复闭环(2026-06-18·workflow w999qdu86 3 agent + 主代核查):
- 🔴1 BUG-260618-11 已修:commands.rs:289-303 ai_approve None 分支 match 三路分流(Ok(Some)→状态判断 / Ok(None)→未找到 / Err(e)→tracing::error+明确 DB 故障 Err),对齐 audit.rs audit_finalize。原 unwrap_or_default 已消。行为变更:DB 故障现返「查询审批记录失败(DB 故障),请重试」明确错误(原误为「未找到挂起」),同属 Err 分支语义不变。
- 🟡4 处理:#2 context.rs:56 chars_ratio 0.35 加注释标注偏保守(值未变,降值属行为变更本次不做) / #3 types.ts:209 IntelligenceTier 加注释对齐 CostTier + UX-260618-04 决策 / #5 audit.rs:402 find_cached_high_risk_result 加性能注记(session lock 内串行 DB 查询线性增长,批量预取架构改暂未做) / #4 system role 完备性 grep 核验 PASS(14 处 role 赋值全 user/assistant 无 system;2 处比较点 AiChat.vue:421/2545 只读渲染;发送路径仅 push user/assistant,system 不可编辑不可发送)
- 主代核查:cargo check --workspace EXIT 0(4 pre-existing dead_code warning 基线)+ vue-tsc EXIT 0 + 独立 grep 印证 agent selfCheck 无污染
- 🔴1 待修项已闭环,todo BUG-260618-11 已销账
CR-260618-12 ToolCard.vue 工具结果渲染 8 项(workflow w2drz3ppo·8 agent 并行核验 isReal 8/8+主代统筹实施·工作区未提交·commit-policy-deferred) — ✅ 已审(PASS·主代自测)
- 结论(2026-06-18·workflow w2drz3ppo 8 agent 并行核验 + 主代统筹实施 + vue-tsc 全量验证 + 独立 grep 核验): ✅ PASS — 🔴0 🟡0 ⚪1
- 验证: vue-tsc --noEmit EXIT 0 / grep 印证 ToolCard.vue 22 处新字段 + i18n 18 处新 key 全落地。
8 项实施(主代统筹:合并冲突/修死代码位置/补漏字段):
| # | 项 | 判定 |
|---|---|---|
| 1 | UX-05 run_workflow 显 execution_id(formatToolResult+toolResultSummary 加 case,删误导 workflowHint,旧 key 保留防引用) | ✅ |
| 2 | UX-06 patch_file 模板分支渲染 diff 红绿行(复用 ai-tool-diff-pre)+resultDiffLines computed(parsed.diff 截断 120 行) | ✅ |
| 3 | UX-07 delete_file 软删补 backup_path(formatToolResult+toolResultSummary+i18n 加槽) | ✅ |
| 4 | UX-08 read_file 模板 has_more 显「shown/total 行,已截断」 | ✅ |
| 5 | UX-09 advance_task 加 review_rounds(>0 显退回累加) | ✅ |
| 6 | UX-10 list_trash(被 UX-12 list_* 重写吸收,无独立改动) | ✅ 吸收 |
| 7 | UX-11 list_directory truncated 显截断提示 | ✅ |
| 8 | UX-12 list_* 重写修 Array.isArray 对象误判+结构化列表+file_info modified+write_file old_size/encoding+rename_file cross_volume/bytes_moved | ✅ |
主代统筹裁决(审查防污染,不盲应用 agent edits):
- 冲突吸收:UX-10/12 都加 list_trash case + trashCount(文案冲突),采纳 UX-12(修 Array.isArray 对象误判真实 bug——后端返 {items,total,has_more} 对象非数组,原判断恒 false 致折叠态无计数),UX-10 整条吸收
- 死代码位置修正:write_file 有专属模板分支拦截,formatToolResult write_file case 不触发;old_size/encoding 改模板分支(主渲染路径)非 agent 建议的 formatToolResult case
- type 去重:12 缺字段合并 ToolResult type 一处 Edit(agent 说缺 truncated/review_rounds/bytes_moved 实际已有,只补真缺)
- task_id 漏列拦截:UX-05 agent 用 r.task_id 但 typeFieldAdditions 漏,vue-tsc 拦 TS2339,主代补 task_id(印证 agent edits 自身不一致,vue-tsc 必验)
审查防污染印证:8/8 isReal=true,每份 selfCheck 独立 grep tool_registry.rs 后端返回印证。todo line 号漂移(diffLines agent 说 :678 实际 :696)被主代 Read 核验拦截。单文件域 ToolCard.vue 主代统筹实施(避免并行冲突),workflow 价值在 8 工具并行核验 fan-out + 审查防污染独立核验。
- ⚪ WATCH-1: list_directory/list_* 截断文案硬编码 {n:1000}(后端 tool_registry.rs:880 max_entries=1000),后端上限变更需同步前端文案
- 待修项回流 todo: 无 🔴/🟡 项
CR-260618-13 SMELL-P0-1吞错降级加warn+B-260618-06表格CSS+coordinator空壳评估(workflow w5siwnipj·6 agent并行核验+主代统筹实施·工作区未提交·commit-policy-deferred) — ✅ 已审(PASS·主代自测)
- 结论(2026-06-18·workflow w5siwnipj 6 agent 并行核验 + 主代统筹实施 + cargo/vue-tsc 全量验证 + 独立 grep 核验): ✅ PASS — 🔴0 🟡0 ⚪1
- 验证: cargo check -p devflow EXIT 0(4 pre-existing dead_code warning 基线:PendingApproval/state 字段,非本批) / vue-tsc --noEmit EXIT 0。
4 项实施(主代统筹)+ 2 项 no-action:
| # | 项 | 判定 |
|---|---|---|
| 1 | B-260618-06 markdown 表格 display:block CSS(ai-md.css:59 全局根因 + AiChat.vue:3366 局部) | ✅ 两处移除 display:block/overflow-x:auto,table 恢复 display:table 列对齐,气泡 .ai-msg-bubble--ai.ai-md overflow-x:auto 承载宽表格滚动 |
| 2 | SMELL-P0-1 agentic.rs:348 provider 池吞错 | ✅ match + tracing::warn 降级(空 Vec 走原空池兜底零行为变更) |
| 3 | SMELL-P0-1 knowledge_inject.rs:130,139,312 检索/解析吞错 | ✅ 三处 match + tracing::warn 降级(空 Vec 不注入/提炼跳过零行为变更) |
| 4 | SMELL-P0-1 idea.rs:292-296 tags JSON 解析吞错 | ✅ match + tracing::warn 降级(空 tags 继续评估,tags 影响 scoring ±0.5~1.5 但评估不应因坏 tags 阻塞) |
| 5 | SMELL-P0-1 audit.rs:344(吞错) | ❌ 误报 no-action(audit_finalize CR-260618-11 已修三路 match,line 漂移+旧版本) |
| 6 | SMELL-P2-4 coordinator.rs 空壳 | ❌ no-action(line 3 模块注释已有「⚠ B 路线占位...勿删」标注齐全,零外部调用,保留 B 路线预留点) |
主代统筹裁决(审查防污染,独立 grep 核验 agent selfCheck):
-
agent selfCheck 6/6 准确(主代独立 Read ai-md.css/knowledge_inject.rs/idea.rs 印证 currentCode 逐字无误,behaviorChange=false 判定可信:加 warn 不改返回值,空 Vec 仍走原降级路径)
-
audit 误报印证审查防污染价值:todo line 声明 audit.rs:344 吞错,独立 grep 核验实为 CR-11 已修的三路 match(:337-347),unwrap_or_default 仅剩 :274(from_str)/:499(to_string)非 DB——line 漂移+旧版本双重原因,workflow agent 独立核验拦截
-
CSS 方案主代补强:agent 建议全局 ai-md.css 移除 display:block,主代核验确认全局影响面(ProjectDetail/Ideas/Knowledge/TaskDetail 同引用),宽表格滚动仅 AiChat 气泡场景需补 overflow,其他页 markdown 表格少宽表可接受;采纳 agent 核心理念(移除 display:block 恢复列对齐)+ 主代补 AiChat 气泡 overflow-x:auto
-
⚪ WATCH-1: SMELL-P0-1 58 处 unwrap_or_default 全量排查降 P2(5 高危已清,余为 Option 取默认/JSON 序列化等低危,非紧急)
-
待修项回流 todo: 无 🔴/🟡 项
CR-260618-14 安全并行批·df-execute补测试+前端ErrorBoundary+6篇文档实施状态标注+executor run评估(workflow wowdnw4ba·5 agent并行·主代独立核验·工作区未提交·commit-policy-deferred) — ✅ 已审(PASS·主代自测)
- 结论(2026-06-18·workflow wowdnw4ba 5 agent + 主代 cargo/test/vue-tsc 全量验证 + 独立 grep 核验): ✅ PASS — 🔴0 🟡0 ⚪1
- 验证: cargo check --workspace EXIT 0 / cargo test -p df-execute 5 passed 0 failed / vue-tsc --noEmit EXIT 0。
5 项逐项核验:
| # | 项 | 判定 |
|---|---|---|
| 1 | SMELL-P0-4 df-execute 补测试(tests/shell.rs 5 #[tokio::test] 覆盖成功/非零退出/超时/env注入/working_dir + shell.rs:55 过时TODO注释清理) | ✅ execute逻辑零改动,主代 cargo test 5 passed |
| 2 | SMELL-P2-2 前端 ErrorBoundary(main.ts app.config.errorHandler + ErrorBoundary.vue onErrorCaptured 降级UI+重试 + i18n error.ts×2 中英对称) | ✅ 未嵌入仅提供能力,App.vue 未改零行为变更 |
| 3 | SMELL-P1-8 文档组1(B-03/AiNode自审/类型对齐 3篇加「实施状态(2026-06-18核对)」标注段) | ✅ 不改设计正文,DOC2 行号经独立 grep 修正 |
| 4 | SMELL-P1-8 文档组2(F-01 标 cost/intel 解耦改方向/F-05 标数据模型偏离/secret下沉 标方案B全落地) | ✅ router.rs:27-35/56-63 + provider.rs:97/105-106 file:line 佐证 |
| 5 | SMELL-P2-1 executor run 重构评估 | ✅ no-action(SMELL描述过时:run方法实测 151行+2参 非描述282行+8参,SW-01 TOCTOU保留 line 136/138-153,描述系历史形态) |
主代核查·审查防污染印证:
-
df-execute tests: cargo check --workspace 默认不编译 tests target,主代补 cargo test -p df-execute 验证 5 测试编译+逻辑双通过(防 check 假绿)。
-
executor no-action 印证铁律价值:agent 现场读源码发现 SMELL-P2-1 描述(282行+8参)系历史形态,当前 run 方法 151行+2参已可接受,不盲改(避免动 SW-01 TOCTOU 敏感逻辑引入回归)。源码形态 > todo 描述。
-
6 篇文档标注段独立 grep 核验全在(line 7-11),file:line 佐证真实。ErrorBoundary.vue onErrorCaptured:21 + main.ts errorHandler:12 grep 命中。
-
⚪ WATCH-1: ErrorBoundary.vue 当前未嵌入任何组件树(仅 main.ts errorHandler 全局兜底生效),后续需包裹易错子树时按需引入(零行为变更设计意图)
-
待修项回流 todo: 无 🔴/🟡 项
CR-260618-15 B-260618-23最大轮次修法B+SMELL-P1-2/P1-3样板消除评估(workflow wuirgcxoy·3 agent·主代独立核验·工作区未提交·commit-policy-deferred) — ✅ 已审(PASS·主代自测)
- 结论(2026-06-18·workflow wuirgcxoy 3 agent + 主代 vue-tsc 验证 + 独立 grep 核验): ✅ PASS — 🔴0 🟡0 ⚪1
- 验证: vue-tsc --noEmit EXIT 0(B-260618-23 前端) / P1-2/P1-3 no-action 无 rust 改动 cargo 不需。
3 项逐项核验:
| # | 项 | 判定 |
|---|---|---|
| 1 | B-260618-23 Agentic 最大轮次修法 B(App.vue:215-224 onMounted loadAll 后加 setAgentMaxIterations/setAgentMaxRetries 恢复同步 clamp 对齐 GP + GeneralPanel:266 双保险) | ✅ done 修bug正向,主代 vue-tsc EXIT 0 |
| 2 | SMELL-P1-2 .map_err 抽 helper | ✅ no-action(前提过时:err_str helper 已存在 mod.rs:23·纯 to_string 样板 0 残留·101 处已用 err_str·主代 grep 印证) |
| 3 | SMELL-P1-3 useTauriCommand composable | ✅ no-action(前提不成立:views 仅 AuditLog:102 直接 invoke·invoke 已统一 api 层·try-catch 副作用异构·主代 grep 印证) |
主代核查·审查防污染印证:
-
两 no-action 印证源码形态 > todo 描述:agent 现场读源码发现 err_str helper 早前已落地(P1-2)、invoke 已统一 api 层(P1-3),不盲改。主代独立 grep 印证:err_str 在 mod.rs:23 / to_string 残留仅 mod.rs:22 注释字面量 / views invoke 仅 AuditLog:102。
-
B-260618-23 修 bug 行为变更正向(重启后正确恢复持久值),clamp 边界与 GeneralPanel 逐字对齐(Math.min(50,Math.max(1,||10)) / Math.min(10,Math.max(0,??3))),GeneralPanel onMounted sync 保留双保险(IPC 幂等)。
-
⚪ WATCH-1: B-260618-23 修法 B 依赖 appSettings SQLite 持久化(前端已落 DB),重启后 App.vue loadAll 读真值同步后端。若用户报告仍未生效,查后端 set IPC 是否真落 AtomicUsize + loadAll 是否在发消息前完成
-
待修项回流 todo: 无 🔴/🟡 项
CR-260618-16 SMELL-P1-1 crates/全域unwrap排查+P1-4聚合评估+P2-3死字段评估(workflow w8774xcev·7 agent·主代独立核验·工作区未提交·commit-policy-deferred) — ✅ 已审(PASS·主代自测)
- 结论(2026-06-18·workflow w8774xcev 7 agent + 主代 cargo/test 验证 + 独立 grep 核验): ✅ PASS — 🔴0 🟡0 ⚪2
- 验证: cargo check --workspace EXIT 0 / cargo test -p df-workflow EXIT 0(dag 注释不影响)。
7 项逐项核验:
| # | crate | 判定 |
|---|---|---|
| 1 | df-ai-core+types | ✅ no-action(31处unwrap全#[cfg(test)],生产零危险) |
| 2 | df-ai | ✅ no-action(21处全测试,2处生产expect已注释不变量 context:499/model_probe:34) |
| 3 | df-storage | ✅ no-action(~50处全测试,全程?+map_err健康) |
| 4 | df-workflow | ✅ done(dag.rs:106/135两处运行时unwrap加safe注释,SW-01保留) |
| 5 | df-execute | ✅ no-action(unwrap零)+P2-3评估(env死字段5构造点全空HashMap) |
| 6 | df-nodes | ✅ no-action(75处全测试)+P1-4评估(缓做)+P2-3评估(NodeOutput.metadata死字段) |
| 7 | df-ideas+project | ✅ no-action(49处全测试) |
主代核查·审查防污染印证:
-
unwrap 排查绝大多数 no-action 印证 crates/ 错误处理已健康(之前多批重构清理):生产 unwrap 全在 #[cfg(test)] 或已是安全 expect/unwrap_or。仅 df-workflow dag.rs 加 2 处 safe 注释。主代独立 grep 核验 dag.rs:106/135 注释存在 + SW-01 TOCTOU(:136/141/150/163-166)完整保留。
-
P2-3 描述错误修正:todo:185 写「NodeContext.metadata」有误,源码为准 NodeContext(node.rs:13-26)无 metadata 字段,含 metadata 的是 NodeOutput(node.rs:34)且是死字段(2构造点初始化空+0消费)。ShellRequest.env 同死字段。源码形态 > todo 描述。
-
P1-4 评估:df-nodes 拆 df-task-state-machine 缓做(task_state_machine.rs 零 crate 依赖+单一消费者+拆出不解锁循环依赖,收益不抵成本)。
-
⚪ WATCH-1: crates/ 生产 unwrap 仅 df-workflow 2 处加注释,若未来新代码引入生产 unwrap 需重新评估
-
⚪ WATCH-2: NodeOutput.metadata + ShellRequest.env 均死字段(0消费),如需清理建议直接删字段(降级方案)或改结构体(纯整洁低优先)
-
待修项回流 todo: 无 🔴/🟡 项
CR-260618-17 SMELL-P1-7 bool评估+P1-5下沉评估+NodeOutput.metadata实删+ShellRequest.env评估(workflow weckqp9mv·4 agent·主代独立核验·工作区未提交·commit-policy-deferred) — ✅ 已审(PASS·主代自测)
- 结论(2026-06-18·workflow weckqp9mv 4 agent + 主代 cargo 验证 + 独立 grep 核验): ✅ PASS — 🔴0 🟡0 ⚪1
- 验证: cargo check --workspace EXIT 0(4 warning 全 pre-existing dead_code 基线·非本次引入)。
4 项逐项核验:
| # | 任务 | 判定 |
|---|---|---|
| 1 | SMELL-P1-7 | ✅ no-action(enum 负收益·bool 直映射 DB·2 crud+2 IPC 调用者紧邻定义·真正歧义前端 store 拆 TS 方法非推 enum·IPC 引 enum 触 Tauri 序列化 prod 报错) |
| 2 | SMELL-P1-5 | ✅ no-action(advance_task_atomic 已领域层 df-nodes/task_advance_node.rs:43·3 IPC 纯转发✅;record_to_idea 下沉违反依赖倒置·df-ideas→df-storage 倒依赖·IPC 是 adapter 正确归属) |
| 3 | NodeOutput.metadata | ✅ done(实删 node.rs 字段+2 构造点 empty()/from_value()·0 消费者·零行为变更) |
| 4 | ShellRequest.env | ✅ no-action(前提错·测试 #4 execute_env_injection 实塞 KV 透传子进程验证·活跃消费链非死字段) |
主代核查·审查防污染印证:
-
4 项 3 个 no-action 印证代码库健康。仅 NodeOutput.metadata 实删(纯死代码零消费)。主代 grep 核验 node.rs struct 仅 data 字段 + empty/from_value 唯二构造。
-
P2-3 深化:批次3 评估为「保留或删·低优先」,批次4 实删 metadata(env 经核为活跃消费链保留)。
-
⚪ WATCH-1: 其他会话并发改主代码,本核查为 cargo check 快照·源码形态可能已变(memory review-batching-worktree-transient 教训)
-
待修项回流 todo: 无 🔴/🟡 项
CR-260618-18 UX-260618-13 stripMd 列表摘要 MD 剥离(主代串行·规避 AiChat God 文件·工作区未提交·commit-policy-deferred) — ✅ 已审(PASS·主代自测)
- 结论(2026-06-18·主代串行实施 + vue-tsc 验证): ✅ PASS
- 验证: vue-tsc EXIT 0。
改动:
- 新建
src/utils/markdown.tsstripMd(剥离粗体/斜体/删除线/标题/行内代码/代码块围栏/列表/引用/链接/图片等 MD 语法·保留文字内容·空输入返空串)。 Knowledge.vue:71(item.content) /Projects.vue:148(project.description) /Ideas.vue:47(idea.description slice) 三列表摘要接入 stripMd。- 修自引入 bug:首版注释含
*/子序列(**/__/*)致 JSDoc 块注释提前闭合 → TS1011/1127·改安全中文措辞。
主代自测·审查防污染:
-
AiChat 标题 strip 子项(待核 title.rs)规避 God 高频文件·留待并发期后。
-
前端纯新增 util + 单行插值·vue-tsc EXIT 0 独立核验。
-
待修项回流 todo: 无 🔴/🟡 项
CR-260618-19 idea.rs:111 promoted_to is_some+unwrap 改 if let Some(Explore2 巡查核验真项·主代串行·工作区未提交·commit-policy-deferred) — ✅ 已审(PASS·主代自测)
- 结论(2026-06-18·主代串行 + cargo 验证 + 独立 grep 核验): ✅ PASS
- 验证: cargo check --workspace EXIT 0(4 warning 全 pre-existing dead_code 基线·非本次引入)。
- 改动:
promote_idea中if record.promoted_to.is_some() { return Err(format!("灵感已立项: {}", record.promoted_to.unwrap())); }→if let Some(promoted_to) = &record.promoted_to { return Err(format!("灵感已立项: {}", promoted_to)); }。消除is_some()守卫后冗余二次unwrap·改借用·零行为变更。
主代核查·审查防污染印证:
-
Explore2 开放式扫 5 候选·独立 grep 核验后仅此项真:script_node.rs:46
unwrap_or(-1)已安全不 panic(注释 ROI 低) / AuditLog.vue:96 误判(空数据 length=0≠PAGE_SIZE→hasMore 正确 false) / Tasks.vue:144 projectFilters 与 getProjectName 不同用途非重复 / ConnectionPanel.vue 文件不存在(Explore2 虚构)。防污染拦下 4 误报·命中率 20%。 -
待修项回流 todo: 无 🔴/🟡 项
CR-260618-20 批次6 测试补测 scan/router/migrations(workflow w07wahoti·3 agent 并行·零行为变更·主代 grep 核验测试数一致·工作区未提交·commit-policy-deferred) — ✅ 已审(PASS·主代核验)
- 结论(2026-06-18·workflow w07wahoti 3 agent + 主代 grep 核验): ✅ PASS
- 3 crate 补测·零行为变更(只加
#[cfg(test)] mod·不改生产):- df-project scan.rs +10(normalize_path 跨平台×3 / is_monorepo workspaces:null 防回归×3 / collect_images 徽章过滤×4)·agent 自报 cargo test 25 passed
- df-ai router.rs +3(多模态子集[Text,Vision]过滤 / enabled=false 混池 / 空池 select() 返 None)·自报 112 passed
- df-storage migrations.rs +4(column_exists 列存在/不存在/表不存在/精确匹配·:memory: SQLite)·自报 33 单测+11 集成
- 主代 grep 核验(防污染·源码形态 > check 快照·memory review-batching-worktree-transient):scan.rs
#[test]=25(15旧+10新✅) / router.rs=15(12旧+3新✅) / migrations.rs=4(新增✅)·与 agent 自报全一致。
主代核查·审查防污染印证:
-
零行为变更:cfg(test) 隔离·concurrent 会话改生产不影响 test 编译。agent 三段式自验 cargo(memory workflow-cargo-timeout-wrap)·grep 测试数一致强佐证。
-
测试路 Explore 10 候选核验:shell.rs 批次1 已覆盖(过时) / human_node reject 已充分覆盖(:833-848·低估) / adversarial 有 mod tests(错报 0) / ai_tools+migrations+前端utils 真 0。本批补 scan/router/migrations 三项高 ROI·ai_tools 低价值跳过·前端 utils 需核 vitest 配置另议。
-
待修项回流 todo: 无 🔴/🟡 项
CR-260618-21 ai_tools 补 6 sync test + risk_level 前端核验(主代串行·工作区未提交·commit-policy-deferred) — ✅ 已审(PASS·主代自测)
-
结论(2026-06-18·主代串行 + cargo test 验证): ✅ PASS
-
验证: cargo test -p df-ai ai_tools::tests 6 passed(112 filtered·现有测试零冲突)。
-
ai_tools.rs +6 sync test(零行为变更·只加
#[cfg(test)] mod):- risk_level_serde_lowercase(Low/Medium/High→"low"/"medium"/"high"·serde rename_all 验证)
- register_and_get_tool(注册后可查·不存在返 None·len/is_empty)
- register_same_name_overwrites(同名二次注册 HashMap insert 覆盖语义·后注册 risk_level 胜出)
- tool_definitions_and_names(注册后 definitions/names 列表正确)
- default_is_empty(Default trait 空注册表)
- object_schema_collects_required(required 字段收集·is_required true 入 required)
-
risk_level 前端核验:
src/api/types.tsgreprisk_level0 命中 → 后端PendingApproval.risk_level(mod.rs:410)经 IPC 序列化但前端不消费 → 真死(坐实 SW-260618-21 risk_level 项·佐证选项 a 清理可行)。注:diff活跃(:258 AiApprovalRequired + :328 ToolResult·UX-260618-06)非死。 -
待修项回流 todo: 无 🔴/🟡 项
CR-260618-22 PendingApproval.risk_level 死字段删(主代串行·多角度分析确定推进·工作区未提交·commit-policy-deferred) — ✅ 已审(PASS·主代自测)
- 结论(2026-06-18·主代串行 + cargo check 验证 + 独立 grep 核验): ✅ PASS
- 验证: cargo check --workspace EXIT 0(
PendingApproval.risk_leveldead_code warning 消失·剩diff+releases/node_executions基线)。
多角度分析·确定推进:
- 字段死坐实:前端
types.tsrisk_level0 命中(前端不消费)·后端 cargo dead_code 报 never read·0 读取消费者。 - 删波及可控:recover_pending 过滤语义保留(改
if risk_from_str().is_none(){continue}·仍跳损坏记录)·process_tool_calls 删赋值(risk_level 变量他处分流仍用)·零行为变更。
改动:
mod.rs:410删pub risk_level: RiskLevel字段 +:45删use df_ai::ai_tools::RiskLevelimport(删字段后 unused)。audit.rs:282recover_pending 删risk_level: risk赋值 +:275过滤改if risk_from_str(&rec.risk_level).is_none() { continue }(语义保留)。audit.rs:671process_tool_calls 删risk_level,赋值(risk_level 变量他处分流仍用)。
主代 grep 核验(防污染):
-
AuditRecord.risk_level(audit.rs:71·:115 序列化返 AuditLog)活跃保留。 -
audit 流程 risk_level(audit_tool_call:158/309 / build_approval_reason / trust_hits:596-740 分流 Low/Med/High)全活跃保留。
-
PendingApproval 构造的 risk_level 赋值(:282/:671)全删·grep 确认。
-
待修项回流 todo: 无 🔴/🟡 项
CR-260618-23 SW-260618-21 b 预留功能标 allow 消 dead_code warning(主代串行·自主决策 b·工作区未提交·commit-policy-deferred) — ✅ 已审(PASS·主代自测)
-
结论(2026-06-18·主代串行 + cargo check 验证): ✅ PASS·cargo check --workspace EXIT 0 0 warning(原 4 dead_code 全消)。
-
自主决策 b(保留+标 allow):5 处预留/IPC 字段标
#[allow(dead_code)]+ 注释预留意图·零波及消 warning:SessionStateenum(mod.rs:172)+session_statefn(:393):预留读视图(SW-02 类终态化复用·0 消费者保留扩展点)AppState.releases(state.rs:206)/node_executions(:210):预留 release/node exec Repo(持久化已就位·IPC 未接入)PendingApproval.diff(mod.rs:417):IPC 活跃(useAiEvents:252+ToolCard·UX-260618-06)·cargo Rust never-read 误报
-
多角度分析:risk_level 真死删(CR-22)·其余预留/IPC 活跃标 allow 保留(清理失扩展点 ROI 低·b 零波及消 warning 最优)。
-
待修项回流 todo: 无 🔴/🟡 项
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_registry1091→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.tsrestoreUiState去export(零外部调用) ·markdown.tsstripMd 围栏正则[a-zA-Z]*→[^\n]*(吃任意 infostring 如 rust,norun) ·time.tsformatDate读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.rsis_non_chat_model删|| id.contains("-search")(误剔合法 search-augmented chat 模型 gpt-4o-search-preview·davinci-search 仍覆盖旧变种)+ 补单测is_non_chat_model_keeps_search_augmented_chat。
- God 拆分 a(SMELL-P0-2):
- 验证:
cargo check --workspaceEXIT 0(0 warning) /cargo test df-ai119 passed /cargo test -p devflow test_build_ai_tool_registry_baseline_tool_count1 passed /vue-tscEXIT 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:44formatDate 漏.value(Agent C 铁证):legacy:falsecomposition 模式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:19stripMd 围栏正则边缘回归:[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 体 0registry.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.rskeyring 3 处错误带 provider id(entry_for/set/delete) ·df-execute/shell.rs:102超时消息带命令名 ·tool_registry.rs run_commandtimeout_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)。
- wo7d6zdqm 错误消息/安全(主代实施):
- 验证:
cargo check -p devflow -p df-storage -p df-executeEXIT 0 /vue-tscEXIT 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(可选·非必修):
Knowledge.vue submitCreate(:438)/ProjectDetail.vue handleApproval(:417) 缺显式if(submitting) return入口 guard(其余 5 处有)。实际防并发由模板:disabled="submitting"兜住(按钮点不动·无重入),IPC 路径单调用,风险极低。可选补 guard 对齐范式一致性。ConnectionPanel.vue saveConn(:152) 是同步函数(无 await),submitting try/finally 同步置位即复位,此处 submitting 实际无防双击语义(纯占位/视觉)。无功能影响,可选移除或改 async。
已审归档
已审 CR 段迁独立文件: 待审查归档/2026-06.md