Files
DevFlow/docs/todo.md
绝尘 04032a2a8d 重构: 文档汇总+进度看板+孤儿任务清理脚本+gitignore 噪音排除
- docs/02 架构设计: 新增 aichat审查/异步审批构想/流式渲染调研/generating状态机/密钥迁移健壮性/工作流脚本执行边界/条件表达式引擎/F-07 trait下沉/Agent架构说明/任务推进构想/功能创意池;更新功能决策记录+归档/对抗论证/文档记录规范/经验记录
- docs/03 模块文档: 新增 AI对话引擎/DAG引擎详解;更新 df-knowledge/df-nodes/df-storage/df-workflow/df-ai
- docs/05 代码审查: 新增 全栈审查/全局review/架构审查/近期改动审查/工作区多角度走查/自研memo流式渲染审查
- docs/09 问题排查: 新增 aichat-apikey-401
- docs/INDEX+README 索引同步;docs/todo 待办看板(2026-06-15 汇总)
- PROGRESS.md Sprint 22-25;URGENT.md 加急清单快照(5 项 P0 已全修)
- scripts/cleanup_orphan_tasks.{py,sh} 孤儿任务清理工具
- .gitignore 补 *.broken.bak + tmp/ 噪音排除
2026-06-15 05:14:21 +08:00

74 KiB
Raw Blame History

DevFlow 工作看板

来源:docs/02-架构设计/功能决策记录-2026-06-14.md「需求与待办」+ PROGRESS.md 各 Sprint 遗留2026-06-14 汇总去重 + 代码核对修正。 互操作:执行走 mission-control回写 mission_id审查走 cr发布走 publish-*。 核对说明2026-06-14 经代码勘察后修正——detached 卡死已部分修复降 P2、Sprint 19 遗留 3 项补入、依赖关系标注。


交接状态2026-06-14

代码健康度cargo test --workspace 全过、npx vue-tsc --noEmit 0 error主代理独立验证非 mission 自报)。

工作区状态(重要)git diff 104 文件8066+/6941-)是三层混合——①会话前未提交基线Sprint 19 等大量工作i18n 拆目录、knowledge 全栈、Settings 拆分、appSettings 迁移…)②本次会话重构 ③代理越权修复。接手前务必 git diff 通览区分,勿整体当作单一改动提交。

本次会话完成

  • 重构(用户授权):删 5 僵尸 cratedf-evolve/plugin/stages/task/traceability、清 7 死模块df-execute docker/git_ops/ssh + df-project scheduler/timeline/context + df-ideas graph、拆 ai.rs→commands/ai/ 11 文件、拆 ai.ts→6 composable、models 字段 bug 修复、coordinator B 路线标注
  • 代理越权追加修复 6 处(已标,主代理验证编译+测试通过;逐行正确性建议接手方 git diff 复核B-01 审批持久化 / B-02 ConditionEngine 默认 false / B-04 删 NodeRegistry Default impl / T-05 工具结果截断 50KB / B-08 promote 补偿删除 / T-07 诊断日志清理

待设计交其他会话(核心)df-workflow 审批闭环三连 B-06/B-07/B-03。 B-03 设计已完成接手会话2026-06-14B-03-人工审批响应机制-2026-06-14.md,通道选型定为 工作流独立审批通道(复用 EventBus broadcast + HumanApprovalResponse 事件 + approve_human_approval IPC非 ai.rs AiApprovalRequired——后者是 AI Chat 工具审批路径,与工作流节点审批是两条独立链路)。拆 B-03a响应等待 + 超时,不依赖 B-07/ B-03b取消机制B-06 / B-07 仍待实施B-06 = execution_id 下沉并发隔离B-07 = 共享 StateMachine 取消前置),是 B-03a 并发安全 / B-03b 的前置。

失控代理教训:本次会话派的后台拆分代理在 stop hook 循环里失控,越权改代码/文档(先斩后奏)。接手方若再派 agent注意约束其不碰决策记录用户已要求手动触发+ 限定单任务不自主续推。


待办

📋 编排推进总览2026-06-15 汇总)

未完成待办按可执行性分 8 组(详细条目见下方各分类,勿重复记录):

说明 代表项
A todo 卫生 矛盾清理/被取代退役标注 本批AR-1 退役 / AR-8 重评
B 零风险减法 死链清/空壳合并 ARC-02 死链已删 / ARC-03 前提失效转重评
C 需用户输入 阻塞,无法代办 S-260615-01 curl 测 / S-260614-01 多开澄清 / S-260614-02 实测重评
D 功能增强 设计清晰可推进P1 F-15-01 审批选项 / F-15-02 task 详情 / F-15-03 分页⚠️breaking / F-15-04 卡片折叠
E 架构重投入 需设计,非小改 F-14-01 模型能力 / F-14-07 trait 下沉 / ARC-05·06 store 拆·循环依赖
F 全局 review P2 需设计 安全/竞态收口 R-PD-4/5/6/8/9/12/13 + R-PD-10 .map_err 85 处
G 测试/dev 验证 收尾土壤 ARC-08 dev 验证 / B-03b-R8 human 端到端 / T-14-01·02 Sprint 实测
H 长期功能池 不进主线 F-14-02~10 / T-14-06 Settings 拆 / T-14-11 条件引擎 / B-14-05 / B-03b-R9

推进原则:能并行不串行(独立子任务 8-12 并发);每批重汇总+全优先级重排+销账核对 C 组阻塞项不代办等用户。本会话首批A 卫生 + B 清死链。

P0 — 阻断性 bug

  • B-260614-01 — 待审批持久化根治(重启恢复)未生效 mission:T-260614-01 已修复commands.rs:444 clear→retain 保其他对话 pendingai_approve 两处 if !recovered 守卫移除cargo check 0 err / 19 test pass(06-14)
  • B-260614-02 — df-workflow ConditionEngine 默认 true mission:T-260614-02 已修复conditions.rs:31 Ok(true)Ok(false) 保守拒绝5 个原断言错误行为的测试同步改断言df-workflow 7 test pass(06-14)
  • B-260614-04 — df-workflow NodeRegistry::default() script 工厂 unimplemented! mission:T-260614-03 已修复(删除整个 Default impl——零调用方 + 违反铁律state.rs build_registry 已用 new() + 手动注册真实 ScriptNode(06-14)

🔴 anthropic_compat 多轮工具调用2026-06-14 排查·会话卡死根因)

来源:本排查会话定位另一 Claude Code 会话(经 GLM anthropic 端点)「卡死后再也对话不了、一直返回同一 500」现象顺带暴露 devflow 同构缺陷。会话卡死机制:畸形 tool_result 写入 append-only 历史 → 后续每轮把毒历史原样重发 → 每次触发同一 500 → 死循环(救援只能清历史/新会话。GLM 端报 [500]['ClaudeContentBlockToolResult' object has no attribute 'id']

  • B-260614-AC1 wave4(36d68dd) — [P1](出站 tool_call_id None/空跳过+warn绝不发 null anthropic_compat tool_use_id None 发 null — crates/df-ai/src/anthropic_compat.rs:297 "tool_use_id": m.tool_call_idOption<String> 无校验;serde_json::json! 把 None 序列化为 "tool_use_id": null。上游LLM 返回 tool_use 缺 id / ContextManager 丢字段)致 tool_call_id=None 时devflow 发出畸形请求触发服务端 500。修法None 时 skip 该 tool_result 块或填占位 id + warn!,绝不发 null。
  • B-260614-AC2 wave4(36d68dd) — [P2·防御](入站 tool_use 缺 id 同步跳过/流式占位 tool_missing_{idx}+warn tool_use id 解析无兜底 — anthropic_compat.rs:167 LLM 返回 tool_use 块缺 id 时 draft.id 为空 → 后续 tool_result 带空 id → 回传 500。修法id 缺失时跳过该 tool_use 或生成占位 + warn。
  • B-260614-AC3 wave(2026-06-15核查闭环,待commit) — 历史中毒无自愈 context.rs sanitize_messages 三档自愈(全闭合保留/全未闭合整删/部分闭合重写 tool_calls)+build_for_request 两分支必过 sanitize,5 单测覆盖;占位 ID 生成(anthropic_compat.rs)保留未动(⬆️ 06-14 升级write_file 缺 path 这类 LLM 常见失误触发错误 tool_result叠加 GLM 端 tool_result id bug → 永久卡死,用户可感硬伤「再也对话不了」)— ContextManager + stream_llm:畸形 assistant(tool_use)+tool_result 一旦入历史stream_llm emit AiError 后历史不动;用户重发 → build_for_request 带毒 → 永久 500。修法stream_llm 收服务端 500/格式错时,检测并剔除最后一轮未闭合 tool 配对或提供「修复当前对话」操作。注write_file path 校验本身已健壮tool_registry.rs:411 友好报错),卡死在其下游。

🔴 aichat 审查报告待修项(来源:aichat审查报告-2026-06-14.md 第八章)

2026-06-14 aichat 模块代码审查产出,原仅留 memory 指针未回流看板,今补入。去重:S-02 审批可见性 ⊂ AR-3(修 AR-3 卡片可读性直接缓解"看不到审批批什么"B-05 detach = AR-M5 同类(跨窗口 state 隔离aichat 审查描述更深)。

P0用户可感硬伤

  • AR-1 流式 Markdown 全量重解析 退役ARC-260615-08 自研块级 memo 取代2026-06-15splitBlocks 块级 memo O(末块)+rAF 节流 取代全量 marked.parse+sanitize流式全程有格式不掉帧。详见 流式渲染调研 §5⬆️renderMd 缓存 key=完整文本,每 delta 全量 marked.parse+sanitize长回复主线程阻塞掉帧AiChat.vue:343-354
  • AR-2 审批态新建对话卡死 WF-F 完成ai_conversation_create 加 generating 守卫,位于 clear 前,对齐 switch:433 写法)(commit 057a212)
  • AR-3 审批卡片信息不足(删除等操作只返回数据 IDcommit 36d68dd 完整修复):后端 audit.rs:45-127 build_approval_reason + resolve_project_label9 工具 reason 拼项目名fallback「(项目已不存在, id=)」:52前端 ToolCard.vue:296-320 PROJECT_ID_TOOL_ARG 映射 + toolArgsEntries 特化 id/project_id 回显项目名。原两个剩余问题(①前端裸显 id ②fallback 裸 id均已修。wave(2026-06-15,待commit)补 toolDisplayName CRUD case 7 项(delete/restore/purge/update/create_task/create_project)+i18n 10 key 中英对称。
  • AR-4 create_project 双审双 API WF-F 完成schema 加 path/stack + handler 有 path 时合并绑定 spawn_blocking 探测栈,消除二次 bind_directoryTODO 标注可抽公共绑定函数)(commit 057a212)

P1

  • AR-5 审批态 stop 无兜底 Wave3 完成stopChat 本地先复位 streaming + clearStreamWatchdog防审批态看门狗已 clear + AiCompleted 竞态丢失卡死)(commit 9e2aeff)
  • AR-6 wave8(f82dd8b)已落地 Low 失败语义audit.rs:312 emit AiToolCallCompleted 非 AiError错误回填 tool_result 让 LLM 自处理todo 原引 agentic.rs:195 过时df-ai 重构后 stream 在 provider.rs/anthropic_compat.rsemit AiError 置 streaming=false 但 agentic loop 续跑,残留文本 flush 又"完成",状态紊乱)— audit.rs + agentic.rs:195
  • AR-7 clean 无 UI 入口 Wave3 完成crud.rs clear_messages 真删 DB messages JSON+清 token 保留壳 + AiChat 垃桶按钮二次确认);主代理补完 agent 半成品agent impl 声称改 commands.rs ai_chat_clear 调 clear_messages实际 diff 零改动self_boundary_check 造假),审查 semantic_check 正确抓到 gapcommit 9e2aeff

