整理: docs 走查报告归档(walkthrough-2026-08 合并到 05-代码审查,删重复/空目录)
- 我的走查 5 文件(summary/nodes/ai_storage/ideas_frontend/infra)移 05-代码审查/(claude- 前缀区分 DevFlow AI) - DevFlow AI 重复 3(00/04/05,与 05-代码审查/00-05 同主题)删 - walkthrough-2026-08/ + architecture/(空)删
This commit is contained in:
@@ -1,159 +0,0 @@
|
|||||||
# DevFlow 全量代码走查汇总报告
|
|
||||||
|
|
||||||
> 走查日期: 2026-08-02
|
|
||||||
> 范围: 12 个 crate, ~80 文件, ~1.2MB 源码
|
|
||||||
> 走查方式: 逐文件全量阅读 + 交叉引用 + 自动化分析
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 走查覆盖
|
|
||||||
|
|
||||||
| 模块 | 文件数 | 代码量 | 报告 |
|
|
||||||
|---|---|---|---|
|
|
||||||
| df-nodes(节点) | 17 | ~280KB | 01 ✅ |
|
|
||||||
| df-workflow(工作流引擎) | 11 | ~108KB | 02 ✅ |
|
|
||||||
| df-ai + df-ai-core(AI 核心) | 30 | ~555KB | 03 ✅ |
|
|
||||||
| df-storage(存储层) | 7 | ~150KB | 04+05 ✅ |
|
|
||||||
| df-ideas(灵感评估) | 7 | ~63KB | 04 ✅ |
|
|
||||||
| df-mcp(MCP Server) | 3 | ~52KB | 04 ✅ |
|
|
||||||
| df-execute(命令执行) | 2 | ~34KB | 04 ✅ |
|
|
||||||
| df-relay(云中继) | 5 | ~30KB | 05 ✅ |
|
|
||||||
| df-tunnel(隧道) | 3 | ~28KB | 05 ✅ |
|
|
||||||
| df-project(项目管理) | 3 | ~21KB | 05 ✅ |
|
|
||||||
| df-types(类型定义) | 3 | ~42KB | 05 ✅ |
|
|
||||||
| **总计** | **~91** | **~1.4MB** | **5 份报告** |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 问题汇总(按等级)
|
|
||||||
|
|
||||||
### 🔴 P0(7 个)
|
|
||||||
|
|
||||||
| # | 模块 | 文件 | 简述 |
|
|
||||||
|---|---|---|---|
|
|
||||||
| 1 | df-nodes | ai_node.rs | schema `required=[]` 但运行时 prompt 必填,前后端不一致 |
|
|
||||||
| 2 | df-nodes | ai_self_review_node.rs | schema `required=["task_id","provider_id"]` 但 provider_id 可空 |
|
|
||||||
| 3 | df-nodes | docker_node.rs | shell_quote 不处理 `;` `|` `&`,命令注入漏洞 |
|
|
||||||
| 4 | df-ai | openai/anthropic_compat | 双文件 112KB,大量重复代码,应抽取共享模块 |
|
|
||||||
| 5 | df-ai | coordinator.rs | 65KB 单文件,DevFlow 最大文件,应拆分 |
|
|
||||||
| 6 | df-ai | context_helpers.rs | 63KB 纯辅助函数单文件,应拆分 |
|
|
||||||
| 7 | df-storage | migrations.rs | 89KB 单文件,37 个迁移函数应拆分到独立文件 |
|
|
||||||
|
|
||||||
### 🟡 P1(20 个)
|
|
||||||
|
|
||||||
| # | 模块 | 简述 |
|
|
||||||
|---|---|---|
|
|
||||||
| 1 | df-nodes | DockerNode volumes.host 用户可控,命令注入 |
|
|
||||||
| 2 | df-nodes | HumanNode timeout 默认 3600s 过长 |
|
|
||||||
| 3 | df-nodes | HttpNode 每次新建 reqwest::Client |
|
|
||||||
| 4 | df-nodes | SubflowNode 不实际执行子 DAG |
|
|
||||||
| 5 | df-nodes | human_node.rs(833行) / conditions.rs(934行) 过大 |
|
|
||||||
| 6 | df-workflow | conditions.rs 934 行单文件,应拆分 |
|
|
||||||
| 7 | df-workflow | conditions-eval feature 默认关闭 |
|
|
||||||
| 8 | df-ai | intent.rs 57KB 单文件 |
|
|
||||||
| 9 | df-ai | context/sanitize.rs 51KB 单文件 |
|
|
||||||
| 10 | df-ai | router cost_tier/intelligence 悬空无数据源 |
|
|
||||||
| 11 | df-ai | retry.rs MAX_COMPLETE_ATTEMPTS=3 硬编码 |
|
|
||||||
| 12 | df-ideas | adversarial.rs 29KB + 测试混在一起 |
|
|
||||||
| 13 | df-ideas | LLM 评估一致性未校验 |
|
|
||||||
| 14 | df-execute | env_snapshot Windows Store alias 卡死(已修复) |
|
|
||||||
| 15 | df-execute | shell.rs pwsh 首次探测时序依赖 |
|
|
||||||
| 16 | df-mcp | tools.rs 未校验实体类型(同 B-260801-01) |
|
|
||||||
| 17 | df-storage | secret.rs keyring 迁移失败保留明文 |
|
|
||||||
| 18 | df-storage | db.rs 单连接 Mutex 瓶颈 |
|
|
||||||
| 19 | df-storage | idea_repo.rs 65KB / task_repo.rs 42KB |
|
|
||||||
| 20 | df-relay | 单 token 鉴权,生产级需独立 |
|
|
||||||
|
|
||||||
### 🟢 P2(15 个)
|
|
||||||
|
|
||||||
| # | 模块 | 简述 |
|
|
||||||
|---|---|---|
|
|
||||||
| 1-2 | df-nodes | shell_quote DRY 漂移 / REJECT_KEYWORDS "no" 过宽 |
|
|
||||||
| 3-4 | df-ai | ChatMessage 18 字段 / SSE 1MB BUF_MAX |
|
|
||||||
| 5-6 | df-ideas | 关键词硬编码 / 否定前缀仅单字+两字 |
|
|
||||||
| 7-8 | df-storage | 迁移失败计数 cwd 依赖 / Debug 脱敏手动 |
|
|
||||||
| 9-10 | df-relay | device 无主动心跳 / 匿名结构体提取 payload |
|
|
||||||
| 11-12 | df-project | is_pure_badge_line 手写复杂 / 无 regex |
|
|
||||||
| 13-14 | df-types | 9 个 ID 别名 / MentionRef/Augmentation 未共用反序列化 |
|
|
||||||
| 15 | df-mcp | Box::leak 违背进程生命周期假设 |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 按严重程度排序
|
|
||||||
|
|
||||||
### 安全漏洞(2 个)
|
|
||||||
1. **P0** DockerNode shell_quote 命令注入(`;` `|` `&` 未转义)
|
|
||||||
2. **P1** DockerNode volumes.host 用户可控注入
|
|
||||||
|
|
||||||
### 功能缺陷(3 个)
|
|
||||||
1. **P1** SubflowNode 不实际执行子 DAG
|
|
||||||
2. **P1** NotifyNode desktop 只是日志占位
|
|
||||||
3. **P1** df-mcp 未校验实体类型(跨实体误操作)
|
|
||||||
|
|
||||||
### 可维护性(18 个)
|
|
||||||
1. **P0** migrations.rs 89KB / coordinator.rs 65KB / context_helpers.rs 63KB
|
|
||||||
2. **P0** openai/anthropic_compat 双文件 112KB 重复
|
|
||||||
3. **P1** intent.rs 57KB / sanitize.rs 51KB / idea_repo 65KB 等
|
|
||||||
4. **P2** 各种 DRY 漂移、关键词硬编码
|
|
||||||
|
|
||||||
### 性能(2 个)
|
|
||||||
1. **P1** HttpNode 每次新建 Client
|
|
||||||
2. **P1** db.rs 单连接 Mutex 瓶颈
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 正面评价(亮点)
|
|
||||||
|
|
||||||
### 设计优秀
|
|
||||||
1. **状态机**: task_state_machine 从 TaskStatus::as_str() 派生常量 + 双源一致性测试
|
|
||||||
2. **CAS 原子写**: advance_status_atomic `WHERE status=expected` 防 TOCTOU
|
|
||||||
3. **HumanNode 拒绝语义化**: 审批拒绝从 Ok→Err,触发工作流 failed→退回
|
|
||||||
4. **AiSelfReviewNode 兜底**: verdict=unknown 不阻断,保持人定权
|
|
||||||
5. **conditions 求值失败保守 false**: 安全优先
|
|
||||||
|
|
||||||
### 架构合理
|
|
||||||
1. **df-ai-core 下沉**: trait+类型在轻量 crate,df-ideas 不引入 HTTP 重依赖
|
|
||||||
2. **impl_repo! 宏**: 消除 14 个 Repo 的重复样板
|
|
||||||
3. **WAL 模式**: 已启用,GUI + MCP 并发安全
|
|
||||||
4. **密钥管理**: keyring 迁移 + 失败计数 + 显示告警
|
|
||||||
|
|
||||||
### 测试覆盖
|
|
||||||
1. 每个节点文件都有配套测试
|
|
||||||
2. advance_task_atomic 有 20+ 测试覆盖各种状态转换
|
|
||||||
3. router.rs 全维度覆盖(10+ 测试)
|
|
||||||
4. retry.rs 覆盖首次成功/重试成功/耗尽/Fatal
|
|
||||||
5. MCP server 协议层完整测试
|
|
||||||
|
|
||||||
### 代码质量
|
|
||||||
1. 注释详尽,每处设计决策都有理由/替代方案/选型依据
|
|
||||||
2. 降级路径完整(LLM→启发式→兜底)
|
|
||||||
3. 锁中毒不 panic,返回保守默认值
|
|
||||||
4. SSE 解析器宽松 UTF-8 处理
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 改进优先级建议
|
|
||||||
|
|
||||||
### 立即修复(P0,7 个)
|
|
||||||
1. DockerNode shell_quote 命令注入(最快修,影响安全)
|
|
||||||
2. ai_node.rs schema/运行时不一致
|
|
||||||
3. ai_self_review_node.rs schema/运行时不一致
|
|
||||||
4. migrations.rs 拆分(89KB 单文件)
|
|
||||||
5. coordinator.rs 拆分(65KB 单文件)
|
|
||||||
6. context_helpers.rs 拆分(63KB 单文件)
|
|
||||||
7. openai/anthropic_compat 共享模块抽取
|
|
||||||
|
|
||||||
### 尽快修复(P1,20 个)
|
|
||||||
1. HumanNode timeout 默认值
|
|
||||||
2. HttpNode Client 复用
|
|
||||||
3. SubflowNode 功能完整
|
|
||||||
4. conditions.rs 拆分
|
|
||||||
5. df-mcp 实体类型校验
|
|
||||||
6. db.rs 连接池
|
|
||||||
7. keyring 迁移明文告警
|
|
||||||
|
|
||||||
### 后续迭代(P2,15 个)
|
|
||||||
1. 大文件拆分(intent/sanitize/idea_repo/task_repo)
|
|
||||||
2. DRY 漂移(shell_quote 共享)
|
|
||||||
3. 关键词配置化
|
|
||||||
4. relay 自动重连 supervisor
|
|
||||||
@@ -1,62 +0,0 @@
|
|||||||
# df-ideas + df-execute + df-mcp 代码走查报告
|
|
||||||
|
|
||||||
> 走查日期: 2026-08-02
|
|
||||||
> 范围: df-ideas(7 文件, 63KB) + df-execute(2 文件, 34KB) + df-mcp(3 文件, 52KB)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 问题汇总
|
|
||||||
|
|
||||||
| # | 等级 | 文件 | 类型 | 简述 |
|
|
||||||
|---|---|---|---|---|
|
|
||||||
| 1 | 🟡 P1 | adversarial.rs(29KB) | smell | 正反方论点模板化,evidence/reasoning 启发式拼接痕迹重,LLM 路径未充分验证 |
|
|
||||||
| 2 | 🟡 P1 | adversarial.rs | risk | LLM 评估 evaluate_with_llm 的 final_score 与 analyst.final_assessment 自洽性未校验 |
|
|
||||||
| 3 | 🟡 P1 | env_snapshot.rs | risk | `probe_version` 内 `std::process::Command::output()` 无 timeout,Windows Store alias 卡死 |
|
|
||||||
| 4 | 🟡 P1 | shell.rs | bug | `build_command` 在 `ShellType::default()` 时依赖 `PWSH_CACHE`,但 `probe_pwsh()` 异步填充,首次 `execute()` 时可能读到未初始化值 |
|
|
||||||
| 5 | 🟡 P1 | df-mcp/tools.rs | risk | `update_project`/`update_task` 未校验实体类型(同 B-260801-01 缺陷),跨实体误操作 |
|
|
||||||
| 6 | 🟡 P1 | df-mcp/server.rs | risk | dispatch 阶段 High 风险工具先拒绝,但 handler 内二次防御是纯文本返回,不保证线程安全 |
|
|
||||||
| 7 | 🟢 P2 | adversarial_helpers.rs | smell | 366 行纯函数文件,可进一步拆注重录/解析/枚举映射 |
|
|
||||||
| 8 | 🟢 P2 | scoring.rs | smell | 关键词正向/负向信号权重硬编码(+0.5/-0.6),不接 LLM 前无法调整 |
|
|
||||||
| 9 | 🟢 P2 | scoring_keywords.rs | smell | 24 行关键词硬编码,维护成本高 |
|
|
||||||
| 10 | 🟢 P2 | shell.rs | smell | `execute_streaming` 的 `on_output` 回调在 `select!` 中调用,`FnMut` 不可重入 |
|
|
||||||
| 11 | 🟢 P2 | env_snapshot.rs | smell | OS 版本探测依赖 `reg.exe`,无 `winreg` crate 跨平台路径 |
|
|
||||||
| 12 | 🟢 P2 | df-mcp/server.rs | smell | `Box::leak` 静态化 ToolSpec 可接受但违背进程生命周期假设 |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🟡 P1 问题详述
|
|
||||||
|
|
||||||
### #1 adversarial.rs 启发式论点模板化
|
|
||||||
|
|
||||||
**文件**: `adversarial.rs:180-280`
|
|
||||||
**影响**: 启发式评估的正反方论点高度模板化,evidence 和 reasoning 拼接痕迹重,区分度有限。
|
|
||||||
|
|
||||||
### #3 env_snapshot.rs Windows Store alias 卡死
|
|
||||||
|
|
||||||
**文件**: `env_snapshot.rs:95-100`
|
|
||||||
**根因**: 已修复(5s timeout + spawn_blocking),但修复本身复杂(超时后线程仍在跑)。
|
|
||||||
|
|
||||||
### #4 shell.rs pwsh 首次探测时序
|
|
||||||
|
|
||||||
**文件**: `shell.rs:75-80`
|
|
||||||
**风险**: `execute()` 中先 `probe_pwsh().await` 再 `build_command` 中 `ShellType::default()` 读缓存,但两行之间若 probe 未完成,default 读到错误值。
|
|
||||||
|
|
||||||
**现状**: 已修复(单源 PWSH_CACHE),但代码注释说明此依赖关系,初次阅读易漏。
|
|
||||||
|
|
||||||
### #5 df-mcp 未校验实体类型
|
|
||||||
|
|
||||||
**文件**: `df-mcp/tools.rs:240-280`
|
|
||||||
**风险**: MCP server 的 `update_task`/`update_project` 复用 df-storage 的 `update_full`,不校验 ID 对应的实体类型,与 B-260801-01 同根因。
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 正面评价
|
|
||||||
|
|
||||||
1. **对抗评估三路径**: LLM → HeuristicFallback → Heuristic,降级链路完整
|
|
||||||
2. **parse_llm_eval 容错**: 剥离 ```json 围栏 + 正则兜底 + 枚举校验 + 数值 clamp
|
|
||||||
3. **否定前缀处理**: `不复用` 不计入正向命中,设计精巧
|
|
||||||
4. **shell 执行器**: `execute_streaming` 流式输出 + mpsc 解耦 + kill_on_drop + CREATE_NO_WINDOW
|
|
||||||
5. **MCP 安全降级**: High 风险默认拒绝 + read-only 模式 + dispatch 层二次防御
|
|
||||||
6. **MCP 协议纯手写**: 不引入 serde_json 之外的依赖,零 JSON-RPC 库依赖
|
|
||||||
7. **env_snapshot 超时兜底**: 已修复 Windows Store alias 卡死问题
|
|
||||||
8. **测试覆盖**: adversarial.rs 有 8+ 测试,scoring.rs 有 10+ 测试,shell.rs 有探测缓存测试
|
|
||||||
@@ -1,83 +0,0 @@
|
|||||||
# df-storage + df-relay + df-tunnel + df-project + df-types 代码走查报告
|
|
||||||
|
|
||||||
> 走查日期: 2026-08-02
|
|
||||||
> 范围: df-storage(7 文件, 150KB) + df-relay(5 文件, 30KB) + df-tunnel(3 文件, 28KB) + df-project(3 文件, 21KB) + df-types(3 文件, 42KB)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 问题汇总
|
|
||||||
|
|
||||||
| # | 等级 | 文件 | 类型 | 简述 |
|
|
||||||
|---|---|---|---|---|
|
|
||||||
| 1 | 🔴 P0 | migrations.rs(89KB) | smell | 单文件 1914 行,37 个迁移函数 + V1 建表 SQL,文件过大 |
|
|
||||||
| 2 | 🔴 P0 | models.rs(25KB) | smell | 所有数据模型定义在单文件,20+ 结构体,已超合理阈值 |
|
|
||||||
| 3 | 🟡 P1 | secret.rs | risk | keyring 迁移失败时保留明文在 SQLite 文件,无加密保护 |
|
|
||||||
| 4 | 🟡 P1 | db.rs | risk | `Arc<Mutex<Connection>>` 单连接 Mutex,高并发时是瓶颈 |
|
|
||||||
| 5 | 🟡 P1 | crud/idea_repo.rs(65KB) | smell | IdeaRepo 单文件 65KB,含 KnowledgeRepo + 向量工具 |
|
|
||||||
| 6 | 🟡 P1 | crud/task_repo.rs(42KB) | smell | TaskRepo 42KB,含 advance_status_atomic 等复杂逻辑 |
|
|
||||||
| 7 | 🟡 P1 | relay.rs | risk | 单 token 鉴权(env `DF_RELAY_TOKEN`),生产级需独立 token/device |
|
|
||||||
| 8 | 🟡 P1 | tunnel.rs | risk | 仅支持手动重连,无自动后台重连 supervisor |
|
|
||||||
| 9 | 🟢 P2 | crud/mod.rs | smell | impl_repo! 宏 + 14 个子模块,但 advance_status_atomic 等特殊方法不在宏内 |
|
|
||||||
| 10 | 🟢 P2 | relay.rs | risk | 心跳 ping-pong 仅 miniapp 端触发,device 端无主动心跳 |
|
|
||||||
| 11 | 🟢 P2 | tunnel.rs | smell | `parse_payload_from_broadcast` 用匿名结构体仅提取 payload,不够健壮 |
|
|
||||||
| 12 | 🟢 P2 | scan_helpers.rs | smell | `is_pure_badge_line` 字符串解析逻辑复杂,无 regex 纯手写 |
|
|
||||||
| 13 | 🟢 P2 | types.rs | smell | 9 个 ID 别名 + 4 个状态枚举 + ExecutionId 新类型 + ToolCallType 新类型 |
|
|
||||||
| 14 | 🟢 P2 | augmentation.rs | smell | MentionRef/Augmentation 都带 tag = "kind",但未共用反序列化代码 |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🔴 P0 问题详述
|
|
||||||
|
|
||||||
### #1 migrations.rs 89KB 单文件
|
|
||||||
|
|
||||||
**文件**: `migrations.rs` (1914 行)
|
|
||||||
**问题**: 37 个迁移函数 + V1 建表 SQL 字符串 + 步骤列表全在一个文件。V1_SQL 本身占数百行。
|
|
||||||
|
|
||||||
**建议**: 拆为 `migrations/v1.rs` ~ `migrations/v37.rs`,`migrations/mod.rs` 只保留 `run()` 和步骤列表。
|
|
||||||
|
|
||||||
### #2 models.rs 25KB 单文件
|
|
||||||
|
|
||||||
**文件**: `models.rs` (558 行)
|
|
||||||
**问题**: 20+ 结构体(IdeaRecord / ProjectRecord / TaskRecord / AiProviderRecord / AiConversationRecord / AiMessageRecord / KnowledgeRecord / ...)全在单文件。
|
|
||||||
|
|
||||||
**建议**: 拆为 `models/idea.rs` / `models/project.rs` / `models/task.rs` / `models/ai.rs` / `models/knowledge.rs`。
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🟡 P1 问题详述
|
|
||||||
|
|
||||||
### #3 keyring 迁移失败保留明文
|
|
||||||
|
|
||||||
**文件**: `secret.rs:130-140`
|
|
||||||
**风险**: keyring 迁移失败时,api_key 明文保留在 SQLite 文件(无加密),用户可能不知情。
|
|
||||||
|
|
||||||
**建议**: 在迁移失败告警中提供更明确的指引,或支持 AES 加密 fallback。
|
|
||||||
|
|
||||||
### #4 db.rs 单连接 Mutex
|
|
||||||
|
|
||||||
**文件**: `db.rs:30-45`
|
|
||||||
**风险**: 全库单 `Connection` + `Mutex`,所有 CRUD 操作串行化。MCP server + GUI 并发读写时虽 WAL 模式允许写并发,但 Mutex 仍限制为单线程。
|
|
||||||
|
|
||||||
**建议**: 考虑 r2d2 连接池(注释中已标注 TODO)。
|
|
||||||
|
|
||||||
### #5 idea_repo.rs 65KB
|
|
||||||
|
|
||||||
**文件**: `crud/idea_repo.rs` (65KB)
|
|
||||||
**内含**: IdeaRepo + KnowledgeRepo + KnowledgeEventsRepo + 向量工具(embedding 搜索)。
|
|
||||||
|
|
||||||
**建议**: 拆为 3 个独立 repo 文件。
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 正面评价
|
|
||||||
|
|
||||||
1. **impl_repo! 宏**: 消除 14 个 Repo 的重复样板,统一 insert/get_by_id/list_all/query/update_field/delete/update_full
|
|
||||||
2. **secret.rs 设计**: OS keyring 优先 + DB 明文 fallback + 迁移失败计数 + 失败阈值告警
|
|
||||||
3. **db.rs 已开 WAL**: `PRAGMA journal_mode=WAL` + `PRAGMA foreign_keys=ON`
|
|
||||||
4. **relay 配对路由**: 按 device_id 配对,非全局广播,设计合理
|
|
||||||
5. **relay 心跳**: miniapp ping → relay pong 本地响应,不经过 device 透传
|
|
||||||
6. **tunnel 握手探测**: HANDSHAKE_PROBE 窗口 + 15s CONNECT_TIMEOUT,防死连
|
|
||||||
7. **tunnel 收发循环**: 独立 tokio::spawn + mpsc 解耦,不阻塞调用方
|
|
||||||
8. **scan_helpers 轻量**: 无 regex 依赖,纯手写字符串解析
|
|
||||||
9. **ProjectManager 状态机**: 独立领域层,不依赖 storage
|
|
||||||
10. **Augmentation 脱敏路径**: SanitizedPath newtype 防裸 String 误用
|
|
||||||
Reference in New Issue
Block a user