Files
DevFlow/PROGRESS.md
绝尘 0789a36030 新增: todo 补 6 项缺口 + PROGRESS Sprint 21(workflow 推进)
todo: T-03 标(WF-B⑤解决)+ 补 F-07 df-ai-core/F-08 决策治理/F-09 status治理/F-10 知识库MCP/T-11 条件引擎/T-12 df-ideas死代码(决策记录+PROGRESS 缺口补进看板)
PROGRESS: Sprint 21 记录 A/B/C/D 四 workflow(commit 3f0839a/d5a6417/02ff88f/22964a2)+ 验证结论
2026-06-14 14:33:52 +08:00

747 lines
68 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# DevFlow — 项目进展与工作交接
> 创建: 2026-06-10 | 最后更新: 2026-06-14 | 当前阶段: list_directory 防爆 + localStorage→SQLite 统一持久化 + token/发送 bug 修复(Sprint 19) → 项目管理模块代码审查 + 全局核对(Sprint 20未改代码)
---
## 一、项目速览
| 项目 | 值 |
|------|-----|
| 定位 | AI 原生创作流程驾驶舱,从想法到创作成果的全流程管理 |
| 技术栈 | Tauri v2 + Vue 3 + TypeScript + Pinia / Rust Workspace (13 crate) / SQLite |
| 路径 | `E:/wk-lab/devflow/` |
| 架构文档 | `ARCHITECTURE.md` (22,745 字) |
| Git 状态 | 未首次 commit代码全在 untracked |
| AI 能力 | df-ai OpenAI/Anthropic 双协议 Provider + 12 工具 + Agentic Loop |
---
## 二、代码规模统计
### Rust 后端 (78 个 .rs 文件)
| Crate | 文件数 | 总行数 | 有效行 | 实现程度 |
|-------|--------|--------|--------|---------|
| df-core | 4 | 429 | ~260 | ✅ 完整 — 错误/事件/状态枚举/ID生成 |
| df-workflow | 9 | 908 | ~620 | ✅ 核心 — DAG拓扑排序/执行器/状态机/事件总线 可用 |
| df-storage | 5 | ~2,100 | ~1,400 | ✅ 完整 — 连接/迁移/建表(V1-V8) + impl_repo! 宏 CRUD + KnowledgeReposearch/list_by_status/set_embedding/search_vector 等)+ 余弦相似度工具函数 |
| df-execute | 5 | 203 | 129 | ⚡ 混合 — Shell 执行器真实可用Docker/SSH/Git 骨架 |
| df-ideas | 7 | 761 | ~500 | ✅ 评分/对抗启发式已真实化Sprint 9— 捕获/评估/晋升/关联图 有逻辑,晋升/关联图仍骨架 |
| df-project | 5 | 272 | 175 | ⚡ 混合 — 数据模型/Timeline 可用,调度器 骨架 |
| df-ai | 9 | 1,965 | ~1,300 | ✅ 完整 — OpenAI/Anthropic 双协议 Provider + 流式 SSE + 上下文窗口(ContextManager 分组滑窗) + token usage 解析 + 12 工具 |
| df-nodes | 9 | ~500 | ~350 | ⚡ 混合 — script_node接 Shell/ ai_node接 df-aiSprint 7真实可用human_node 半实现(审批响应 TODO其余骨架 |
| **合计** | **53** | **~7,400** | **~4,800** | 已删除 5 个零引用 crate2026-06-14原 78/9100/5900 |
### 前端 (9 页面 + 2 组件 + Store + i18n)
| 类别 | 文件数 | 行数 | 状态 |
|------|--------|------|------|
| Vue 页面 | 9 | ~3,372 | ✅ UI 全部真实 — 无空壳(含 AiHome/AiDetached|
| Vue 组件 | 2 | ~1,400 | ✅ AiChat主面板+ ConfirmDialog |
| Pinia Store | 4+ | ~800 | ✅ composable 模式View 已引用Sprint 4 接入)|
| Router | 1 | ~90 | ✅ 10 条路由含动态路由Sprint 7 增 AiHome/AiDetached|
| i18n | 2 | ~94 | ✅ 已注册 main.tsSprint 7+ localStorage 持久化 |
| 设计系统 | 1 | 105 | ✅ CSS 变量/动画/Arco 暗色覆盖 |
| **前端合计** | | **~8,812** | |
> Tauri Commands 已达 **57 个**project/task/idea/workflow + AI 对话/工具/审批/Provider/技能全功能 + 知识库 11 个),见后端 src-tauri/src/commands/。
**前端关键问题**Sprint 4/7 已全部解决):
- ~~所有 View 组件数据硬编码~~ ✅ Sprint 4 接 Store 真数据
- ~~所有按钮事件处理函数为空函数~~ ✅ Sprint 4 接 Store action
- ~~i18n 插件未注册~~ ✅ Sprint 7 注册 + $t() 全 view 改造
- ~~Arco Design 组件库未实际使用~~ ✅ 已用(表单/弹窗/消息等CSS 变量覆盖暗色
---
## 三、架构分层与依赖关系
```
真实可用路径(有端到端逻辑):
df-core (类型基础)
→ df-workflow (DAG 拓扑排序 + 执行器 + 状态机 + EventBus)
→ df-execute/shell (tokio::process Shell 执行)
→ df-storage (SQLite 连接 + 迁移 + 建表)
待打通路径(骨架就位,需填充):
df-workflow → df-nodes (8种节点 execute() 待实现)
~~df-workflow → df-stages (11种阶段节点 execute() 待实现)~~ — df-stages 已移除2026-06-14 零引用清理)
~~df-ai → LlmProvider 实现~~ ✅ 已打通OpenAI/Anthropic 双协议真实 HTTPSprint 5/8
~~df-storage → 所有 crate 的 CRUD 操作~~ ✅ 已打通impl_repo! 宏 CRUD + 多 RepoSprint 2
~~Tauri commands → Rust 业务逻辑~~ ✅ 已打通47 commands 全接业务Sprint 3
~~Vue Views → Pinia Store → Tauri IPC → Rust~~ ✅ 已打通Sprint 4
```
---
## 四、全局性问题
| # | 问题 | 影响 | 优先级 | 状态 |
|---|------|------|--------|------|
| 1 | **无 CRUD 层** — df-storage 只有建表 | 所有 crate 无法持久化数据 | P0 | ✅ Sprint 2 |
| 2 | **Tauri IPC 未建** — 只有 greet 示例 command | 前端无法调用后端 | P0 | ✅ Sprint 317 commands |
| 3 | **Store 未接入 View** — 两套独立硬编码数据 | 数据流断裂 | P0 | ✅ Sprint 4 |
| 4 | **AI Provider 无实现** — trait 定义完整但无 HTTP client | AI 功能全部不可用 | P1 | ✅ Sprint 5 |
| 5 | **同层节点未并行** — DagExecutor 有 TODO 注释 | 工作流执行效率 | P1 | ✅ Sprint 3join_all |
| 6 | **条件表达式引擎** — 仅支持 true/false 字面量 | 条件分支不可用 | P2 | ⬜ 待办 |
| 7 | **i18n 未注册** — 翻译文件存在但未挂载 | 多语言不生效 | P2 | ✅ Sprint 7 |
| 8 | **未 git commit** — 代码全 untracked | 无版本基线 | P0 | ✅ Sprint 2 |
| 9 | **AI 删项目绕过软删** — tool_registry:263 `repo.delete` 物理删IPC 走 `soft_delete` 进回收站AI 层缺 restore/purge/list_trash 工具(仅 project 表有回收站设计,故最该修) | AI 对话删项目 = 数据丢失不可恢复,与 UI 删语义割裂 | P1 | ⬜ Sprint 20 待修批1 |
---
## 五、Phase 规划与当前进度
### Phase 1 — 引擎骨架 ✅ 完成
| 任务 | 状态 | 说明 |
|------|------|------|
| df-core 类型系统 | ✅ 完成 | 错误/事件/状态枚举/ID生成 |
| df-workflow DAG 引擎 | ✅ 完成 | 拓扑排序/执行器/状态机/EventBus |
| df-storage SQLite 基础表 | ✅ 完成 | 6 张表 + 4 索引,缺 CRUD |
| df-execute Shell 执行 | ✅ 完成 | tokio::process 实现 |
| 最小前端:项目列表 + 工作流日志 | ✅ 完成 | Sprint 45 页面接 Store + 创建/运行交互 |
| 验证3 节点简单工作流 | ⬜ 待验证 | 后端就绪,需端到端跑通 |
| df-storage CRUD 层 | ✅ 完成 | Sprint 26 Repo + impl_repo! 宏Sprint 3 增 BranchRepo |
| 对抗式评估系统 | ✅ 完成 | Sprint 6AdversarialEngine + 正反方辩论 + AI 分析师 |
| Migrations V2关联字段 + branches 表) | ✅ 完成 | Sprint 3 |
| Executor 同层并行 + 状态转换校验 | ✅ 完成 | Sprint 34 单测全绿 |
| Tauri IPC 命令 | ✅ 完成 | Sprint 317 commands + 事件转发 |
| Store 接入 View | ✅ 完成 | Sprint 4API 层 + composable Store + 5 页面改造 |
### Phase 2 — AI 集成 ✅ 核心完成
| 任务 | 状态 | 说明 |
|------|------|------|
| df-ai Provider 实现 | ✅ | OpenAI 兼容 HTTP client流式 SSE 解析 |
| AI 工具注册 + V3 迁移 | ✅ | AiToolRegistry + 12 工具list/create/update/delete + 文件系统) |
| AI IPC 命令 | ✅ | 17 个 AI command对话/工具执行/审批门控) |
| AI Chat 面板 | ✅ | 侧边栏 + 分离窗口 + 拖拽调宽 + 对话管理 |
| Agentic Loop | ✅ | 多轮工具调用循环max 10 轮)+ 中/高风险人工审批 |
| AI Node 实现 | ✅ | df-nodes 接 df-aiconfig 驱动 providerbase_url/api_key/model/prompt→ OpenAICompatProvider.complete → 输出 text/model/usage注册 "ai" 节点;未端到端实测 |
| **AI Chat LLM 优化** | ✅ ABCD 完成 | 任务 #43P0 可靠性 ✅P1 上下文窗口ContextManager 分组滑窗)✅ + 并行化(工具 join_all / save 后台)✅;**Sprint 14 流式 token 用量记录usage 解析 + 累加落库 + 展示 + Settings 开关)✅**Part C 并发 Semaphore双层 + 运行时可调)+ Part D Settings UI ✅Sprint 16Review 两轮 8 修复 ✅ | |
### Phase 3 — 想法池 + 多项目 (3-4 周) | 🚧 进行中 — Sprint 9 评估闭环已通(启发式评分 + 对抗评估接 IPC晋升前端层闭环多项目/关联图待续Sprint 12 全面审查修 5 项前端 bug置信度条/状态选择/删除确认等),死代码组缓另会话重审
### Phase 4 — 节点丰富 + 阶段插件 (3-4 周) | ⬜ 未开始
### Phase 5 — 体验打磨 (4-6 周) | ⬜ 未开始
---
## 六、工作迭代日志
### [Sprint 1] 2026-06-10 — 项目初始化
**工作内容**
- 创建项目骨架:`bun create vite` + Tauri v2 + Cargo Workspace
- 编写完整架构文档 `ARCHITECTURE.md` (22,745 字)
- 13 个 Rust crate 全部创建,类型系统和接口设计完整
- 9 个 Vue 页面 UI 全部编写(~3,372 行),设计系统完善
- 4 个 Pinia Store 定义state + computed
- i18n 中英文翻译
**代码规模**Rust ~4,108 行 / Vue+TS ~3,896 行 / 总计 ~8,000 行
**遗留问题**
1. 所有数据硬编码,无持久化
2. 前后端未桥接
3. 未做 git commit
**下一步建议**
1. 首次 git commit 建立基线
2. 优先实现 df-storage CRUD 层(所有持久化的前置条件)
3. 实现 Tauri IPC 命令层
4. 将 Store 接入 View替换硬编码数据
5. 端到端验证3 节点简单工作流跑通
---
### [Sprint 2] 2026-06-10/11 — 设计审查 + 对抗论证 + 阻塞项修复
**工作内容**
- 三路功能审查(架构/前端/数据模型):发现 4 条核心路径全断、缺 10 张表、状态枚举三套不一致
- 三路对抗论证(市场/技术/需求"魔法打败魔法"):综合结论 = 方向有价值、scope 必须砍 60%
- 修复 Phase 1 阻塞项Shell Windows 兼容cmd /C、状态枚举统一types.rs 为准、DAG 序列化DagDef + NodeRegistry
- 实现 df-storage CRUD 层6 Repo + impl_repo! 宏 + spawn_blocking + 列名白名单)
- ScriptNode 接入 df-execute Shell 执行器
- 建立 docs/ 8 层文档体系(中文命名)
- 新增设计文档:业务系统设计、对抗论证裁决报告、想法探索-对抗式评估
**关键决策(详见 docs/02-架构设计/对抗论证裁决报告.md**
- 定位调整:"产研操作系统" → "本地优先的个人开发流程驾驶舱"
- 砍掉:插件系统、经验进化(自动)、需求-测试追溯、多模型路由、Agent 协作
- 降级:想法池(简化+对抗式评估、标注TODO 扫描器)、决策留痕(字段级)
- Phase 1 只激活 6 个 crate其余 7 个标记预留
- 验证策略:先自用 3 个月再决定是否对外
**遗留问题**
1. Executor 同层并行化 + StateMachine 转换校验(任务 #8
2. Migrations V2 补字段promoted_to/workflow_def_id/project_id 等)+ branches 表(任务 #9
3. Tauri IPC / 前端 Store 对接尚未开始
4. Sprint 2 的代码变更未 commit
**下一步**
1. commit Sprint 2 变更
2. Migrations V2 + Executor 并行化
3. Tauri IPCAppState + project/task/workflow commands
4. 前端类型对齐 + Store 接 View
### [Sprint 3] 2026-06-11 — Migrations V2 + Executor 并行化 + Tauri IPC三代理并行
**工作内容**(三个子代理并行,目录互不重叠):
- **Migrations V2**df-storage/df-core版本推进到 2 — ideas 补 promoted_to/ai_analysis/scores、tasks 补 workflow_def_id/base_branch、workflow_executions 补 project_id/task_id、新建 branches 表(含 2 索引BranchRecord/BranchRepo/BranchStatus 枚举同步落地ALLOWED_COLUMNS 白名单 +8 列
- **Executor 并行化**df-workflow同层节点改 futures::join_all 并发三阶段模式串行准备→并发执行→串行收尾规避借用冲突StateMachine 增加转换校验(仅 Pending→Running、Running→Completed/Failed 合法set_xxx 改返回 Result4 个单测全绿(含并行耗时断言 <180ms、失败中止下游层
- **Tauri IPC**src-tauriAppStatedb + 6 Repo + EventBus + NodeRegistry+ 17 个 commandproject/task/idea CRUD + run_workflow/list/get executionsrun_workflow 先落库 status=running 立即返回 execution_id事件经 app.emit("workflow-event") 转发前端完成后回写状态。注意NodeRegistry 不能用 default()script 工厂是 unimplemented! 占位),改为 new() + 手动注册真实 ScriptNode
**验证**cargo check 通过(仅 1 个 dead_code 警告releases/node_executions Repo 暂无 command 使用cargo test -p df-workflow 4 passed
**遗留问题**
1. executor 失败路径只发 NodeFailed 不发 WorkflowFailed目前由 run_workflow 在 IPC 层补发——后续应下沉到 executor
2. 前端 Store/View 仍硬编码,未调用任何 command
3. NodeRegistry::default() 的 unimplemented! 占位是隐患,应改为注册真实节点或移除
**下一步**
1. 前端类型对齐id: string、状态枚举对齐 types.rs+ src/api/ 封装层
2. Store 加 action 接 API核心 4 页面Dashboard/Projects/ProjectDetail/Tasks接 Store
3. 端到端验证tauri dev 创建项目 → 运行 3 节点工作流 → 日志实时展示
### [Sprint 4] 2026-06-11 — 前端交互功能API 层 + Store + 5 页面)
**工作内容**
- **API 层**:新建 `src/api/` 目录 — types.ts与 Rust Record 严格对齐)+ project/task/idea/workflow 四个 invoke 封装 + 事件监听listen workflow-event
- **Store 重写**`stores/project.ts` 改为 composable 模式reactive 全局状态 + 12 个 actions + computed stats不依赖 Pinia
- **Projects.vue**:接 Store 真数据 + 创建项目模态框(名称/描述)+ 卡片点击跳详情页 + status 中文映射
- **ProjectDetail.vue**:路由参数加载项目 + 真实任务列表 + **3 节点 Shell DAG 工作流运行**(环境检查→运行测试→构建产物)+ 实时事件日志 + 创建任务模态框 + onUnmounted 清理监听
- **Tasks.vue**:项目/状态双筛选联动 + 创建任务模态框(选择项目+标题)+ 状态/优先级中文映射
- **Ideas.vue**:捕捉想法模态框 + 选中详情tags JSON 解析、scores 展示)+ 删除功能
- **Dashboard.vue**:统计卡从 Store computed 计算 + Active Projects/Idea Pool 接真数据 + quickCapture 跳 Ideas
**代码变更**13 files, +1059/-486
**遗留问题**
1. 端到端验证未完成:需 tauri dev 实际创建项目→运行工作流→确认日志展示
2. 无数据时空状态展示较简陋
3. ~~Settings/Knowledge/Decisions 三个页面仍为硬编码 demo~~ ✅ Sprint 7 已解决(三 view 接 stores/{knowledge,settings}.ts无 ref([ 硬编码)
**下一步**
1. 端到端验证tauri dev → 创建项目 → 运行 3 节点工作流 → 日志实时展示
2. 修复验证中发现的问题
3. 考虑 Phase 2 规划
### [Sprint 5] 2026-06-11 — AI Chat 全功能Provider + 工具执行 + Agentic Loop
**工作内容**
- **df-ai Provider**OpenAI 兼容 HTTP clientSSE 流式解析ChatMessage/CompletionRequest 类型系统
- **V3 存储迁移**ai_providers、ai_conversations、ai_tool_executions 三张表 + 对应 Repo
- **AI IPC 命令层**17 个 command — 对话发送/流式推送、工具执行/审批门控(低风险自动/中高风险人工、对话管理CRUD + 切换)
- **AI 工具注册**12 个工具 — list_projects/tasks/ideas只读、create_project/task/idea创建、update_project更新、delete_project删除、read_file/list_directory/write_file文件系统
- **Agentic Loop**多轮工具调用循环max 10 轮),流式输出→检测工具调用→执行→结果回传→继续,中高风险暂停等审批后恢复
- **AI Chat 前端**:侧边栏面板 + 拖拽调宽 + 分离独立窗口 + 对话列表管理 + 工具审批弹窗 + AgentRound 多轮消息
- **Tauri Capabilities**ai-detached 窗口权限配置
**代码变更**20+ files新增 ~2000 行
**遗留问题**
1. ~~空白屏问题Vite 启动正常122s、HTML 200但 webview 显示空白~~ ✅ Sprint 7 已修复index.html 主题防闪烁脚本 + 启动计时埋点 __APP_T0 + body 背景色)
2. AI Node 未实现 — 目前只有骨架,需接入 df-ai 的 LlmProvider任务 #44
3. AI Chat LLM 调用逻辑待优化长对话可靠性、大任务执行稳定性、token 消耗控制(任务 #43)— **P0 可靠性已在 Sprint 6 完成P1 token 控制待办**
**下一步**
1. 排查并修复空白屏问题
2. 实际验证 AI Chat 端到端(选 Provider → 发消息 → 工具调用 → 审批)
3. HumanNode + Settings 页面
4. AI Chat LLM 调用逻辑优化(任务 #43
5. AI Node 实现(任务 #44
### [Sprint 6] 2026-06-11 — AI Chat 调用可靠性 P0 + 前端类型修复
**工作内容**
**A. AI Chat 调用可靠性 P0df-ai + src-tauri跨前后端 6 文件)** — 三路代理核对(调用链/上下文-token/前端)后定位可靠性死锁类问题,本轮按"先保命"只做 P0 五项P1 token 控制设计已定,留待下轮):
- **P0-1 连接超时**`openai_compat.rs` Client 加 `connect_timeout(30s)` 防连接阶段无限 hang不设总 timeout避免 reqwest 总时长限制误砍流式长生成任务)
- **P0-2 流式 idle timeout**`stream_llm``tokio::time::timeout(120s)``stream.next()`,防"连上后中途静默"无限 hang
- **P0-3 断连检测丢弃残缺**:维护 `finished_received` 标志,流尽未收到 finished 信号 → emit AiError + **丢弃残缺响应不当完整入库**(防脏历史污染)
- **P0-4 停止生成**`AiSession.stop_flag: Arc<AtomicBool>` + 新 `ai_chat_stop` command + 前端停止按钮streaming 时切换为珊瑚红方块按钮run_agentic_loop/stream_llm 多检查点响应,停止后保留已生成文本
- **P0-5 切对话防护**`ai_conversation_switch` 生成中拒绝切换(防 active_conversation_id 被改导致旧 loop 的 save_conversation 串台写库)
**B. 前端既有类型错误修复14 处,让 `bun run build` 通过)**
- `types.ts`:删重复的 `WorkflowEventPayload`declaration merging 冲突)
- `stores/project.ts`:补 `invoke` import + `payload.event.data` 类型断言 + **return 包 `reactive()` 自动解包 computed**(一处解决 Dashboard/ProjectDetail 的 store.stats/pendingApproval 解包,消费端零改动)
- `Ideas/Tasks/ProjectDetail`:去掉 `parseInt(number)` 误用 → `new Date(timestamp)`
- `ProjectDetail.vue`:删 unused `nextTick` import
- `AiChat.vue`:删死代码 `TOOL_STATUS_MAP` + `toolStatusLabel`
**C. AI Chat 代码审查修复9 处ai.rs + openai_compat.rs** — 对 P0 代码做 /review 审查后修复cargo check ✓:
- 🔴① `finish_reason="length"`max_tokens 截断)纳入 finished — 修「大任务输出撞 4096 上限被误判断连、丢弃整段响应」(与 ④ 配合是本轮关键)
- 🔴② 路径校验最小加固:正斜杠→反斜杠规范化 + 拒 `..` 遍历 + 扩 `.aws`/`.gnupg`(根治 workspace 白名单 + canonicalize 待定边界后再做)
- 🔴③ tool_calls 按 index 排序assistant 消息 line506 + tool_result line709 两处),消 HashMap 迭代乱序
- 🔴④ max_tokens 4096→8192贴合大任务
- 🟡⑤ `ai_chat_stop` 在审批等待态清 pending_approvals + 复位 generating原 stop_flag 无人读取,停止按钮表面无反应、会话卡 generating=true
- ⚪⑨ 4 个 i18n 小函数language_instruction/capability_section/behavior_rules/context_label合并为 `system_prompt_parts`
- ⚪⑩ `extract_title` 单次 chars 遍历
- ⚪⑪ reqwest builder 降级加 `warn!`
**代码变更**df-ai/openai_compat.rs、src-tauri/{commands/ai.rs, lib.rs}、前端 7 文件(+ C 轮 reviewai.rs、openai_compat.rs
**验证**cargo check -p devflow ✓(仅既有 warning、vue-tsc --noEmit ✓、bun run build ✓built in 2.47s
**遗留问题 / 下一步**
1. **P1 token 控制(任务 #43 续)**:流式 usage 采集(`stream_options:{include_usage:true}` + SSE usage 字段)+ token 预算自适应窗口chars≈/3.5 启发式估算)+ 历史摘要压缩(早期摘要 + 近期全文)—— 设计已定,未实施。**⚠️ usage 采集 2026-06-11 用户叫停暂缓结构层写一半已回退P1 从 token 估算/裁剪/摘要续**
2. **实测验证**`cargo tauri dev` 跑起来验证停止按钮/超时/断连真实生效(本轮仅编译 + 类型验证)
3. 停止生成边界LLM 正常输出时停止立即生效(<1sidle无输出时最多等 120s idle timeout —— P2 可用 `tokio::sync::Notify` 优化为绝对即时
4. ~~Sprint 5 遗留的空白屏问题仍待排查~~ ✅ Sprint 7 已修复(用户实测确认)
### [Sprint 7] 2026-06-11 — 空白屏修复 + i18n 接入 + 剩余页面接 Store
**工作内容**
- **空白屏修复**(前端):`index.html` 加主题防闪烁脚本localStorage `df-theme` 渲染前置 `data-theme`+ 启动计时埋点 `window.__APP_T0` + body 背景 `#0c0e1a``main.ts``.use(i18n)` 并打印 mount 耗时日志。用户实测确认空白屏消失
- **i18n 接入**`main.ts` 注册 `i18n` 插件;`i18n/index.ts` 完整legacy:false / globalInjection / zh-CN 默认 + en fallback / localStorage `df-language` 持久化App.vue 导航与各 view 改 `$t()`
- **剩余 3 页面接 Store**`Knowledge.vue`/`Settings.vue`/`Decisions` 去硬编码 `ref([...])`,对接新建 `stores/{knowledge,settings,ai}.ts`
- **新路由**`/` redirect → `/ai-home`,新增 `AiHome.vue`(默认落地页)/`AiDetached.vue`(分离窗口);路由 9→11 条
- **df-nodes 实现度修正**:核对发现 `script_node.rs` 早为真实实现(接 df_execute Shell + 非零退出码判断),`human_node.rs` 半实现(发 `HumanApprovalRequest` 事件 + 超时循环,但审批响应 TODO 直接返回"同意")—— 非文档原记"全骨架"
**遗留问题 / 下一步**
1. **P1 token 控制(任务 #43 续)**仍待办usage 采集用户叫停,从 token 估算/裁剪/摘要续)
2. **条件表达式引擎**conditions.rs 仍 true/false 字面量)— P2 未动
3. ~~AI Node 实现(任务 #44~~ ✅ 本轮已实现:`ai_node.rs` 接 df-ai `OpenAICompatProvider`,从 `ctx.config` 读 base_url/api_key/model/prompt/system_prompt/temperature/max_tokens 调 `complete()`prompt 支持上游输入优先;`df-nodes/Cargo.toml` 加 df-ai 依赖;`state.rs` build_registry 注册 "ai"。cargo check ✓(未端到端实测真实 LLM 调用)
4. **df-stages** 11 个 execute() 全空骨架 — Phase 4
5. **HumanNode 审批响应闭环**:目前直接返回"同意",需前端审批弹窗回写结果
### [Sprint 8] 2026-06-12 — Anthropic 协议 + 切对话不中断 + 技能联想需求调研
**工作内容**
**A. aichat 升级 A 路线UX 快赢,已实现并验证)** — 详见 memory `aichat-roadmap-ab-split`
- **Anthropic 协议 Provider**:新增 `crates/df-ai/src/anthropic_compat.rs`,实现 `LlmProvider` trait 覆盖 Anthropic Messages API`x-api-key` + `anthropic-version`、顶层 `system`、必填 `max_tokens`、SSE event 类型解析、`content_block` tool_use。按 `provider_type` 路由分发(`run_agentic_loop` / `ai_node`)。支持 GLM 订阅端点 `https://open.bigmodel.cn/api/anthropic`**用户实测对话流式 OK**
- **切对话不打断生成**:后端 `AiChatEvent` 全变体加 `conversation_id`agentic loop spawn 前快照 conv_id所有 emit 填充;`ai_conversation_switch` 生成中只读返回;前端 `stores/ai.ts` 按 conversation_id 路由(后台对话事件不污染当前视图,完成/错误时刷新侧边栏)
- **审查项落地**:删全屏 Tool Approval Modal保留行内卡片审批、错误友好化`friendlyError` 正则映射 404/401/timeout/network → 中文提示 + `isError` 红色气泡)、智能滚动(`isNearBottom` < 80px 阈值、provider bar 点击切换、未配 provider 空状态引导、删死 class
- **B 路线(规划式多智能体)单独立项**:填 `coordinator.rs` + `conditions.rs` 空壳,详见 memory `aichat-decision-capability`
**B. 技能联想功能(首批 Claude 3 类,已实现待实测)**
- **需求**aichat 输入框输入 `/` → 联想列出本机 Claude 技能SKILL.md按输入过滤选中插入 `/name`;发送时后端读 SKILL.md 全文注入 system prompt / context
- **首批数据源 = Claude 3 类**SKILL.md frontmatter 统一 `name` / `description` / `user_invocable` / `metadata.argument-hint` / `triggers[]`,只取 `user_invocable: true`
1. Claude skills`~/.claude/skills/*/SKILL.md`23 个sleep / mission-control / idea / cpa 等)
2. Claude commands`~/.claude/commands/*.md`1 个idea
3. Claude plugins`~/.claude/plugins/marketplaces/**/skills/*/SKILL.md`caveman 全家、官方 frontend-design / skill-creator / mcp-server-dev、wuming prompt-optimizer`cache/``marketplaces/` 重复需按 path 去重)
- 加项目级 `.claude/skills` + `.claude/commands`DevFlow 暂无)
- **实现要点**:① 后端新 IPC `list_skills()` 扫 Claude 3 类来源解析 frontmatter + 按 path 去重,返回 `[{name, description, argument_hint, triggers, source}]`;② 前端输入框 `/` 触发联想浮层(名称 + description`/name` 发送 → 后端读 SKILL.md 注入 context④ 跨平台 home 路径dirs crate
**C. 多工具 skill 体系调研结论(仅记录,后续按需扩展)**
| 工具 | 本机状态 | skill 机制 | 是否纳入 |
|------|---------|-----------|---------|
| Claude Code | ✅ 已装 | SKILL.mdskills + commands + plugins 三类) | ✅ 首批数据源 |
| Codex (OpenAI) | ✅ 已装 | SKILL.md`~/.codex/vendor_imports/skills/skills/.curated/*/SKILL.md`39 个figma / notion / playwright / security / vercel·netlify·render-deploy / latex 等frontmatter 与 Claude 一致,可统一解析) | ⏳ 后续可扩展 |
| openclaw | ✅ 已装 | 多 agent gateway`~/.openclaw/openclaw.json` 注册 8 agent 绑各 workspace + glm-5经飞书 channel binding非 SKILL.md`agents/` 实体目录暂空 | ❌ 属 agent 选择层,非 skill 联想,暂不纳入 |
| opencode | ❌ 未装 | AGENTS.md + custom agents + slash commands机制待确认 | ⏳ 待装后调研 |
**代码变更**A 路线 — `crates/df-ai/src/{anthropic_compat.rs, lib.rs}``src-tauri/src/commands/ai.rs``crates/df-nodes/src/ai_node.rs``src/views/Settings.vue``src/stores/ai.ts``src/components/AiChat.vue``src/api/types.ts`
**遗留问题 / 下一步**
1. **技能联想B已实现待实测**`ai_list_skills` IPC扫 skills/commands/plugins 三类 + frontmatter 解析 + name 去重)+ `ai_chat_send``skill` 参数读 SKILL.md 注入 system prompt + 前端 `/` 浮层(↑↓ 导航 / Enter·Tab 选中 / chip 显示 / Esc 关。cargo check ✓7 warning 既有)/ bun build ✓4.68s)。实测:重启 dev → AiChat 输入 `/` → 选技能 → 发送
2. **A 路线剩余场景实测**:切对话不中断(场景 2/3、错误友好化场景 4待用户实测
3. **B 路线(规划式能力)**coordinator / conditions 空壳,单独立项
### [Sprint 9] 2026-06-12 — 灵感模块评估闭环(启发式评分 + 对抗评估接 IPC
**工作内容**
- **df-ideas 修复与真实化**:① 修 adversarial.rs E0308 类型错(`AdversarialEval.negative: Argument` vs `generate_negative_argument``CounterArgument` 直接赋值df-ideas 实际编译不过——前文档"cargo check 通过"为误记)→ 删 CounterArgument、正反方归一 Argument② scoring.rs 三维固定 5.0 → 内容启发式priority / 描述充实度 / tags / 中英关键词clamp 0-10③ adversarial.rs 正反方论点/evidence 基于真实 idea 内容生成confidence 由评分驱动final_score=综合评分AssessmentLevel 由 overall 映射
- **devflow 接 df-ideas**`src-tauri/Cargo.toml` +df-ideas +chrono 依赖df-ideas 此前为孤儿 cratedevflow 未依赖、零 IPC 接入)
- **evaluate_idea IPC**commands/idea.rs取 IdeaRecord → record_to_idea 转 df-ideas::Idea → ScoringEngine + AdversarialEngine.evaluate → 组装前端扁平结构(对齐 Ideas.vue AdversarialEval interface→ 写回 scores中文维度 0-100/score0-100/ai_analysis/status=pending_review → 返回更新记录lib.rs 注册
- **前端接真实评估**api/idea.ts +evaluatestores/project.ts +evaluateIdea actionIdeas.vue 删 mockEval 调真实 + evaluating loading 态
- **审核修 2 bug**:① recommendation 大小写(后端原 "With Resources" 与前端 assessmentLabel 全小写 map key 不匹配致中文标签不显示)→ 全小写空格;② assessmentClass 生成的 class 与 CSS 类名不一致致 badge 无色 → map 映射到 .immediate/.soon/.conditional/.revised/.defer/.cancel
**代码变更**df-ideas/{scoring,adversarial}.rs、src-tauri/{Cargo.toml,commands/idea.rs,lib.rs}、前端 {api/idea.ts,stores/project.ts,views/Ideas.vue}8 文件)
**验证**cargo check -p df-ideas ✓、cargo check -p devflow ✓、bun run build ✓vue-tsc + vite 3.3s
**遗留问题 / 下一步**
1. 对抗评估仍启发式,未接 df-ai LlmProvider设计LLM 生成正反方论点 + 启发式 fallback
2. promotion.rs do_promote 仍 TODO晋升走前端 createProject 闭环,不经 df-ideas/promotion
3. evaluate_idea 用 list_all().find() + 5 次 update_fieldIdeaRepo 无 get/多字段更新,量小可接受)
4. IdeaGraph 关联图零接入(自动关联发现/聚类待续)
5. scores JSON 含「综合」维度也被雷达图渲染一行(小瑕疵)
### [Sprint 10] 2026-06-12 — AiChat 工具卡片自动折叠(卡片级折叠 + 新内容追加自动收起)
**工作内容**
- **需求**对话中工具调用卡片List Projects / List Tasks / Create Idea / List Ideas / 读取文件等)完成后仍整卡铺开,多步调用时界面臃肿。目标——展示更友好紧凑:所有卡片可点击 header 展开/收起,新内容追加时旧卡片自动收起为单行 header类似 ChatGPT/Cursor 旧 tool call 折叠)
- **卡片级折叠**(区别于 read_file 已有的内容级折叠):`.ai-tool-card` 内 body 区(骨架屏/审批/拒绝/file/dir/write/通用结果)包进 `.ai-tool-body``v-show` 控制显隐header 加 `@click` + ▸ 箭头指示器;新增 `expandedCards` Set + `toggleCardExpand` + `cardCollapseClass`,与既有 `expandedTools`read_file 预览级)职责分离不互相干扰
- **自动收起**deep watch `store.state.messages` + 轻量 JSON snapshot diff 检测新内容(新消息 / toolCall 状态变化 / 文本增长)→ 清除旧 completed/rejected 的展开态,保留 running/pending 活跃卡片;`isFirst` guard 防首次加载/切对话误触发
- **running/pending_approval 强制展开**(需看骨架屏与审批按钮);`v-show` 保留 DOM 避免重挂载
**代码变更**`src/components/AiChat.vue`template header/body 包裹 + script 状态与 watcher + style 折叠态),单文件 7 处改动
**验证**vue-tsc --noEmit ✓(运行时待 `bun run tauri dev` 实测多步工具调用折叠效果)
**遗留问题 / 下一步**
1. ~~审查项 ①~~ ✅ 已落地2026-06-12`isRunningOrPending(status)``shouldKeepOpen(tc)``running` / `pending_approval` / `rejected` / `write_file` 强制展开(短结果不折叠、原因/路径不丢失),仅 `read_file` / `list_directory` / 通用 JSON 大体量结果折叠。vue-tsc --noEmit ✓。决策详见 [功能决策记录 - 短结果保持展开](docs/02-架构设计/功能决策记录.md)
2. 实测验证tauri dev 发多步工具调用消息,观察"执行中展开→完成→新内容追加自动收起→点击 header 重展开"
### [Sprint 11] 2026-06-13 — AI Chat LLM 优化(上下文窗口管理 + 并行化)
**任务 #43 续**Part A + B 落地Part C/D 待续)
**工作内容**
**Part A: 上下文窗口管理df-ai/context.rs + ai.rs 接线)** — 长对话无限增长致 `context_length_exceeded` 死锁
- **A1 ContextManager**`crates/df-ai/src/context.rs` 新增 ~350 行TokenEstimator 字符粗估chars×0.35 + per_message 4 + per_tool_call 30零依赖保守 ±15%+ ContextConfigmax_tokens 128k / output_reserve 8192 / safety 0.85+ 分组滑动窗口淘汰——淘汰单元保工具调用三元组原子性ToolCallHead + ToolResultTail* + 紧随文本 Assistant 同进同出),保护区最后 6 条永不裁裁剪仅影响发送视图build_for_request 返裁剪 Vec不影响持久化all_messages_clone 返全量。5 单测全绿(短对话无裁剪 / 超预算裁剪保保护区 / 三元组原子性双分支 / replace 重估 token / restore 重建缓存)
- **A2 ai.rs 接线**~15 处AiSession.messages 类型 `Vec<ChatMessage>``ContextManager`;核心 run_agentic_loop 用 `build_for_request(sys_tokens)` 替代全量 `.clone()`save/title 用 `all_messages_clone()`switch 用 `restore_from_messages()``replace_tool_result` 收敛为 ContextManager 方法DRY删自由函数
**Part B: 并行化改造ai.rs** — 串行瓶颈 + Completed 事件阻塞
- **B1 process_tool_calls 并行化**Low 风险工具 `futures::future::join_all` 并行 execute + 即时 emit Completed结果串行回填 session.messagesN 个独立工具 ≈ 最慢一个耗时,原 N 倍串行Med/High 仍串行审批门控。tool_result push 顺序变化无语义影响LLM 按 tool_call_id 关联,不看绝对位置)
- **B2 正常完成后台化**save+extract+title 打包同一 `tauri::async_runtime::spawn`(非裸 spawn save——保 maybe_spawn_extraction 读已落库消息的顺序依赖Completed 事件即时下发
- **B3 标题后台化**`ensure_conversation_title` 签名收 `provider_config` 克隆进 task 自建 provider`&dyn` 非 'static 无法 move`spawn_ensure_title` 后台(含 2 处 stop 路径)
**关键取舍**:①打包 spawn 而非裸 spawn save保 extract 顺序依赖);②并发 upsert 低概率丢少量 token 可接受(非功能错误);③停止路径保持同步 save避免 stop 后即发新消息的并发 upsert 竞态丢 token
**代码变更**`crates/df-ai/src/context.rs`(新增)、`src-tauri/src/commands/ai.rs`(核心改造)、`docs/02-架构设计/功能决策记录.md`8 条新决策Part A 2 + Part B 3 + 既有的)
**验证**cargo check -p df-ai ✓5 单测绿、cargo check -p devflow ✓6 既有 warning无 error无单测回归
**遗留问题 / 下一步**
1. **Part C/D 未做**todo #48-52 已建)—— Part C 双层 Semaphoreglobal 默认 3 / per_conv 默认 2+ 3 LLM 调用点stream_llm / 标题 / 提炼)加 permit + `ai_set_concurrency_config` commandPart D Settings.vue 两 setting-row + localStorage 持久化 + onMounted 同步
2. **实测验证**P1tauri dev 验证长对话裁剪行为 + 多工具并行耗时 + Completed 事件即时性
### [Sprint 12] 2026-06-13 — 灵感模块全面审查 + A 类问题修复
**工作内容**
- **df-ideas 灵感模块全面审查**(前端 Ideas.vue / api / store + IPC idea.rs + crate 7 文件 + df-project/manager + df-storage/crud按「界面展示 / 交互 / 功能可用性 / 合理性」+「功能架构 / 代码逻辑 / 代码架构」六维逐条核对,共 12 项发现🔴5 🟡5 ⚪2。复核确认 12 项全部真实存在、无误判无虚报。
- **修复 A 类 5 项**(明确知道怎么做、零争议,全在 Ideas.vue
- ① 置信度进度条不显示填充(`::after` 无 width + 锚点跑到 `.debate-column`)→ 拆 `.confidence-bar`(灰轨)+ `.confidence-fill`(填充层,正绿反红),删失效 `::after`
- ② 状态 select 改选不生效v-model 绑只读 computed 致写失败、回弹并写回旧 status→ 弃 v-model`:value` + `@change``event.target.value`
- ③ 删 `filterIdeas` 空函数及其 `@input` 绑定filteredIdeas 本是 computed 自动响应)
- ④ 删除想法加 `confirm()` 二次确认
- ⑥ 对抗评估标题加「启发式」tag诚实标注当前为启发式非 LLM避免「对抗辩论」措辞误导
- **决策**:死代码/双套抽象组⑦⑧⑨⑩缓到另一会话届时重新审核问题真实性B 类(⑤⑥根治⑪⑫)方案未定,待定方向后再推。
**代码变更**`src/views/Ideas.vue`(单文件 9 处:模板 5 + script 3 + CSS 2 段)
**验证**`vue-tsc --noEmit` ✓(零错误零输出)
**遗留问题 / 下一步**
1. **B 类(有必要但方案未定)**:⑤ 立项引导(三种改法改变产品流程语义:放宽显示条件 / 保持 approved 门槛加提示 / 评估达标自动 approved/ ⑥ 对抗评估接 df-ai LlmProvider 根治(大工程,单独立项;当前 UI「启发式」标记为临时绕过/ ⑪ 状态常量集中(跨 Rust+TS 双侧IdeaStatus 枚举已有但 IdeaRecord 用 String 落库)/ ⑫ 实体↔Record 映射(评估为合理分层,建议不改)
2. **缓组(另会话重审真实性后再动)**:⑦ df-ideas 死代码空壳capture/graph/evaluator/promotionIdeaGraph 关联图是已知下一步增强需求,删/留需定)/ ⑧ 两套 Recommendation 枚举 + 两套评估入口并存adversarial 6 变体实用 vs evaluator 5 变体仅死代码引用)/ ⑨ PromotionPolicy 三档死枚举 / ⑩ Idea 实体构造分散record_to_idea 与 IdeaCapture::capture 字段重叠)
3. **实测验证**tauri dev 看置信度条彩色填充 / 状态切换生效 / 删除弹确认 / 评估区「启发式」标
### [Sprint 13] 2026-06-13 — 文档记录治理体系(路由规范 + decision-record skill + 降频自检 hook
**背景**:功能决策/需求散落于对话、PROGRESS、模块文档缺统一真相源与触发机制。建立「单一真相源 + 自动自检」治理体系。
**工作内容**
- **文档记录规范**`docs/02-架构设计/文档记录规范.md` 新建核心原则SSOT / 不复制只引用 / 决策与流水分离 / 先主后辅)+ 文档职责矩阵(每类信息唯一主文档)+ 内容路由表 + 更新顺序 + 唯一性记录与检测(记前 grep 查重 / 单向引用 / 定期扫描)+ 与 skill 关系 + 治理体系实现决策hook 设计取舍)
- **功能决策记录扩展**`docs/02-架构设计/功能决策记录.md`):约定节加需求条目说明;末尾新增「需求与待办」总览(📋 待做需求表 + 需求澄清)——散落各决策条目 📐/🚧 状态的待办汇集为单一清单
- **decision-record skill 增强**`~/.claude/skills/decision-record/SKILL.md`):除「为什么这么定」决策,增记需求细节(待做/规格/澄清);维护规则(记前查重 / 演进 `→` 标注 / 定期压缩防爆炸);原则补「更新优先于新增」
- **降频自检 Stop hook**`~/.claude/hooks/dr-check.sh` + `settings.json` Stop 配置):累计 ≥10 轮 或 (>1 轮 且 距上次 ≥10 分钟) 才注入自检提示触发 skill纯脚本计数无 API替代每轮自检省 ~90% token`stop_hook_active` guard 防循环;状态按项目隔离(`~/.claude/.dr-state/`,不污染 git。设计取舍详见 [文档记录规范 - 治理体系实现决策](docs/02-架构设计/文档记录规范.md)
- **修 `docs/INDEX.md` 误登记**PROGRESS 实际在根级,移除 `07-项目管理/` 树下的重复登记行
**代码变更**:非产品代码——`docs/02-架构设计/{文档记录规范.md,功能决策记录.md,INDEX.md}``~/.claude/{skills/decision-record/SKILL.md,hooks/dr-check.sh,settings.json}`
**验证**hook 逻辑实测(首战静默初始化 / 2-9 轮静默计数 / 第 10 轮或 ≥10 分钟触发 / 防循环 guard无 jq 依赖纯脚本
**遗留问题 / 下一步**
1. hook 实际长期触发频率待观察10 轮 / 10 分钟阈值是否合理,按需调)
2. 决策爆炸后执行首次压缩(> 300 行 / 老 Sprint > 3 / 单域 > 10 条触发归档或拆域)
### [Sprint 14] 2026-06-13 — 流式 token 用量记录 + Provider 默认态持久化
**工作内容**
**A. 流式 Token 用量获取 + 记录 + 展示 + 设置开关**(跨 df-ai/df-storage/src-tauri/前端11 文件)— `stream_llm` 全程丢弃 token 计数、`AiCompleted.total_tokens` 恒 0 的旧疾根治Sprint 6 P1 token 控制中「usage 采集用户叫停」项重启落地):
- **Provider 层 usage 解析**`StreamChunk``usage: Option<TokenUsage>`OpenAI 开 `stream_options:{include_usage:true}` 末 chunk 取累计 usageAnthropic `message_start`/`message_delta` 累积output_tokens 当累计值覆盖,非增量)
- **累加落库**`ai_conversations``prompt_tokens`/`completion_tokens`V5 迁移);`save_conversation` upsert 走累加模式(读旧值叠加,非覆盖——保审批暂停→恢复跨 loop 实例总用量正确);`run_agentic_loop` 局部累加器每轮叠加
- **前端展示 + 开关**store 双状态 `lastTokenUsage`(单次)+ `convTokenTotal`(对话累计,切对话从 DB 加载AI 气泡底部 token 条(默认关闭,`df-show-token-usage` 开关放 Settings
- **model 记录**:消息级 model + 对话级 models 数组C+B`default_model` 配置值补填不覆盖
**B. Provider 默认态持久化is_default 重启丢失 bug 修复)** — 「设为默认」重启后丢失、两条记录都显示「设为默认」按钮的 bug 根治:
- 根因:`is_default` 字段恒写 `false` + `ai_set_provider` 只改内存 session 不落库 → 重启 session 清零默认全丢
- 修复:`ai_set_provider` 互斥落库(目标 true/其余 false仅写变化记录`ai_save_provider` 新建首个自动默认;`ai_list_providers` 直返 DB 值;`active_provider_id` 降为运行时缓存
**代码变更**A — df-ai/{provider,openai_compat,anthropic_compat}.rs、df-storage/{models,crud,migrations}.rs、src-tauri/commands/ai.rs、前端 {types,stores/ai,components/AiChat,views/Settings}11 文件B — src-tauri/commands/ai.rs3 函数)
**验证**cargo check --workspace ✓0 error6 既有 warning、vue-tsc --noEmit ✓。**未 tauri dev 运行时实测**
**遗留问题 / 下一步**
1. tauri dev 实测token 落库 / 切换对话总量加载 / 重启保默认 / 首个自动默认
2. `ai_save_provider` get_by_id 双调用review 🟡①,冗余往返,待合并)
3. Settings 页面 UI 重构Part D用户说稍后
4. model UI 展示(暂缓)
### [Sprint 15] 2026-06-13 — 知识库 Tier 1 全栈打通 + Phase 5.5 向量检索
**工作内容**
**Tier 1 知识库双向闭环AI Chat ↔ 知识库,全栈打通)** — candidate→published 状态机 + AI 提炼 + 手动录入 + 知识注入:
**A. 存储层df-storageV7/V8 迁移)**
- V7 建表 `knowledges`id/kind/title/content/tags/status/confidence/reuse_count/verified/source_project/source_ref/created_at/updated_at3 索引
- V8 幂等补列 `embedding BLOB`PRAGMA table_info 探测,同 v4/v5/v6 模式)
- `KnowledgeRecord`models.rs`embedding: Option<Vec<u8>>`
- `KnowledgeRepo`crud.rs`search()`LIKE 双分支,按 kind 可选过滤)/ `list_by_status()`CASE WHEN confidence 语义排序)/ `increment_reuse_count()`SQL 原子 +1/ `top_used()`;向量扩展:`set_embedding()` / `search_vector()`(纯 Rust 余弦批量比较skip 维度不匹配);工具函数:`f32s_to_blob` / `blob_to_f32s` / `cosine_similarity`
**B. 领域层df-evolve**
- `KnowledgeStatus` 枚举Candidate/PendingReview/Published/Archivedsnake_case`from_str`/`as_str`
- `Confidence` 枚举High/Medium/Low同上
- `Knowledge` struct移除 `effectiveness` 字段,时间字段统一 String 毫秒(对齐全部既有 model
- `pattern.rs`:清理死参数 `result_quality: f32`
**C. IPC 层src-tauri/commands/knowledge.rs 新建11 个 Command**
- `knowledge_{list,get,search,create,update_status,record_reuse,list_candidates,archive,get_config,save_config,extract_now}`
- 状态转换合法矩阵硬编码candidate→{pending_review|published|archived}; pending_review→{published|archived}; published→{archived}
- `knowledge_archive`(软删除,匹配 `ai_conversation_archive` 语义)
- 配置读写:`knowledge_{get,save}_config`(读写 `AppState.knowledge_config: Arc<Mutex<KnowledgeConfig>>`
- 手动提炼:`knowledge_extract_now`
**D. AI 集成ai.rs知识注入 + 提炼)**
- `build_knowledge_context()``auto_inject` 开关 → `hybrid_search()` top-3 → `increment_reuse_count` fire-and-forget → 注入 system prompt 头部
- `extract_knowledge_from_conversation()`:后台 spawnmin_messages≥4 守卫 → 取最后 6 条消息 → LLM JSON 提炼 → 逐条写 candidate提炼失败仅 warn 不阻断
- `maybe_spawn_extraction()`agentic loop 两处正常退出统一调用(`OnComplete` 默认模式)
**Phase 5.5 — 向量检索Settings 开关,默认关闭)**
- `LlmProvider::embed()` trait 方法:默认返回 Erropenai_compat 实现 POST `/v1/embeddings`(按 index 排序)
- `KnowledgeConfig` 加三字段:`vector_enabled`(默认 false/ `embedding_provider_id`(排除 anthropic/ `embedding_model`
- `generate_embedding()`:截断 8000 字 → build_provider → embed()
- `spawn_embedding_for_knowledge()`:知识发布时 fire-and-forget 生成嵌入(不在 candidate 阶段浪费调用)
- `hybrid_search()`三层降级链——开关关→LIKE; embed 失败→LIKE; 正常→双信号排序(同时命中>仅 LIKE>仅向量 cos≥0.3);不引入 sqlite-vec规避 Windows MSVC C 扩展编译风险)
- `Settings.vue`:语义检索开关 + v-if 联动 embedding provider 下拉 + 模型名输入
**E. 前端TypeScript + Vue**
- `types.ts``KnowledgeRecord` / `CreateKnowledgeInput` / `KnowledgeConfig`(含 vector 三字段)
- `api/knowledge.ts`新建11 个 invoke 封装)
- `stores/knowledge.ts`完全重写getter 模式,消除全部 15 条 mock + localStorage
- `Knowledge.vue`(完全重写:知识库/审核收件箱双 Tab + 状态徽章 + confidence 指示器 + 新增对话框 + 候选 badge
- `App.vue`:侧栏候选 badge`candidateCount` refstore loadCandidates 后更新)
**F. 配置设计**AppState 内存 + IPC非 Tauri config 插件):
- `KnowledgeConfig`state.rsauto_extract / trigger_mode / min_messages / idle_timeout_ms / auto_inject / vector_enabled / embedding_provider_id / embedding_model
**代码变更**df-storagemodels.rs/crud.rs/migrations.rs/ df-evolveknowledge.rs/pattern.rs/ src-tauristate.rs + commands/knowledge.rs 新建 + commands/ai.rs + lib.rs/ 前端api/types.ts + api/knowledge.ts 新建 + api/index.ts + stores/knowledge.ts + views/Knowledge.vue + views/Settings.vue + App.vue。约 1,400 行 Rust + 700 行 TS。
**验证**cargo check 0 error ✓vue-tsc 0 error ✓。**未 tauri dev 运行时实测**
**遗留问题 / 下一步**
1. tauri dev 实测 10 项功能验证清单(手动录入 / 审核流 / 归档 / 检索注入 / reuse_count / AI 提炼 OnComplete / AI 提炼 Manual / 配置修改 / 注入开关 / 矛盾场景)
2. 向量检索待实测(需配 embedding provider + 开启开关 + 发布 ≥1 条知识后验证混合排序)
3. Tier 2 待做ai_node prompt 注入 / 工作流 NodeFailed→pitfall / 决策记录→architecture_pattern前置 traceability 持久化)
4. 知识库 API 对外暴露MCP Shell 封装,外部工具 Claude Code/CodeX/Cursor 使用)
### [Sprint 16] 2026-06-13 — AI Chat LLM 优化收尾(Part C/D + Review 修复) + AI Node 单测
**工作内容**
- **Part C LLM 并发控制**`state.rs` 新增 `LlmConcurrency`(双层 `Arc<Mutex<Arc<Semaphore>>>` — 全局默认 3 / 单对话默认 2,运行时替换内层 Arc 重建);`ai.rs` 3 个叶子 LLM 调用点(stream_llm / generate_title / extract_knowledge)加 permit,acquire 顺序固定 global→per_conv 防死锁,stream 后显式 `drop` 不占工具执行槽;新增 `ai_set_concurrency_config` command(运行时调并发上限);`lib.rs` 注册
- **Part D Settings UI**`Settings.vue` 通用设置区加「全局最大并发 / 单对话并发」两 setting-row + 前端 clamp(1-10 / 1-5)+ debounce 300ms + localStorage 持久化 + onMounted 启动同步 + onUnmounted 清 timer
- **Review 两轮 8 修复**:首轮 6(① per_conv 单例语义注释 / ② save-extract 并发注释改正 / ③ permit 显式 drop / ④ Settings clamp / ⑤ 合并 to_chat_messages 进 all_messages_clone / ⑥ system prompt 超 budget warn)+ 复审 2(后端 set_concurrency 补 clamp 边界对齐前端 / onUnmounted 清 debounce timer)
- **AI Node 单测**`ai_node.rs` 重构抽 `parse_params` 纯函数(execute 参数解析剥离,单测不 mock LLM 零网络)+ 7 单测(缺参×3 / prompt 上游优先回退 / config 取值 / 可选默认值 / 显式参数解析)
- **任务收尾**#43/#44 → completed(代码 + 单测全绿,GUI 实测转跟踪);新增 #54(GUI 动态实测跟踪任务)
**代码变更**
- `crates/df-ai/src/context.rs`(Review ⑤⑥ — 合并 to_chat_messages / system prompt 超 budget warn)
- `src-tauri/src/state.rs`(LlmConcurrency 双层 Semaphore + per_conv 单例语义注释)
- `src-tauri/src/commands/ai.rs`(permit×3 + drop / process_tool_calls join_all 并行 / save 后台 spawn / ai_set_concurrency_config command + clamp)
- `src-tauri/src/lib.rs`(注册 ai_set_concurrency_config)
- `src/views/Settings.vue`(并发 UI + clamp + debounce + onUnmounted)
- `crates/df-nodes/src/ai_node.rs`(parse_params 重构 + 7 单测)
- `docs/02-架构设计/功能决策记录.md`(新增「AI Node」域记 parse_params 决策 + per_conv 退化条目)
**验证**cargo check 0 error ✓ / df-ai context 5 单测 ✓ / df-nodes ai_node 7 单测 ✓ / vue-tsc 0 error ✓。**未 tauri dev 运行时实测**(转 #54 跟踪)
**遗留问题 / 下一步**
1. **#54 GUI 动态实测**(用户跑 tauri dev,Claude 核对日志):长对话裁剪(context_trimmed 日志 + DB 全量)/ 多工具并行(Low join_all 时序)/ save 异步不阻塞 Completed / 双层 Semaphore 限流(多对话撞 RPM)/ Settings 并发即时生效 + 刷新保持 / DAG ai 节点真调 LLM
2. ~~AI Node 可补 GLM 集成测试~~ ✅ 已补并通过:`glm_live_complete`(`#[ignore]` + env var)真调 GLM glm-4-flash 返回"通过",usage 解析正确(provider 调用层验证;GUI DAG 触发仍属 #54)
### [Sprint 17] 2026-06-13 — 模块文档↔代码一致性审查(4 文档纠错补全)
**工作内容**:
- **审查范围**:docs/03 模块文档(df-ai / df-storage / df-workflow)+ docs/01 技术文档(SQLite-CRUD 模式)共 4 份 vs 对应 crate 代码,三代理并行审查
- **🔴 硬伤 28 全修**:df-ai(LlmProvider trait 签名 / 删 OpenAI 虚构 idle-timeout + finished_received / ContextManager 方法名 replace_tool_result_content + build_for_request 返回元组 / Token 公式 / Anthropic usage take() / 工具归属)/ df-storage(V1 表名 / Repo 表名 releases·workflow_executions / search published 过滤 / increment_reuse_count updated_at / cosine epsilon / blob 截断)/ SQLite-CRUD 整篇过时(表 6→11 / CRUD 待→已 / 时间 INTEGER→TEXT / 写返回 ()→String·bool / 连接池→单连接 / schema.rs→migrations.rs)/ df-workflow(Node trait 按值 + 默认 false + node_type / 文件名 conditions·eventbus / 虚构事件区分已发未发)
- **⚪ 虚构 7 全清**:df-workflow(阻塞节点「等待人工操作」标未实现 / 持久化快照删改仅内存态 / 断点续跑补无暂停恢复机制)/ df-ai(conditions.rs 不存在,清状态表 + 决策缺口表虚构引用 / AiToolRegistry「12 工具」夸大改基础设施)
- **🟡 核心 8 + 碎琐 10 补全**:df-ai(apply_openai_sse / apply_anthropic_event 纯函数 / ContextManager 6 pub 方法 / Anthropic 事件全集 / 文件结构 router·stream / URL 三分支 / finish=length / max_tokens 4096 / PROTECT_COUNT / budget 公式)/ df-workflow(NodeRegistry / DagDef / StateMachine / Dag API / NodeContext·NodeOutput 字段 / EventBus API / 条件引擎默认放行 warn)/ df-storage(list_non_archived / set_archived 例外对照)
**代码变更**:无(纯文档纠错,代码未动)
**验证**:每项修正均经代理 Read 代码复核签名/SQL/行为后改;git diff 4 文档落地(df-ai 443 / df-storage 134 / SQLite-CRUD 56 / df-workflow 122 行变动)
**遗留问题 / 下一步**:
1. 4 文档已与代码实质一致;后续若改 df-ai/df-storage/df-workflow 公开接口,需同步对应模块文档(文档治理:模块文档随代码变)
2. df-evolve(knowledge.rs / pattern.rs)本轮未审 — docs/03 无对应模块文档,若补可另起审查
### [Sprint 18] 2026-06-13 — 知识生命线(详情页 + 溯源 + 引用 + 生命周期)
**工作内容**:
- **根因**:知识库 candidate 卡片点不开详情、不能编辑、看不到"为什么产生";reasoning 字段被 prompt 要求但写库丢弃(bug);increment_reuse_count 只 +1 不记去向;无状态变更历史。用户要求呈现知识完整生命周期:产生→审核→引用→归档,且约束异步不阻塞、代码简洁易扩展。
**A. 存储层(df-storage,V10 迁移)**:
- V10:幂等补 `knowledges.reasoning TEXT` 列 + 新建 `knowledge_events` 审计表(id/knowledge_id/event_type/source_ref/context_json/timestamp + 3 索引)
- `KnowledgeRecord``reasoning: Option<String>`;新增 `KnowledgeEventRecord`(6 字段)
- `KnowledgeEventsRepo`(impl_repo! 宏 7 方法 + 扩展 `list_by_knowledge`/`list_by_knowledge_type`);5 处显式 SELECT 列列举 + from_row + insert/update body 全线接 reasoning
**B. 后端埋点(src-tauri)**:
- **新建 `commands/knowledge_timeline.rs`** — `KnowledgeTimeline` 独立记录器(持 Arc<Database>),便捷方法 record_extracted/referenced/status_change/created,内部 `fire()` 吞错误 fire-and-forget。各业务流程只调一行,不内联写 SQL(代码简洁约束)
- `extract_knowledge_from_conversation`:回填 reasoning(修 bug)+ 查对话标题 + insert 后记 extracted 事件
- `build_knowledge_context`:加 conv_id 参数 + spawn 块内 increment_reuse_count 后记 referenced 事件(conv_id+query);调用点上移 conv_id 快照
- `knowledge_create/update_status`:记 created/status_changed 事件(归档复用 status_changed,删 dead code EVENT_ARCHIVED/record_archived)
- 3 新 IPC command:`knowledge_get_detail`(聚合 knowledge+events)/`knowledge_update`(部分更新编辑)/`knowledge_events`(查生命线);AppState 加 `knowledge_events` Repo;lib.rs 注册
**C. 前端**:
- types.ts:KnowledgeRecord 加 reasoning + 新增 KnowledgeEventRecord/KnowledgeDetailPayload/UpdateKnowledgeInput
- api/store:各加 getDetail/update/getEvents
- **Knowledge.vue 全面重构**:Ideas 式左右分栏(左卡片列表 @click 选中 / 右详情四分区 — ①基本信息+编辑 ②溯源(产生方式/来源对话/AI reasoning) ③引用记录(复用次数+最近 N 条) ④生命周期时间线)。可编辑 title/content/tags/confidence
**关键决策**(详见 docs/02-架构设计/功能决策记录.md):① 独立 events 表非 JSON 嵌主表(引用数百次防行膨胀);② 独立 KnowledgeTimeline 记录器(不散落埋点);③ 归档复用 status_changed(防冗余);④ reasoning 回填(修 prompt 要求但丢弃的 bug)
**代码变更**:df-storage(migrations/models/crud)+ src-tauri(state/knowledge_timeline 新建/ai/knowledge/lib/mod)+ 前端(types/api/knowledge.ts/stores/knowledge.ts/Knowledge.vue)= 12 文件
**验证**:cargo check --workspace ✓(仅既有警告)/ vue-tsc --noEmit ✓ 零错误 / cargo test -p df-storage ✓ 21 单测全过。**未 tauri dev 运行时实测**
**遗留问题 / 下一步**:
1. **#54 GUI 实测**:AI 对话结束→提炼→收件箱→点详情看 reasoning+来源;发布→生命线 status_changed;新对话注入→referenced 事件;编辑 candidate→保存
2. 老库历史 candidate 无 reasoning/events,详情页降级展示(手动录入/无溯源)——属预期兼容
3. knowledge_events 纯追加表,长期可清理 >90 天 referenced 事件(本次不做)
### [Sprint 19] 2026-06-14 — list_directory 防爆 + localStorage→SQLite 统一持久化 + token/发送 bug 修复
**工作内容**:用户报多个 AiChat bug + 提需求:list_directory 扫出 13782 项塞爆对话;token 显示"0 in";发送卡住/留框;LLM 并发上限太小;localStorage 散落要统一入 SQLite。同时用户并行主导 ai.rs→ai/ + ai.ts→composables 模块拆分(我观察配合,不接管)。
**A. list_directory 递归防爆(Part A)**:
- `list_dir_recursive`(ai/tool_registry.rs)加噪音目录剪枝(`.git`/`node_modules`/`target`/`dist`/`build`/`.next`/`.cache`/`__pycache__`/`.venv`/`venv`/`.idea`)——**列出但不深入内部**;硬上限 1000 条 + `truncated` 标志;默认 max_depth 3→2;加 `skip_noise_dirs` 参数(默认 true,AI 看编译产物 dist/target 时传 false)
- 根因:AI 广扫项目根传 `recursive:true`,噪音目录铺平致 13782 项塞进对话 message(UI 卡 + token 爆)
**B. localStorage → SQLite 统一持久化(Part B)**:
- 新建 `app_settings` KV 表(V13 迁移)+ 手写 `SettingsRepo`(get/set/get_all/delete,不走 `impl_repo!` 宏因 KV 无固定 schema);4 IPC(settings_get/set/get_all/delete);AppState 加 settings 字段
- 前端 `appSettings` store(reactive 缓存 + 300ms debounce + `useSetting` ref)+ api 封装
- **11 key 迁移**:敏感 `df-connections` + UI 偏好(theme/language/ai-width/ai-ui/token/concurrency)+ `df-ai-active-conv`;**例外 `df-ai-gen`/`df-ai-text`**(流式临时快照,高频写留 localStorage)。App.vue onMounted 一次性迁移旧 localStorage
**C. Bug 修复**:
- **token prompt=0**:GLM 流式 usage 带 completion 不带 prompt → 加估算兜底(provider 返回 0 时按请求消息 `TokenEstimator::estimate_message` 求和)
- **发送卡住/留框**:`sendMessage` IPC 失败时无 catch → streaming 永真(光标卡死)+ handleSend 回填输入(消息已显示);改 try/catch 回滚 streaming + 清空气泡占位
- **LLM 并发上限**:三层(模板 max / JS Math.min / 后端 .clamp)全去上限,保留 min=1 + `per-conv ≤ global` 约束
**D. token 暴增诊断 + 清理**:
- 查 SQLite 实数据:对话 e4365d47 累积 in=115万 / out=2万 / 消息体 1.6MB
- 根因:**单条 list_directory 工具结果 1.2MB**(13782 项,Part A 修复前产生)落库后每轮重发 + save 累加 → 暴增;token 估算准,膨胀是真(非估算锅)
- 删除污染对话(`ai_conversations` 1 行 + `ai_tool_executions` 123 行)
**E. 模块拆分(用户主导,本会话发生,我配合不接管)**:
- `ai.rs`(2651 行)→ `ai/` 11 子模块(agentic/audit/commands/conversation/knowledge_inject/mod/prompt/skills/stream_recv/title/tool_registry),旧 ai.rs 删
- `stores/ai.ts`(749 行)→ 薄壳 + `composables/ai/*`(events/stream/send/conversations/window/panel)
- `df-evolve` crate 移除(workspace/代码零引用)
- 踩坑(glob 重导出命令宏符号 / super 路径失效 / 0 字节残留触发 E0761)已记入经验记录.md
**关键决策**(详见功能决策记录 / 经验记录):① list_directory 剪枝 + skip_noise 保留访问能力(定点查/强制递归两路通);② KV 表统一持久化复用 SettingsRepo(兑现经验记录预言);③ token 估算兜底(provider 不报时按消息估);④ 发送失败回滚 streaming;⑤ 并发去上限保 per-conv≤global
**代码变更**:src-tauri(`commands/ai/` 新模块 + `commands/settings.rs` + state.rs + lib.rs)+ crates/df-storage(migrations V13 + crud SettingsRepo)+ 前端(api/settings.ts + stores/appSettings.ts + App.vue/Settings.vue/composables/ai/* + i18n)≈ 25 文件
**验证**:cargo check ✓ / vue-tsc ✓ 零错 / tauri dev 启动 ✓ 运行;token/发送/并发/list_directory 已实测
**遗留 / 下一步**:
1. **Fix 1(待用户最终定)**:工具结果入库前截断 50KB(堵 `read_file` 1MB 洞 + 防御);Fix 2(放宽旧工具结果裁剪)因 Part A 已杀主源,延后不做
2. Settings.vue(1037 行)拆 panel 子组件——早前建议,用户已做 ai.rs,此件待评估
3. 诊断日志清理(handleEvent/approveToolCall 早期调试 console.log 残留)
### [Sprint 20] 2026-06-14 — 项目管理模块代码审查 + 全局核对3-agent review 验证)
**工作内容**: 应用户要求审查「项目管理 / 项目导入 / 生命周期可用性」(后端 commands/project.rs + ai/tool_registry.rs + df-project/scan.rs + 前端 Projects.vue / ProjectDetail.vue。先 3-agent 并行 review 出 15 项发现,剔幻觉 2 项read_readme 命名误判 / conflict.name null 过度防御)后剩 13 项;再应要求**全局核对**grep 全仓库 6 维度)确认每项发现是孤例还是系统性,保证全局成立有效。**本次仅审查 + 核对,未改代码。**
**验证结论**: 13/13 发现**事实全部成立**无幻觉。4 处行号偏差(① 249→263 / ⑤ 113→136 / ⑫ 130→145 / ③ 未标→2712 处范围需补(⑧ 实 8 处非 3 处 / ③ 漏 relocate:212
**🔴 必须修复3**:
1. **AI delete_project 硬删绕过软删**tool_registry.rs:263 `repo.delete` 物理 DELETE vs IPC project.rs:120 `soft_delete` 进回收站)—— 同一操作两种后果AI 对话删 = 数据丢失不可恢复UI 删 = 可恢复。**数据安全缺口**
2. **AI 缺回收站生命周期工具**restore/purge/list_deleted 全无)—— ProjectRepo 有完整方法crud.rs:572/591/610/634+ IPC 全注册project.rs:125-145AI 层零覆盖,割裂工作流
3. **collect_sample 同步 IO 阻塞 async**project.rs:271 在 async fn 内直接同步调 df-project::scan—— 对比 scan_project_stack:182用了 spawn_blocking不一致
**🟡 建议改进6**: ④ normalize_path 两份重复project.rs:154 + tool_registry.rs:180/ ⑤ update 白名单双份不同步tool_registry:136 硬编码 vs crud.rs:287 allowed_columnsidea_id 字段不同步)/ ⑥ AI 扫描 + 目录状态文案硬编码未走 $tProjects.vue:33/195 + ProjectDetail.vue:93/ ⑦ parseStack 两份重复Projects.vue:143 + ProjectDetail.vue:321/ ⑧ 原生 alert/confirm全局 8 处非仅 ProjectDetail 3 处Ideas.vue:378/391 同病)/ ⑨ collect_sample 无文件大小预检scan.rs:151/205 read 全文后截断)
**⚪ 可选3**: ⑩ LLM 无超时project.rs:297 占 llm_concurrency permit 无限 await/ ⑪ JSON 提取取首尾花括号project.rs:368-369 多 JSON 场景错)/ ⑫ create_project 无 path 参数tool_registry:145 需 create+bind 两步)
**全局核对关键定性**6 维度 grep 全仓库):
- **① 是 project 特例但最该修**: soft_delete/回收站机制**全仓库仅 project 一张表有**task/idea/branch/release/workflow 本就物理删,无语义不一致);正因 project 唯一设计回收站AI 硬删直接击穿其数据安全设计
- **⑧ 系统性**: 全仓库 8 处原生弹窗ProjectDetail 4 + Projects 2 + Ideas 2非局部
- **③ 范围补报**: 不只 :271relocate_project_path:212 同步 detect_stack 同样阻塞3 处未包 spawn_blocking vs 1 处包了
- **src-tauri 层自身干净**: `std::fs` 同步调用零匹配,阻塞全在跨 crate 调同步的 df-project::scan
- **④⑤⑦ 精准**: 全仓库确为两份/一处无更多副本validate_path/resolve_workspace_path 是安全校验,职责不同非 normalize 重复
**未改代码**(待用户定推进批次)
**遗留 / 下一步(修复批次建议)**:
- **批1 数据安全**: ①AI delete 改 soft_delete+ ②(补 restore/purge/list_trash 三工具,复用 ProjectRepo 对应方法)
- **批2 阻塞 + 去重**: ③(:270/:271/:212 三处统一 spawn_blocking+ ④(抽公共 normalize_path 到 df-project/df-core+ ⑤tool_registry 复用 allowed_columns_for
- **批3 前端**: ⑥(补 i18n key+ ⑦(抽 src/utils/project.ts+ ⑧(全局 8 处 alert/confirm 换 Arco Modal
- ⚪ 可选: ⑨⑩⑪⑫ 按需
---
### [设计] 2026-06-14 — B-03 人工审批响应机制设计
**工作内容**df-workflow HumanNode 审批响应机制设计B-260614-03。勘察确认链路基础设施 90% 已通EventBus broadcast / `HumanApprovalResponse` 事件 / `approve_human_approval` IPC / 前端 store 已接通),唯一缺口为 `human_node.rs:55` 发完请求直接 return "同意"。设计:订阅时序铁律(`subscribe()` 先于 `send(Request)`+ `tokio::select!` 循环(响应 / 超时 / 取消)+ execution_id+node_id 双键过滤 + Lagged 容忍。澄清 B-06/B-07 前置真实影响B-06=并发隔离非单流功能前置B-07=取消必要非充分),拆 **B-03a**(响应等待 + 超时)/ **B-03b**(取消机制:`set_cancelled` + cancel IPC + 前端按钮)。
**产出**:完整设计文档 [B-03-人工审批响应机制.md](./docs/02-架构设计/B-03-人工审批响应机制.md)功能决策记录加「工作流人工审批节点B-03」摘要章节。
**下一步**B-06execution_id 下沉)/ B-07共享 StateMachine前置修复 → 落 B-03a 实现 → B-03b 取消机制补全。
### [Sprint 21] 2026-06-14 — Workflow 编排推进 Sprint 20 批次 + 审批闭环实施
**工作内容**: 以 workflow实施 + 对抗验证两阶段,文件域隔离 + prompt 钉死约束)并行推进 Sprint 20 审查发现 + df-workflow 审批闭环。先 commit 基线 cf017f8Phase2 阶段收尾 167 文件,排除无关的 `src-tauri/儿童每日打卡应用/`),后 A/B/C/D 四 workflow 各独立 commit 隔离可审。失控教训内化workflow 确定控制流替代 background agent stop hook 循环,全程禁碰决策记录 + 禁自主续推。
**A 数据安全**commit 3f0839a: AI `delete_project``repo.delete` 物理删改 `soft_delete` + 新增 `restore_project`/`purge_project`/`list_trash` 三工具(复用 ProjectRepo 回收站方法)+ `list_projects``list_active` 排除回收站验证捕的漏网LLM 原能看到已软删项目。tool_registry.rs。
**B 阻塞去重**commit d5a6417: `collect_sample`/`detect_stack` 四处 `spawn_blocking`(含验证捕的 bind_directory 漏网)+ `normalize_path` 抽公共到 `df-project/scan` + tool_registry `update_project` 复用 crud `is_allowed_column`(删硬编码白名单,与 CRUD 同源。scan.rs/crud.rs/project.rs/tool_registry.rs。
**C 前端**commit 02ff88f: 扫描/目录状态文案走 `$t`zh-CN+en+ `parseStack` 抽公共 `src/utils/project.ts` + 8 处原生 `alert`/`confirm` 全换confirm→ConfirmDialog / alert→Arco Message控制流语义不变。vue-tsc 0 error。8 文件。
**D 审批闭环**commit 22964a2: B-06 DagExecutor 接收 `execution_id` 下沉 NodeContext消除 dummy+ B-07 `node_status` 共享 `self.state_machine.clone()` + B-03a HumanNode `execute` 重写 `subscribe→send→select!`(响应/超时/取消 + execution_id+node_id 双键过滤 + Lagged 容忍,照 B-03 设计)+ eventbus 删 `try_recv_human_approval` 死代码 + human_node 7 单测。executor.rs/workflow.rs/human_node.rs/eventbus.rs。
**验证**: cargo check 0 error / df-storage 32 + df-project 4 + df-workflow 11 + df-nodes 14 test 全过 / vue-tsc 0 error。A/B 各 1 issuelist_projects 泄漏 / bind_directory 漏网主代理补修C/D 验证 safe 0 issue。
**遗留 / 下一步**: B-03b 取消机制(`set_cancelled` + cancel IPC + 前端按钮待做T-09/T-10 非阻断记 todo架构前置 df-ai-coreF-07待设计解锁 F-03。
<!--
### [Sprint N] YYYY-MM-DD — 简述
**工作内容**
- 具体做了什么
**代码变更**
- 修改了哪些文件/Crate
**遗留问题**
- 1. ...
**下一步**
- 1. ...
-->
---
## 七、开发约定
### 构建命令
```bash
# Rust 检查
cd E:/wk-lab/devflow && cargo check
# 前端开发
cd E:/wk-lab/devflow && bun run dev
# Tauri 开发(必须用这个,不能 cargo build
cd E:/wk-lab/devflow && bun run tauri dev
# Tauri 构建
cd E:/wk-lab/devflow && bun run tauri build
```
### 关键设计决策
1. **引擎不绑定业务** — Workflow Engine 只做 DAG 执行,阶段是插件
2. **无 panic** — 所有占位代码返回空/默认值,不使用 `todo!`/`unimplemented!`
3. **本地优先** — SQLite 嵌入,不依赖云服务
4. **想法第一公民** — 想法池独立于项目
5. **多任务/分支并行** — 同一项目多任务各绑 Git 分支
### 复用资源
| 资源 | 路径 | 复用点 |
|------|------|--------|
| u-desk-rust Tauri 经验 | `E:/wk-lab/u-desk-rust/` | Workspace + crate 拆分 + Tauri v2 |
| Rust proxy 工具链 | `E:/wk-oth/rust-work/` | 连接管理,内嵌调用 |
| Tauri 开发铁律 | Memory: `feedback_tauri_dev_rules` | 必须用 `cargo tauri dev/build` |