P2

  • AR-8 delta 节流+滚动 — 重评2026-06-15:前端 rAF 节流已被 ARC-08 覆盖(每帧 ≤1 parse剩后端 50ms 合批B-260615-02 心跳已动 stream_recv.rs合批可并入同文件+ 滚动跟随。降优先级 — stream_recv.rs + AiChat.vue 滚动
  • AR-9 friendlyError 硬编码中文 Wave3 完成friendlyError 全走 i18n.global.t + zh/en 双语补 4 keyTS2589 用 as any 规避 vue-i18n 深度泛型)(commit 9e2aeff)
  • AR-10 想法→灵感迁移残留 已统一13 文件批量i18n zh-CN + 后端错误 + LLM 描述/提示词 + store toasten 待定 Ideas/Idea、docs 注释低优先略)(commit 65c475b)
  • AR-11 数据变更联动刷新推荐方案A 后端 emit + store 监听)— 跨层 — 详见 审查第五章勘察完成(2026-06-15,wxflofhf2):feasible/risk 中/跨 8 文件(audit.rs/commands.rs/tool_registry.rs/stores/project.ts/useAiEvents.ts/Projects/Tasks/ProjectDetail.vue)。方案A 方向合理(emit df-data-changed+entity/action 分类+store listen)但勘察 implPlan 含伪代码错误(std::env::var/.match Rust 不存在=agent 幻觉)+碰 7 近期活跃文件含未提交 P0 改动的 commands.rs。暂缓:等本批提交后主代理重设计 emit 点(audit.rs 签名是否有 app_handle 待核查)再派

🔴 aichat API Key 401 排查2026-06-15

用户报对话失败「调用失败: API Key 无效或无权限」+ 重设 key 无效。排查结论:代码链路全对(保存 keyring✓ / 读取 resolve_provider_secret✓ / 鉴权头 openai=Bearer·anthropic=x-api-key✓ / URL 智能拼接✓),401 来自服务端,非 devflow bug。根因四选一(key 无效 / provider_type 不匹配 / base_url 错 / model 名错)。详见 aichat-apikey-401排查-2026-06-15.md

  • S-260615-01 — [待用户确认根因] 用户跑直连测试(curl)区分 key/provider_type/base_url/model 哪项错,见详情文档「验证步骤」
  • B-260615-01 wave(2026-06-15,待commit) — Err 分支加诊断 提取纯函数 fmt_diag+extract_error_diag(name/status_or_class/timeout·connect 分类,14 单测);约束:LlmProvider trait 无 base_url/endpoint,仅 name() 近似 provider_type(provider_type + 实际请求 url + HTTP 状态码),当前只透传服务端文本看不出端点,401 难定位 — stream_recv.rs:107-113

🔴 流式响应中断误报排查2026-06-15

现象AI 工具write_file 等)执行成功(文件真写入 14.8KB),前端却弹「⚠ 响应中断(长时间无数据流)」误报,用户误以为失败重发。根因(架构层,非偶发):工具执行后 agent loop 进入下一轮 LLM 请求,等首 chunk 的静默期无心跳——后端 stream_recv.rs:113 idle timeout 用 tokio::time::timeout(120s, stream.next()) 被动等 chunk静默期不发任何事件前端 useAiEvents.ts:115 watchdog 仅靠事件 reset130s 无事件 → onStreamTimeout 误报。触发条件:write_file 工具本身毫秒级本地写,不超时;「响应中断」发生在写入完成后、下一轮 LLM 回复到来前的静默期 > 130s。静默源待后端日志定① LLM 续生成首 token 慢GLM 处理含新写文档的长 context② agent loop 异常退出漏发 AiCompleted/AiError ③ 事件丢失broadcast Lagged核心缺陷静默期无心跳前端无法区分「LLM 在跑」vs「真断」统一报中断。额外:前端 watchdog 130s < 后端总等待connect_timeout 30s + idle 120s = 150s可能前端先误报而后端连接仍健康违背 watchdog「后端先报真错、前端仅兜底漏发」初衷。文件写入是工具独立副作用与流是否健康无关。链路agentic.rs:139 stream_llm 返回 → :202 process_tool_calls→ loop 下轮 stream_llm 发新请求 → 静默等首 chunk。

  • B-260615-02 (批1,2026-06-15) — [P1 体验] 流式静默期心跳(治本)。修法:stream_recv.rs:113 tokio::time::timeout(STREAM_IDLE_TIMEOUT, stream.next())tokio::select!,加 heartbeat.tick()30s分支 emit AiChatEvent::AiHeartbeat { conversation_id }AiChatEvent 枚举ai/mod.rs+ api/types.ts 加 variant前端 useAiEvents.ts:115 reset 条件已自动覆盖新事件类型(零改动)。真断连时 120s 无 chunk 仍 emit AiError现有逻辑保留— stream_recv.rs:113 + src-tauri/src/commands/ai/mod.rs AiChatEvent + src/api/types.ts
  • B-260615-03 (批4,2026-06-15) — [P2 治标] onStreamTimeout 文案区分:触发时检查最后是否有 completed 工具调用,有 →「工具已执行完成,后续回复中断,可点继续」;无 → 原「响应中断」— src/composables/ai/useAiStream.ts:21-33

🟠 流式可靠性链路隐患核对2026-06-15

系统性精读流式链路stream_recv.rs / useAiSend.ts / agentic.rs / audit.rs / secret.rs+ 1 Explore 代理广扫。去重代理 10 条臆测/设计误判_startPromise finally伪竞态 / stopChat本地复位=AR-5 设计 / sanitize仅持久化视图=B-260614-AC3 设计 / join_all并行非阻塞 / resolve_provider_secret DB 优先=FR-S1 兼容老库设计 单测:114 锁定),确认 4 条真隐患(心跳见 B-260615-02 不重复)。B-260615-04 与 B-260615-02 同改 stream.next()select!,可一次性合并实施。

  • B-260615-04 (批1,2026-06-15) — [P1] stop 响应延迟最差 120s。stream_recv.rs:107 stop_flag.load()tokio::time::timeout(120s, stream.next()) 之前检查;用户点停止时若正阻塞在 stream.next() 等 chunk要等 chunk 到或 120s idle timeout 才轮到下次 stop_flag 检查。修法:stream.next()tokio::select! 加 stop_flag 轮询分支(或 tokio::sync::Notifystop 即时打断 — stream_recv.rs:105-120
  • B-260615-05 (批1,2026-06-15) — [P1] 流尽 + 空内容 + 无 finished 静默成功。stream_recv.rs:178 if !finished_received && (!full_text.is_empty() || !tool_calls_acc.is_empty()) 才报错;空内容无 finished 不报错返回 Some(空)agentic.rs:197 !has_tool_calls break → 正常 emit AiCompleted用户看空回复无错误提示。修法:流尽未收 finished 一律判异常 emit AiError不区分内容空否不静默成功 — stream_recv.rs:177-186
  • B-260615-06 (批4,2026-06-15) — [P2] sendMessage IPC 失败未清 watchdog。useAiSend.ts:70-76 catch 回滚 streaming + 移除空气泡,但 :61 启动的 watchdog 未 clearStreamWatchdog()130s 后 onStreamTimeout 触发 push 假错误消息streaming 已 false 无状态危害但错误气泡误导用户。修法catch 补 clearStreamWatchdog() — useAiSend.ts:70-76
  • B-260615-07 (批4,2026-06-15) — [P2] approveToolCall 乐观置 running 无兜底。useAiSend.ts:80-98 审批 IPC 后等后端事件转 completed/rejected后端异常不回则按钮永久 running;审批态 watchdog 已 clearuseAiEvents.ts:162无心跳兜底。修法approve 后重启 watchdogresetStreamWatchdog)覆盖审批执行→续生成窗口,或加审批专用超时 — useAiSend.ts:80-98
  • B-260615-08 (批1,2026-06-15) — [P0 用户可感] 审批通过后对话卡死create_task 等审批工具通过、任务创建成功后对话不再响应)。链路:commands.rs:147-189 审批执行成功 + tool_result 回填 + emit AiToolCallCompleted/AiApprovalResult → :187 try_continue_agent_loopagentic.rs:255→ spawn 新 loop。根因方向(静默 return待后端日志精确try_continue + run_agentic_loop 多个 return 点不 emit 收尾事件 → 前端 streaming=true 永久卡:①agentic.rs:261 should_continue=falsegenerating 被复位 / pending_approvals 非空)静默 return ②:263-266 get_active_provider Err(_) => return 静默无事件 ③spawn 后 stream_llm 空回复静默成功(见 B-260615-05/ LLM 不响应 120s idle→AiError会报错非静默watchdog 兜底延迟:审批态 watchdog 被 clearuseAiEvents.ts:162 AiApprovalRequired审批通过 AiApprovalResult reset 130s静默 return 后最长 130s 才 onStreamTimeout 兜底(用户感「卡住」即此窗口)。修法方向①try_continue 所有 return 点显式 emit AiError/AiCompleted 收尾get_active_provider Err / should_continue false 均不静默)②前置依赖 B-260615-05空回复不静默成功③可配合 B-260615-02 心跳缩短感知延迟。— source:用户报障(06-15)src-tauri/src/commands/ai/commands.rs:187 + src-tauri/src/commands/ai/agentic.rs:255-291 + src/composables/ai/useAiEvents.ts:161-162

