Files
DevFlow/docs/待决策.md
2026-06-24 00:29:02 +08:00

32 KiB

待决策队列

职责分离:

  • 主会话(汇总/巡检)→ 【写入】"当前队列",登记待人工决策项(背景 + 决策点 + 选项 a/b/c + 推荐)。
  • 用户(人工)→ 【拍板】选选项或确认推荐,回填理由(可选)。
  • 主会话(拍板后)→ 决策项回流 todo.md 推进 + 迁入"已决归档"。

这里只放需人工决策项(产品取舍 / 方向选型 / 排期 / 用户实测澄清)。不放可自主推进待办(见 todo.md)、不放审查登记(见 待审查.md)。

已决策历史按月归档,见 07-项目管理/待决策归档/。拍板后的项迁入对应 YYYY-MM.md(随时间增长追加月份文件,防本文件膨胀;文件不存在则新建)。 来源:2026-06-16 从 todo.md 抽离③④C类(可自主批 AE-03/复核⑪/UX-04 留 todo 推进)。

决策规则

  • 每条须:背景 + 决策点 + 选项 + 推荐 + 关联 todo。
  • 用户回填:✅ 决策:X(选 + 理由可选)。
  • 拍板后:主会话回流 todo 实施 + 迁入 07-项目管理/待决策归档/YYYY-MM.md(按月文件)。
  • 暂缓项标 ⏸️,不删(条件变化可重启)。

状态图例

🟡 待决 / 已决(回填决策) / ⏸️ 暂缓(待条件)


当前队列

T-260614-11 条件表达式引擎升级

  • 背景:df-workflow conditions 仅支持 true/false 字面量,升级为真表达式求值。引擎设计好但无前端 UI 消费方(demoDag edges 无 condition 字段)。
  • 决策点:求值器实现方式?(已暂缓:等工作流真实场景)
  • 选项:
    • a: 手写求值器
    • b: 复活 set_skipped
    • c: default false + warn(均认可)
  • 推荐:⏸️ 暂缓(无消费方,等 BuildNode 落地跑构建→测试→部署真实场景)
  • 关联:todo T-260614-11
  • 状态:⏸️ 暂缓

🟡 待用户实测/澄清(需用户操作,主会话无法代办)

S-260614-02 审批可见性实测重评

  • 待用户操作:实测 tc 卡片是否渲染。B-01 修复后 pending_approvals 内存态不再被 switch 清空,前端查询有数据,但 state.pendingApprovals 在 AiChat.vue 是否有兜底渲染仍需实测。
  • 选项:A 加兜底渲染 / B 实测确认(去重:AR-3 修完已缓解,改实测重评)
  • 状态:🟡 待用户实测

