diff --git a/Batch.md b/Batch.md index 9860c42..7a9cdaa 100644 --- a/Batch.md +++ b/Batch.md @@ -435,35 +435,76 @@ > 设计文档:[多Agent并行执行与仲裁合并设计-2026-07-01.md](docs/02-架构设计/专项设计/多Agent并行执行与仲裁合并设计-2026-07-01.md) -### Batch 37 — 数据层 + 并行执行 +### 数据层 + Git worktree 隔离 + 并行执行 | # | 任务 | 文件 | |---|------|------| -| 1 | V36 迁移(ai_plans/ai_subtasks/ai_conflicts 3 新表 + ai_messages/ai_tool_executions 加 subtask_id 列) | migrations.rs | -| 2 | PlanRepo / SubTaskRepo / ConflictRepo CRUD | 新 repo 文件 | -| 3 | Coordinator.dispatch 改 JoinSet 层内并行(写 SubTask 降级串行) | coordinator.rs | -| 4 | Token 预算池(超限拒绝新 SubTask) | coordinator.rs | -| 5 | 子 Agent 独立 ContextManager + fork 快照(隔离上下文) | coordinator.rs | -| 6 | 4 个新事件类型(AiPlanCreated/AiSubTaskStatusChanged/AiMergeCompleted/AiConflictResolved) | AiChatEvent | -| 7 | PlanProgress 接入真实状态 + 发送即展示 | PlanProgress.vue | -| 8 | 工具卡按 subtask_id 折叠归组(带 persona 徽章) | MessageList.vue | -| 9 | 前端 PlanRecord/SubTaskRecord/ConflictRecord 类型 | api/types.ts | +| 1 | V36 迁移(ai_plans/ai_subtasks/ai_conflicts 3 新表 + ai_messages/ai_tool_executions 加 subtask_id + subtasks.branch + conflicts.conflict_type) | migrations.rs | +| 2 | PlanRepo / SubTaskRepo / ConflictRepo CRUD + models 结构体 | 新 repo 文件 | +| 3 | Git worktree 生命周期管理(create/commit/merge/remove) | 新 git_worktree.rs | +| 4 | Coordinator.dispatch JoinSet 层内并行(每 SubTask 绑 worktree) | coordinator.rs | +| 5 | Token 预算池(AtomicU64 CAS,超限降级串行) | coordinator.rs | +| 6 | 子 Agent 独立 ContextManager + fork 快照 + worktree_path | coordinator.rs | +| 7 | 层间 merge 到 plan 分支 + 下一层基于 plan 创建 worktree | coordinator.rs | +| 8 | 4 个新事件 + 事件双写(emit + publish_event) | AiChatEvent | +| 9 | 前端类型定义(PlanRecord/SubTaskRecord/ConflictRecord) | api/types.ts | +| 10 | PlanProgress 接入真实状态 + 发送即展示 | PlanProgress.vue | +| 11 | 工具卡按 subtask_id 折叠分组 + persona 徽章 | MessageList.vue | +| 12 | 编译警告清理(coordinator_plan unused / audit 子模块 unused imports) | 各文件 | -### Batch 38 — 仲裁合并 + UI 完善 +### 仲裁合并 + 冲突 UI + 编译检查 | # | 任务 | 文件 | |---|------|------| -| 1 | Coordinator.merge 冲突检测(按文件路径) | coordinator.rs | -| 2 | Reviewer Agent 仲裁(persona.rs 扩展) | persona.rs + coordinator.rs | -| 3 | 冲突 diff 展示 + resolution 按钮 | 新 ConflictResolver.vue | -| 4 | AiConflictResolved 事件闭环 | AiChatEvent | -| 5 | 技术债扫尾(编译警告 / unused import) | 各文件 | +| 1 | Coordinator.merge: git merge-tree 三方合并预检 | coordinator.rs + git_worktree.rs | +| 2 | 冲突检测:同文件路径(file) + 编译失败(semantic) | coordinator.rs | +| 3 | Reviewer Agent 仲裁(persona 扩展:读 diff → 推荐 resolution + 理由) | persona.rs | +| 4 | 合并产出落回主对话(可展开单条,默认折叠) | coordinator.rs + MessageList.vue | +| 5 | ConflictResolver.vue(git diff 展示 + resolution 按钮) | 新组件 | +| 6 | resolve_conflict IPC + AiConflictResolved 事件闭环 | AiChatEvent | +| 7 | 命令互斥锁(run_command 对同目录 npm/cargo 加 mutex) | audit/approval.rs | +| 8 | agentic/mod.rs 拆分(2222行 → 提取 compress/title/knowledge_inject 独立模块) | agentic/*.rs | +| 9 | AiChat 进度条补全(后端 AiAgentRound 补 max_rounds + 前端 completed 计数) | AiChat.vue | +| 10 | context.rs 拆分(1956行 → 提取 sanitize/budget/compress 独立模块) | context/*.rs | -### Batch 39-40 — P1 模板系统 + Git/CI(远期) +### 模板系统 + 节点补齐 -1. YAML 模板加载器 + SubflowNode -2. GitNode(分支/PR/合并) + DockerNode(容器构建/测试) -3. 从模板加载工作流 → Git 分支 → 代码生成 → PR → CI 全链路 +| # | 任务 | 文件 | +|---|------|------| +| 1 | YAML 模板格式定义(DagDef schema: nodes/edges/conditions/persona) | 新设计文档 | +| 2 | 模板加载器(YAML → DagDef 反序列化 + 校验) | df-workflow | +| 3 | SubflowNode(嵌套子工作流节点,递归调 Executor) | df-nodes | +| 4 | GitNode(分支创建/checkout/commit/merge,复用 git CLI) | df-nodes | +| 5 | HTTPNode(通用 HTTP 请求: GET/POST/PUT/DELETE) | df-nodes | +| 6 | NotifyNode(桌面通知 + Webhook: 飞书/钉钉/自定义) | df-nodes | +| 7 | 内置模板 3 个预设(代码审查 / bug修复 / 功能开发) | assets/templates/ | +| 8 | 前端模板选择入口(AiChat 输入框 /template 触发) | AiChat.vue | +| 9 | 模板 CRUD IPC + 前端管理 UI | 新模板管理页 | +| 10 | MessageList.vue 继续拆分(1386行 → 提取 StreamRenderer/ToolCardGroup/EmptyState) | MessageList.vue + 子组件 | + +### Git/CI 集成 + DockerNode + God 文件收尾 + +| # | 任务 | 文件 | +|---|------|------| +| 1 | DockerNode(容器内构建/测试,CLI 模式起步: docker run/exec) | df-nodes | +| 2 | PR 创建链路(GitNode 创建分支 → 提交 → push → 创建 PR) | df-nodes + API | +| 3 | CI 状态读取(调 GitHub/Gitea API 读 PR check 结果) | 新 ci_status.rs | +| 4 | CI 状态面板(前端新组件展示 PR check 通过/失败/pending) | 新 CIStatus.vue | +| 5 | 全链路集成测试(模板加载 → 分支 → 代码生成 → PR → CI → 结果回显) | 集成测试 | +| 6 | ChatInput.vue 继续拆分(1155行 → 提取 MentionPopover/EnrichmentPanel) | ChatInput.vue + 子组件 | + +### 审批政策 + 小程序完善 + 体验收尾 + +| # | 任务 | 文件 | +|---|------|------| +| 1 | 审批策略数据结构(Persona × Node × RiskLevel → Policy) | 新 policy.rs | +| 2 | 策略引擎(替代硬编码 auto_exec_mode 三档,支持细粒度规则) | policy.rs | +| 3 | 策略持久化(app_settings KV 或独立 policy 表 + 热加载) | migrations + repo | +| 4 | 前端策略配置 UI(设置页新增:规则列表 + 新建/编辑/删除) | 新 PolicyPanel.vue | +| 5 | 小程序 MentionInput 接真实数据(替换占位列表为真实技能路由/实体检索) | df-miniapp | +| 6 | 小程序长会话虚拟化(替代 MAX_RENDER_MSGS=200 截断,滚动入视口才 parse) | df-miniapp | +| 7 | 快捷键完善(Ctrl+N/Ctrl+R WebView2 实测 + 绑定决策) | AiChat.vue | +| 8 | ARCHITECTURE.md 状态同步 + 走查报告剩余项扫尾 | 文档 --- diff --git a/docs/02-架构设计/INDEX.md b/docs/02-架构设计/INDEX.md index 2f72793..8799f7a 100644 --- a/docs/02-架构设计/INDEX.md +++ b/docs/02-架构设计/INDEX.md @@ -87,7 +87,8 @@ | [项目知识图谱与任务队列系统-2026-06-26.md](./专项设计/项目知识图谱与任务队列系统-2026-06-26.md) | 📐 设计 | 项目级知识图谱 + 任务队列:依赖解析 / 优先级调度 | | [工程系统设计-2026-06-29.md](./专项设计/工程系统设计-2026-06-29.md) | ✅ 已落地 | 项目多工程(Module) + Git 状态查询 + 文件浏览器 + Git AI 工具(只读3+写3) | | [架构债迁移设计-2026-06-29.md](./专项设计/架构债迁移设计-2026-06-29.md) | 📐 设计草案 | #8/#15/#18/#19 架构债迁移路径(AI状态机抽离/IPC错误结构化/配置统一/连接池) | -| [多Agent并行执行与仲裁合并设计-2026-07-01.md](./专项设计/多Agent并行执行与仲裁合并设计-2026-07-01.md) | 📐 设计 | P0 Batch 37-38 实施依据:混合数据模型(messages加FK列+Plan/SubTask/Conflict独立表)、JoinSet层内并行、Reviewer仲裁、事件协议、UI交互(PlanProgress+工具卡分组+冲突徽章) | +| [多Agent并行执行与仲裁合并设计-2026-07-01.md](./专项设计/多Agent并行执行与仲裁合并设计-2026-07-01.md) | 📐 设计 | 混合数据模型(messages加FK列+Plan/SubTask/Conflict独立表)、Git worktree隔离、JoinSet层内并行、四层冲突防线、Reviewer仲裁、事件协议、UI交互 | +| [后续批次测试用例设计-2026-07-01.md](./专项设计/后续批次测试用例设计-2026-07-01.md) | 📐 测试 | 多Agent并行/worktree隔离/仲裁合并/模板系统/Git-CI/审批政策 的单元+集成+端到端测试用例 | --- diff --git a/docs/02-架构设计/专项设计/后续批次测试用例设计-2026-07-01.md b/docs/02-架构设计/专项设计/后续批次测试用例设计-2026-07-01.md new file mode 100644 index 0000000..5106954 --- /dev/null +++ b/docs/02-架构设计/专项设计/后续批次测试用例设计-2026-07-01.md @@ -0,0 +1,252 @@ +# 后续批次测试用例设计 — 2026-07-01 + +> 覆盖:多Agent并行执行 / Git worktree 隔离 / 仲裁合并 / 模板系统 / Git-CI / 审批政策 +> 关联:[多Agent并行执行与仲裁合并设计-2026-07-01.md](02-架构设计/专项设计/多Agent并行执行与仲裁合并设计-2026-07-01.md) + +--- + +## 一、测试分层 + +| 层级 | 范围 | 工具 | +|------|------|------| +| **单元测试** | 纯函数/数据结构/repo CRUD | `#[test]` Rust / vitest TS | +| **集成测试** | 跨模块协作(dispatch+merge+worktree) | `#[tokio::test]` | +| **端到端** | 用户发消息→Plan→并行→合并→展示 | 手动 + 日志验证 | + +--- + +## 二、数据层与并行执行 测试用例 + +### 2.1 V36 迁移 + +| ID | 场景 | 预期 | +|----|------|------| +| MIG-01 | 新库空跑 V36 | 3 新表 + 2 列 ALTER 成功,ai_plans 为空 | +| MIG-02 | 老库(有数据)跑 V36 | ai_messages/ai_tool_executions 加 subtask_id 列(NULL),原有数据不动 | +| MIG-03 | V36 幂等(重跑) | 不崩溃,版本号已写入直接跳过 | +| MIG-04 | 老库 ai_messages 有 100 条数据 | subtask_id 全部为 NULL,查询不报错 | + +### 2.2 Repo CRUD + +| ID | 场景 | 预期 | +|----|------|------| +| REPO-01 | PlanRepo.insert + get | 写入后能按 id 读回,字段完整 | +| REPO-02 | PlanRepo.update_status | planning→executing→done 状态流转正确 | +| REPO-03 | SubTaskRepo.insert + list_by_plan | 按 plan_id 查子任务,layer 排序正确 | +| REPO-04 | SubTaskRepo.update_status | pending→running→done 流转 | +| REPO-05 | ConflictRepo.insert + list_pending | 按 plan_id 查 resolution=pending 的冲突 | +| REPO-06 | ConflictRepo.resolve | 更新 resolution + resolved_by + resolved_at | +| REPO-07 | SubTaskRepo 查 branch=NULL | 非 Git 工程的 SubTask branch 为 NULL,查询正常 | + +### 2.3 Coordinator 拆解 + +| ID | 场景 | 输入 | 预期 | +|----|------|------|------| +| DEC-01 | 读+写意图 | "先 read 文件再修改" | 2 SubTask(read→write),write deps=[read] | +| DEC-02 | 纯读意图 | "分析现有代码结构" | 1 SubTask(read),无 deps | +| DEC-03 | 纯写意图 | "implement new feature" | 1 SubTask(write),无 deps | +| DEC-04 | 兜底意图 | "你好" | 1 SubTask(default) | +| DEC-05 | 人设分配 | "review this code" | SubTask persona=reviewer | +| DEC-06 | Plan 非空 | 任意非空输入 | plan.tasks.len() >= 1 | + +### 2.4 Git worktree 隔离 + +| ID | 场景 | 预期 | +|----|------|------| +| WT-01 | worktree 创建 | `.devflow/wt/{plan_id}/A` 目录存在,git branch `subtask/{plan_id}/A` 存在 | +| WT-02 | worktree 内 write_file | 写入落到 worktree 目录,主目录文件不变 | +| WT-03 | 同层并行隔离 | SubTask A 写 main.rs,SubTask B 读 main.rs → B 读到的是 fork 基点内容,非 A 的改动 | +| WT-04 | worktree commit | SubTask 完成后 git add+commit,分支有新 commit | +| WT-05 | worktree 清理 | Plan 完成后 `.devflow/wt/{plan_id}/` 目录被移除 | +| WT-06 | 非 Git 工程降级 | 无 .git 的工程 → branch=NULL,走串行,不崩溃 | +| WT-07 | worktree 创建失败 | 磁盘满/权限不足 → 降级串行,日志告警 | + +### 2.5 并行调度 + +| ID | 场景 | 预期 | +|----|------|------| +| PAR-01 | 线性链(2层×1任务) | Layer0 done → Layer1 启动,总耗时≈串行 | +| PAR-02 | 并行层(1层×3任务) | 3 SubTask 并发执行,总耗时≈最慢的一个 | +| PAR-03 | 钻石依赖 | A→{B,C}→D,B/C 并行,D 等 B+C 都 done | +| PAR-04 | 层间隔离 | Layer1 的 SubTask 能读到 Layer0 merge 后的改动 | +| PAR-05 | 单 SubTask 失败 | 标记 error,不中断同层其他 SubTask | +| PAR-06 | 全部 SubTask 失败 | Plan.status=error | +| PAR-07 | SubTask 超时(120s) | 标记 error,其他 SubTask 不受影响 | + +### 2.6 Token 预算池 + +| ID | 场景 | 预期 | +|----|------|------| +| TOK-01 | 预算充足 | try_reserve(10k) → true,consumed+=10k | +| TOK-02 | 预算超限 | consumed=98k,total=100k,try_reserve(5k) → false | +| TOK-03 | 并发 reserve | 2 个 SubTask 同时 reserve(CAS 竞争) | 只有一个成功 | +| TOK-04 | 超限降级串行 | 预算用完 → 剩余 SubTask 串行执行(不拒绝) | + +### 2.7 事件协议 + +| ID | 场景 | 预期 | +|----|------|------| +| EVT-01 | AiPlanCreated | 前端 PlanProgress 立即展示 DAG 层结构 | +| EVT-02 | AiSubTaskStatusChanged | 节点状态从 pending→running→done 更新 | +| EVT-03 | AiMergeCompleted(无冲突) | 合并输出展示,无冲突徽章 | +| EVT-04 | AiMergeCompleted(有冲突) | 冲突徽章出现 | +| EVT-05 | AiConflictResolved | 冲突徽章消失 | +| EVT-06 | 事件双写 | emit 和 publish_event 都触发 | + +--- + +## 三、仲裁合并与冲突 测试用例 + +### 3.1 Git merge 冲突检测 + +| ID | 场景 | 预期 | +|----|------|------| +| MRG-01 | 无冲突合并 | A 改 file1,B 改 file2 → merge-tree 无冲突 → git merge 成功 | +| MRG-02 | 同文件冲突 | A 改 main.rs 第10行,B 改 main.rs 第10行 → conflict markers 出现 | +| MRG-03 | 同文件不冲突区 | A 改 main.rs 第10行,B 改 main.rs 第50行 → git 自动合并成功 | +| MRG-04 | 跨层同文件 | Layer0 改 main.rs,merge 到 plan;Layer1 改 main.rs → 基于已含 Layer0 的版本,无冲突 | +| MRG-05 | 三方合并预检 | git merge-tree 返回非空冲突列表 → 不执行 merge,标记 conflict | + +### 3.2 编译检查(semantic 冲突) + +| ID | 场景 | 预期 | +|----|------|------| +| CMP-01 | 合并后编译通过 | cargo check exit 0 → 无 semantic 冲突 | +| CMP-02 | 合并后编译失败 | A 删函数 foo(),B 在调 foo() → cargo check 失败 → conflict_type=semantic | +| CMP-03 | 前端项目 | tsc --noEmit 失败 → semantic 冲突 | +| CMP-04 | 无构建工具的工程 | 跳过编译检查(无 cargo/tsc) → 不阻塞 merge | + +### 3.3 Reviewer 仲裁 + +| ID | 场景 | 预期 | +|----|------|------| +| ARB-01 | Reviewer 推荐 A | diff_a 更完整 → resolution=a,resolved_by=reviewer | +| ARB-02 | Reviewer 推荐 merged | 两者各有价值 → resolution=merged,给出合并方案 | +| ARB-03 | Reviewer 无法判断 | 两者等价 → resolution=pending,留给用户 | +| ARB-04 | Reviewer 超时 | LLM 调用超时 → 自动降级为 pending | + +### 3.4 冲突解决闭环 + +| ID | 场景 | 预期 | +|----|------|------| +| RSV-01 | 用户选接受 A | resolution=a,文件应用 A 的改动,B 的改动丢弃 | +| RSV-02 | 用户选手动 | resolution=manual,用户在 worktree 手动编辑后 commit | +| RSV-03 | 全部冲突解决 | Plan.status 从 merging→done | +| RSV-04 | 前端徽章更新 | AiConflictResolved 事件 → 冲突徽章消失 | + +### 3.5 合并产出落回主对话 + +| ID | 场景 | 预期 | +|----|------|------| +| OUT-01 | 无冲突合并 | 主对话新增 1 条 assistant 消息(merged_output) | +| OUT-02 | 有冲突合并 | 主对话新增 1 条 + 冲突徽章 | +| OUT-03 | 展开查看子 Agent 轨迹 | 点击展开 → 从 ai_messages WHERE subtask_id=? 加载,按 SubTask 分组 | +| OUT-04 | 折叠状态默认 | 新消息默认折叠,只显示摘要 | + +### 3.6 命令互斥锁 + +| ID | 场景 | 预期 | +|----|------|------| +| LCK-01 | 同目录 npm install 并发 | 第二个等第一个完成才执行(不并行) | +| LCK-02 | 不同目录 npm install | 并行执行(锁 key 含目录) | +| LCK-03 | cargo + npm 同目录 | 不互斥(锁 key 含命令名) | + +--- + +## 四、模板系统 测试用例 + +### 4.1 YAML 模板加载 + +| ID | 场景 | 预期 | +|----|------|------| +| TPL-01 | 合法 YAML 加载 | DagDef 结构完整,nodes/edges/conditions 正确解析 | +| TPL-02 | 缺必填字段 | nodes 为空 → 报错"模板节点不能为空" | +| TPL-03 | 依赖闭环 | A→B→A → 报错"依赖存在环" | +| TPL-04 | 未知节点类型 | node.type="UnknownNode" → 报错"未知节点类型" | +| TPL-05 | 内置模板加载 | 3 个内置模板(代码审查/bug修复/功能开发)全部加载成功 | +| TPL-06 | 自定义模板 CRUD | 创建→读取→更新→删除,持久化到 DB | + +### 4.2 SubflowNode + +| ID | 场景 | 预期 | +|----|------|------| +| SUB-01 | 嵌套子工作流执行 | SubflowNode 加载子模板 → 递归执行 → 返回子工作流结果 | +| SUB-02 | 子工作流审批 | 子工作流内的 HumanNode 审批 → 挂起 → 恢复 | +| SUB-03 | 嵌套深度限制 | 超过 MAX_PLAN_DEPTH → 报错 | + +### 4.3 新节点 + +| ID | 场景 | 预期 | +|----|------|------| +| NODE-01 | GitNode 创建分支 | branch_name 存在,git branch 列表可见 | +| NODE-02 | GitNode commit | 工作区改动已提交,git log 有新记录 | +| NODE-03 | HTTPNode GET | 请求成功,返回 body 存入 NodeOutput | +| NODE-04 | HTTPNode 超时 | 30s 超时 → 返回错误,不阻塞 | +| NODE-05 | NotifyNode 桌面通知 | 系统通知弹出 | +| NODE-06 | NotifyNode Webhook | POST 到飞书/钉钉,HTTP 200 | + +--- + +## 五、Git/CI 集成 测试用例 + +| ID | 场景 | 预期 | +|----|------|------| +| CI-01 | DockerNode 构建成功 | docker run cargo build → exit 0 → 构建产物存在 | +| CI-02 | DockerNode 构建失败 | docker run cargo build → exit !=0 → 返回 stderr | +| CI-03 | PR 创建 | GitNode push → API 创建 PR → PR URL 返回 | +| CI-04 | CI 状态读取 | 调 API → 返回 check 结果(passed/failed/pending) | +| CI-05 | 全链路 | 模板→分支→代码→commit→push→PR→CI→结果回显,全流程不中断 | +| CI-06 | CI 失败时 | 前端 CI 面板显示红色,日志可查看 | + +--- + +## 六、审批政策 测试用例 + +| ID | 场景 | 预期 | +|----|------|------| +| POL-01 | coder+Low → auto | 匹配规则 → 自动执行 | +| POL-02 | coder+High → approve | 匹配规则 → 走审批 | +| POL-03 | reviewer+任意 → auto | reviewer 只读工具,全部自动 | +| POL-04 | 无匹配规则 | 降级到 auto_exec_mode 三档(向后兼容) | +| POL-05 | 策略热加载 | 修改策略 → 下次工具调用立即生效(不重启) | +| POL-06 | 策略冲突检测 | 同一 Persona+Node+Risk 有多条规则 → 优先级最高的生效 | + +--- + +## 七、God 文件拆分 测试用例 + +| ID | 场景 | 预期 | +|----|------|------| +| REF-01 | agentic/mod.rs 拆分 | 拆出 compress/title/knowledge_inject 后,原文件<800 行,cargo check 通过 | +| REF-02 | context.rs 拆分 | 拆出 sanitize/budget/compress 后,原文件<800 行,所有 context 测试通过 | +| REF-03 | MessageList.vue 拆分 | 拆出 StreamRenderer/ToolCardGroup/EmptyState,vue-tsc 通过 | +| REF-04 | ChatInput.vue 拆分 | 拆出 MentionPopover/EnrichmentPanel,vue-tsc 通过 | +| REF-05 | 拆分后行为不变 | 原有所有单元测试/集成测试全绿 | + +--- + +## 八、端到端手动测试 + +| ID | 场景 | 步骤 | 预期 | +|----|------|------|------| +| E2E-01 | 简单并行任务 | 发"先读取 main.rs 再修改 utils.rs" | PlanProgress 展示 2 层,Layer0 读,Layer1 写,最终合并输出 | +| E2E-02 | 并行同文件冲突 | 发"同时重构 auth.rs 的两个函数" | 2 SubTask 并行改同文件 → 冲突徽章 → 用户选择 → 最终输出 | +| E2E-03 | 取消并行任务 | 发消息→Plan 执行中→点停止 | 所有 SubTask 停止,worktree 清理,Plan.status=error | +| E2E-04 | 切换会话后台执行 | 发消息→切换到另一个会话 | 原 Plan 后台继续,PlanProgress 在原会话保留 | +| E2E-05 | 非 Git 工程 | 在无 .git 的项目中发并行任务 | 降级串行执行,正常完成 | +| E2E-06 | 模板驱动全链路 | 选"功能开发"模板→AI 执行 | 从模板加载工作流→创建分支→写代码→测试→PR | +| E2E-07 | 长对话不崩溃 | 50+ 轮对话后发并行任务 | token 预算池正常,不 OOM,PlanProgress 正常展示 | + +--- + +## 九、边界与异常 + +| ID | 场景 | 预期 | +|----|------|------| +| EDGE-01 | 空 Plan | decompose 返回空 Plan → 不启动 dispatch,主对话正常回复(退单 Agent) | +| EDGE-02 | 全部 SubTask 超时 | Plan.status=error,前端展示超时提示,worktree 清理 | +| EDGE-03 | Git 不可用 | git 命令失败 → 降级串行,日志告警,不崩溃 | +| EDGE-04 | DB 写入失败 | PlanRepo.insert 失败 → 降级不落库,内存态执行,日志告警 | +| EDGE-05 | worktree 磁盘满 | 创建失败 → 降级串行 | +| EDGE-06 | token 预算=0 | 设置项 df-ai-plan-token-budget=0 → 不限制(等价无限) | +| EDGE-07 | 冲突解决时会话删除 | resolve_conflict IPC 到达时会话已删 → 忽略,清理 conflict 记录 |