squash合并: - 意图识别层论证(8维度+10业界佐证) - 多主题上下文管理愿景+并存论证+补充论证(多轮agentic) - 架构设计文档物理分类(四子目录+INDEX+命名规范+引用同步+边界清晰化) - 前端架构技术债清单归档
18 KiB
构想: 任务推进全局设计(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 输出纯文本,要判通过与否得约定结构化输出 + 解析:
{ "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 执行/自审/核对链形同虚设。
收口措施
- 从 tasks 白名单移除
"status" - advance_task 成为 status 唯一写入路径(AI 触发也走它)
- 删除/改写
update_field_allows_tasks_status单测 - advance_task 内联
validate_task_status值域校验
状态集清理(非「定稿」)
对抗验证纠误:前端早已 5 态,后端 enum 多 3 个僵尸死状态(InReview/Testing/Blocked 零使用)。是「清理僵尸」非「7→5 定稿」。
措施:删后端 enum 死状态 + merged→done 改名 + 迁移前抽样 + status 值域校验。
-- 迁移(幂等,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 源码验证是空壳):
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:
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 执行)。护栏不变:
- per-task 互斥锁:
task_locks: Arc<Mutex<HashMap<String, Arc<Mutex<()>>>>> - 闸门工作流去重:起 run_workflow 前查 running/interrupted 工作流
- WorkflowEvent 加 execution_id + 转发过滤(防多任务事件串台)
- 审批请求带 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 执行/自审是长时异步过程,崩溃恢复更关键:
- 启动孤儿清理:
UPDATE workflow_executions SET status='interrupted' WHERE status='running' - 审批请求持久化:HumanNode 阻塞前落库(node_executions status='pending'),启动恢复
- AI 执行状态持久化:AI 执行(长时)需 checkpoint,崩溃后能恢复或安全重做(阶段二+)
- 审批拒绝语义化:HumanNode/AiNode 区分同意/拒绝/block,拒绝走失败路径不当 Ok
- 重复触发守卫:advance_task 入口检查 running/interrupted 工作流
前端改造(对抗验证新增 + AI 推进适配)
- pendingApprovals 数组化(按 execution_id 索引)
- liveEvents 按 task 路由:event payload 加 task_id,store 改 liveEventsByTask
- 任务卡 AI 推进可视化:显示当前在哪个环节(AI 执行中/AI 自审中/待人工核对/第 N 轮)
- 按钮防重入:advancingTaskIds: Set
- 确认式更新:等 IPC/workflow 事件再刷 task,非乐观更新
- AI 产出展示:AI 执行的 diff、AI 自审的意见清单,供人核对时查看
- 统一错误桥接:全局 watch state.error → Message.error
- 回调判定: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 推进需环节可见 |
演进记录
- 多角度论证收敛:kind 二分、状态机不抽层、阶段一范围精简、闸门策略
- 对抗性验证升级(5 维度):状态机收口/并发/崩溃恢复/一致性/前端——挖出 P0 致命项(旁路、审批拒绝=成功、TOCTOU、纯内存)
- AI-First 定位确认:任务由 AI 执行→AI 自审→人工最终核对。补执行层(原方案最大盲区),advance_task 触发者改 AI,AI 审/loop 升必需,merge 升级为「人监督 AI」实质关卡