文档: 决策单拍板留痕并落 DRY 走查报告

D2 黑名单放行拍板补留痕,relay token 不引具体值
DRY 技术债 Top12 清单落专项设计,高风险名单一项本轮收口
This commit is contained in:
lxy
2026-10-01 08:28:08 +08:00
parent e3a8a8cffb
commit 3861e13b32
3 changed files with 79 additions and 4 deletions
@@ -0,0 +1,75 @@
# DRY 技术债走查报告(2026-10-01)
> 范围:全库(src-tauri + src),origin/main..HEAD 30 笔提交走查的横向延伸。
> 方法:只读审计,按(漂移后果 × 重复量)降序。纯相似但不漂移的不算债。
> 本轮已收口:#3。其余待排期,收敛方向已给出,勿新造抽象层。
## 汇总
| # | 债务 | 重复量 | 漂移后果 | 状态 |
|---|------|--------|----------|------|
| 1 | emit+publish 双写样板 ~50 处 | ~120 行 | 已发生(BUG-260805-02 只 emit 未 publish 丢事件) | 待排期 |
| 2 | KV 引号归一 7 处 3 种策略并存 | ~25 行 | 已发生(auto-execute medium/all 档静默失效注释自证) | 待排期 |
| 3 | 高风险工具名单 TS↔Rust 双写 | 名单×2 | 已漂移:前端缺 10 个 High 工具,审批后二次确认漏弹 | ✅ 本轮收口 |
| 4 | 噪音目录名单 4 处 4 套 | ~25 行 | 已漂移(AI 搜索与文件树过滤集合不一致) | 待排期 |
| 5 | 工具元数据 match 表散布 5 处 | ~90 行 | 已漂移(幽灵 edit_file/list_dir 分支永不命中) | 待排期 |
| 6 | 相对时间阶梯 3 套实现 | ~45 行 | 用户可见不一致(同为更新时间三种分档) | 待排期 |
| 7 | insert system 警示骨架 4 处同构 | ~100 行 | conv 生命周期语义变更需 4 处同改 | 待排期 |
| 8 | 压缩关键词兜底块逐字双胞胎 | ~35 行 | 两条失败路径易只改其一产生行为分叉 | 待排期 |
| 9 | formatWaitTime+等待阈值双写三处 | ~36 行 | 审批浮窗与主窗「变红」时刻分叉风险 | 待排期 |
| 10 | 灵感 statusOptions 双写 | ~20 行 | 透传链断一处详情页回退英文原值 | 待排期 |
| 11 | truncate 家族(同名不同义陷阱) | ~30 行 | fetch_url 与 audit 同名函数语义分叉误导复用 | 部分收口 |
| 12 | LOCK-SLOW 持锁计时样板 ~29 处 | ~145 行 | 低(阈值/行号写死变量名,维护噪音) | 待排期 |
## 明细与收敛方向
### 1. emit+publish 双写样板
- 正典:`stream_recv.rs:152 emit_ai_chat_event`(私有,仅内部可用)
- 手抄:chat.rs ×21、audit/mod.rs ×12、audit/approval.rs ×4、agentic/mod.rs ×7、settings.rs 等,全库 emit 59 处
- 收敛:helper 提为 pub(crate) 挪 event_bus.rs,手抄点全量替换;emit_fatal_error 内部 error_type 两端不一致(emit=Network/publish=None)顺带修
### 2. KV 引号归一三种策略
- trim 版(audit/mod.rs:318)/from_str 版(lib.rs:215,唯一能处理转义的写法)/bool 版(audit/mod.rs:345,默认值两处相反)
- 收敛:df-storage 或 state.rs 加 `get_string_norm/get_bool_norm`,lib.rs from_str 版为正典
### 3. 高风险工具名单(✅ 已收口 2026-10-01)
- 原状:useToolApproval.ts 手写 7 项 ↔ 后端 RiskLevel::High 17 个,缺 10 个(download_file/generate_image/git_merge/delete_module/run_workflow/mysql_execute/ssh_exec/mongo_insert/mongo_update/mongo_delete)
- 收口:新增 `ai_list_tools` IPC(注册表只读投影 name+risk),前端启动拉取构建名单,手写表降级为兜底(元数据未到/垫片环境生效);此后新增 High 工具只注册后端,前端自动跟上
### 4. 噪音目录名单
- 4 处:tool_registry.rs:968(12 项)/module.rs:662(6 项)/module.rs:1135 内联/skills.rs:164
- 后果实例:build/.next/.cache/.venv 被 AI search_files 扫到却在文件树隐藏;技能扫描被 target/ 深度递归拖慢
- 收敛:tool_registry 的 `is_noise_dir`(已 pub(crate))上移为唯一实现,分档用参数不用第二份名单
### 5. 工具元数据表散布
- path_auth.rs:48 文件工具集/agentic/helpers.rs:176+291(含不存在的 edit_file、list_dir 别名)/audit/data_change.rs:30/audit/cache.rs:449/tool_registry.rs:937
- 收敛:declare_tool! 注册点带元数据(path_args/只读/entity-action),5 处 match 改查 AiToolRegistry 单例
### 6. 相对时间阶梯
- 正典 utils/time.ts:46;GitChanges.vue:278(多 yesterday 档+30 天截断);KnowledgeDetail.vue:321(30 天回退绝对日期)
- 收敛:formatRelative(v, opts?) 加两参,调用方收敛
### 7/8. agentic 警示插入骨架与压缩兜底双胞胎
- mod.rs 2419/2448/2495 + cache.rs:497 同构 insert_at(0, system);context_lifecycle.rs:223↔332 逐字双胞胎
- 收敛:`insert_system_notice(session_arc, conv_id, text, log_tag)` 单函数;keyword_fallback_commit 单函数
### 9. 审批等待格式化与阈值
- useToolApproval.ts:95 ↔ ApprovalPopup.vue:200(formatWaitTime 逐字同款)+ 300/120 阈值第三处
- 收敛:沉 src/utils/time.ts(formatWaitTime + waitLevelOf)
### 10. 灵感状态表
- Ideas.vue:219 ↔ IdeaDetail.vue:518(详情页依赖父级透传)
- 收敛:statusOptions 表移 constants/project.ts,statusLabelKey 导出纯函数
### 11. truncate 家族
- 正典 audit/utils.rs:32(补 …);fetch_url.rs:655 同名不同义(返回元组);generate_image.rs:460、knowledge_inject.rs:544 手写 take(500)
- 已收口部分:tools/knowledge.rs 本地截断已改调正典(本轮)
- 残留收敛:正典上移共享位改名 truncate_chars_ellipsis;fetch_url 改名 truncate_markdown 消同名陷阱
### 12. LOCK-SLOW 样板
- 29 处 × 5 行,变量名编码行号(__hold610),阈值 30ms 逐处复制
- 收敛:`log_slow_lock(instant, site)` 单行化或 TimedLockGuard(Drop 打点)
## 总体评价
前端健康度好于 Rust:api/ 层已收口 invoke、useConfirm 已消灭确认弹窗重复、useTurnTrace 纯函数复用方向正确。Rust 侧债务集中在 agentic/mod.rs 接缝(#1/#7/#8)与「注册表之外的第二份工具知识」(#4/#5),后者建议优先收口到 AiToolRegistry 单点——新增工具要改 5-6 处的现状是最大的持续负债。
@@ -108,12 +108,12 @@
### A 系(授权体验,用户需求)
- **A1 「信任所有目录」总开关**: `check_file_tool_auth`(audit/path_auth.rs)读 Settings KV,bypass 开启时 NeedsAuth→Authorized;Settings AI 面板加开关;开启时对话区常驻横幅「授权已放行」防静默裸奔。**黑名单保留硬拒**(凭据目录自保护,见决策 D2)
- **A1 「信任所有目录」总开关**: `check_file_tool_auth`(audit/path_auth.rs)读 Settings KV,bypass 开启时 NeedsAuth→Authorized;Settings AI 面板加开关;开启时对话区常驻横幅「授权已放行」防静默裸奔。**黑名单保留硬拒**(凭据目录自保护,见决策 D2)(0929 后拍板改向:黑名单一并放行,见 D2 留痕)
### 新增决策卡
- **D1 智能化功能取舍**: S 系接线类(S1/S2)已派工;产品类空白待拍板优先级 — 工作流失败 AI 诊断/Dashboard AI 周报(真实进度替换硬编码映射表)/任务推进风险检查/对话转任务草稿/项目健康度。建议先做「Dashboard 进度真实化」(非 AI 也该修,constants/project.ts:52-59 硬编码百分比)再挑 1-2 个 AI 触点
- **D2 授权总开关是否连黑名单一起放行**: 建议否(黑名单是 .ssh/.aws/凭据自保护非体验问题);若确要全放,须二次确认+风险自担提示
- **D2 授权总开关是否连黑名单一起放行**: 建议否(黑名单是 .ssh/.aws/凭据自保护非体验问题);若确要全放,须二次确认+风险自担提示 → 0929 后拍板:改为连黑名单一并放行(体验优先),二次确认+常驻横幅已落地
## 三、留痕
@@ -47,7 +47,7 @@ wss://u-relay.1216.top/ws/miniapp device_id 配对 /
## 四、风险与决策点
1. **鉴权债**:relay 全局共享 token(`devflow-relay-default-token`,per-device token 留 Phase3 未做),持 token 者可冒充任意 device_id。自用可接受;devflow 与 miniapp 共用 relay 时建议补
1. **鉴权债**:relay 全局共享 token(默认值硬编码 lib.rs:219,值不在此引用;per-device token 留 Phase3 未做),持 token 者可冒充任意 device_id。自用可接受;devflow 与 miniapp 共用 relay 时建议补
2. **能力边界(勘察中)**:u-claw WS 渠道背后是完整 agent(会话/技能/意志卡)还是简化执行,决定「集成 u-claw 能力」含金量 —— 待 u-claw 侧勘察
3. **流式粒度**:progress/result 块级聚合非逐 token,aichat 首版按块级渲染
4. **多轮上下文**:request_id 单次请求语义,跨轮会话锚点在 u-claw 侧如何维持 —— 待勘察
@@ -69,7 +69,7 @@ devflow 现有 df-tunnel 是 **Device 角色**(连 `/ws/device`,服务 miniapp
- WS 客户端:Rust 层新写轻量 client(TunnelClient trait 可并存新实现,`df-tunnel/src/tunnel.rs:61`)或前端 TS 移植 relay.ts;推荐 Rust 层(与工具形态同侧)
- 配置落位:地址/独立 device_id → `app_settings` KV(照抄 `relay_url` 模式,`lib.rs:194-217`);token → OS keyring(照抄 provider api_key 模式);默认关,对齐 u-claw `cfg.WS==nil` 零行为变化模式
- 注意:现有 token 硬编码在 `lib.rs:219`(`devflow-relay-default-token`),本项实施时顺带配置化
- 注意:现有 token 硬编码在 `lib.rs:219`(值不在此引用),本项实施时顺带配置化
## 六、待补槽位(勘察代理回报后增量更新)