# 定时代码走查 — 第 7 轮(2026-06-15) > 触发:定时走查 cron(每 30 分钟)。范围 = **stores 独立 store 垂直切片**(ai/knowledge/appSettings/index,未审)+ 核 CR-24/26/27 修复。 > 方法:主代理 git show 3 提交 + 1 路代理走查 stores。 > 性质:核对记录,不改产品代码(本会话 session-role-diagnose-only)。todo 见 `docs/todo.md`。 > 关联:[第1-6轮](./)。 --- ## CR-24/26/27 ✅(价值第 6 次闭环) | 提交 | CR | 修复 | |---|---|---| | ef2d033 | CR-24 ✅ | AiChat onBeforeUnmount 补 `store.stopListener()` + useAiEvents stopListener 补 `clearStreamWatchdog()`(卸载清 130s watchdog 避免写已卸载 state)| | 7637f29 | CR-26 ✅ | project.ts `_activeTaskProject` 三态(undefined 不触发/all 全量/具体 id)+ Tasks.vue 空态兜底(89 行)| | 5e6aa79 | CR-27 ✅ | Dashboard 删决策/批注死代码(-96 行)+ stage 颜色 + refresh try/catch | **CR-25(分离窗口状态机 R3/R4/R5)仍存**(无提交提及,接收方未修或在做)。 --- ## 🔴 knowledge error 通道断(P1,CR-08 深化) ### CR-260615-28 [P1] state.error 死字段 + create 语义矛盾 - **state.error 死字段**:knowledge.ts:19,49,53,64,74,105 写入 `state.error`,但 **grep 全应用零消费**(Knowledge.vue store.error 零命中)→ 用户遭遇加载/检索/配置失败只看空白列表,无错误提示 - **CR-08 深化**:CR-08「store error fallback 11 处中文」只记了硬编码,**整个 error 通道前端是断的**(写了从不读)— 比中文硬编码更严重 - **create 语义矛盾**:create(:80-85) 成功后调 loadCandidates,若 loadCandidates 失败把错误塞 state.error,但 create 已返回 record 给调用方(认为成功) **修**:Knowledge.vue 接 error banner/toast,或删 state.error 改 throw 由调用方 catch + create 内 loadCandidates 失败不污染 error。 --- ## ✅ ai.ts 状态机完整(亮点,验证修复质量) 四核心态 `streaming/generatingConvId/currentText/queue` 在 **6 复位点闭环**,无卡死 streaming=true 缺口: - AiCompleted(useAiEvents:189-217)/ AiError(:220-235) + queue=[](B-32) - onStreamTimeout(useAiStream:25-28) + queue=[] + running→rejected(B-33) - sendMessage catch(useAiSend:99-105)/ approveToolCall catch(:121-133) + queue=[] - stopChat(:149-154) 本地先复位再发停止信号(不依赖后端 AiCompleted,防审批态看门狗已 clear 致 AiCompleted 竞态丢失) - 分离窗口 resumeInDetached(useAiWindow:111) 先 invoke('ai_is_generating') 核对(R4 防 df-ai-gen 残留假气泡) > 验证:B-32/33/ef2d033 修复质量扎实,状态机无非法组合残留。 ## ✅ appSettings 双源同步(亮点) 三态 `cache(reactive)↔SQLite↔ref`: - set 乐观写 cache + debounce 300ms 合并 + pendingValues 取最新值(非定时器快照),落库失败仅日志(UI 一致性优先,不回滚致不一致) - useSetting 双 watch `Object.is` 守卫防循环 - switchConversation 双 token 竞态防护(useAiConversations:44,48,52,122 `_latestSwitchId`) --- ## 🟡 P2/P3 新发现 ### CR-260615-29 [P2] ai.ts messages 无上限 + knowledge 竞态/错误不一致 - **ai.ts messages 单对话无上限**:useAiSend push user+ai / useAiEvents push err/审批 / useAiStream push delta,单对话线性增长(切换对话整体替换是减负点,但同对话不轮换),长会话+大工具结果内存可观 - **knowledge 异步无竞态**:loadList/search/loadConfig 无请求序号(messages 有 switch token),快速连点后返回覆盖先 - **knowledge 错误处理不一致**:load*/search 有 catch 兜底,create/updateStatus/archive/saveConfig/extractNow 直抛(调用方无 catch 致 unhandled) ### CR-260615-30 [P3] appSettings useSetting 对象值不落库(边界) useSetting 双 watch `Object.is` 守卫对值类型完美防循环,但**对象/数组值深 mutate**(`r.value.x=1`)时 `Object.is(v,cache[key])` 同引用恒 true → 不触发 set 落库,静默不持久化。当前无 bug(useSetting 多绑值类型,df-ai-ui 走 set 整对象替换),隐式契约。 --- ## 📊 本轮摘要 | 类别 | 数 | 代表 | |---|---|---| | 价值闭环 | 3 | CR-24/26/27 全修(修复质量好)| | P1 新发现 | 1 | knowledge error 通道断(CR-28,CR-08 深化)| | P2/P3 新发现 | 2 | ai.ts messages 无上限 + knowledge 竞态(CR-29)/ useSetting 对象值边界(CR-30)| | 亮点 | 2 | ai.ts 状态机完整(6 复位点,验证修复质量)/ appSettings 双源同步设计扎实 | **本轮价值**: 1. **knowledge error 通道断**是新维度发现 — CR-08 只记中文硬编码,实际整个 error 通道前端断的(写了从不读),用户看不到知识库错误 2. **ai.ts 状态机完整肯定前几轮修复质量**(B-32/33/ef2d033 闭环无卡死缺口)— 走查不仅找问题也验证修复 3. CR-24/26/27 三项 P1/P2 全修,走查↔接收方闭环高效(第 6 次闭环) **方法论**:第 5 个垂直切片(stores),knowledge error 通道断是新发现维度(超越 i18n 的功能缺陷)。ai.ts 状态机完整是「走查验证修复」价值(非只找 bug)。 todo 映射:CR-260615-28(P1 knowledge error)/ CR-29(P2 messages+竞态)/ CR-30(P3 useSetting 边界)。