T-260614-01 多项 tauri dev 实测

  • 待用户操作:Sprint 9/10/14/15/16/18 多项未 tauri dev 实测 — 评分 IPC 缩放 / update_full / promote_idea / Store getter / token 落库 / 知识库 Tier 1 全栈 / LLM 并发 Semaphore / 知识生命线(#54 跟踪)。
  • 状态:🟡 待用户实测

T-260614-02 切对话不中断路由实测

  • 待用户操作:部分场景运行时实测(A 路线场景 2/3)。
  • 状态:🟡 待用户实测

S-260623-01 「自托管」含义澄清

  • 背景:用户要求设置支持「自主执行(含高危)+ 自托管」。自主执行含高危已实现 —— autoExecuteMode 三档 low/medium/all(AdvancedSection.vue F-#97, 2026-06-22),all = 完全 AI 接管含高危(delete/purge/run_command),选时二次确认。设置 → 高级 → AI 自动执行范围。但「自托管」grep 全项目无匹配,含义未明确。
  • 待用户澄清:「自托管」指什么?
  • 选项:
    • a: 自托管 AI 模型 endpoint(用户配自己的模型 API/本地模型,非默认 provider)
    • b: 自管执行策略(= autoExecuteMode 已覆盖,无需另做)
    • c: 自托管后端服务(用户自部署 df-relay/df-tunnel,非默认 u-work.1216.top)
    • d: 其他(用户补充)
  • 关联:task105 / memory(设置自主执行已实现)
  • 状态: 自用阶段定案(2026-06-23) —— 用户决策:小程序当前自用(开发阶段),分发是产品终态但留后续(过渡期靠改 device_id 实现多机)。故「自托管」现阶段 = 已实现的自主执行(autoExecuteMode all 含高危),无另义。分发阶段再做配置层(MINIDEC-01)+ 配对(MINIDEC-02)。

B-260617-11 tauri.conf.json 打包目标收窄确认

  • 状态: 已决(2026-06-18) — 已迁入归档。决策:A 临时本地构建,要求高速。提交前 revert 为 "all"

🟡 待设计/架构演进(有决策点,需方案设计或长期规划)

ARC-260615-07 架构重构批(排期/优先级决策)

  • 背景:src-tauri IPC 编排层 5711 行成事实业务层,7 项架构债。df-core→df-types 已完成(CR-61),剩 6 项独立大改。
  • 决策点:6 项重构何时做/优先级/是否做(每项 ROI 与风险权衡,无法纯技术论证——做不做是资源/产品取舍)
  • 选项(剩余 6 项):
    • a: df-app 抽取(IPC 编排层 5711 行独立 crate)
    • b: AI agent loop 从 IPC 下沉 df-ai(逻辑与 IO 分离)
    • c: 类型契约 ts-rs 代码生成(替代手写 types.ts)
    • d: AiSession 多会话(B 路线前置,关联 S-260614-01)
    • e: AppState 分组(5711 行 state 拆分)
    • f: IPC 命名统一
  • 推荐:⏸️ 缓做(重构低 ROI,当前功能优先;待稳定后按 d→b→a 顺序,d 是 B 路线前置可先)
  • 关联:todo ARC-260615-07 / memory aichat-arch-extensibility
  • 状态:🟡 待排期决策

UX-260617-01 aichat 消息全量重叠(待 DevTools 定位根因)

  • 背景:用户实测消息大量重叠堆叠。5 角度分析排除 CSS/scoped/DOM,核心嫌疑虚拟滚动 IO 半激活态不一致 + height=0 未设 minHeight → slot 塌 0 → 重叠。
  • 决策点:根因确切触发路径(需 DevTools 实测,静态分析已到极限)
  • 选项:
    • a: 虚拟滚动 IO/RO 时序竞态(主嫌疑,unload 分支 minHeight 兜底修复)
    • b: 其他(DOM 结构问题,需 DevTools 实查)
  • 推荐:待用户 DevTools 实测(shouldRenderMsg 卸载时检查 slot 实际高度 + IO unobserve/observe 时序),定位后修法明确(unload 分支 minHeight fallback)
  • 关联:todo UX-260617-01 / docs/05-代码审查/AI聊天组件极端数据场景分析-2026-06-17.md
  • 状态:🟡 待 DevTools 验证根因

UX-260617-28 双监听器同通道(长期架构演进)

  • 背景:useAiEvents + useAiContext 各自 listen('ai-chat-event'),人工 AiCompressing flag 协调防双重处理,非架构保证。未来新增事件处理可能触发双重 bug。
  • 决策点:是否升级单一分发器模式(架构保证)
  • 选项:
    • a: 保持现状(AiCompressing flag 协调够用)
    • b: 单一分发器(架构保证,但大改)
  • 推荐:⏸️ 暂缓(当前 flag 协调有效,未来新增事件处理触发双重 bug 时再升级)
  • 关联:todo UX-260617-28 [INFO]
  • 状态:⏸️ 长期(INFO,当前够用)

B-260618-03 路由解耦 cost_tier/intelligence(用户已全局决策去掉,工程大需专项)

  • 背景:用户 2026-06-18 决策「API 无判别依据的 cost_tier/intelligence 去掉,不写死不瞎填」。当前 router.rs 用 cost/intel 做硬过滤(步骤4 min_intelligence / 步骤5 max_cost)+ 排序(步骤7 Reverse(cost_tier)),但这两维度 100% 由 model_probe 瞎猜(预设表+启发式),零客观依据。GLM-5.2 被猜成 standard/medium(名不沾词素走兜底),title/compress 按 max_cost 过滤可能选不到合适模型。
  • 决策点:用户已全局决策去掉。本项是落地(自主可推进)。记待决策因:工程大(~30 Edit)+ 主链路由行为变更需 cargo test router 全验证 + title/compress 选模型退化需在场核对。
  • 选项:
    • a: 自主推进(用户已决策,专项会话充分资源 + cargo test router 全验证 + 实测 title/compress 选模型)
    • b: 等用户在场专项(核对路由行为退化 + 实测)
  • 实施清单(勘察完成 2026-06-18):
    • router.rs:TaskRequirements 删 min_intelligence(:29)/max_cost(:31)字段 + 删步骤4 filter(:62)/步骤5 filter(:63) + 步骤7 max_by_key 改纯 weight 删 Reverse(cost_tier)(:65) + 注释更新(:28/:31/:48-51/:55)
    • 9 调用点删 min_intelligence/max_cost 传参:project.rs:535-536/631-632 · compress.rs:62-63 · knowledge_inject.rs:61-62/346-347 · agentic.rs:414-415 · title.rs:88-89 · ai_node.rs:203-204 · adversarial.rs:161-162
    • import 清理:调用点 CostTier/IntelligenceTier 不再用则删 import(title.rs/compress.rs 用 CostTier;多处用 IntelligenceTier)
    • test:router.rs 多 test 改/删(max_cost_filters_expensive / max_cost_none_allows_any / same_weight_picks_cheaper_cost_tier / intelligence 相关 + TaskRequirements 构造删字段)
    • ModelConfig.cost_tier 字段保留(B-04 model_probe 去瞎填处理数据源,不删字段)
    • df-ai-core/model.rs 注释更新(:47/:60 提及 router max_cost/min_intelligence)
  • 推荐:a 自主推进(用户已全局决策,方向明确),建议专项会话充分资源;title/compress 失去 max_cost 约束后纯 weight 选模型,需核对 weight 配置合理(用户在 Settings 配)
  • 关联:todo B-260618-03/04/05 · UX-260618-04 前端 cost/intel 标签(依赖本项)
  • 状态: 已实施(2026-06-18 workflow wexu1isx1,主代核查 cargo check --workspace EXIT 0 + cargo test df-ai 109 passed + vue-tsc EXIT 0;SW-02 借用 E0502 主代修)。title/compress 纯 weight 选模型退化点:用户核对 Settings weight 配置(同 weight 并列 max_by_key 返回最后一个)

ARC-260618-01 God 文件拆分批(架构重投入·需设计)

  • 背景:2026-06-18 架构坏味道扫描出 3 个 God 文件:tool_registry.rs 1091行单函数(SMELL-P0-2)/AiChat.vue 4026行单组件(SMELL-P0-3)/crud.rs 2212行(SMELL-P1-9)。均属"功能能跑但维护成本高/测试难"的技术债,非功能 bug。
  • 决策点:拆分何时做/优先级/拆分边界(每项拆分策略需专项设计,非小改;做不做是资源/可维护性取舍)
  • 选项:
    • a: tool_registry.rs 按 CRUD/文件/工作流分组拆注册函数(每个<200行,单文件域,风险中) — 已实施(2026-06-18 workflow w2xkw4ybh data 抽出 + 主代 sweep 批4)·build_ai_tool_registry 1091→7 行·抽 register_data_tools(18 持 db 工具)+ register_file_tools(10 文件工具)·加基线测试 test_build_ai_tool_registry_baseline_tool_count(Database::open_in_memory·断言 len()==28 + tool_names() 集合)·主代核查 cargo check --workspace EXIT 0 / cargo test df-ai 119 passed / devflow 基线 1 passed / vue-tsc EXIT 0
    • b: AiChat.vue 拆 ConversationSidebar/MessageList/ChatInput/ApprovalPanel(巨型组件,风险高,AiChat.vue 已在频繁改动需择稳定窗口) — 🟡 待排期(并发改中缓)
    • c: crud.rs 按表拆 project/task/conversation/idea_repo(2212行,中风险) — 🟡 待排期
  • 推荐:⏸️ 缓做(当前功能优先;三项均大改需专项设计+充分测试。建议按 a→c→b 顺序,a 单文件域最独立先做已实施,b 待 AiChat 改动沉淀后)
  • 关联:todo SMELL-P0-2/P0-3/P1-9
  • 状态:🟡 待排期决策(a 已实施·b/c 待排期:b AiChat 并发改中缓·c 待专项窗口)

SMELL-P1-6 String→newtype 强类型(需设计)

  • 背景:execution_id/status/tool_type 等 5+ 处用裸 String,类型安全弱(混用/拼写错编译期不拦)。改 newtype(ExecutionId 等)需全栈波及(Rust struct 字段 + serde + IPC 边界 + 前端 ts 类型)。注:status 场景 df-types 已有 TaskStatus enum,部分代码用 String 而非 enum。
  • 决策点:做不做 + newtype 边界(仅 Rust 内部 vs 跨 IPC 到前端)
  • 选项:
    • a: 全栈 newtype(Rust+IPC+前端,类型安全最强,波及大)
    • b: 仅 Rust 内部 newtype(IPC 边界仍 String,折中)
    • c: 不做(String 够用,status 已有 enum 部分覆盖)
  • 推荐:⏸️ 缓做(全栈波及大 ROI 中等;倾向 b 折中或 c 现状 enum 已部分覆盖。若做需专项设计 newtype 边界)
  • 关联:todo SMELL-P1-6
  • 状态:🟡 待设计决策

SW-260618-21 死代码预留功能清理批(清理 vs 保留)

  • 背景:2026-06-18 深层 sweep 核验出 4 类「0 外部消费者但设计预留」符号。清理减负 vs 保留未来功能取舍。注:PendingApproval.diff 经 IPC 活跃(useAiEvents:252 event.diff→tc.diff + ToolCard:44/754/772 渲染·UX-260618-06 审批 diff)非死代码不删;transition_status 已删(批次7·0 消费者+TODO 未实现)。
  • 核验(独立 grep 2026-06-18):
    • SessionState enum + session_state()(mod.rs:172/393):0 外部调用·注释「读状态统一走 session_state() 收敛」设计预留(待重构 SW-02 类终态化复用)
    • AppState.releases/node_executions(state.rs:206/210):\.releases\b|\.node_executions\b 0 字段访问·df-storage ReleaseRepo/NodeExecutionRepo 预留(未来 release mgmt/node exec log)
    • PendingApproval.risk_level(mod.rs:410): 已删(2026-06-18·前端 types.ts 0 字段坐实真死·零波及·CR-22)
  • 决策点:清理 0 消费者预留 vs 保留未来功能
  • 选项:
    • a: 全清理(删 SessionState/releases/node_executions/risk_level·连带 df-storage repo 定义·减 dead_code warning·但失去预留扩展点)
    • b: 全保留+标 #[allow(dead_code)] 注释预留意图(消 warning·保留未来·零波及)
    • c: 部分(SessionState/releases 近期无计划清·risk_level 核前端类型后定)
  • 推荐:⏸️ b 保留+标 allow(预留设计意图明确·清理失去未来扩展点 ROI 低;标 allow 消 warning 即可·零波及)
  • 关联:批次7 transition_status 已删 / CR-22 删 risk_level / CR-23 标 allow 5 处
  • 状态: 已实施 b(2026-06-18·主代自主决策·risk_level 删 + 预留/diff 标 allow·cargo 0 warning)

F-260616-09-B 多会话并发架构 B 阶段实施决策(设计完成 2026-06-19·待拍板)

  • 背景:F-09 B 阶段设计文档完成 F-09-多会话并发架构设计-2026-06-19.md。核验发现 A 路线补漏已全部落地(commands.rs:1404-1409 + useAiConversations.ts:80-83)→ 阶段1 跳过。AiSession 12 字段。阶段2(B 主体,批1-8)待启动。
  • 决策点:
    • ⚠️ b-1(关键·须拍板):messages 是否 per-conv。原决策 b「messages 按 conv reload(不 per-conv)」与决策 e「切换不退出各自跑完」矛盾(单例 messages 下旧 loop push 污染新 conv,B-260615-11 退出校验必须保留→与 e 冲突)。设计推荐修正 b 为 messages per-conv(e 的技术必然必要条件,侵入面增量极小:ContextManager 挪 HashMap)。
    • ⚠️ c-1:global permits=3 默认值 + Settings 加「并发会话数上限」配置项。
    • e-1(主代已定):旧 loop save_conversation 保持原路径(save 接 conv_id 零改动)。低风险技术细节,主代裁决采纳。
  • 推荐: b-1 采纳(messages per-conv,技术必然)+ c-1 保持 3 + Settings 配置 + e-1 原路径。拍板后启动阶段2 批1(PerConvState 数据结构 + 访问器)。
  • 关联:todo F-260616-09 / 设计文档 / memory aichat-arch-extensibility
  • 状态: 主代自主裁决采纳(2026-06-19) —— 用户授权「自主推进,能多角度确定的方案不等审批」。b-1 多角度论证充分(messages per-conv 是决策 e 技术必然必要条件,无替代);c-1 合理默认(global=3,Settings 配置后续);e-1 零改动技术细节。启动阶段2 批1。用户醒后可追认/推翻。

F-260619-05 任务可关联灵感(产品粒度/方向决策·todo 已登记)

  • 背景:tasks 表无 idea 关联字段;projects 已有 idea_id REFERENCES ideas(id) 模式。用户要任务关联灵感。todo.md 已登记(设计点+改动点+验收)。
  • 决策点(产品取舍,需用户拍板):
    • 粒度:一对一(source_idea_id,任务来源单灵感)vs 一对多(related_idea_ids JSON,借鉴 releases.task_ids)
    • 存储:tasks 加 idea_id 列(迁移,复用 projects.idea_id 外键)vs 关联表 task_idea_links(多对多,灵活复杂)
    • 方向:单向(任务→灵感)vs 双向(灵感侧反向显示关联任务列表)
  • 推荐:tasks 加 idea_id REFERENCES ideas(id)(复用 projects 模式,1对1 起步,单向,后续按需扩展)。低侵入(单列迁移 + Repo 白名单 + 工具 idea_id 参数 + 前端展示)。
  • 关联:todo.md F-260619-05(设计点详情)
  • 状态: 已实施(2026-06-20 调研确认)— tasks.idea_id 1对1 单向已落地:TaskRepo idea_id 字段(task_repo.rs:34 row.get / :52 INSERT / :63 UPDATE / :83 SELECT 全含)+ create_task 工具 idea_id 可选参数(tool_registry.rs:637「可选传 idea_id 关联灵感(1对1 单向)」)。复用 projects.idea_id 模式,粒度 1对1/单向/单列,符合推荐方向。前端任务卡片展示灵感来源(可选增强)待补。

消息级溯源 P2 切读策略(技术决策·大改需知情)

  • 背景:消息级溯源 P0(地基 ai_messages 表 CR-10)+ P1(溯源字段 CR-12)完成。P2 切读是拆表实际启用(读写路径从 ai_conversations.messages JSON 切到 ai_messages 表)。
  • 决策点(技术策略,影响读写路径改造):
    • a 三阶段渐进(设计推荐):Phase1 脏标记 → Phase2 双写(旧列+新表)→ Phase3 切读删旧列。安全(双写期可对比回退),有性能开销+复杂。
    • b 一次性切读:直接切+删旧列。简单,但切读前无回退(风险)。
  • 推荐:a 三阶段渐进(低风险,设计推荐)。但大改(ContextManager restore/clear/compress/replace 读写路径 + save_conversation 双写 + V22 删旧列重建表),需充分测试。
  • 关联:消息级溯源 P0(CR-10 )/ P1(CR-12 )/ 消息拆分存储设计文档
  • 状态:🟡 待用户拍板(P2 是否现在做 + 策略 a/b)。大改建议用户知情后启动。

BUG-260623-03 审批 pending 无超时兜底(aichat 卡死·架构)

  • 背景:实测会话 4ae73423 末尾 advance_task 触发审批 __PENDING__ 后,agentic/mod.rs:1464 loop return,恢复唯一依赖用户主动 ai_approve。全库无审批超时定时器(cache.rs:31 占位标记无时间戳)。用户离开/忘记 → generating=true 永久挂起,会话卡死,用户须手动重发(且该会话 token 已大,重发易触上限)。属 aichat 中断B,非 generating 状态机卡死(generating 已收敛 GeneratingGuard)。
  • 决策点:审批 pending 超时兜底怎么实现?
  • 选项:
    • a: 后端 per-conv 定时器(到期自动 reject + emit 超时,触及 AiSession 单例 + 定时器机制,最彻底)
    • b: 前端倒计时提示(用户可见到期,后端不变,最小改动)
    • c: 无超时(现状,靠用户手动)
  • 推荐:b 前端倒计时(最小改动不触 AiSession;用户可见主动处理)。a 后端定时器最彻底但触及单例大改,归 devflow-async-approval-concept
  • 关联:memory devflow-async-approval-concept / docs/05-代码审查/aichat-会话实测分析-2026-06-22.md(CR-260622-01 修正)
  • 状态:🟡 待决策

df-miniapp 全功能审查(2026-06-23 workflow wll7qabgr + 主代补审)

6 区域并行审查(chat/会话页/useAiChat/连接层/组件/工程)。已自主实施:F1 看门狗 clearWatchdog 兜底 / F2 regenerate 守卫 / F3 flushCurrentText id 精确回填 / F9 stop 终态兜底 + 停止按钮(原无停止入口) / F21 连接状态中文文案 + 手动重连 / switch default 分支 / 二进制帧 warn / scheduleReconnect maxAttempts / 删 test 死页。以下为需决策项。

MINIDEC-260623-01 relay 配置层范围(F15·产品方向·分发卡点)

  • 背景:config.ts relayHost/deviceId/token 全硬编码(setConfig 零调用方,storage 未接,无设置页)。当前填测试服 wss + 本机 device_id(联调期)。分发后用户无法改连自托管中继 → 连不上。
  • 决策点:配置层做到什么程度?
  • 选项:
    • a: 完整设置页(表单 + setConfig 接 storage 持久化 + getConfig 回退),用户可改 relay/device/token
    • b: 仅接 storage 持久化(setConfig 真生效,无 UI,靠代码/build env 注入)
    • c: MVP 接受硬编码(仅自用联调),设置页立项后续
  • 推荐:b 至少接 storage(成本极小让配置真生效);a 设置页 UI 视分发排期。依赖 S-260623-01「自托管」含义(c 自托管后端 → 必须 a)。
  • 关联:S-260623-01 / memory cross-end-rust-backend
  • 状态:⏸️ 暂缓(2026-06-23) —— 用户决策:当前自用,硬编码够;分发阶段(产品终态)再做设置页。过渡期多机靠改 device_id。

MINIDEC-260623-02 配对绑定流程(F16·跨端大改)

  • 背景:ControlMessage.pair 类型已定义但从不发送,deviceId/token 靠用户手抄(查桌面端 KV)。无二维码配对/绑定校验链路。
  • 决策点:配对流程是否本轮做?
  • 选项:
    • a: 完整配对(桌面端生成 QR → relay 校验绑定 → miniapp 扫码获 device_id/token)
    • b: MVP 过渡(设置页手填 + UI 提示去哪找 device_id/token)
    • c: 不做(手抄够用)
  • 推荐:⏸️ b MVP 过渡(a 跨端协作工作量大,依赖 MINIDEC-260623-01 设置页先落)
  • 关联:MINIDEC-260623-01
  • 用户已定未来愿景(2026-06-23):分发阶段做完整配对授权,三步:① 设备端弹二维码 ② 小程序扫码识别并授权,双方来回点击确认 ③ 授权管理(设定授权的权限范围等)。本轮不做,留专项。
  • 状态:⏸️ 暂缓(2026-06-23) —— 当前自用靠手抄 device_id;分发阶段按上述愿景做完整 QR 配对 + 权限范围管理(跨端 df-miniapp/df-relay/桌面端协同,专项立项)。

MINIDEC-260623-03 WS 重连续流策略(F10·行为差异·需拍板)

  • 背景:watchdog 在 WS 重连后不重启。重连期间 device 续推 AiTextDelta 会丢(断连窗口)或半截文本错位。当前断连 onStatus 已 reset generating + clearWatchdog(连接断肯定停),但重连后续流未处理。
  • 决策点:重连后续流策略?
  • 选项:
    • a: onStatus 'connected' 主动发 load_messages 重新同步整个会话(最稳,但重置视图)
    • b: 收到 AiTextDelta 时若 !generating 隐式恢复 + 补 assistant 占位(最平滑,有幽灵续流风险)
    • c: 不处理(接受断连窗口该轮丢失)
  • 推荐:c 现状(MVP 断连窗口丢失可接受,a/b 复杂度高)。重度依赖移动端弱网再升级 a。
  • 状态: 已实施 a(2026-06-23)—— 用户决策「断网不丢消息 + 从远端拉完整」。useAiChat syncOnConnect:ws 'connected' → 发 load_messages 拉完整历史(断网期间 missed 消息恢复 + 兼修冷启动空白 P1-C)。cargo check 0 + vue-tsc 0 + build DONE。

MINIDEC-260623-04 审批双源状态分裂统一(F4/F5/F6/F13·渲染源决策)

  • 背景:审批状态双写——pendingApprovals 数组 + messages[].toolCalls.status。AiApprovalRequired 双写为源头,AiError/switchConversation 只清 pendingApprovals 一侧(messages 内 tc 留陈旧 pending_approval)→ 可能渲染陈旧审批按钮,点 approve 命中已失效 tool_call。chat 页按 m.toolCalls 内联渲染审批按钮,pendingApprovals 仅顶部徽标计数。
  • 决策点:统一单一渲染源?
  • 选项:
    • a: 以 pendingApprovals 为准(messages tc 仅显示 status 不渲染按钮)—— 改 chat 页渲染逻辑(行为变更)
    • b: switchConversation/AiError 清 pendingApprovals 时同步遍历 messages 把 pending_approval 标 rejected —— 改 useAiChat 状态清理(纯后端态,UI 不变)
  • 推荐:b 同步清理(最小行为变更,治陈旧按钮根因)。a 渲染源统一更彻底但 UI 改动大。
  • 关联:BUG-260623-03(审批超时,后端侧)
  • 状态: 已实施 a 单一渲染源(2026-06-23)—— 用户决策「审批断网重连恢复卡片状态」。审批卡改从 pendingApprovals 独立面板渲染(与 messages 解耦,避重连 load_messages 替换 messages 的竞态);remote_bridge 加 sync_pending 路由(读 AiSession.pending_approvals 按 conv 过滤重发 AiApprovalRequired/AiDirAuthRequired);useAiChat onStatus 'connected' 清 pendingApprovals + 发 sync_pending 重建;handleEvent 加同 id 去重防竞态重复。内联工具卡保留状态徽标/参数/结果(按钮移面板)。cargo 0 + vue-tsc 0 + build DONE。

MINIDEC-260623-05 会话页管理缺口(删除/重命名·需后端命令)

  • 背景:conversations/index.vue 仅列表/切换/新建/下拉刷新。无删除/重命名(需后端 delete_conversation/rename_conversation 命令 + remote_bridge 路由,当前无)。
  • 决策点:miniapp 是否需要会话管理?
  • 选项:
    • a: 本轮加(后端命令 + bridge 路由 + 会话页长按菜单)
    • b: 暂不做(用户回桌面端管理,MVP 仅查看/切换)
  • 推荐:⏸️ b 暂不做(miniapp 定位轻量操作终端,会话管理桌面端足够)
  • 状态: 重命名已实施 / 删除暂缓(2026-06-23)—— 用户决策「小程序对齐桌面端能改会话名」。remote_bridge 加 rename_conversation 路由(调 ai_conversation_rename + 推 AiConversationList 刷新);useAiChat renameConversation 方法(乐观本地更新);conversations/index.vue 长按会话 uni.showModal 编辑。删除会话暂不做(桌面端管理)。cargo 0 + vue-tsc 0 + build DONE。

MINIDEC-260623-06 心跳/历史替换协议(F8/F20·跨模块·低优先)

  • 背景:(F8)心跳活性检测依赖「任意入站消息」,低活跃场景每 ~60s 误判半开死连接触发无谓重连(relay 无 pong);(F20)AiMessageHistory 整体替换会丢弃正在进行的乐观气泡(device 主动推历史路径难区分 load 响应)。
  • 决策点:是否本轮改 relay 协议?
  • 选项:
    • a: relay 加 pong + 历史事件加 load_id/sync_source flag(跨模块改 df-relay + 后端 events)
    • b: 前端缓解(放宽 DEAD_FACTOR / 「仅本地空才替换历史」启发式,语义脆弱)
    • c: 暂缓(MVP 低频空闲场景可忍)
  • 推荐:⏸️ c 暂缓(跨模块改动 ROI 低)
  • 状态:⏸️ 暂缓

MINIDEC-260623-07 regenerate 零调用方 + 备份组件漂移(P3 收尾)

  • 背景:(1) useAiChat.regenerate() 零调用方(全死,已加 generating 守卫防御);(2) MdView.vue/MentionInput.vue 因绕工具组件解析 bug 被 chat 页内联,源文件保留备用但已与内联实现漂移(MdView 无 mdCache、MentionInput 是 MVP 占位)——「拆回」时会引入旧实现。
  • 决策点:regenerate 加 UI(重发按钮)or 删?备份组件同步/删/保留?
  • 选项:
    • a: regenerate 加重发按钮 + 备份组件同步内联实现(或删)
    • b: regenerate 删减负 + 备份组件保留标注释(预留工具 bug 修复后拆回)
  • 推荐:b(regenerate 删减负,备份保留预留意图)。或 a 视移动端重发需求。
  • 状态: 随 P1-F 选 a(2026-06-23)—— 🟡 收尾批给 regenerate 加「重发」UI 入口(对齐桌面端),故保留函数不再删;备份组件(MdView/MentionInput)保留预留注释(绕工具解析 bug,未来拆回)。

workspace_root 分发适配(编译期 CARGO_MANIFEST_DIR 写死,跨机器/跨平台失效)

背景:workspace_root_path()(state.rs)/ workspace_root()(tool_registry.rs)/ workspace_root_str()(mod.rs)三处同源用 env!("CARGO_MANIFEST_DIR")(编译期写死编译机源码路径)。DevFlow 打包分发后:

  • 用户机器无编译机路径(如 E:\wk-lab\devflow)→ workspace_root 失效
  • 跨平台(Windows/Linux 各发行版)各自编译机路径写死,分发到不同机器/平台均失效
  • 影响:相对路径锚点(check_path_authorization / resolve_workspace_path_impl)+ 默认白名单(default_with_root)+ run_command 默认 working_dir 均依赖此值,分发后指向不存在路径 → AI 文件工具全部失效

当前(开发机自用):CARGO_MANIFEST_DIR = 开发机 DevFlow 源码,AI 访问源码合理。仅开发期有效。

根因:workspace_root 语义错位 — 当前 = DevFlow 自身源码目录(开发 DevFlow 的语义);但 DevFlow 分发后是"用户用它开发自己项目的工具",workspace_root 应 = 用户项目(动态,非编译期)。

方向(运行期动态 workspace_root):

  • a current_exe 安装目录:std::env::current_exe().parent()。分发后 = 安装目录。但安装目录非用户工作空间(AI 应访问用户项目,非 DevFlow 安装目录)。语义仍错。
  • b 用户项目绑定(推荐方向):workspace_root 概念淡化,默认白名单 = 用户绑定项目(projects.path,reload_allowed_dirs 已读),相对路径锚 = 当前活跃项目目录。无固定编译期 root。最贴合"用户用 DevFlow 开发自己项目"语义。需改 check_path_authorization / resolve 锚活跃项目(当前锚固定 workspace_root)。
  • c 用户配置工作空间:KV workspace_path,用户首启配置。灵活但需 UI + 首启引导。
  • d 混合:debug 开发期 CARGO_MANIFEST_DIR(源码)/ release 分发期 current_exe 或用户项目(cfg!(debug_assertions) 区分)。过渡方案。

决策点:

  • workspace_root 语义(DevFlow 安装目录 vs 用户项目 vs 用户配置工作空间)
  • 相对路径锚点(固定 root vs 活跃项目)
  • 是否区分开发期/分发期(cfg!(debug_assertions))
  • docs/kms 开发机暴露(随 b/c 自然解决:无固定 root 则 docs/kms 不在默认白名单)

关联:F-260619-03 去固定根(已删 is_authorized 硬编码放行)/ projects.path 自动授权(reload_allowed_dirs)/ memory devflow-project-path-binding 状态:🟡 待决策(workspace_root 运行期动态方案 a/b/c/d)。分发前必须解决(否则分发后 AI 文件工具全部失效)。

2026-06-23 进展(BUG-260623-01):实测会话 6acb7f9b 暴露 write_file/append_file/rename_file 父目录校验误用 workspace_root(tool_registry.rs:1112/1418/1555 原用 starts_with(workspace_root()))→ 用户授权的其他项目目录(ai-news 等)parent 不 starts_with devflow 源码目录 → 误拒「禁止在项目目录之外创建目录」(用户授权了仍拒)。已修:三处改用 allowed_dirs.is_authorized(parent) 脱离 workspace_root。仍写死残留(待本决策 a/b/c/d 根治):delete_file:1482 trash 目录 / resolve_workspace_path_impl:380 相对路径 join / run_command:1791 working_dir 默认。


F-260619-03 路径授权政策:工程内默认免授权(用户 2026-06-20 指令)

用户政策指令:"默认直接访问,明确知道无权限才申请"。

背景:F-260619-03 Phase C 去固定根(b22e9ae)后,reload_allowed_dirs 在 KV allowed_dirs 或 projects.bind_directory 非空时丢失 workspace_root,致工程内路径(如 docs/)误弹窗。用户反馈"本来就有访问权限,为什么还来申请"。详见 todo BUG-260620-05。

决策点(语义范围澄清):

  • 层1 工程内默认免授权(dev 自用足够):reload_allowed_dirs 无条件保留 workspace_root(state.rs:618 去 all_dirs.is_empty() 包裹)。工程内路径默认放行,workspace_root 外非白名单仍弹窗。1 行修复,确定性 bug(注释承诺失配)。
  • 层2 全局默认放行(语义翻转):is_authorized 改黑名单制——非黑名单路径默认放行,仅明确敏感(系统目录/凭据)拒。等于实质去掉白名单授权机制。安全风险大(任何非黑名单路径 AI 可访问),涉 P0 去固定根决策方向推翻。

与 P0 去固定根冲突:P0(CR-260620-01 ⑤)决策"去掉代码硬编码固定放行,用户从白名单删工程根后工程根也需授权"。层1 恢复工程内免授权=部分推翻 P0。但 P0 "用户删 root" 语义当前未落地(set/get filter root,root 不可删),层1 不破坏现有能力。

与分发适配衔接:层1 workspace_root = CARGO_MANIFEST_DIR(编译期写死),开发机自用有效;分发后失效则依赖 projects.path 自动授权(reload 已读 project_dirs)。分发适配见上节"workspace_root 分发适配"方案 b。

倾向:层1(满足 dev 自用 + 不破坏安全 + 修注释承诺失配的确定性 bug)。层2 若需全局放行另立专项。 状态:🟡 待用户拍板(层1 确定性 bug 可直改 1 行;层2 语义翻转需明确安全边界)。


已决归档

按月归档(随时间增长追加月份文件,防主文件膨胀):

  • 2026-06.md — 2026-06 已决策/已实施/已排期/已解决历史(③类产品取舍 12 项 / ④类设计方向 6 项 / 重投入排期 8 项 / ④类续 5 项 / C类已解决 2 项)

新月份拍板项累积时,新建 YYYY-MM.md 承载。