diff --git a/docs/walkthrough-2026-08/ai_storage_walkthrough.md b/docs/05-代码审查/claude-df-ai-storage-走查-2026-08-02.md similarity index 100% rename from docs/walkthrough-2026-08/ai_storage_walkthrough.md rename to docs/05-代码审查/claude-df-ai-storage-走查-2026-08-02.md diff --git a/docs/walkthrough-2026-08/nodes_walkthrough.md b/docs/05-代码审查/claude-df-nodes-走查-2026-08-02.md similarity index 100% rename from docs/walkthrough-2026-08/nodes_walkthrough.md rename to docs/05-代码审查/claude-df-nodes-走查-2026-08-02.md diff --git a/docs/walkthrough-2026-08/ideas_frontend_walkthrough.md b/docs/05-代码审查/claude-ideas-前端-走查-2026-08-02.md similarity index 100% rename from docs/walkthrough-2026-08/ideas_frontend_walkthrough.md rename to docs/05-代码审查/claude-ideas-前端-走查-2026-08-02.md diff --git a/docs/walkthrough-2026-08/infra_walkthrough.md b/docs/05-代码审查/claude-基建-剩余模块-走查-2026-08-02.md similarity index 100% rename from docs/walkthrough-2026-08/infra_walkthrough.md rename to docs/05-代码审查/claude-基建-剩余模块-走查-2026-08-02.md diff --git a/docs/walkthrough-2026-08/summary.md b/docs/05-代码审查/claude-汇总-2026-08-02.md similarity index 100% rename from docs/walkthrough-2026-08/summary.md rename to docs/05-代码审查/claude-汇总-2026-08-02.md diff --git a/docs/walkthrough-2026-08/00-汇总报告.md b/docs/walkthrough-2026-08/00-汇总报告.md deleted file mode 100644 index 05f17d1..0000000 --- a/docs/walkthrough-2026-08/00-汇总报告.md +++ /dev/null @@ -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 \ No newline at end of file diff --git a/docs/walkthrough-2026-08/04-df-ideas-execute-mcp-walkthrough.md b/docs/walkthrough-2026-08/04-df-ideas-execute-mcp-walkthrough.md deleted file mode 100644 index dd4c172..0000000 --- a/docs/walkthrough-2026-08/04-df-ideas-execute-mcp-walkthrough.md +++ /dev/null @@ -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 有探测缓存测试 \ No newline at end of file diff --git a/docs/walkthrough-2026-08/05-df-storage-relay-tunnel-project-types-walkthrough.md b/docs/walkthrough-2026-08/05-df-storage-relay-tunnel-project-types-walkthrough.md deleted file mode 100644 index 62318b6..0000000 --- a/docs/walkthrough-2026-08/05-df-storage-relay-tunnel-project-types-walkthrough.md +++ /dev/null @@ -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,高并发时是瓶颈 | -| 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 误用 \ No newline at end of file