# 构想: 任务推进全局设计(AI-First 推进链) — 2026-06-14 > 性质: 架构设计 / 实现方案 > 关联: df-workflow · AiNode/HumanNode · knowledge 状态机范式 · devflow AI-First 定位(kms/devflow_ai_first_model.html) > 修订: > - 多角度对抗论证收敛(kind/状态机不抽层/范围精简) > - 对抗性验证升级(5 维度:收口/并发/崩溃/一致性/前端) > - **AI-First 定位确认**:任务由 AI 执行→AI 自审→人工最终核对(人从操作者转为审批者) --- ## 定位:AI-First 推进链(核心转向) devflow 是 AI-First 工具。任务推进**不是人点按钮的操作流,是 AI 的执行流**: ``` todo ──AI执行──▶ in_progress ──AI自审──▶ review_ready ──人工核对──▶ done AiNode AiNode HumanNode AI 干活 AI 审 AI 的活 人最终把关 AI 产出 ``` - **AI 执行**:任务内容由 AI 干(写代码、改文件、跑测试)。干完自动推进,人不必手动点「开始」。 - **AI 自审**:AI 审 AI 自己的产出(code review,结构化结论)。审过推进,审出问题退回重做。 - **人工最终核对**:人在 merge 关卡最终把关 AI 产出。**这是 AI-First 的核心契约——人监督 AI**,不是人确认自己的活。 **advance_task 的默认触发者从「人」变成「AI」**(执行/自审完成事件触发),人可介入/覆盖/微调。人从「操作者」转为「审批者」。 ### 这修复了对抗验证的 merge 零因果批评 对抗验证 Agent 4 批评「单人场景 merge 审批零因果——自审自批≈手切」。**AI 执行 + 人工核对**正好修复:merge 不再是人确认自己的活,而是**人监督 AI 的活**——从形式主义升级为实质关卡。 --- ## 背景 项目管理任务维护目前**只能创建,不能推进**——前端状态标签纯展示无入口。根因缺「推进编排层」:状态字段、工作流引擎、分支表、状态机范式各干各的,且**完全缺 AI 执行层**。 ## 痛点 | 已有能力 | 位置 | 现状 | |---|---|---| | 任务状态字段(裸 String,无值域校验) | `models.rs:52` | 无状态机、无联动、前端不暴露 | | 工作流引擎(ScriptNode/HumanNode/**AiNode**) | `df-workflow/*` + `df-nodes/*` | 三种节点现成,AiNode 注释明示设计意图「AI 分析→人工审批」,但推进链没用上 | | 分支表状态 | `models.rs:69` | 语义同构,未联动 | | 状态机范式 | `knowledge.rs:53` | 只在 knowledge 用 | | **AI 执行能力** | `df-ai` provider + `ai_node.rs` | AiNode 通用 LLM 调用现成;agent 级「写代码改文件」能力渐进 | --- ## 核心模型:AI-First 推进链 + 状态机 ### 状态机(AI 推进 + 退回 + 旁路) ``` AI执行闸门 AI自审闸门 人工核对闸门 todo ───────────▶ in_progress ──────────▶ review_ready ──────────▶ done ▲ │ │ └── AI自审block/人工拒绝 ┘ │ (AI 重做) ▼ abandoned (任意态可放弃,终态不可逆) ``` **退回边** `review_ready → in_progress`:AI 自审 block 或人工拒绝 → 退回让 AI 重做。AI 推进下退回比人推进更频繁(AI 反复审自己),故 loop 管理必要。 ### 闸门策略(三闸门各司其职,都必需) | 边 | 闸门 | 节点 | 阶段一 | 阶段二 | |---|---|---|---|---| | `start` | **AI 执行** | AiNode/agent | ✅ 必需(最小形态) | + git worktree(code kind) | | `ready` | **AI 自审** | AiNode | ✅ 必需 | + lint/test 真校验 | | `merge` | **人工核对** | HumanNode | ✅ 必需(人监督 AI) | + git merge 副作用 | | `abandon` | 无 | — | 直接转 | 直接转 | 三闸门都必需(不再是「merge 强制 + start/ready 关闭」)——AI 推进链上每环都有节点把关。 ### ⚠️ 失败路径定义(含 AI 执行/自审失败) | 失败场景 | 工作流结果 | 任务状态 | 反馈 | |---|---|---|---| | **AI 执行失败**(agent 报错/超时) | failed | 保持 todo | 「AI 执行失败:<错误>」,人可重试或介入手干 | | **AI 自审 block**(审出严重问题) | failed | **退回 in_progress**(AI 重做) | 「AI 自审未通过:<问题清单>」 | | **AI 自审 warn**(轻微问题) | completed(带警告) | 推进到 review_ready | 警告附在任务上,人核对时可见 | | **人工拒绝** | failed | **退回 in_progress**(AI 重做) | 「人工核对未通过:<意见>」 | | **闸门脚本失败**(阶段二 lint/test) | failed | 保持推进前 | 「闸门失败」 | | **审批超时/取消** | failed/Err | 保持推进前 | 「超时/已取消」 | | **应用崩溃** | running 孤儿 | 保持推进前,可重新推进 | 启动提示「检测到中断的推进」 | **关键**:AI 自审/人工核对的「拒绝/block」→ 退回 in_progress 让 AI 重做(不是退回给人干——AI-First 下人是审批者不是执行者)。 ### AI 自审结果处理(建议性 vs 强制) AiNode 输出纯文本,要判通过与否得约定结构化输出 + 解析: ```json { "verdict": "pass" | "warn" | "block", "issues": [...], "summary": "..." } ``` - `pass`:推进;`warn`:推进但带警告;`block`:退回 in_progress - 默认 AI 自审走 verdict 判定(非纯建议),否则 AI 推进链断在人审前 - 人审(merge)仍是最终关卡,可覆盖 AI 自审结论 --- ## AI 执行层(新增,核心缺口) 任务内容由谁干——这是原方案的最大盲区。AI-First 下由 AI 执行。 ### 实现形态 - **AiNode/agent 执行**:start 闸门触发 AiNode(或更复杂的 agent 编排)干活——读任务描述 + 项目上下文 → 写代码/改文件/跑测试 → 产出 diff - **执行能力渐进**:阶段一最小形态(AiNode 跑执行 prompt / 接现有 AI 工具链),阶段二+ 逐步增强(agent 多步、文件操作、git worktree 内执行) - **执行产出**:代码 diff / 文件变更 / 测试结果,供下游 AI 自审节点消费 ### advance_task 触发者变更 - **默认**:AI 执行完成事件 → 自动触发 advance_task(start→推进) - AI 自审完成 → 触发 advance_task(ready→推进或退回) - 人工核对完成 → 触发 advance_task(merge→done) - **人可介入**:任何节点人能手动推进/覆盖/接手(人转手干) --- ## 【P0】状态机收口(对抗验证最高优先级) ### 致命漏洞:update_task 是公开旁路 `task.rs:74` update_task 白名单含 `"status"`(`crud.rs:291`),任意调用方一行绕过所有闸门和状态机。且 `crud tests:249` 单测固化旁路。AI 推进下更危险——AI agent 若能调 update_task 改 status,整个 AI 执行/自审/核对链形同虚设。 ### 收口措施 1. 从 tasks 白名单**移除 `"status"`** 2. **advance_task 成为 status 唯一写入路径**(AI 触发也走它) 3. 删除/改写 `update_field_allows_tasks_status` 单测 4. advance_task 内联 `validate_task_status` 值域校验 --- ## 状态集清理(非「定稿」) 对抗验证纠误:前端早已 5 态,后端 enum 多 3 个僵尸死状态(InReview/Testing/Blocked 零使用)。是「清理僵尸」非「7→5 定稿」。 措施:删后端 enum 死状态 + `merged→done` 改名 + 迁移前抽样 + status 值域校验。 ```sql -- 迁移(幂等,conn.transaction() 包裹) UPDATE tasks SET status='done' WHERE status='merged'; ``` --- ## 任务类型:阶段一不加 kind 对抗验证:阶段一 code/generic 行为零差异,违反 YAGNI。阶段二 git 联动需要区分时再加 kind(ALTER + 回填 generic)。`tags` 保留承担语义标注(doc/design)。 **AI 推进下的 kind 意义**:阶段二+ AI 执行内容按 kind 分化(code 任务 AI 写代码、doc 任务 AI 写文档、design 任务 AI 出图)。阶段一 AI 执行最小形态不区分,随能力增强再分。 --- ## 状态机实现:不抽层 + 下沉 SQL enum 补 `can_transition_to`(不新建 state_machine.rs,knowledge validate_transition 源码验证是空壳): ```rust impl TaskStatus { pub fn can_transition_to(&self, to: &TaskStatus) -> bool { match (self, to) { (Todo, InProgress | Abandoned) => true, (InProgress, ReviewReady | Abandoned) => true, (ReviewReady, Done | Abandoned | InProgress) => true, // 可退回(AI 重做) _ => false, } } } ``` **状态机下沉 SQL**(TOCTOU 根治):advance_task 的校验+写入合并为带前置条件的 UPDATE: ```sql UPDATE tasks SET status=:new, updated_at=:now WHERE id=:id AND status=:expected -- affected_rows==0 即状态已变,拒绝 ``` 终态保护:`AND status NOT IN ('done','abandoned')`。 --- ## loop 管理(AI 推进下必需) AI 自审/人工核对退回 → AI 重做 → 再审 → 可能反复。加 `review_rounds: i32` 计数,退回时 +1: - 任务卡显示「第 N 轮 review」(迭代可见性) - 可选:轮数过高提示「是否卡住」(不强制终止——单人/AI 决定何时 done) - 强制终止/阈值不做(over-engineering) --- ## 并发与一致性护栏(对抗验证新增) AI 推进下并发更常见(多个任务并行 AI 执行)。护栏不变: 1. **per-task 互斥锁**:`task_locks: Arc>>>>` 2. **闸门工作流去重**:起 run_workflow 前查 running/interrupted 工作流 3. **WorkflowEvent 加 execution_id** + 转发过滤(防多任务事件串台) 4. **审批请求带 task_id**(task_id + execution_id + node_id 三元组) --- ## 数据一致性:跨表事务 `crud.rs` 无跨表事务,advance_task 多表写(task.status + workflow.status + 阶段二 branches/projects)半成品无法回滚。promote_idea 补偿范式不适用更新型。 措施:**补 `Database.transaction()`**(OwnedTransaction),advance_task 事务内提交。迁移幂等(column_exists + WHERE + conn.transaction 包裹)。tags 写入校验。 --- ## 崩溃恢复(对抗验证新增,AI 推进下更关键) AI 执行/自审是长时异步过程,崩溃恢复更关键: 1. **启动孤儿清理**:`UPDATE workflow_executions SET status='interrupted' WHERE status='running'` 2. **审批请求持久化**:HumanNode 阻塞前落库(node_executions status='pending'),启动恢复 3. **AI 执行状态持久化**:AI 执行(长时)需 checkpoint,崩溃后能恢复或安全重做(阶段二+) 4. **审批拒绝语义化**:HumanNode/AiNode 区分同意/拒绝/block,拒绝走失败路径不当 Ok 5. **重复触发守卫**:advance_task 入口检查 running/interrupted 工作流 --- ## 前端改造(对抗验证新增 + AI 推进适配) 1. **pendingApprovals 数组化**(按 execution_id 索引) 2. **liveEvents 按 task 路由**:event payload 加 task_id,store 改 liveEventsByTask 3. **任务卡 AI 推进可视化**:显示当前在哪个环节(AI 执行中/AI 自审中/待人工核对/第 N 轮) 4. **按钮防重入**:advancingTaskIds: Set 5. **确认式更新**:等 IPC/workflow 事件再刷 task,非乐观更新 6. **AI 产出展示**:AI 执行的 diff、AI 自审的意见清单,供人核对时查看 7. **统一错误桥接**:全局 watch state.error → Message.error 8. **回调判定**:run_workflow 完成回调 advance_task 条件 `task_id.is_some()` --- ## 两阶段落地 ### 阶段一:AI-First 推进链 + 工程护栏 **推进链**: - 状态集清理(删僵尸 + merged→done)+ enum 补 can_transition_to - **状态机收口**(移除 status 白名单 + advance_task 唯一入口 + 值域校验)← P0 - advance_task + 状态机下沉 SQL + on_task_advanced 空钩子 - **AI 执行闸门**(AiNode 最小形态)+ **AI 自审闸门**(AiNode 结构化 verdict)+ **人工核对闸门**(HumanNode) - **失败路径定义**(AI 执行失败/AI 自审 block/人工拒绝→退回重做) - **loop 管理**(review_rounds 计数) - per-task 锁 + 闸门去重、跨表事务、WorkflowEvent 加 execution_id、启动孤儿清理 + 审批持久化 - WorkflowRecord 填值 + event payload 加 task_id - 前端:pendingApprovals/liveEventsByTask/advancingTaskIds/确认式更新/AI 推进可视化 **触发者**:advance_task 支持 AI 事件触发 + 人手动介入双通道。 ### 阶段二:Git + 联动 + AI 执行增强 - 加 kind 字段;code kind 闸门脚本换 git 命令串;start/ready 接真 git/lint/test - AI 执行增强(agent 多步、worktree 内执行、文件操作) - 填 on_task_advanced:分支联动 + 项目 completed(含边界守卫) - BranchRecord 加 worktree_path ### Git 集成:直接外部命令 git 是 ScriptNode/AiNode 一串命令,不特殊化。不建 worktree.rs/df-git crate;不做 git 检测框架。硬依赖 git ≥2.20。非 code 任务不依赖 git。 ### 联动策略 阶段一剥离分支联动和项目 completed(~90 行 + 边界漏洞),阶段二填钩子返工 <30 行。 --- ## 落地改动点(阶段一,按优先级) | 级 | # | 文件 | 改动 | |---|---|---|---| | **P0** | 1 | `crud.rs`+`task.rs` | 移除 status 白名单 + advance_task 唯一入口 + 值域校验 + 改单测 | | **P0** | 2 | `task.rs` | advance_task + 状态机下沉 SQL + on_task_advanced 空钩子 + **支持 AI 事件触发** | | **P0** | 3 | 闸门 DAG 模板 | **AI 执行(AiNode)+ AI 自审(AiNode verdict)+ 人工核对(HumanNode)三闸门** | | **P0** | 4 | `human_node.rs`+`ai_node.rs`+`executor.rs` | **审批/自审拒绝语义化**(block/拒绝走失败路径不当 Ok) | | **P1** | 5 | `task.rs`/`models.rs` | **review_rounds 计数**(退回 +1) | | **P1** | 6 | `state.rs` | per-task 锁 + 闸门去重 | | **P1** | 7 | `db.rs`/`crud.rs` | 补 Database.transaction() + 事务包裹 | | **P1** | 8 | `events.rs`+`workflow.rs` | WorkflowEvent 加 execution_id + 转发过滤 | | **P1** | 9 | `state.rs` init | 启动孤儿清理 + 审批持久化恢复 | | **P1** | 10 | `types.rs` | 删 enum 僵尸 + 补 can_transition_to | | **P1** | 11 | 迁移 | merged→done(幂等 + 事务)| | **P1** | 12 | `workflow.rs` | run_workflow 加 task_id/project_id + event payload 加 task_id + 完成回调 | | **P1** | 13 | `models.rs` | TaskRecord 加 tags(kind 推阶段二)+ review_rounds + 白名单 | | **P1** | 14 | 前端 `project.ts`/vue | pendingApprovals 数组 + liveEventsByTask + advancingTaskIds + 确认式更新 + **AI 推进环节可视化** + **AI 产出/diff 展示** | | **P2** | 15 | `constants`+i18n | merged→done 键名 + tags + review_rounds 文案 + AI 环节文案 | | **P2** | 16 | `project.ts` | 全局 error 桥接 | --- ## 决策护栏(触发反转条件) | 决策 | 反转条件 | |---|---| | AI-First 推进(AI 执行→自审→人核对) | AI 执行能力长期不足/不可靠 → 退回人执行 + AI 辅助审 | | 阶段一不加 kind | 阶段二 doc/design 真要 AI 执行不同内容;或按 kind 统计 | | 状态机不抽层 | 第三处状态机需统一审计 | | 阶段一剥离联动 | 用户验收反馈「想看到项目自动完成」 | | 不提前集成 git | worktree 异常恢复需 Rust 逻辑 | | 状态机收口 | 出现「需批量脚本直接改 status」运维场景 → 另开受控入口 | | AI 自审走 verdict 判定(非纯建议) | AI 自审误判率高 → 降级为建议性,人审全权 | --- ## 决策清单(人定取舍 · why) | # | 决策 | 否决备选 | why | |---|---|---|---| | 1 | **AI-First 推进链**(AI 执行→AI 自审→人工核对) | 人点按钮推进 | devflow 是 AI-First 工具,任务是 AI 的执行流非人的操作流 | | 2 | **advance_task 默认 AI 触发**,人可介入 | 仅人触发 | AI 执行/自审完成自动推进;人转审批者 | | 3 | **AI 自审走 verdict 判定**(pass/warn/block) | 纯建议 | AI 推进链需 AI 自审能阻断,否则断在人审前 | | 4 | **人工核对 = 人监督 AI**(非自审自批) | 人确认自己的活 | 修复 merge 零因果;AI-First 核心契约 | | 5 | **拒绝/block → 退回 AI 重做**(非退回人干) | 退回人执行 | AI-First 下人是审批者不是执行者 | | 6 | **loop 管理 review_rounds**(AI 推进必需) | 无计数 | AI 反复审自己,循环比人推进频繁 | | 7 | 状态机收口(移除 update_task status) | 保留旁路 | 对抗验证:旁路让状态机形同虚设,AI 推进下更危险 | | 8 | 阶段一不加 kind,阶段二再加 | 阶段一二分 | 对抗验证:阶段一零行为差异 | | 9 | 状态机不抽层,enum 补方法 | 抽通用层 | 源码验证空壳 | | 10 | 状态机下沉 SQL(WHERE 前置) | 纯内存校验 | 对抗验证:根治 TOCTOU | | 11 | 失败路径全覆盖(含 AI 执行/自审失败) | 只描述快乐路径 | 对抗验证:拒绝被当成功是语义反转 | | 12 | 补跨表事务 | 无事务多写 | 对抗验证:半成品无法回滚 | | 13 | 崩溃恢复(孤儿清理+审批持久化+AI 执行 checkpoint) | 纯内存 | AI 执行长时异步,崩溃恢复更关键 | | 14 | WorkflowEvent 加 execution_id | 全局单通道 | 对抗验证:多任务事件串台 | | 15 | 状态集清理后端僵尸(非 7→5 定稿) | 当作待决策 | 对抗验证:前端早已 5 态 | | 16 | 闸门三必需(AI执行/AI自审/人工核对) | merge 强制+其余关 | AI 推进链每环都有节点把关 | | 17 | 阶段一剥离联动 | 顺带联动 | ~90 行+边界漏洞 | | 18 | 预留 on_task_advanced 钩子 | 不预留 | 阶段二补是挂插件 | | 19 | git=闸门脚本调外部命令 | worktree.rs/df-git crate | YAGNI | | 20 | merged→done(迁移) | 文案分流 | 命名中性化 | | 21 | 前端 pendingApprovals 数组 + 确认式更新 + AI 环节可视化 | 单值/乐观 | 对抗验证:多任务并发;AI 推进需环节可见 | --- ## 演进记录 1. **多角度论证收敛**:kind 二分、状态机不抽层、阶段一范围精简、闸门策略 2. **对抗性验证升级(5 维度)**:状态机收口/并发/崩溃恢复/一致性/前端——挖出 P0 致命项(旁路、审批拒绝=成功、TOCTOU、纯内存) 3. **AI-First 定位确认**:任务由 AI 执行→AI 自审→人工最终核对。补执行层(原方案最大盲区),advance_task 触发者改 AI,AI 审/loop 升必需,merge 升级为「人监督 AI」实质关卡