重构: 拆agentic.rs第一批GeneratingGuard(strategy自底向上)
- 新建 agentic/guard.rs(69行): GeneratingGuard struct+new/reset/disarm/Drop(F-09 batch2 per_conv双写语义保留, pub(super)可见性) - agentic.rs 1221→agentic/mod.rs 1165行: mod guard + use GeneratingGuard + 删原定义 - loop主体(run_agentic_loop/try_continue/stream_one_provider/compress)原位保留(后续批,高风险) helpers未建: 无独立纯helper可抽(DEFAULT_*被state.rs引用留原位, PROTECT_COUNT loop绑定) 主代兜底: cargo check --workspace 0 + test 98 + grep guard抽离/mod.rs use印证 strategy: 自底向上, 单批1-2文件原子, loop主体留后续批(行为敏感需充分测试)
This commit is contained in:
67
docs/todo.md
67
docs/todo.md
@@ -489,3 +489,70 @@
|
||||
— 新建 `crates/df-mcp/` + `src-tauri/src/main.rs` + `src-tauri/Cargo.toml` + 可选 `crates/df-ai/src/ai_tools.rs`
|
||||
|
||||
---
|
||||
|
||||
### 💡 2026-06-19 新需求(AI 工具文件访问动态权限模型·已分析·待实施)
|
||||
|
||||
> 用户需求:将现有 `workspace_root` 单一根目录模型,升级为**动态白名单池 + 运行时权限申请**机制(类似 macOS / VS Code 的权限申请模式)。解决「锁太死」(只能绑定单一 workspace_root)和「放太宽」的矛盾。
|
||||
>
|
||||
> **与 MCP Server(F-260619-02)无关**:本需求是 DevFlow 应用内部 AI 工具(read_file/write_file 等)的文件系统访问权限升级,不涉及对外 MCP 协议暴露。
|
||||
|
||||
- [ ] **F-260619-03 [P1]** — **AI 工具文件访问动态权限模型:workspace_root 单根 → 动态白名单池 + 运行时申请**
|
||||
|
||||
**核心机制**:当 AI 调用 `read_file` / `write_file` 等文件系统工具时,路径校验从「单一 workspace_root 前缀匹配」升级为「动态白名单池校验 + 未命中则挂起 Agentic Loop 向前端弹窗申请授权」。
|
||||
|
||||
**数据结构变更**:
|
||||
|
||||
1. **持久化白名单**(Settings KV 存储):`app_settings` 表 key=`allowed_dirs`,value=JSON 数组 `["E:/wk-lab/u-abc", "E:/wk-lab/u-img"]`。前端 Settings 页提供列表增删改查 UI。
|
||||
2. **会话级临时白名单**(内存):`AiSession` 新增 `session_allowed_dirs: HashSet<PathBuf>`,仅限当前会话有效。
|
||||
3. **全局状态**:`AppState` 引入 `AllowedDirs { persistent: HashSet<PathBuf>, session: HashSet<PathBuf> }`,替代写死的 `workspace_root()`。
|
||||
|
||||
**权限拦截与申请流程**:
|
||||
1. **规范化路径**:`canonicalize`(解析软链接、`.` 和 `..`)。
|
||||
2. **检查白名单**:判断 `canonicalize` 后的真实路径是否在持久化或会话白名单中(`real_path.starts_with(allowed_dir)`)。
|
||||
3. **命中则放行**:执行原逻辑。
|
||||
4. **未命中则拦截**:挂起当前 Agentic Loop → Tauri 事件向前端弹窗 `AiDirAuthRequired { path, tool_name }` → 用户选择「仅本次」(加入 session_allowed_dirs)/「未来都允许」(写入 DB Settings + 更新 persistent)/「拒绝」→ 恢复执行。
|
||||
|
||||
**授权粒度**:弹窗中建议授权目标文件所在的**项目根目录**(而非具体文件),减少弹窗频率。用户可在弹窗中手动收窄或放宽范围。
|
||||
|
||||
**安全防护(三层)**:
|
||||
- **第一层 canonicalize**:解析软链接后校验真实路径,防软链接逃逸(授权目录本身也需 canonicalize)。
|
||||
- **第二层白名单**:`real_path.starts_with(allowed_dir)` 校验。
|
||||
- **第三层黑名单兜底**:保留现有 `validate_path`,禁止系统敏感目录(`/etc`、`/var`、`C:\Windows\System32` 等)。
|
||||
|
||||
**写操作额外约束**:写操作(write_file/delete_file/patch_file)即使目录已授权,仍走现有 RiskLevel 审批流(Medium/High 需用户确认);`delete_file` 始终 High 风险审批,不受白名单影响。
|
||||
|
||||
**分阶段实施**:
|
||||
|
||||
| 阶段 | 内容 | 复杂度 | 优先级 |
|
||||
|------|------|--------|--------|
|
||||
| **Phase A** | Settings 持久化白名单 + `resolve_workspace_path` 改造为多目录校验(canonicalize + starts_with) | 低 | P1 |
|
||||
| **Phase B** | 会话级临时授权 + Agentic Loop 挂起/恢复 + 前端弹窗 UI + Tauri 事件 | 高 | P2 |
|
||||
| **Phase C** | 软链接深度防护 + 系统目录黑名单完善 + 写操作额外约束 | 中 | P2 |
|
||||
|
||||
Phase A 成本最低但收益最大——立即解决「只能绑定单一 workspace_root」的限制,且为后续动态授权打好数据基础。
|
||||
|
||||
**与现有架构的契合点**:
|
||||
- SettingsRepo KV 存储:已有,`allowed_dirs` 直接复用,零迁移成本。
|
||||
- RiskLevel 审批流:已有完整 tool approval 机制,动态授权可视为「路径级别的 approval」。
|
||||
- Agentic Loop:已有挂起/恢复能力(审批等待),扩展路径授权挂起是同构的。
|
||||
- Tauri 事件系统:已有 `ai-chat-event`,新增 `AiDirAuthRequired` 事件类型即可。
|
||||
|
||||
**关键改动点**:
|
||||
- `tool_registry.rs`:handler 闭包需引入 `AllowedDirs` 的 `Arc` 引用(当前闭包是无状态 `Box::new(|args| ...)`),调整注册逻辑。
|
||||
- `resolve_workspace_path`(或等效路径校验函数):从单一 workspace_root 前缀匹配 → 多目录白名单 canonicalize 校验。
|
||||
- `state.rs`:AppState 新增 `allowed_dirs` 字段。
|
||||
- `commands/ai/mod.rs`:AiSession 新增 `session_allowed_dirs` 字段。
|
||||
- `agentic.rs`:捕获 `PATH_AUTH_REQUIRED` 信号 → 挂起 → emit 事件 → 等待恢复。
|
||||
- 前端 Settings 页:新增「授权目录」管理 UI。
|
||||
- 前端 AiChat:新增路径授权弹窗组件。
|
||||
|
||||
**验收标准**:
|
||||
1. Settings 页可管理持久化授权目录列表(增删改查)
|
||||
2. AI 访问授权目录内文件正常执行,无额外弹窗
|
||||
3. AI 访问授权目录外文件时弹窗申请,用户可选择「仅本次」/「未来都允许」/「拒绝」
|
||||
4. 软链接逃逸被 canonicalize 校验拦截
|
||||
5. 系统敏感目录始终被拒绝(黑名单兜底)
|
||||
6. `cargo check --workspace EXIT 0` + `vue-tsc EXIT 0`
|
||||
|
||||
— `src-tauri/src/state.rs` + `src-tauri/src/commands/ai/{mod.rs,tool_registry.rs,agentic.rs}` + `src-tauri/src/commands/settings.rs` + 前端 Settings 页 + AiChat 弹窗组件
|
||||
|
||||
|
||||
Reference in New Issue
Block a user