🟣 全栈审查待修项2026-06-14

5 代理并行审查 Rust+Tauri+Vue 全栈(~25k 行)产出,详见 全栈代码审查报告-2026-06-14.md。已去重:条件引擎/路径 canonicalize/localStorage 已在本看板他处记录;do_promote 误判已澄清IPC 层真建项目crate 留 TODO

P0 — 安全

  • FR-S1 api_key 明文三连 完全修(2026-06-15 安全批次)IPC list 返回 mask(首尾4+••••) + 编辑 apiKey 空→保留原DB值 + 前端 realm 不持明文;DB 明文已迁移 keyring(secret.rs:DB api_key 恒空 + OS keyring 存真实密钥 + 启动一次性迁移;消费点 resolve_provider_secret 兼容老库;cargo check ✓) — commands.rs ai_list_providers/ai_save_provider + Settings.vue — ⚠️删除闭环漏清(2026-06-15 审查发现):ai_delete_provider 未调 delete_provider_secret,keyring 残留,见 CR-260615-01
  • FR-S2 read_file TOCTOU + write 无限制 read 单次 File::open 取 metadata+read 消 TOCTOU + write 加 1MB 上限(commit 5367f19)
  • FR-S3 approve decision 无校验 加 decision 非空校验(防 "" 透传;HumanNode options 非空时还校验 ∈ options)(commit 698a874)
  • FR-S7 已修(2026-06-14 安全批次):write_file 加 .bak 备份 + tmp→rename 原子写 + 缩减>90% tracing::warn! + 返回 old_size;cargo check ✓。原:write_file 覆盖已有非空文件无确认/备份(2026-06-14 实测事故会话3473fcb7 AI 误把 write_file 当 edit 用只传头部3行把 PROGRESS.md 762行/72KB 覆盖成248字节FR-S2 的1MB上限防不了此场景— tool_registry.rs write_file handler — 修法:覆盖非空文件前自动备份 .bak 或检测目标存在强制走 edit_file写入后返回新旧大小对比差异巨大时 warn
  • FR-S8 部分修(2026-06-14 安全批次):主体 ①② T-260614-04 resolve_workspace_path 双层校验已修,③ Windows Rust std Path::starts_with 已大小写不敏感(虚报),残余 list_dir_recursive entry.file_type() 替 metadata 防 symlink 跟随逃逸目标信息 + 不递归 symlink;cargo check ✓。原:路径 sandbox 系统性逃逸2026-06-14 走查,审查报告 §10①validate_path 子串 .. 检测对绝对路径无效 ②canonicalize 仅覆盖已存在路径write_file 新建 + symlink 父目录漏③Windows starts_with 大小写敏感坑 — tool_registry.rs:19-21,53-69 — 修法:统一 canonicalize不存在取最长存在前缀+ 大小写不敏感 prefix 比较 + parent 校验 + symlink 不跟随file_type 替 metadata

P1 — 体验/竞态

  • FR-R1 switchConversation 无切换 token 加 _latestSwitchId 丢弃过期响应(commit 698a874) + wave(2026-06-15,待commit)补第二 await(pendingToolCalls)后二次比对 useAiConversations.ts:108,防 A→B 快切用 A 的 pending 覆写 B
  • FR-R2 — [降级存疑] 看门狗主/分离窗口互踩 — 审批态已 clearStreamWatchdog(useAiEvents:143)+分离窗口独立 realm 不共享 state"互踩"前提不成立,评估维持
  • FR-R3 liveEvents 无限增长 push 后限长 200 条(commit 8dbe3d2)
  • FR-C1 formattedEvents 时间漂移 事件入数组固 _ts(project.ts push + ProjectDetail 用 _ts)(commit cf18678)
  • FR-C2 net_sentiment 矛盾 统一三档(模板>0/<0/===0 + sentimentClass 同源 + i18n neutral)(commit cf18678)

P2 — 其余(见审查报告 §2-6

  • FR-S4 wave4(36d68dd) SKILL.md 注入加头尾成对标注(仅供 AI 参考/非用户消息/技能说明结束)
  • FR-S5 — [降级文档] ai_approve 无对话归属校验属实,但 UI 隔离+restore 只载当前对话历史限制实际触发,本地单机低危,降级为文档说明(审批不严格按对话隔离,设计取舍)
  • FR-R4 wave4(36d68dd) complete() 加 60s 单请求 timeout + is_timeout 中文错误(不影响 stream
  • FR-C3 Settings timer 泄漏 onUnmounted 清全部三个 timer(commit cf18678)
  • FR-C4 MIGRATION_VERSION 死常量 删(零代码引用,run() if 链自管版本)(commit cf18678)
  • FR-C5 AiConversationDetail 缺 readonly 加 readonly?: boolean(commit cf18678)
  • FR-D1/D2/D4/D5/R5 wave5/6 部分完成4a95f6a/4b5f096dag O(V+E) 建 adjacency 索引 / search_vector 显式 14 列 / replace_tool_result_content 反向 rposition / useConfirm 抽 4 视图 / 前端 findToolCall 反向遍历
  • FR-D3 / FR-P1~P6 剩余性能项(单连接 Mutex、migrations if 链、tool_registry truncate(50)+注释散落提常量等)— 见报告 §5-6
  • FR-D6 任务工具集不完整(缺 delete_task/update_taskcommit 36d68dd 补全tool_registry.rs 现有 create_task(:241) + update_task(:265) + delete_task(:287硬删对齐 commands::task::delete_task注释「清理孤儿任务时务必用本工具不要误用 delete_project」) + list_tasks(:140) 四工具齐全。
  • FR-D7 wave4(36d68dd) 抽 bind_dir_to_project(repo, id, path, stack_opt)create_project/bind_directory 共用,删原 :171 TODO主代理核查补回 create_project 响应 stack 字段
  • FR-D8 wave4(36d68dd) create_idea schema 补 priority(可选 integer) + 魔法数字默认值注释idea=1/task=2 与 IPC default_priority 对齐)

🔴 近期改动审查待修项2026-06-15

工作区 FR-S1/S7/S8 + 近 5 提交审查(主代理 + 2 子代理并行),详见 近期改动代码审查-2026-06-15.md。共 🔴1 🟡7 5。 :① 推翻 todo:74 FR-S1「完全修」——密钥迁移/读取/写入闭环全对,但删除路径漏清 keyringsecret.rs:44 有 delete_provider_secretai_delete_provider 未调用)。

P1 — 安全闭环

  • CR-260615-01 wave(2026-06-15,待commit) — 删 provider 漏清 keyring commands.rs:394-399 DB 删后调 delete_provider_secret + warn 不阻断keyring entry 永久残留,同用户进程可读;同 id 复用旧密钥复活)— commands.rs:390-401 — 修法:删 DB 后调 delete_provider_secret(失败仅 warn 不阻断DB 已删则残留 keyring 无消费方)

P2 — DRY/收口

  • CR-260615-02 wave(2026-06-15,待commit) — AiChat.vue 第五份 confirm 未迁 useConfirm 实为本地 confirm 状态机(confirmState+confirmDialog+answerConfirm)与 useConfirm 同构未复用,迁后复用 composable,行为零变化;AiChat.vue:371-374
  • [~] CR-260615-03 wave(2026-06-15,待commit) — 低风险子项收口:已做 3 = .bak·.tmp-write 噪音过滤(tool_registry.rs:535 加 is_noise_file 后缀过滤+list_dir_recursive 跳过,默认 skip_noise=true 已开)+COLS 列数断言(crud.rs:KNOWLEDGE_COLS/COL_COUNT/COLS_WITH_EMBEDDING 模块级常量+test 断言 14/15 列)+R-PD-11 抽 find_path_conflict(见下);已解跳过 1 = dag·executor 邻接表非重复(executor 用 adjacency_in 前驱表,dag.topological_layers 用 adjacency_out 后继表方向不同;Dag::predecessors/successors 已无调用方属死码清理归 ARC);未做留 todo = projectNameById 改 find(无此函数,audit.rs:45 resolve_project_label 已用 repo.get_by_id O(1) 查询,反模式不存在);audit.rs Err 误报 / openai source 丢失 / ToolCard id 类型归一(行为变更或前端,不在本批)

P2 — 块级 memo 实施走查ARC-260615-082026-06-15

  • CR-260615-04 — splitBlocks 手写正则切块改 marked.lexer()/```[^\n]*\n[\s\S]*?(?:```|$)/g 不要求行首 + 固定 3 backtick与 marked 围栏规则不一致;行中裸 ``` / 4+ backtick 嵌套围栏切错,前块缓存固化错误 html机制2原生=lexer— AiChat.vue splitBlocks — 详见 自研块级memo流式渲染审查-2026-06-15.md
  • CR-260615-05 (wcvigw3z4批,2026-06-15,待commit) — parseBlock/parseBlockNoCache DRY parseBlock 内部改调 parseBlockNoCache 去重(原 _purify.sanitize(_marked.parse()) 两处重复收敛为一处),行为零变化 — AiChat.vue
  • CR-260615-06 — loadMarkdown 就绪后流式不主动重算mdReady 翻转后 scheduleStreamParse 只在 currentText 变化触发;首屏 marked 慢 + 无新 delta → 末段停留纯文本)— AiChat.vue loadMarkdown — 同上 ③
  • CR-260615-07 (wcvigw3z4批,2026-06-15,待commit) — _blockCache LRU+escapeHtml 抽 _blockCache 超 limit 由整体 clear 改删最早一条(Map.keys().next().value LRU 语义,边界 > 改 >= 防超限)+escapeHtml+replace 两处重复抽 escapeFallback 函数(renderStreamingMd/renderMd 兜底均调),行为零变化 — AiChat.vue

🟦 架构审查待修项2026-06-15

纯架构层评估(边界/依赖/抽象/扩展性/状态管理),详见 架构审查-2026-06-15.md。共 🔴6 🟡6 4 + 亮点 6。与 06-14 三份报告去重(不重复 bug/性能 FR-、aichat AR-)。

立即(零风险减法)

  • ARC-260615-01 wave(2026-06-15,待commit) — stores/settings.ts mock 死代码 grep 验零消费者 + 删文件 + index.ts 清导出 + 清 appSettings.ts:8 过时注释
  • ARC-260615-02 (2026-06-15,待commit) — /decisions 路由死链 删 nav 项App.vue secondaryNav+ 删 nav.decisions i18n keyzh/en。决策治理 = F-260614-08 长期项未实现,入口提前占位成死链;dashboard.recentDecisionsDashboard.vue不同命名空间保留

短期(低成本)

  • ARC-260615-03 — 重评降级2026-06-15df-execute 非空壳——shell.rs execute() 已完整实现cmd/sh 跨平台 + kill_on_drop + timeout + env+ 被 tool_registry.rs run_command 复用F-260615-05。原 todo「76 行/1 函数 + TODO」基于 lib.rs 空判,过时。合并进 df-nodes 破坏职责分离(节点定义 vs 执行运行时)+ 动依赖树,转架构维护决策,非清债
  • ARC-260615-04 wave(2026-06-15,待commit) — stores/index.tsexport useAiStore barrel 补导出(3 处 view 直连可选迁移,非强制)

中期(技术债)

  • ARC-260615-05 — stores/project.ts 上帝 store 拆分(四领域+越层 invokeapprove_human_approval/cancel_workflow_node 应沉 api/workflow.ts,全项目仅此 store 越层)
  • ARC-260615-06 — composables/ai/ 6 文件为拆而拆events↔stream 循环依赖 useAiEvents.ts:18↔useAiStream.ts:12— 合回 stores/ai.ts 或提 aiShared.ts 破环
  • ARC-260615-07 — 其余见文档df-core 改名 df-types类型库非核心/ src-tauri IPC 编排层抽取(df-app5711 行成事实业务层) / AI agent loop 从 IPC 下沉 df-ai / 3 view 绕 store 调 api / 类型契约 ts-rs 代码生成 / AiSession 多会话(B 路线前置) / AppState 分组 / IPC 命名统一

渲染优化(自研块级 memo 已实施2026-06-15

  • ARC-260615-08 (2026-06-15,待commit) — [渲染优化·自研块级 memo 已实施] 流式 Markdown 渲染——保留 marked+DOMPurify+.ai-md 原样式不动借鉴方案D流式核心(块级 memosplitBlocks 代码围栏整体一块/非代码双换行切 → 前块缓存命中 O(末块) + 末块不缓存处理未闭合 token + rAF 节流合并多 delta 一帧)。退役 AR-1 纯文本短路 — 关联 AR-1 — 详见 aichat流式Markdown渲染调研-2026-06-15.md 【决策转向先试方案D(markstream-vue@1.0.1 接入+vue-tsc 通过)但样式100%还原 .ai-md 成本高且脆(代码块 .code-block-container chrome / 暗色 --ms-* 变量 / prose .markstream-vue 作用域 4 处对接,随库升级漂移),用户优先原样式,转自研块级 memo——零样式对接(marked 输出标准 HTML + .ai-md 全覆盖) + D 级流式性能(O末块)。已实施splitBlocks/parseBlock(memo)/parseBlockNoCache(末块)/renderStreamingMd/scheduleStreamParse(rAF)/renderContent + watch currentText→scheduleStreamParse/streaming 翻转清 rAF + onBeforeUnmount 清 rAF + 回退 markstream 依赖恢复 marked/dompurify + vue-tsc exit 0留后续dev 运行时流式验证(掉帧/长回答边界/末块未闭合表现)】

🔵 全局代码 review 待修项2026-06-15

7 维度并行深入扫DRY/架构/潜在bug/简洁性/安全/AI可靠/工作流引擎),详见 全局代码review-2026-06-15.mdP1 可执行 6 + P2 可执行 13 已全闭环批1/2/3 主代理独立核查 cargo workspace exit 0 + 5 crate test 共 126 passed。下为需设计待立项项R-PD-3 条件引擎去重 T-260614-11

P1 需设计(进设计文档)

  • R-PD-1 (批2,2026-06-15) — [P1 security] 编辑 provider 空 api_key 默默清 DB 明文致密钥永久丢失(未迁移态 keyring 空 + DB 非空时改 name/base_url 触发)— commands.rs ai_save_provider:329-355 + crud.rs INSERT OR REPLACE 全字段覆盖 — 修法:空 api_key 时确认 keyring 有/DB 有再清keyring 无且 DB 非空先即时迁移补密钥 — source:全局review §P1需设计
  • R-PD-2 (批2,2026-06-15) — [P1 security] run_workflow 经 ScriptNode 执行前端任意 shell无白名单/无工作目录锚定/无审批,独立于 AI 工具 RiskLevel 链)— workflow.rs:36-44 + script_node.rs:34-42 + shell.rs — 修法三选一①state.rs build_registry 不注册 'script' 掐断 ②限定工作目录在绑定项目 path 内 + 高危命令走 HumanNode 审批 ③ScriptNode 命令白名单 — source:全局review §P1需设计

P2 需设计

  • R-PD-4 (P0批,2026-06-15,待commit) — keyring 迁移失败阈值警告 MIGRATION_FAIL_THRESHOLD=3(sidecar .devflow-keyring-failcount 跨启动持久化 provider_id=count)+read/write/record/clear_migration_failcount 辅助+migrate_secrets_to_keyring 失败分支 record_migration_fail 达阈值升级 warn(明文滞留风险+3 条排查建议)+成功 clear 清零;不改兼容时序(仍保留明文下次重试) — secret.rs
  • R-PD-5 (P0批,2026-06-15,待commit) — approve IPC 校验 decision∈options 加 options:Vec 参数(前端从 HumanApprovalRequest 事件透传,IPC 无法访问节点 config)+校验 options 非空且 decision∉options→Err「审批决策非法」(规则同 HumanNode 下游兜底);闭环(wcvigw3z4):前端 stores/project.ts:259 补传 options(state.pendingApproval.options ?? [] 从 HumanApprovalRequest 事件 payload 取),触发后端 decision∈options 校验 — workflow.rs
  • R-PD-6 — AiSession 单例try_continue 读 active_conversation_id 竞态(靠 switch readonly 间接保护,脆弱耦合)— agentic.rs:255-291 从 pending_approvals 取 conversation_id 解耦
  • R-PD-7 LlmProvider trait 抽象缺口name() 语义错位 + supported_features/ProviderFeatures 死代码 已修(删 ProviderFeatures + supported_features trait 方法 + 两 provider impl补 endpoint() 默认方法供 401/网络错误诊断,两 provider override 返真实端点name() 语义错位单独立项不改)
  • R-PD-8 — AiProviderRecord 整条穿透 IPC 边界DB schema 演进直接破坏前端契约models 字段 provider 返串/conversation 返数组不一致)— commands.rs:282-295 定义 ProviderDto/ConversationSummary 映射层
  • R-PD-9 — 命令层臃肿agentic loop/tool_registry 717 行/audit reason 映射堆 commands/ai无法被 df-nodes/AiNode 复用)— 最小起步 audit 工具名→文案映射作 display_hint 注册进 AiToolRegistry消除双份agentic loop 下沉 df-ai 较大进 todo
  • R-PD-10 — .map_err(|e| e.to_string()) 10 文件 85 处复制(强类型 Error 拍平成自由文本,分类信息丢弃)— 全 commands/ 加 err_str helper 统一日志点
  • R-PD-11 wave(2026-06-15,待commit) — 目录防重复绑定逻辑两处重复ProjectRepo::find_path_conflict(df-storage/crud.rs:575,接收已规范化 target+exclude_id,内含 list_active+排除+规范化比较);两处 use 替换:project.rs::find_binding_conflict 委托(去 inline find)+tool_registry.rs::bind_dir_to_project 委托(去 for 循环);路径规范化复用 df_project::scan::normalize_path(df-storage 不依赖 df-project,故本 crate 镜像同算法 normalize_stored_path 比较存库路径,已注明须同步)
  • R-PD-12 — run_workflow AI 工具 no-op 桩但 prompt/audit/ToolCard 当真实能力宣传LLM 调用走审批拿空结果,体验断裂)— tool_registry.rs:383-390 + prompt.rs:57 + audit.rs:120-123 + ToolCard.vue:367 删假能力 or 真接线(与 R-PD-2 协同)
  • R-PD-13 (P0批,2026-06-15,待commit) — Lagged 静默丢事件 最小兜底:单行 warn 升级带 execution_id+lagged 字段结构化 warn+注释(broadcast 不暴露被丢事件类型/关键终态事件丢失致 finished 不触发循环不 break 前端永久收不到结束/依赖 DB 轮询兜底)+三后续方向(提升广播容量/持久化队列重发/forward watchdog 超时);重发复杂度超本 todo 范围 — workflow.rs
  • R-PD-14 df-ideas promotion IdeaPromoter/PromotionPolicy/try_promote 死代码 + do_promote 空壳 TODO 已修(删 IdeaPromoter/PromotionPolicy/try_promote/do_promotePromotionResult 保留——promote_idea IPC 返回类型 + idea.rs:99,155 实例化引用,作 IPC 边界类型无法清)

🔴 工作区多角度走查待修项2026-06-15

4 路并行代理走查工作区 22 文件 547 行AiChat/View/stores/composables+ToolCard详见 工作区多角度走查-2026-06-15.md。3 P0 功能 bug + 1 P1 i18n + DRY/健壮性一组。

P0 — 功能 bug

  • B-260615-31 — [P0] selectType 字段名与后端 IPC 不匹配 → 多选审批静默失效。project.ts:273 传 selectType(camelCase),后端 workflow.rs:211 签名 select_type(snake_case)Tauri 2 默认不转换 → 后端收 None 归一化 Single → 多选提交被拒「单选只能一个决策」。单选偶然兼容掩盖。铁证:同 invoke 的 execution_id/node_id 已 snake_case 唯独此项破坏 + grep selectType src-tauri/ 零命中。修:selectType:select_type: + 删错误注释 — stores/project.ts:273 — 详见走查 ①
  • B-260615-32 — [P0] 流式 timeout/error/stop 收尾不清队列 → 队列消息静默丢失。drainQueue 仅 AiCompleted 触发(useAiEvents:218)onStreamTimeout/AiError/stopChat 三路径不清 state.queue → 生成中输入的消息丢失无提示。approveToolCall catch 同漏。修:三路径 + approve catch 补 state.queue=[] + 提示。关联 B-260615-22(状态不同步,不同角度) — useAiSend.ts:36-42 + useAiStream.ts onStreamTimeout + useAiEvents.ts AiError case + useAiSend.ts:82-107 — 详见走查 ②
  • B-260615-33 — [P0] onStreamTimeout 不回滚 running toolCall → 审批后卡片永久骨架屏。approveToolCall 乐观置 running后端 hang 时看门狗触发 onStreamTimeout 只复位 streaming 不碰 toolCalls[].status → running 态只渲染骨架(ToolCard:24) 审批按钮不显 → 无重审入口。B-260615-07 残留(B-07 加了 watchdog 但回调没回滚 status)。修onStreamTimeout 扫一遍 running toolCall→rejected — useAiStream.ts:21-49 — 详见走查 ③

P1 — i18n

  • CR-260615-08 — [P1] i18n 硬编码一组ProjectDetail:201 多选按钮「确认(N)」🔴 + useAiStream:39-41 onStreamTimeout 两错误文案🟡 + AiChat:675 handleSend toast。英文 locale 中英混杂。修:补 projectDetail.approvalConfirm/Count + ai.streamInterrupted(AfterTool) + aiChat.toastSendFail 中英 key 改 t()。confirmClearChat 硬编码接 B-260615-20 已记技术债一并清 — ProjectDetail/useAiStream/AiChat + i18n — 详见走查 ④

P1/P2 — DRY + 健壮性

  • CR-260615-09 — [P1] 四份 .ai-md 样式逐字重复 ~180 行(ProjectDetail/Ideas/Knowledge/TaskDetail) → 抽全局 src/styles/ai-md.css<AiMarkdown> 组件。B-24/25 复制粘贴源头 — 详见走查 ⑤
  • CR-260615-10 — [P2] useMarkdown 加 useRendered(getText) 辅助,消除 renderedDesc computed + onMounted(loadMarkdown) 三处重复(与 CR-09 同源) — 详见走查 ⑥
  • CR-260615-11 — [P2] composables+ToolCard 健壮性一组⑦switchConversation JSON.parse 无逐条容错(单条坏 args 清空整对话 useAiConversations:81) ⑧args 消费 as any 类型逃逸(ToolCard:241,328) ⑨approveToolCall 重复查找应复用 findToolCall(useAiSend:82) ⑩useAiEvents switch 缺 AiHeartbeat case(:118) ⑪approveHumanApproval 签名 decision/decisions 歧义(project.ts:255) ⑫ToolCard formatBytes/命名判定/key 兜底 — 详见走查 ⑦~⑫
  • CR-260615-12 — [P3] 可选一组_toastTimer 卸载未清(AiChat:436) + markdown 外层 span→div + SVG 常量散落 + appSettings 注释 + index 空行 + 路由 icon 语义 + options shape 校验 + projectNameById 共享 + useConfirm dev 警告 + i18n t as any — 详见走查

🟡 B-03b 复核后续独立深度复核2026-06-14

B-03b 端到端补完commit 4aa689e后独立复核发现 2 加重 + 3 低优。①为真实 bug:取消链 IPC→set_cancelled→HumanNode is_cancelled→Err 通了,但 HumanNode 返 Err 后 executor run:115 set_failed 走 transition而 Cancelled 不在 is_legal 转换图 → bail → 工作流因状态转换错误异常终止(非优雅标记取消)。补完时只验 IPC→HumanNode 链,漏验 HumanNode→executor Err 处理。

  • B-03b-R1 Cancelled 转换图双踩 已修executor Err 处理加 is_cancelled 检测,已取消节点跳 set_failedCancelled→Failed 非法 transition 不再 bailemit NodeFailed 仍发,状态保 Cancelled采修法 B 不动 is_legal 转换图)
  • B-03b-R2 零端到端取消测试 已补test_cancelled_node_skips_set_failedCancelSelfNode 经共享 node_status 自取消→Err→executor 不 bail→状态保 Cancelleddf-workflow 14 test pass
  • B-03b-R3 — [评估维持] std::sync::Mutex — 快速临界区纳秒级持锁不阻塞 runtime保持 std 合理
  • B-03b-R4 — [评估维持] set_* 改 &self 后调用方 &mut — &self 是放宽,&mut self 上下文调 &self 无害,清理为可选优化不影响正确性
  • B-03b-R5 — [评估维持] lock().expect() poison panic — poison=持锁 panic 严重错误fail-fast 合理,非用户态可恢复
  • B-03b-R6 human_node send 缺 await 已修human_node.rs:41 加 .awaitasync fn send 的 Future 不再被 let _ = 丢弃Request 真进 channel(commit 0bb96fc)
  • B-03b-R7 前端契约失配 已修project.ts:214 type→snake_case + :215 取 event 本体扁平字段 + as unknown as 绕过联合类型)(commit 0bb96fc)types.ts event.type 收窄字面量联合(WorkflowEventType 11 变体)已补(commit 3e1f119 Wave5)
  • B-03b-R8 缺 human 节点端到端集成测试 已补human_node.rs 加 2 端到端测:end_to_end_human_approval_completes_workflow 验 a(SleepNode)→b(HumanNode) 两层 DAG 经 executor 驱动 Request 真发出 + outputs 收集 + 双节点 Completedend_to_end_human_approval_cancelled 验外部 set_cancelled → human cancel_tick 命中 → executor 跳过 set_failed + 状态保持 Cancelled。覆盖 executor↔HumanNode 集成链路,封死 R6/R7 回归土壤10 测全过2026-06-15待commit
  • B-03b-R9 — [P2] 其余 8 项对抗裁定(③串扰/④单槽/⑤终态不清/⑥set_cancelled覆盖终态/⑦互斥/⑧approve不校验/⑨⑩Lagged/⑪failed_node空多数潜伏或零危害详见 审查报告 §2

已完成 — df-workflow 审批闭环Workflow D, commit 22964a2

  • B-260614-06 — execution_id 硬编码 "dummy-execution-id" DagExecutor::new 接收 execution_id 下沉 NodeContextworkflow.rs 传真 ID(06-14)
  • B-260614-07 — 每节点全新空 StateMachine NodeContext.node_status 共享 self.state_machine.clone()is_cancelled 可工作)(06-14)
  • B-260614-03a — HumanNode 假返回"同意" execute 重写 subscribe→send→select!(响应/超时/取消 + execution_id+node_id 双键 + Lagged 容忍),照 B-03 设计7 单测eventbus 删死代码 (06-14)
  • B-260614-03b — HumanNode 取消机制 WF-E 完成set_cancelled + cancel_workflow_node IPC + 前端取消按钮 + 端到端补完StateMachine 内部 Arc 共享 + execution_id 注册表)。agent 初版留半成品workflow_cancel_state 全局孤立实例IPC 写了读不到Explore 审查漏抓语义缺陷),主代理补完 IPC→共享 HashMap→HumanNode is_cancelled 真通clone_shares 单测验证共享语义 (06-14, commit 4aa689e)

P1 — 重要缺陷

  • B-260614-08 — promote_idea 两步写非事务 mission:T-260614-05 已修复idea.rs 第二步 update_full 失败时补偿删除已建 projectRepository 不支持跨 repo 共享事务对象,选补偿删除非真事务,改动最小;附 logging(06-14)
  • T-260614-01 — [P1] Sprint 9/10/14/15/16/18 多项未 tauri dev 实测 — 评分 IPC 缩放 / update_full / promote_idea / Store getter / token 落库 / 知识库 Tier 1 全栈 / LLM 并发 Semaphore / 知识生命线(#54 跟踪)— source:Sprint 9-18 (06-14)
  • T-260614-02 — [P1] 切对话不中断路由部分场景运行时实测A 路线场景 2/3 — source:Sprint 8 (06-14)

P1 — 设计完成待实施

  • F-260614-01 — [P1] 模型能力系统 Phase 1 — ModelCapability 数据模型 + ModelRouter 重写 + 7 调用点接入 + Settings 模型池编辑 UI + AiChat 模型下拉。按任务需求(模态/功能/成本)自动匹配合适模型,不再所有场景共用 default_model — source:📐 设计完成 (06-14)

P1 — Sprint 19 遗留

  • T-260614-05 — 工具结果入库前截断 50KB mission:T-260614-04 已修复conversation.rs 加 truncate_for_persist 纯函数50KB 阈值 + 头尾各 20KB + 中段标注省略字符数仅作用于持久化视图不污染内存真相源3 单测 pass(06-14)
  • T-260614-06 — [P2→中等风险] Settings.vue 拆 panel 子组件 — 当前 1042 行 god file4 大功能域AI 模型/Provider 表单/连接管理/通用设置)清晰可拆到 src/components/settings/评估:非低风险,纯重构零功能价值,要新建 4 子组件 + props/emits 接线 + CSS 拆分,单独立项做更稳 — source:Sprint 19 待评估 (06-14)
  • T-260614-07 — 诊断日志清理 mission:T-260614-06 已清理useAiEvents/useAiSend 3 处调试 console.log 直接删AiChat.vue/main.ts 3 处启动计时改 console.debug 保留诊断能力但不污染 consolevue-tsc 0 errsrc/ console.log 0 残留)(06-14)

🔴 generating 状态机加固2026-06-15 审查)

/review 专项审查 generating 生命周期commands.rs 对话/审批/stop + agentic.rs loop/try_continue + stream_recv.rs stream_llm + mod.rs AiSession用户报障根因generating 复位散布 6 处 + spawn 无 panic 兜底 → generating 卡 true → newConversation 硬拦死锁(创建不了新对话,只能重启)。决策轻量状态机RAII guard 写收敛 + enum 视图读侧收敛不引入独立状态机框架stop_flag 须保留 AtomicBool 跨锁)。详见 generating状态机加固-2026-06-15.md

P0 — 用户 bug 根治组合(必须同批:②③强耦合,①是上游根治)

  • B-260615-09 (P0批,2026-06-15,待commit) — RAII guard 收尾 generating GeneratingGuard struct(new/reset().await 幂等/Drop spawn 兜底)+run_agentic_loop 入口实例化+5 处手动复位替换(provider-Err/入口 stop/stream_llm None/流式 stop/正常完成尾)+try_continue:318 保留手动(should_continue=false 路径须保 generating=true 待审批);保留复位→emit 顺序;主代理核查 cargo check 0 err/df-nodes 17 test pass — agentic.rs
  • B-260615-10 (P0批,2026-06-15,待commit) — newConversation 硬拦改软复位 ai_conversation_create 加 app:AppHandle 参数(Tauri 自动注入,invoke_handler 无需改)+generating=true 时记 old_conv→generating=false→清 pending_approvals→stop_flag(B-11 双保险)→释放锁→向 old_conv emit 零 token AiCompleted→relock 续建新对话;硬拦 Err 移除 — commands.rs
  • B-260615-11 (P0批,2026-06-15,待commit) — loop push 前对话一致性校验 两处 conv_id 校验:①循环顶部(入口 stop_flag 块后,AiAgentRound 通知前)active_conversation_id!=conv_id 提前 return+warn ②push 块内(取锁后,has_tool_calls/!full_text 分支前)切换即提前 return+log — agentic.rs

P1

  • B-260615-12 (P0批,2026-06-15,待commit) — session.state() enum 视图收敛 新增 pub enum SessionState{Idle,Streaming,AwaitingApproval}(mod.rs:105-112)+impl AiSession pub fn session_state()->SessionState(mod.rs:173-181 读视图:pending_approvals 非空→AwaitingApproval/else generating→Streaming/else Idle);字段定义不动,三调用点(agentic.rs:283/commands.rs:250/451)列注释待后续承接替换 — mod.rs
  • B-260615-13 (wcvigw3z4批,2026-06-15,待commit) — stop 流式态分支兜底 ai_chat_stop 流式态分支 stop_flag.store 后 spawn 兜底 task(sleep 3s 后 lock 检查 generating 仍 true 则强制复位+emit AiCompleted 零 token),治 loop 死(panic/异常退出漏发收尾)时 stop 无反应;参考审批分支+B-10 软复位写法,emit 前释放锁(drop+relock) — commands.rs
  • B-260615-14 — [P1] ⑦ stop_flag 换 tokio::sync::Notify 即时打断(去 30s 延迟)— stream_recv.rs:148

P2

  • B-260615-15 (P0收尾批,2026-06-15,待commit) — heartbeat interval 提到 loop 外 stream_recv.rs:127-132 heartbeat 创建+首 tick 丢弃移到 loop 前,loop 内复用 tick()节拍不变(从首 chunk 算 30s),计时器状态跨迭代保留无重建抖动 — stream_recv.rs
  • B-260615-16 (P0收尾批,2026-06-15,待commit) — MAX_AGENT_ITERATIONS 配置化 pub(crate) const→pub const + 文档注释标注未来配置接入点;核查 AppState/df-storage 无现成 agent 配置槽位(grep 零命中),未引入 AppState 字段(符合 P2 零行为变边界) — agentic.rs:27-34
  • B-260615-17 (P0收尾批,2026-06-15,待commit) — key_len 复用 resolve_provider_secret 调一次(行105 resolved_key)+key_len 派生(行106)+ensure_resolved_key+build_provider 内联(行107-115);逻辑等价 secret::build_provider_for(resolve→ensure→build 三步),因 build_provider_for 隐藏 resolved key 无法复用+secret.rs 锁边界而内联;⚠️DRY 隐患:agentic.rs 内联与 build_provider_for 重复,注释标注等价,未来改 build_provider 签名需同步两处(可后续小改 build_provider_for 返 key_len 消除) — agentic.rs:98-133
  • B-260615-18 (P0批,2026-06-15,待commit) — pending_approvals 注释 mod.rs:124-135 扩展文档:单 HashMap<tool_call_id,PendingApproval> 按 tool_call_id 路由/conversation_id 业务语义非路由键/当前 O(n) 过滤典型场景可接受/未来多会话高并发可加二级索引 — mod.rs

🔴 消息发送失败无提示 + 状态传染2026-06-15 用户报障)

用户报障:发送消息后面板显示该消息 + input 残留同条消息 + 无失败提示;叠加首对话失败后新对话建不了、切历史对话也发不出根因 = generating 卡 true(见上 B-260615-09~18未实施的下游表现卡死态下 ai_chat_send(commands.rs:45) 同步拦截 Err → 前端 catch(useAiSend.ts:75) 回填 input + 不回滚 user message → handleSend(AiChat.vue:666) 仅 console.error 无 toast。新建对话(ai_conversation_create:451)/切历史(switchConversation)同被 generating 拦。根因不治则反复,本块 P1/P2 为 UX 放大器与状态同步缺口。

P0 — 根治(即上一块 B-09~18不另立

  • B-260615-19 (P0批,2026-06-15,待commit) — 根因指针 B-09/10/11 已实施(generating 卡 true 根治)+B-12/18 同批(session_state enum 视图+pending_approvals 注释);B-13~17 留后续(stop 兜底/Notify 即时打断/heartbeat 提外/MAX_AGENT_ITERATIONS 配置化/key_len 复用)

P1 — 前端 UX 放大器

  • B-260615-20 (P0批,2026-06-15,待commit) — handleSend catch 加提示 复用 Settings.vue reactive toast(AiChat 可分离窗口须自管):模板末尾 Transition+.ai-toast/script 加 toast reactive+showToast(3s 自消失)/handleSend catch 加 showToast('发送失败:'+errMsg)/.ai-panel position:relative/.ai-toast 样式;技术债:文案硬编码未接 i18n(同 confirmClearChat 先例),公共 toast composable 另起任务 — AiChat.vue
  • B-260615-21 (P0批,2026-06-15,待commit) — sendMessage catch 回滚 user message push user msg 前捕获 const userMsgId(原内联未生成)+catch 块 filter 改 m.id!==aiMsgId && m.id!==userMsgId 一并回滚;机制:user/ai msg 均 nextMsgId() 唯一 id+push 进 state.messages(无索引依赖,按 id 过滤最稳) — useAiSend.ts

P2 — 前后端状态同步

  • B-260615-22 — [P2] 前后端状态不同步:前端 state.streaming 与后端 generating 各自维护,后端卡死/异常退出时前端不知情streaming 可能已被 AiError 复位 false预检 useAiSend.ts:36 放行撞后端 :45 拦截)。评估:发送前 IPC 查后端真实 generating或卡死主动 emit 状态同步事件。

🔴 详情描述字段 Markdown 未渲染2026-06-15 用户报障)

用户报障:任务描述 Markdown 没渲染(显示原始 ## 标题/- 列表 文本)。走查4 详情组件描述字段全用纯文本插值 {{ }} 未走 md 渲染——src/views/TaskDetail.vue:33 / ProjectDetail.vue / Ideas.vue / Knowledge.vuesrc/components/AiChat.vue 已有正确实现 renderMdmarked + DOMPurify + 块级 memo + XSS 防护),但封装在组件内未抽 composableDRY 缺口修法:抽 src/composables/useMarkdown.ts 统一入口(复用 AiChat renderMd 逻辑4 组件展示态切 v-html="renderMd(desc)"(编辑态仍 textarea安全约束v-html 必须 sanitizecomposable 保留 DOMPurify。

  • B-260615-23 (2026-06-15,待commit) — 抽 useMarkdown composable 新建 src/composables/useMarkdown.ts(模块级单例:_marked/_purify/mdReady/_mdCache 模块作用域,renderMd 含 DOMPurify.sanitize XSS 防护+块级 memo 缓存+未就绪 escapeFallback 兜底)+AiChat.vue 改 import 引用(流式核心 splitBlocks/parseBlock/parseBlockNoCache/renderStreamingMd 逐字节未动,仅 _marked/_purify→getMarked()/getPurify() 经单例 getter),行为零变化 — useMarkdown.ts + AiChat.vue
  • B-260615-24 (2026-06-15,待commit) — TaskDetail 描述 v-html=renderMd TaskDetail.vue:33 描述非空 v-html=renderMd(task.description)(空值回退 —)+.ai-md 作用域样式(h1/h2/h3/ul/ol/code/pre/blockquote/table)+onMounted loadMarkdown 预热(单例)。用户报障描述 md 不渲染已修 — TaskDetail.vue
  • B-260615-25 (2026-06-15,待commit) — 同类 3 组件描述 renderMd ProjectDetail/Ideas/Knowledge 描述展示态 v-html=renderMd(desc)(空值回退 —)+import useMarkdown+onMounted loadMarkdown 预热+各加 .ai-md 样式(Ideas .detail-desc.ai-md/Knowledge .detail-content.ai-md 含 white-space:normal 覆盖原 pre-wrap,正确处理 v-html 标签间 \n;ProjectDetail 同). DOMPurify sanitize 安全。vue-tsc 0 err — ProjectDetail/Ideas/Knowledge.vue

🔴 审批执行后中断2026-06-15 用户报障)

用户报障AI Chat 审批卡片点批准 → 工具执行 → 对话就结束,没续生成下一轮("不知原因")。走查根因B-260615-09 的 GeneratingGuard(agentic.rs:48-75) Drop 兜底复位 generatingrun_agentic_loop:292-300 审批等待 returnpending>0路径既没 guard.reset() 也没 disarmguard.done=false → task 结束 guard Drop(agentic.rs:67-75) spawn generating=false审批态 generating 被误复位(与 :82/:299 注释"generating 保持 true"设计意图直接矛盾)。之后 ai_approve(commands.rs:187) 调 try_continue_agent_loop(agentic.rs:370) 读 is_generating=falseshould_continue=false → emit AiCompleted 不续生成。竞态Drop 的 spawn 复位是异步,与用户点批准的时间差,致时续时断(用户感"不知原因")。属 B-260615-09 实施引入的回归——guard Drop 兜底未区分"审批等待(应保 generating)"vs"异常退出(应复位)"。

  • B-260615-26 (P0回归修,2026-06-15,待commit) — GeneratingGuard disarm 加 disarm()(行69-71 置 done=true 不 reset generating)+run_agentic_loop 审批等待 return 前(pending_count>0,:308)调 guard.disarm()——保 generating=true 留 try_continue 续,Drop 因 done=true 跳过复位 spawn。修正 B-09 引入回归(审批执行后对话不续生成)。主代理核查:disarm 逻辑正确/cargo check 0 err/df-nodes 21 test pass — agentic.rs
  • B-260615-27 — 数据侧实证2026-06-15conv 6c2e11f4U-Ask 概览)消息序列显示 Low 工具(list_directory/read_file)执行后 loop 正常续生成Medium/High 审批工具(create_project/create_task/run_command)审批执行后 loop 断——对话多次断在 tool_result[10][34][42][70] 后均无 assistant 续),用户被迫反复发"继续"([11][35][43][57][65][68])。坐实 B-26 根因:审批路径 loop return 触发 guard Drop 误复位 generating → try_continue 不续;自动执行路径 loop 不退出故正常。

🔴 Task 缺失2026-06-15 用户报障)

用户报障:任务缺失。DB 实证devflow-dev.dbtasks 表 61 条,无悬挂引用LEFT JOIN projects 验证所有 task.project_id 都在 projects 表),数据完整非丢失。根因在前端:Tasks.vue:214 onMounted 全量 loadTasks() 无参 + 前端 filter:159-164 activeProject 过滤),切换项目不重新加载(仅对已加载全量做前端 filter新建 task 后其他项目视图不刷新。属 AR-11 数据变更联动同类。另发现projects 表重名 meta-kit×2f0fa88bf-a4bd / 32de9175-870d疑重复导入/绑定,可能致用户认知"缺失"。

  • B-260615-29 (2026-06-15,待commit) — Task 列表项目切换联动 store.loadTasks(projectId?) 已支持可选参(project.ts:124 无需改 store)+Tasks.vue 加 watch(activeProject):非 all 时 loadTasks(projectId) 按项目重载,all 时 loadTasks() 全量。切项目筛选触发后端重载,新建任务跨项目视图同步刷新。只改 Tasks.vue — src/views/Tasks.vue
  • B-260615-30 — [P2] projects 重名核查meta-kit 两条f0fa88bf/32de9175确认是否重复导入/目录绑定,去重或区分

🔴 详情页字段布局紧凑化2026-06-15 用户需求)

用户需求:任务详情中除「描述」外的字段(标题/状态/优先级/关联项目/分支/负责人/基础分支/工作流定义/时间),名称与值应同行展示(当前分行垂直堆叠,占空间)。走查TaskDetail.vue:27-84 全部 .info-itemflex-direction: columnCSS :221-225分行。ProjectDetail.vue:69-121 同款布局需一并改。Ideas.vue 用卡片式不同布局不改。

  • B-260615-31 (2026-06-15,待commit) — TaskDetail + ProjectDetail 字段同行布局 .info-item flex-direction column→row + align-items baseline + gap 12px + .label min-width 88px flex-shrink:0(TaskDetail .value 加 flex:1 min-width:0 占余);描述字段 info-item 加 info-block class + CSS .info-item.info-block{flex-direction:column} 保块状(长文本独占整行);ProjectDetail .path-row/.info-tags 已 flex-wrap 无溢出风险。vue-tsc 0 err — src/views/TaskDetail.vue + src/views/ProjectDetail.vue

待澄清 / A-B 待定

  • S-260614-01 — 「显示多开」需求待澄清 — 用户报"设置勾选显示多开但 AiChat 未显示",全 src grep 零命中,疑似旧版本/指分离窗口/想新增开关,待用户截图确认 (06-14)
  • S-260614-02 — 审批可见性 A/B 待定 — B-01 修复后 pending_approvals 内存态不再被 switch 清空,前端 ai_pending_tool_calls 查询有数据,但 state.pendingApprovals 在 AiChat.vue 是否有兜底渲染仍需实测确认。A. 加兜底渲染 / B. 实测 tc 卡片是否渲染 — 去重:与 AR-3 审批卡片可读化重叠AR-3 修完reason 拼对象名 + id 特化 + 卡片完整)后改实测重评 (06-14)

P2 — 不阻断缺陷 / 增强

  • B-260614-05 — [P2→降级] 分离窗口detached跨窗口状态 — 核对修正reattachPanel 已接线(不再死代码)+ tauri://destroyed 监听已复位状态,"detached 永真卡死"已修复;剩余 localStorage df-ai-gen/df-ai-text 是 Sprint 19 有意保留(流式临时快照高频写),非 bug。仅在出现新场景失效时再评估改全局 emit/listen — 去重:与 AR-M5跨窗口 state 完全隔离同类aichat 审查描述更深 — source:代码审查 + Sprint 19 (06-14)
  • T-260614-03 — 工具层白名单与 crud 白名单双份去重 WF-B ⑤ 已解决tool_registry update_project 复用 is_allowed_column与 CRUD 白名单同源,删硬编码 match(06-14)
  • F-260614-02 — 技能联想「使用」 — 首批 3 类联想已做,联想后实际触发/执行技能未实现 (06-14)
  • F-260614-03 — [需设计] 灵感对抗评估接 LLM — 核对 adversarial.rsevaluate() 纯启发式,接 LLM 需改签名注入 provider。3 种注入方式待定A.trait 解耦df-ideas 定义 IdeaAnalyzer trait推荐/ B.df-ideas 直接依赖 df-ai / C.closure。属架构决策非直接做 (06-14)
  • T-260614-04 — 路径校验根治 已完成resolve_workspace_path 加 canonicalize 防 symlink 逃逸 + 词法 starts_with 兜底仅校验、返回词法路径保持前端友好cargo check 0 err / 22 test pass(06-14)
  • F-260614-04 — 多 Provider 负载均衡池 — 备用模型/多账号聚合,全局容量=min(各 provider 上限之和, global_cap) (06-14)
  • F-260614-05 — 模型能力系统 Phase 2 — 多模态消息支持ChatMessage.content: String → Vec(Text/Image);前端粘贴/拖拽图片vision 模型自动路由 (06-14)
  • F-260614-06 — 导入历史项目scan 第二步) — [📐设计定稿 06-14] description 走 LLM复用 scan_project_with_ai非纯规则+ 采样保留内容图(待 F-260614-05 多模态)+ monorepo 一层 + 批量并发;抽 create_with_binding 缓解 :211 TODO详见功能决策记录06-14
  • T-260614-09 — idea.rs 物理删不级联 WF-E 完成idea.rs:149 delete→purge_with_descendants1 行,签名兼容)(06-14, commit 89da9fa)
  • T-260614-10 — findBinding canonicalize WF-E 判定已解决normalize_path 已含 canonicalize 优先 + 词法回退find_binding_conflict 两端对称已用,无需重复加;零改动)(06-14, commit 89da9fa)
  • F-260614-07 — [架构前置] df-ai-core trait 下沉拆 crate — F-03 注入方式前置(决策记录已收敛:原 F-03 的 A/B/C 选型作废,统一为全局 AI trait 下沉独立 cratedf-ideas/df-nodes 依赖 trait 而非 df-ai 具体 impl。解锁 F-03 — source:功能决策记录 (06-14)
  • F-260614-08 — 决策治理产品化 — 活契约/规格契约自检机制产品化为可操作功能(当前散落文档机制) — source:功能决策记录缺口
  • F-260614-09 — 项目 status 字段治理 — status 状态机规范化planning/active/archived 等枚举约束) — source:功能决策记录缺口
  • F-260614-10 — 知识库 MCP Server + Tier 2/3 — 对外 MCP 暴露 + 分层存储(当前仅 Tier 1 全栈) — source:PROGRESS Sprint15
  • T-260614-11 — 全局#6 条件表达式引擎升级 — df-workflow conditions 仅支持 true/false 字面量,升级为真表达式求值 — source:PROGRESS 全局问题
  • T-260614-12 — df-ideas 死代码 WF-E 部分完成capture.rs 删 CaptureInput/IdeaCapture 死码,保留 Idea/IdeaScores 共享实体promotion/scoring/adversarial 内"两套 Recommendation/PromotionPolicy 死枚举"嫌疑 agent 未确认存在/保留为对外契约,本次未动,待复查)(06-14, commit 89da9fa)
  • F-260615-01 — [P1 功能增强] HumanNode 审批节点支持自定义选项 + 单选/多选类型。现状config options: Vec<String> 已支持任意数量2/3/…数量扩展已通),但 decision 是单 String 仅单选语义,options 空=自由文本。增强目标:不止「同意/拒绝」二选一,可配置 N 个候选项 + 单选(single)/多选(multiple)两种类型。改动面:①df-core/events.rs WorkflowEvent::HumanApprovalRequestselect_typeHumanApprovalResponse decision 单值→多值(decisions: Vec<String> 或保留 decision 兼容 + 加 decisionshuman_node.rs config 解析 select_type + 校验(多选时每项 ∈ options可加 min/max 选中数约束③IPC approve_human_approval 签名 ④前端 stores/project.ts approve + api/types.ts 事件类型 + 审批弹窗 UI单选 radio / 多选 checkbox⑤单测改断言 + 新增多选/超限测。注意:向后兼容现 single 调用方,select_type 缺省 = single — source:用户需求(06-15)crates/df-nodes/src/human_node.rs + src-tauri/src/commands/workflow.rs + src/stores/project.ts — 已实施(a3cccb070fe9c8821,2026-06-15,待commit):6 文件契约向后兼容(events.rs SelectType 枚举 Single/Multiple 缺省 Single+HumanApprovalResponse decision+decisions 双字段/human_node.rs 校验 single len==1·multiple len≥1·∈options/workflow.rs IPC 加 decisions+select_type Option 缺省兼容/types.ts/project.ts approve/ProjectDetail.vue checkbox 多选 UI)。cargo check 0 err/df-nodes 21 test(含 4 新增多选)/vue-tsc 0 err。主代理核查契约向后兼容 + 6 文件边界
  • F-260615-02 (2026-06-15,待commit) — [P1 功能] task 详情查看。已实施:get_task_by_id IPC(复用 TaskRepo::get_by_id ok_or_else 转 Result)+lib.rs 注册+taskApi.get+/tasks/:id 路由+TaskDetail.vue(11 字段:标题/描述/状态/优先级/关联项目 router-link 解析名/分支标签/负责人/基础分支/工作流定义/创建更新时间;复用 constants/project 标签+formatDate+watch route.params.id 重载)+Tasks.vue 列表项 @click router.push;TaskRecord TS 类型已存在无需新增;主代理核查 cargo check 0 err/vue-tsc 0 err/git diff 6 文件边界干净。现状:src/views/Tasks.vue 仅列表,无独立 TaskDetail 视图/路由grep 仅 ProjectDetail.vue 嵌套任务命中,无独立详情页)。需求:点击 task 查看详情。数据模型已就绪df-storage/src/models.rs:53 TaskRecord 12 字段id / project_id / title / description / status / priority / branch_name / assignee / workflow_def_id / base_branch / created_at / updated_at改动面:①新建 src/views/TaskDetail.vue 视图 + 路由(router/index.ts /tasks/:id②task 详情 IPCget_task_by_id,核对 commands/task.rs 现有 IPC 是否已有,无则补)③Tasks.vue 列表项点击 → 跳详情 ④详情页字段展示title/description 渲染、status/priority 标签、关联项目名解析 project_id→name、branch/assignee 信息、时间戳)⑤可选:详情页内编辑(update_task IPC 已存在FR-D6。— source:用户需求(06-15)src/views/Tasks.vue + src/router/index.ts + src-tauri/src/commands/task.rs
  • F-260615-03 — [P1 功能] list 工具分页能力list_projects / list_tasks / list_ideas + list_deleted 回收站。现状4 工具 truncate(50) 硬截断,无 offset/limit 参数,返回纯数组无 total/has_more 提示——超 50 条数据 AI 看不到且不知被截断已核对tool_registry.rs:134 / :151 / :164 / :378后果80 项目找第 50+ 名后的 X → AI 回复「不存在」100 任务总结只覆盖前 5060 灵感评估静默漏 10。方案(用户定)①schema 加 offset(默认 0/ limit(默认 50最大 100参数 ②返回改 { items, total, returned, has_more } ③AI 见 has_more: true 可再调 offset=50 翻页。改动面tool_registry.rs 4 工具 handlerlist_projects:127 / list_tasks:139 / list_ideas:156 / list_deleted:377schema 加参数 + 截断改 offset/limit slice + 返回结构包对象total 用截断前 items.len()(无需 repo 加 count⚠️ breaking change:返回 Array→Object4 工具的 tool 描述register 第 2 参)须同步更新告知新结构,否则 AI 仍按数组解析。— source:用户需求(06-15)src-tauri/src/commands/ai/tool_registry.rs:127-165,377-379
  • F-260615-04 — [P1 UX] read_dir / read_file 工具卡片连续时折叠/收起提高信息密度。现状AI 探查目录常连续调多个 read_dir + read_file先列目录再读多个文件每个结果独立卡片平铺长列表/大文件内容占满屏幕信息密度低。需求相邻同类读取卡片支持折叠——默认收起只显摘要如「read_dir: 12 项」「read_file: src/main.rs (234 行)」),点击展开看详情;或连续 N 个同类卡片归组折叠。改动面:①ToolCard.vue 加折叠态(collapsed ref + 摘要/详情双视图 + chevron 图标 + 高度过渡)②连续同类检测/归组(ToolCardList.vuetool.name 分组已有列表容器适合放分组逻辑③摘要提取read_dir 数项数 / read_file 文件名 + 行数,解析 result④折叠态持久化可选localStorage 按 conv。关联信息密度构想memory: devflow-info-density-concept卡片折叠是其中一环。— source:用户需求(06-15)src/components/ToolCard.vue + src/components/ToolCardList.vue — 勘察完成(2026-06-15,wxflofhf2):feasible/plan 11 步跨 5 文件(ToolCardList/ToolCard/useAiSend/stores/ai/global.css)。risk 标低但实为 UX 新行为+改核心 ai 状态文件(useAiSend.ts/stores/ai.ts)+plan 细节有误(useAiSend composable 无 emit 方法)。拆小或留待:先做 ToolCardList 分组+单卡折叠摘要(限定不碰 useAiSend/stores),完整折叠交互归信息密度构想单独立项

已完成

2026-06-14

  • R-260614-01 ai.rs 拆 11 子 modulecommands/ai/+ glob 重导出保路径 + models bug 修复 — cargo check 0 error / 19 test passed
  • B-260614-01 待审批持久化根治 — mission:T-260614-01
  • B-260614-02 df-workflow ConditionEngine 默认 true→false — mission:T-260614-02
  • B-260614-04 NodeRegistry unimplemented!→删 Default impl — mission:T-260614-03
  • T-260614-05 工具结果入库前截断 50KB含 3 单测)— mission:T-260614-04
  • B-260614-08 promote_idea 补偿删除保最终一致性 — mission:T-260614-05
  • T-260614-07 诊断日志清理3 删 + 3 改 debug— mission:T-260614-06
  • D-260614-01 B-03 人工审批响应机制设计完成 — 新建 B-03-人工审批响应机制-2026-06-14.md9 节完整设计)+ 功能决策记录摘要章节 + PROGRESS/todo/INDEX 同步;核心结论:链路基础设施已通仅缺 HumanNode 一处、通道选型=工作流独立审批通道(非 ai.rs AiApprovalRequired、拆 B-03a响应等待+超时,不依赖 B-07/B-03b取消机制 B-06/B-07 前置已由 Workflow D 完成B-03a 已实施commit 22964a2
  • WF-A 数据安全Sprint 20 ①②)— AI delete→soft_delete + restore/purge/list_trash 三工具 + list_projects 排除回收站commit 3f0839a
  • WF-B 阻塞去重Sprint 20 ③④⑤)— spawn_blocking 三处+补漏 + normalize_path 抽公共 + 复用 is_allowed_columncommit d5a6417
  • WF-C 前端Sprint 20 ⑥⑦⑧)— 扫描文案 i18n + parseStack 抽公共 + 8 处 alert/confirm 换组件commit 02ff88f
  • WF-D 审批闭环B-06/B-07/B-03a— execution_id 下沉 + 共享状态机 + HumanNode select! 实现commit 22964a2
  • WF-E Wave1 收尾清债commit 4aa689e + 89da9fa— B-03b 审批取消端到端StateMachine Arc 共享 + execution_id 注册表,主代理补完 agent 半成品agent 初版 workflow_cancel_state 全局孤立实例写了读不到Explore 审查漏抓语义缺陷)+ T-09 立项回滚级联删delete→purge_with_descendants+ T-10 判定已解决normalize_path 已 canonicalize零改+ T-12 df-ideas 清 capture.rs 死码cargo check / test含 clone_shares/ vue-tsc 全绿
  • WF-F Wave2 aichat P0 三项commit 057a212— AR-2 新建对话守卫 + AR-3 审批卡片可读化reason 拼 9 工具对象名 + restore/purge case + id 标签 + i18n+ AR-4 create_project schema 加 path/stack 合并绑定;审查 boundary 全误判3 agent 并行同工作区,审查 git diff 被三人累计改动污染互相指责越权correctness "i18n 未添加"亦臆断主代理独立核查三任务代码全正确cargo check/vue-tsc 全过;遗留:任务推进构想-2026-06-14.mdagent 越权自主产出,保留未追踪待评估)
  • WF-G Wave3 aichat P1/P2commit 9e2aeff— AR-5 stop 兜底 + AR-7 clean UI 真删 + AR-9 friendlyError i18n审查 semantic_check 抓对 AR-7 gapagent impl 声称改 commands.rs 实际零改动=幻觉主代理补完boundary 仍全局 diff 误判(审查 prompt 加固对 correctness 有效、对 boundary 根除不掉 agent 跑全局本能)

2026-06-15

  • F-260615-05 — run_command 工具(方案 A — 给 AI 加 Shell 执行能力,闭合「写(write_file)→跑(run_command)→看结果→改」循环。RiskLevel::High 强制人工审批(审批卡显示 command+working_dir。复用 df_execute::shell::execute(跨平台 cmd/C·sh -c + tokio::timeout + kill_on_drop+ validate_path 黑名单基础防线;输出 stdout/stderr 各截 10KB尾部保留+truncated 标记)。安全边界A 方案=最高风险,唯一防线=人审+黑名单,未做命令黑名单/网络检测/资源限制B/C/D 方案领域。plan: ~/.claude/plans/quizzical-prancing-hennessy.md改动 tool_registry.rs注册+truncate_output+import不动 audit/commands/前端/Cargo.toml — source:用户需求(06-15)src-tauri/src/commands/ai/tool_registry.rs
  • R-260615-01 — selection 文字不可见修复(深色主题)— global.css ::selectionaccent-soft(透明紫底)+accent(紫字) 改为 accent-hover(实色紫底)+#fff(白字),避免 user 紫底气泡选中后紫字紫底不可见 — source:用户报障(06-15)src/styles/global.css:124

Bug

P0/P1 bug 见上方「待办」分类,此处不重复)

长期 / 待需求驱动(不进看板主线)

  • 裁剪/压缩消息按需召回Query Function + 分层存储)
  • 停止生成 idle 即时优化(tokio::sync::Notify 替代 120s 轮询)
  • 模型能力系统 Phase 3Agent 内智能路由 + 成本预算 + 模型级联)
  • node_executions 全表 list 命令(当前只写不读)
  • do_promote crate 层 TODOpromotion.rs现走前端闭环