Files
DevFlow/docs/05-代码审查/定时走查-2026-06-15-第2轮.md
绝尘 f30df333b3 docs: 巡检简报+todo 回写(2026-06-15 第2轮)
巡检发现:
- 2196c77 workflow 整文件替换回退破坏(AiChat+Ideas 12项功能)
- B-260615-03 truncated 标志已落地
- AR-8-scroll scrollToBottom smooth 已补
- CR-260615-09 .ai-md 残余:4详情页各21处 scoped .ai-md
  (全局 ai-md.css 75行已建,旧副本待清理但非阻塞)
2026-06-15 17:23:57 +08:00

124 lines
9.4 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.
# 定时代码走查 — 第 2 轮2026-06-15
> 触发:定时走查 cron每 30 分钟)。本轮范围 = 自上次走查起新增 6 提交(`fddca9d`/`892a642`/`19d64fc`/`d809cf4`/`8710d6c`/`06a2dea`)前端改动 + 工作区未提交(`types.ts`/`project.ts` M
> 方法3 路后台代理并行AARC-05 store 拆分 / BB-22 状态同步含 B-32/33 核对 / CCR-11 健壮性+工作区未提交)+ 主代理地面核对(`useAiStream.ts`/`useAiSend.ts`/`workflow.rs`/`f93b758` 提交)。
> 性质:核对记录,不改产品代码(本会话 session-role-diagnose-only。todo 待修项见 `docs/todo.md`。
> 关联:[定时走查-2026-06-15-P0复核.md](./定时走查-2026-06-15-P0复核.md)(第 1 轮B-32/33 结论被本轮纠正)。
---
## 核心结论3 前端 P0 全修(第 3 次纠正过时认知)
| P0 | 第1轮判断 | 第2轮地面复核 | 提交 | 处置 |
|---|---|---|---|---|
| **B-34** selectType | 已修 ✅ | 已修 ✅(确认) | — | 保持 ✅ |
| **B-32** 队列收尾 | 「未修」 | **已修 ✅** | `f93b758` | todo 标 ✅纠正第1轮 |
| **B-33** 骨架屏 | 「未修」 | **已修 ✅** | `f93b758` | todo 标 ✅纠正第1轮 |
**B-32/B-33 地面证据**`useAiStream.ts` 当前 81 行第1轮 Read 时为 73 行旧版):
- `:28` `state.queue = [] // B-32:超时收尾同步清队列` + useAiEvents.ts:225(AiError) + useAiSend.ts:152(stopChat)/124(approveToolCall catch) **四路径全清队列**
- `:43-45` onStreamTimeout 单遍反向扫描 running toolCall → rejected合并探测 completed 为单次 O(n),实现干净)
**B-32/B-33 修复提交**`f93b758`「修复: B-32+33 流式收尾清队列+回滚 running toolCall」3 文件 +18/-7。
> 第1轮「B-32/33 未修」为过时快照working tree 当时旧版,与 B-34 同根因)。**定时走查连续 3 轮纠正过时 P0 判断**B-34 → B-32 → B-33说明走查必须以地面 Read 为准,不可信赖记忆/旧快照。前端 3 P0 至此全部闭环。
---
## 新发现 P0AR-11 前端 listener 永不 attach功能半接通死代码
**位置**`src/stores/project.ts:31-55`(定义)+ `:109-110`export+ `src/App.vue:203-213`onMounted 未挂载)
**根因**:工作区未提交改动新增 `startDataChangedListener`/`stopDataChangedListener` 两函数 + export但**全项目零调用方**grep 确认)。后端 `emit_data_changed`audit.rs:259-270+ 自动执行路径audit.rs:351+ 审批路径commands.rs:175三处 emit 已就位且逻辑正确,事件 `df-data-changed` 正常发出,但前端 `listen('df-data-changed', …)` 永不执行 — 监听器从未 attach。
**影响**AR-11「数据变更联动刷新」功能**完全失效**。用户通过 AI 工具create/update/delete project/task/idea改数据后列表不自动刷新仍需手动刷新正是 AR-11 要消除的痛点)。后端 emit 成死事件。
**修复方向**`App.vue` onMounted 调 `await projectStore.startDataChangedListener()`onUnmounted 调 `stopDataChangedListener()`(对齐 `ProjectDetail.vue:463/470` 的 workflow listener 生命周期模式,数据变更可能来自任意页面)。
**性质**:工作区未提交半成品(非历史遗留,非 ARC-05 拆分收尾)。代理 C 确认 diff 是纯 AR-11 新增。
> todo:77 AR-11 条目原标「暂缓」第2轮复核更正为「后端已实施 ✅,前端半接通 🔴」。
---
## ARC-05 上帝 store 拆分 — 质量评级:优
**提交** `8710d6c``project.ts` 362→barrel + 5 子 storestate/projects/tasks/ideas/workflow
**3 项硬指标全部兑现**
| 指标 | 证据 |
|---|---|
| barrel 零改动兼容 | 逐字段比对 8710d6c~1 与 8710d6c 的 `return reactive({...})`37 key 完全一致8 getter state + clearError + 9 project + 4 task + 6 idea + 7 workflow actions + pendingApproval/stats computed。state getter 用 `get projects() { return state.projects }` 保留「避免 loadXxx 重赋值后视图为空」关键设计 |
| state 真单例 | state.ts 模块级 `export const state = reactive({...})`ESM 保证全 app 单实例4 子 store import 同一引用 |
| 依赖图无环 | 4 子 store 互不 import只依赖叶子 `./state`barrel 单向依赖子 store无循环/无初始化顺序陷阱 |
**🟡 建议 3**
1. `state.ts:32-37` 可变 `let _eventUnlisten` 跨模块共享 + setter依赖 ESM live-binding运行时正确但反直觉建议注释点明或并入 reactive
2. **AR-11 监听器已侵入 barrel**working tree project.ts:31-55违反「纯 barrel」定位 — 建议抽第 6 子 store `project/dataChange.ts`(与上面 AR-11 P0 同源)
3. `projects.ts:105` clearError 夹在 projects return 语义错位(属 state 层建议移除barrel 已独立从 state 导入)
**⚪ 可选 2**:注释「四子 store」实为 5 文件(四领域+共享 state/ createXxx 入参类型内联可抽 types。
**✅ 亮点**:越层 invoke 下沉彻底(`approve_human_approval`/`cancel_workflow_node` 下沉 `api/workflow.ts:39-54`B-34 snake_case 对齐在 api 层统一)/ ProjectStore 类型 + 单例 `_storeInstance` 保留 / view 端 7 处 `useProjectStore` 零改动。
---
## B-22 前后端状态同步 — 实现质量良好
**提交** `d809cf4``ai_is_generating` IPCcommands.rs:12+ sendMessage 预检useAiSend.ts:27
**设计对症**:双源(前端 streaming / 后端 generating各自维护确有不同步风险发送前查后端真值对症。
**竞态窗口可接受**`useAiSend.ts:42` 查后端与 `:97` 实际 sendMessage 之间有窗口,但后端 `ai_chat_send:57` 原子检查+占用(`if session.generating { Err }` + `generating=true` 同锁内)是真兜底。前端预检仅优化 UX提前入队而非发出去被拒降级路径完备IPC 失败 catch 退化为原 streaming 预检)。
**回归安全**正常事件流delta/tool/AiAgentRound/AiCompleted/AiError未改仅 sendMessage 入口前置预检,不影响 handleEvent。
**🟡 Issue 1**`useAiSend.ts:53-57` 入队分支复位 `streaming=true` 但**未启动看门狗**resetStreamWatchdog 只在 :89 正常发送路径调)。极端卡死场景(后端既不 emit、Drop spawn 又未执行streaming 可能永真。建议入队分支也调一次 resetStreamWatchdog代价一行。非 d809cf4 新引入回归onStreamTimeout 本就依赖正常路径启动的看门狗)。
**信息 Issue 2**`useAiSend.ts:60-61` 注释「streaming=true 但后端 false」描述与实际复位方向onStreamTimeout/AiError 复位 streaming=false有歧义建议改注释。
---
## CR-11 健壮性批fddca9d— ✅5 亮点 + 1 死逻辑副产品
**子项 ⑦⑧⑨⑩⑪⑫ 全部实施**
**✅ 5 亮点**
1. `useAiConversations.ts:77-93` JSON.parse 逐条 try/catch原单条坏 args 清空整对话 → 单条降级空对象)
2. `useAiEvents.ts:130-133` AiHeartbeat 显式 case 防 TS 穷举穿透
3. `useAiSend.ts:84-85` 复用 findToolCall消除内联 flatMap+find 重复 + 反向扫描 O(1) 均)
4. `ToolCard.vue:236-242` argString 去 3 处 `as any``Record<string,unknown>` 类型收窄
5. `workflow.ts:44-92` approveHumanApproval 签名收敛 `(decisions: string[], comment?)`(消除单/多选调用方歧义)
**⚠️ ⑪ 实施引入死逻辑CR-260615-18**`workflow.ts:67-68` `decision = selectType === 'multiple' ? decisions[0] ?? '' : decisions[0] ?? ''` 两分支返回值完全相同,三元无意义。后端 workflow.rs:291-296 有兜底。修:直接 `const decision = decisions[0] ?? ''`
**🟡 其他**CR-19action 字段 emit 但前端不消费,契约冗余)/ CR-20stopDataChangedListener try/catch 过度防御,与 workflow.ts:108 不一致)。
---
## P0 汇总(仍未修)
| ID | 问题 | 状态 |
|---|---|---|
| B-260615-35 | broadcast Lagged 兜底仅 warn → 终态事件丢失前端永久卡死(后端 workflow.rs:90-110 | **未修**第1轮发现本轮确认仍在|
| AR-11 前端 | listener 永不 attachApp.vue 未挂载) | **未修**(本轮新发现,工作区半接通)|
---
## 📊 本轮摘要
| 类别 | 数 | 代表 |
|---|---|---|
| P0 全修确认 | 3 | B-34保持✅/ B-32 / B-33第1轮过时本轮纠正|
| 新发现 P0 | 1 | AR-11 前端 listener 永不 attach功能半接通|
| 仍存 P0 | 2 | B-35 broadcast Lagged后端/ AR-11 前端 attach |
| ✅ 质量肯定 | 2 | ARC-05 store 拆分(优)/ CR-11 健壮性批5 亮点)|
| 🟡 建议 | 6 | ARC-05 三项 / B-22 看门狗 / CR-18 死逻辑 / CR-19·20 |
| ⚪ 可选 | 4 | ARC-05 两项 / ToolCard 兜底 |
**本轮价值**:第 3 次纠正过时 P0 判断B-32/33 实已修f93b758前端 3 P0 全闭环;新发现 AR-11 前端 listener 永不 attach工作区半接通死代码功能未闭环肯定 ARC-05 拆分3 硬指标全兑现)与 CR-11 健壮性批质量。
**方法论警示**:连续 3 轮纠正过时判断B-34→B-32→B-33根因是第1轮 Read 到 working tree 旧版73 行)而 HEAD 已是新版81 行)。**走查必须每次地面 Read不可信赖上轮快照**。后续走查代理 prompt 应强调「以当前 working tree + HEAD 为准git log 看提交,勿用记忆」。
todo 映射B-32/33 标 ✅ + 复核更正 / AR-11todo:77状态更新 / CR-11todo:212标 ✅ / 新增 CR-260615-18/19/20。