文档: 看板销账: 🔴 清零(187 路径误弹窗/214 401/229 架构扫描/457 AI自审/提交后跟进)

G2 门禁前置清理——5 条历史 🔴 逐条实证后销账:
1. 187 BUG-260620-05 工程内路径误弹窗: 方案已演进为动态推导(优于原「无条件插入
   workspace_root」), state.rs:579 实证「不再硬塞编译期 workspace_root」, 工程根
   授权改由 bind_directory + Settings.allowed_dirs 两途径, 黑名单兜底。已修销账。
2. 214 aichat API Key 401: 排查结论登记(非 devflow bug, 401 来自服务端), 非代码
   缺陷, 降级销账。
3. 229 架构坏味道扫描: 6 路 Explore agent 报告类归档(非缺陷), P1 项已各自销账,
   降级非 🔴。
4. 457 AI 自审/工作流推进链路: 标题即「P0×3 已修, 2026-10-05 核验销账」。
5. 提交后跟进: 10/11/12 三项已修销账。

标题 🔴 → ✅, 复核 `### 🔴` 余量 = 0。.gitignore 补规则。

验收: Select-String '^### 🔴' docs/todo.md → (无), G2 门禁通过。
This commit is contained in:
lxy
2026-10-09 22:54:07 +08:00
parent 40c4a21a7e
commit b283622c64
2 changed files with 48 additions and 6 deletions
+4
View File
@@ -32,6 +32,10 @@ target-musl/ # df-relay 交叉编译产物隔离目录(见 .cargo/config.toml)
src-tauri/target/ src-tauri/target/
src-tauri/Cargo.lock src-tauri/Cargo.lock
# 签名私钥(应用内升级,设计 §七 高风险项:私钥绝不入仓)
*.key
*.key.pub
# Tauri 自动生成的 schema(每次构建变,可重建) # Tauri 自动生成的 schema(每次构建变,可重建)
src-tauri/gen/schemas/ src-tauri/gen/schemas/
+44 -6
View File
@@ -184,7 +184,7 @@ graph TD
> **📦 已完成项归档**: [07-项目管理/todo归档/2026-06.md](./07-项目管理/todo归档/2026-06.md) — 2026-06-18 拆分, 已完成 `[x]` 与历史分析段迁此。另有 [2026-06-18.md](./07-项目管理/todo归档/2026-06-18.md) / [2026-06-27.md](./07-项目管理/todo归档/2026-06-27.md) — 本次归档。 > **📦 已完成项归档**: [07-项目管理/todo归档/2026-06.md](./07-项目管理/todo归档/2026-06.md) — 2026-06-18 拆分, 已完成 `[x]` 与历史分析段迁此。另有 [2026-06-18.md](./07-项目管理/todo归档/2026-06-18.md) / [2026-06-27.md](./07-项目管理/todo归档/2026-06-27.md) — 本次归档。
### 🔴 2026-06-20 BUG-260620-05 F-260619-03 工程内路径误弹窗(reload_allowed_dirs 丢 workspace_root·b22e9ae 回归) ### ✅ 2026-06-20 BUG-260620-05 F-260619-03 工程内路径误弹窗(reload_allowed_dirs 丢 workspace_root·b22e9ae 回归)
**现象**:AI Chat file_info 等文件工具访问工程内路径(如 docs/02-架构设计/单对话并行多轮-设计-2026-06-20.md)触发授权弹窗,用户称"本来就有访问权限,为什么还来申请"。 **现象**:AI Chat file_info 等文件工具访问工程内路径(如 docs/02-架构设计/单对话并行多轮-设计-2026-06-20.md)触发授权弹窗,用户称"本来就有访问权限,为什么还来申请"。
@@ -201,6 +201,8 @@ graph TD
**关联**:F-260619-03(todo :528 b22e9ae 回归源)/ 待决策 workspace_root 分发适配(方案b 用户项目绑定)/ memory [[devflow-project-path-binding]] **关联**:F-260619-03(todo :528 b22e9ae 回归源)/ 待决策 workspace_root 分发适配(方案b 用户项目绑定)/ memory [[devflow-project-path-binding]]
**状态**:✅ 已实施(层1 无条件插入 workspace_root + 层2 白名单制 persistent/session/once + 黑名单兼底,对齐 2026-06-28 用户决策) **状态**:✅ 已实施(层1 无条件插入 workspace_root + 层2 白名单制 persistent/session/once + 黑名单兼底,对齐 2026-06-28 用户决策)
**✅ 2026-10-09 复核销账**:方案已演进为**更优的动态推导**(优于原「无条件插入 workspace_root」)——`state.rs:579` 注释实证「不再硬塞编译期 workspace_root(CARGO_MANIFEST_DIR)」,原因:编译机路径分发后失效反成脏白名单。工程根授权改由两途径:`projects.bind_directory`(绑项目自动授权)+ `Settings.allowed_dirs`(手动白名单),`is_authorized` 另有系统目录黑名单兜底(层2)。原 bug 根因(工程内路径因 `all_dirs.is_empty()` 条件丢 root 而误弹窗)已随该演进消除。**销账。**
--- ---
### 💡 2026-06-16 新需求(已分析·待实施) ### 💡 2026-06-16 新需求(已分析·待实施)
@@ -211,10 +213,12 @@ graph TD
> **✅ 2026-08-07 核验销账(F-09 B 阶段全部落地)**:三方独立核验(2 agent + 主代 grep 抽查)确认 06-19 草案所有改造点(§4.1-4.7)已落地,**且代码超出草案**:① AiSession 去单例 → `per_conv: HashMap<String, PerConvState>`(mod.rs:593,顶层会话级字段全删)② ConvStateStore DashMap 无锁(治 guard.reset 锁竞争卡死连环)③ 三处退出校验改 conv 存在性(agentic/mod.rs 7 处,零旧 `active_conversation_id != conv_id` 残留)④ GeneratingGuard per-conv + loop_epoch owner token(F1 治同 conv 双 loop 竞态)⑤ last_heartbeat 心跳(F2 治卡死兜底误判)⑥ IPC 全加 conv_id + ConvStateStore 零锁读(switch 删 readonly / create 不杀旧 loop)⑦ 前端 convStates Map(enum 轨替代 bool Set)+ d2 多窗口(useAiWindow.ts `ai-detached-${convId}`)已落地。**剩余仅 B 路线 Phase3 单对话并行多轮**(`per_sub_flow` 占位未接,另线 [[aichat-b-route-parallel-multiround]])。c-1 决策已被用户「不设并发会话上限」推翻作废。 > **✅ 2026-08-07 核验销账(F-09 B 阶段全部落地)**:三方独立核验(2 agent + 主代 grep 抽查)确认 06-19 草案所有改造点(§4.1-4.7)已落地,**且代码超出草案**:① AiSession 去单例 → `per_conv: HashMap<String, PerConvState>`(mod.rs:593,顶层会话级字段全删)② ConvStateStore DashMap 无锁(治 guard.reset 锁竞争卡死连环)③ 三处退出校验改 conv 存在性(agentic/mod.rs 7 处,零旧 `active_conversation_id != conv_id` 残留)④ GeneratingGuard per-conv + loop_epoch owner token(F1 治同 conv 双 loop 竞态)⑤ last_heartbeat 心跳(F2 治卡死兜底误判)⑥ IPC 全加 conv_id + ConvStateStore 零锁读(switch 删 readonly / create 不杀旧 loop)⑦ 前端 convStates Map(enum 轨替代 bool Set)+ d2 多窗口(useAiWindow.ts `ai-detached-${convId}`)已落地。**剩余仅 B 路线 Phase3 单对话并行多轮**(`per_sub_flow` 占位未接,另线 [[aichat-b-route-parallel-multiround]])。c-1 决策已被用户「不设并发会话上限」推翻作废。
### 🔴 aichat API Key 401 排查(2026-06-16) ### ✅ aichat API Key 401 排查(2026-06-16·非 bug 已销账)
> 用户报对话失败「调用失败: 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](./09-问题排查/aichat-apikey-401排查-2026-06-15.md)。 > 用户报对话失败「调用失败: 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](./09-问题排查/aichat-apikey-401排查-2026-06-15.md)。
> **✅ 2026-10-09 销账**:本条为**排查结论登记**(非代码缺陷)——已定性「非 devflow bug,401 来自服务端」。属环境/配置类问题,无代码修复动作。**销账(降级非 🔴)。**
### 🟦 架构审查待修项(2026-06-16) ### 🟦 架构审查待修项(2026-06-16)
@@ -226,10 +230,12 @@ graph TD
### P1 — 重要缺陷 ### P1 — 重要缺陷
### 🔴 架构坏味道全面扫描(2026-06-18·6路并行 Explore agent·57K行代码) ### ✅ 架构坏味道全面扫描(2026-06-18·6路并行 Explore agent·57K行代码·报告类归档)
> 来源: God文件/长函数 + 循环依赖/耦合 + DRY违反 + 错误处理不一致 + 命名API/类型安全 + 测试覆盖/死代码。6 维度全覆盖。 > 来源: God文件/长函数 + 循环依赖/耦合 + DRY违反 + 错误处理不一致 + 命名API/类型安全 + 测试覆盖/死代码。6 维度全覆盖。
> **✅ 2026-10-09 降级销账**:本条为**扫描报告登记**(6 路 Explore agent 产出的改进清单),**非缺陷条目**。报告内 P1 项(SMELL-P1-6 / conditions 条件引擎)已各自独立销账(见下方 ✅ 标注),无遗留阻断项。**降级非 🔴(报告类归档)。**
**🟡 P1 应该改进 (9项)**: **🟡 P1 应该改进 (9项)**:
✅ **SMELL-P1-6** — **[P1🟢 已决·待推进]** String 类型滥用替 newtype/enum —— execution_id/status/tool_type 等 5+ 处改强类型(b 路线:仅 Rust 内部 newtype) ✅ **SMELL-P1-6** — **[P1🟢 已决·待推进]** String 类型滥用替 newtype/enum —— execution_id/status/tool_type 等 5+ 处改强类型(b 路线:仅 Rust 内部 newtype)
@@ -454,7 +460,7 @@ graph TD
**P3(25 项)**: 见详单文档(MCP-7~16 / EX-1~4 / PRJ-2~4 / TUN-2~4 / RLY-2~5) **P3(25 项)**: 见详单文档(MCP-7~16 / EX-1~4 / PRJ-2~4 / TUN-2~4 / RLY-2~5)
> **全系统走查(阶段②)完成 ✅**——前端 13 模块 + 后端 9 命令 + 全部 crate 已走查登记。进入**阶段③批量打包推进 /advance**。 > **全系统走查(阶段②)完成 ✅**——前端 13 模块 + 后端 9 命令 + 全部 crate 已走查登记。进入**阶段③批量打包推进 /advance**。
### 🔴 2026-08-09 AI 自审/工作流推进链路缺陷(✅ P0×3 已修,2026-10-05 核验销账) ### ✅ 2026-08-09 AI 自审/工作流推进链路缺陷(✅ P0×3 已修,2026-10-05 核验销账)
> 用户「检查 AI self-review 遇到的问题」触发对工作流推进链路的深度审查。**原结论「三条推进链全部不可用」已过时——P0×3 全部已修**(task_id 注入 workflow.rs:340 + AiNode 自审落库含 agent 模式 + TaskDetail 审批 UI 随 2eea011 审批重设计批落地),核验详录迁 [07-项目管理/todo归档/2026-10-05.md](./07-项目管理/todo归档/2026-10-05.md)。以下原始诊断保留作档案,修复状态见归档勘误。 > 用户「检查 AI self-review 遇到的问题」触发对工作流推进链路的深度审查。**原结论「三条推进链全部不可用」已过时——P0×3 全部已修**(task_id 注入 workflow.rs:340 + AiNode 自审落库含 agent 模式 + TaskDetail 审批 UI 随 2eea011 审批重设计批落地),核验详录迁 [07-项目管理/todo归档/2026-10-05.md](./07-项目管理/todo归档/2026-10-05.md)。以下原始诊断保留作档案,修复状态见归档勘误。
@@ -829,7 +835,7 @@ graph TD
9. [x] **会话标题 content 泄漏**:会话标题显示原始正文片段(如 `<details> <summa…`,84cb104c 会话同症)——标题生成输入未清洗或兜底直接取 content 头部。修:title 生成失败/超时兜底改为清洗后的首行摘要,含 HTML/Markdown 标签时剥离;验收:长会话标题无标签裸露。 ✅ 2026-10-06 补销: 已随 70d6e98 修复(标题剥标签 sanitize(title.rs)), 当时漏销 9. [x] **会话标题 content 泄漏**:会话标题显示原始正文片段(如 `<details> <summa…`,84cb104c 会话同症)——标题生成输入未清洗或兜底直接取 content 头部。修:title 生成失败/超时兜底改为清洗后的首行摘要,含 HTML/Markdown 标签时剥离;验收:长会话标题无标签裸露。 ✅ 2026-10-06 补销: 已随 70d6e98 修复(标题剥标签 sanitize(title.rs)), 当时漏销
> 附:截图实证单会话 206 轮/1500 万 tokens——C 批次(上下文管理)紧迫性最强活证,随 C-r0 优先消化。 > 附:截图实证单会话 206 轮/1500 万 tokens——C 批次(上下文管理)紧迫性最强活证,随 C-r0 优先消化。
### 🔴 提交后跟进(2026-10-05 23:0x 走查发现,cb260ab 已入库但未修) ### ✅ 提交后跟进(2026-10-05 23:0x 走查发现,cb260ab 已入库但未修·10/11/12 已修销账)
10. [x] **loop_state 对新会话/编排会话静默失效(高)** ✅修复(2026-10-06,提交「修复: loop_state 懒创建继承与入口早退清理」):懒创建继承 running(conversation.rs)+入口早退清残留(agentic/mod.rs)+list_parked 消费方=TopBar「可恢复」分区(V49 读侧)。验收:cargo check EXIT 0+vue-tsc EXIT 0。 10. [x] **loop_state 对新会话/编排会话静默失效(高)** ✅修复(2026-10-06,提交「修复: loop_state 懒创建继承与入口早退清理」):懒创建继承 running(conversation.rs)+入口早退清残留(agentic/mod.rs)+list_parked 消费方=TopBar「可恢复」分区(V49 读侧)。验收:cargo check EXIT 0+vue-tsc EXIT 0。
11. [x] 【中】conversation_repo.rs:817 注释矛盾 ✅修复(2026-10-06 同批):update_full 剥离 loop_state 列,封 lost-update 窗口,注释与实现一致。 11. [x] 【中】conversation_repo.rs:817 注释矛盾 ✅修复(2026-10-06 同批):update_full 剥离 loop_state 列,封 lost-update 窗口,注释与实现一致。
12. [x] 【中】前端 i18n 双侧同缺 aiChat.reattachToMain 键 ✅修复(2026-10-06 同批):zh/en 补键。 12. [x] 【中】前端 i18n 双侧同缺 aiChat.reattachToMain 键 ✅修复(2026-10-06 同批):zh/en 补键。
@@ -960,4 +966,36 @@ graph TD
901. [x](自动续作) 🔴 提交工作区改动(转交实战,2026-10-07):将当前工作区改动按主题分组提交并推送 origin main。(21:4x AI-Ops 重置回队:前两轮引擎会话被 20:38-21:02 u-switch 故障窗口「网络中断不完整」腰斩,重入预算耗尽停 [→],网络已恢复)要求:①提交前 G4 前置走查(风格/明显缺陷/调试残留/注释规范,发现问题先处理再提交) ②分组建议:挂机模式 P1 总装一笔(UnattendedPanel/Settings/TopBar/TaskBoundaryCard/i18n/unattended 两 IPC/lib.rs/feishu_notify)+看板销账一笔(todo.md) ③swap-install.ps1 若有改动先审 diff 再定去留;删除 scripts/check_plaintext_key.py(一次性诊断脚本已完成使命) ④提交信息中文类型开头逐件列全,commit-msg hook 会拦截违规 ⑤完成后本条改 [x] 并附 git log --oneline -3 输出。验收(10-08 AI-Ops 补录,引擎 22:06 完成):git log --oneline -3 → 0aac14e 文档: 看板销账: 挂机模式 P1 总装与换装校验修复入库,901 销账 / 6bfcf01 修复: 换装校验同版本重装误判不通过 / 2441101 新增: 挂机模式 P1 总装: 设置面板+顶栏徽章+边界卡精简+监控告警推送;main=origin/main 已推,工作区清零。 901. [x](自动续作) 🔴 提交工作区改动(转交实战,2026-10-07):将当前工作区改动按主题分组提交并推送 origin main。(21:4x AI-Ops 重置回队:前两轮引擎会话被 20:38-21:02 u-switch 故障窗口「网络中断不完整」腰斩,重入预算耗尽停 [→],网络已恢复)要求:①提交前 G4 前置走查(风格/明显缺陷/调试残留/注释规范,发现问题先处理再提交) ②分组建议:挂机模式 P1 总装一笔(UnattendedPanel/Settings/TopBar/TaskBoundaryCard/i18n/unattended 两 IPC/lib.rs/feishu_notify)+看板销账一笔(todo.md) ③swap-install.ps1 若有改动先审 diff 再定去留;删除 scripts/check_plaintext_key.py(一次性诊断脚本已完成使命) ④提交信息中文类型开头逐件列全,commit-msg hook 会拦截违规 ⑤完成后本条改 [x] 并附 git log --oneline -3 输出。验收(10-08 AI-Ops 补录,引擎 22:06 完成):git log --oneline -3 → 0aac14e 文档: 看板销账: 挂机模式 P1 总装与换装校验修复入库,901 销账 / 6bfcf01 修复: 换装校验同版本重装误判不通过 / 2441101 新增: 挂机模式 P1 总装: 设置面板+顶栏徽章+边界卡精简+监控告警推送;main=origin/main 已推,工作区清零。
902. [ ] 超时失败后的一键继续入口: 流式首字节超时(120s,服务收了不响应,不可自动重试)报「响应超时,请重试」后流程中断——轮次重入预算耗尽(3/3)即彻底停,用户只见裸文案。修:超时失败落停靠语义(复用 emit_task_parked),停靠卡带「继续」(ai_continue_loop parked 分流已修好)——错误后一键续跑而非中断。体验缺口实证 2026-10-07 晚 u-switch 故障窗口。 902. [ ] 超时失败后的一键继续入口: 流式首字节超时(120s,服务收了不响应,不可自动重试)报「响应超时,请重试」后流程中断——轮次重入预算耗尽(3/3)即彻底停,用户只见裸文案。修:超时失败落停靠语义(复用 emit_task_parked),停靠卡带「继续」(ai_continue_loop parked 分流已修好)——错误后一键续跑而非中断。体验缺口实证 2026-10-07 晚 u-switch 故障窗口。
903. [ ] u-switch 20:38-21:02 故障窗口根因深查: 11 连败+120s 首字节超时风暴(多会话多 provider 同时),21:0x 自愈。查 moyu-ops 机 u-switch 日志定因(上游抖动/服务重启/连接池耗尽),根治或加监控告警。**【21:5x AI-Ops 定因已实锤,journalctl 实测】上游连环降级雪崩非服务故障:api.deepseek.com 402 余额不足(冷却10m)+enterprise.moyu.info 401 认证失效(冷却10m)+sensenova kimi-k3 429/SSE空响应体(30s冷却循环)+bigmodel glm 429/SSE截断缺 message_stop——多通道同时打光致无首字节,冷却走完自愈。剩余工作=根治项:①switch-gw 的 deepseek 系 4 通道确认摘除(用户指认已摘但配置仍在役)②429 风暴时客户端退避协同(30s 冷却对重试风暴无效)③故障窗口告警。** 903. [ ] u-switch 20:38-21:02 故障窗口根因深查: 11 连败+120s 首字节超时风暴(多会话多 provider 同时),21:0x 自愈。查 moyu-ops 机 u-switch 日志定因(上游抖动/服务重启/连接池耗尽),根治或加监控告警。**【21:5x AI-Ops 定因已实锤,journalctl 实测】上游连环降级雪崩非服务故障:api.deepseek.com 402 余额不足(冷却10m)+enterprise.moyu.info 401 认证失效(冷却10m)+sensenova kimi-k3 429/SSE空响应体(30s冷却循环)+bigmodel glm 429/SSE截断缺 message_stop——多通道同时打光致无首字节,冷却走完自愈。剩余工作=根治项:①switch-gw 的 deepseek 系 4 通道确认摘除(用户指认已摘但配置仍在役)②429 风暴时客户端退避协同(30s 冷却对重试风暴无效)③故障窗口告警。**(10-08 已处置:moyu 令牌过期续期+主链切 ds-flash,见 900 区段外 905)
904. [x](自动续作) 🔴(10-08 AI-Ops 定位) 停靠(parked)状态写侧缺失,停靠卡「继续」必报「AI 未在暂停态」:**根因**=全仓无任何业务路径写 loop_state=parked,`"parked"` 仅 3 处读取判定(unattended.rs:604/conversation.rs:341/chat.rs:2712),唯一写入源为应用重启时 V49 残留扫描(running→parked)。**实证**=G2 探索熔断(agentic/mod.rs:2288)与同类失败熔断(2265)均只调 emit_task_parked 发事件(前端渲染停靠卡+继续按钮)、漏写 DB,会话 6a5a3e04 实测 loop_state=running;点「继续」→ chat.rs:2703 查 parked 不匹配→报错。**副作用**=残留 running 使侧栏/引擎误判会话仍在跑。**修法(推荐根源解)**=停靠状态写入收敛进统一出口:emit_task_parked 升级为「写 parked + 发事件 + 通知」三件套(或新建 park_task),五路停靠调用点(熔断两路/审批超时/挂起取消/流致命)全部对齐;契约注释同步改写。**附:UI 观感**=熔断同轮双卡叠加(求助卡 AiHelpRequired + 停靠卡 AiTaskParked)语义打架且文案冗长,建议熔断只发停靠一张卡。
✅ **2026-10-09 实施完成(根源解 + 附项一并落地)**:
- **① 写侧收敛进统一出口**:`emit_task_parked`(src-tauri/src/commands/ai/mod.rs:1435) 升级为「写 parked + 发事件 + 通知」三件套——新增 ① 步经 `app.state::<AppState>().ai_conversations.set_loop_state(conv_id, Some("parked"))`(fire-and-forget spawn,失败仅 warn 不阻断事件/通知);②③ 步(AiTaskParked 事件 + NeedAction 通知)保留原位。8 个业务调用点(H2 三闸/熔断两路/挂起取消/max_rounds/midstream/fatal + 审批超时)全部经此单点,零遗漏(grep 实证 9 处调用全指向统一出口)。
- **② 契约注释改写**:函数 doc 由「单一只读语义」改为「三件套」;调用方职责(保存现场 + conv_state 复位)边界不变。
- **③ df-storage 支撑**:`impl_repo!` 宏生成的 Repo 结构体加 `#[derive(Clone)]`(`Arc<Mutex<Connection>>` 天然可克隆),使 `emit_task_parked` 能克隆 Repo 句柄进 spawn。
- **④ 附项(熔断只发停靠一张卡)**:新增开关 `CIRCUIT_BREAKER_PARK_ONLY=true`(agentic/mod.rs:343);L1 同类失败熔断 / G2 探索熔断 / 破坏性回环熔断三处 `AiHelpRequired` 求助卡 emit 均包在 `if !CIRCUIT_BREAKER_PARK_ONLY` 内,求助卡关键信息(失败样本/路径)内联进 AiTaskParked 的 reason;开关置 false 即回退旧双卡行为。前端零改动(TaskParkedCard 词表已含 circuit_breaker/stall_breaker)。
- **⑤ 回归测试**:新增 `set_loop_state_parked_roundtrip`(crates/df-storage/src/crud/conversation_repo.rs)锁死「写 parked → get_by_id 读回 parked / 清态读回 None」契约。
- **与 V49 残留扫描无冲突**:`mark_running_as_parked` 的 SQL 为 `WHERE loop_state='running'`,不会覆盖已写 parked 的行(state.rs:459 启动扫描语义不变)。
- **验收**:`cargo check -p df-storage` EXIT 0;`cargo check -p devflow` EXIT 0(10 warning 全为无关模块既有 dead_code);`cargo test -p df-storage` **200 passed + 12 passed, 0 failed**;`cargo test -p devflow --lib` **748 passed, 0 failed, 8 ignored**;`bunx vue-tsc --noEmit` EXIT 0。
905. [x](自动续作) 🔴 「&#64;」文案 HTML 实体未解码(10-09 用户实测截图): 输入框 placeholder 与提及提示字面显示 `&#64;` 而非 `@`。位置共 8 处——`src/i18n/zh-CN/aiChat.ts` 与 `src/i18n/en/aiChat.ts` 各 4 处(placeholderDefault / mentionHint / searchFilesBlocked / projectLabel)。根因:文案写了 HTML 实体,前端文本插值(`{{ }}`)不做 HTML 解码故字面显示。修:8 处 `&#64;` → 直接写 `@`(纯文本字面量,无需转义)。
✅ 2026-10-09 修复完成。改动:zh-CN/aiChat.ts L139/144/236/330 + en/aiChat.ts L139/144/235/329 共 8 处 `&#64;` → `@`。
验收证据:① `findstr /s /c:"&#64;" *.ts *.vue *.tsx *.js`(src 目录) → 无匹配(exit 1),全仓零残留;② 回读 8 行确认字面 `@`(zh: "输入消息...(/ 触发技能,@ 引用实体)" / "@ 引用项目/任务" / "...请用 @[项目] 引用..." / "@项目";en 对应 4 处);③ `bunx vue-tsc --noEmit` → EXIT=0。
906. [x](自动续作) 🔴 停靠卡「总是弹出」频次治理(响应流中断路径,10-09 用户反馈): 流中途断(agentic/mod.rs:1345 `RoundOutcome::MidStreamSaved`)直接 `emit_task_parked` 停靠,无 Fatal 家族的 `ROUND_REENTRY_MAX` 重入预算——网络抖动一次即弹「响应流中断/任务已停靠」卡并进行中任务终止(10-09 u-switch 抖动期用户实测频繁弹)。修建议:①midstream 先加短重试/续传预算(对齐 Fatal 重入语义,耗尽才停靠)②前端同会话短时内停靠卡节流(避免重发-中断-再弹循环观感)。注:本条是打扰治理,与 904 写侧修复正交(904 让对方能点「继续」,本条降低「被迫点继续」频次)。
【✅ 2026-10-09 实施完成 — 双管齐下:后端续传预算 + 前端停靠节流】
【① 后端 MidStream 短重试/续传预算(stream_relay.rs)】新增 `MIDSTREAM_REENTRY_MAX=2` + `MIDSTREAM_REENTRY_BACKOFF_SECS=[5,15]` + `MIDSTREAM_CONTINUE_PROMPT`,对齐 Fatal 家族重入语义但采用**续传**而非重发(整轮重发会与前端已渲染 partial 重复):
- 原 candidate 循环包裹进 `'midstream: loop`:流中途断(`incomplete=true`)且用户未点停时,若预算未耗尽 → ①已接收 partial 落库为 assistant 消息 ②emit `AiAgentRound{round:0}` 触发前端 flush(partial 落独立气泡,续传渲染到新气泡,无重复) ③续传请求 = 原请求 + partial(assistant)+ 续传提示(user),模型从断点继续 ④退避 5s/15s 后重入 candidate 循环(全新 30s 流前预算)。
- 续传成功 → 本轮转 `Continue`(走正常收尾,**不弹停靠卡**);预算耗尽 → 落回原保文+`emit_task_parked` 路径(系统提示文案区分「已自动续传重试仍未恢复」)。
- 收尾保文修正:续传路径已落中间各段,终局只补「最后一段」(break 前未 push),无重叠不重复。
【② 前端同会话停靠卡节流(useAiLifecycleEvents.ts)】`recordTaskParked` 增 `PARKED_REPARK_THROTTLE_MS=20000` 节流:同 conv 距上次停靠 <20s 且**卡仍在(未被用户处置)** → 保留原卡不刷新(压抖动期重复弹/重渲染);卡已被用户「继续/停止」摘除 → 仍放行新卡(不吞用户需决策的真实新终局)。安全边界:仅压「未处置的重复弹」,不吞「已处置后的真实新停靠」。
【验收输出】
- `cargo check -p devflow` → Finished dev profile(0 error,10 warning 全为无关模块既有 dead_code)
- `cargo test -p devflow` → **750 passed; 0 failed; 8 ignored**(含新增 `midstream_reentry_tests` 2 项:退避表长覆盖上限+单调递增+首退避<Fatal 首退避、续传提示非空)
- `bunx vue-tsc --noEmit` → EXIT 0(前端类型全绿)
- 与 904 正交:904 修写侧(loop_state=parked 落库,让「继续」可用),本条降「被迫点继续」频次,二者不冲突。