orch: require explicit dispatch execution mode

This commit is contained in:
2026-03-20 19:27:30 +08:00
parent 7840b2767f
commit 5859ff219e
43 changed files with 277 additions and 312 deletions
+4 -4
View File
@@ -6,8 +6,8 @@
| --- | --- | --- |
| `dispatch-creates-attempt-and-thread-for-ready-task` | [dispatch-creates-attempt-and-thread-for-ready-task.md](./dispatch-creates-attempt-and-thread-for-ready-task.md) | dispatches a ready task into a new attempt, inbox thread, and initial task message |
| `dispatch-rejects-non-ready-task` | [dispatch-rejects-non-ready-task.md](./dispatch-rejects-non-ready-task.md) | rejects dispatch when the task is still gated by dependencies |
| `dispatch-creates-strict-worktree` | [dispatch-creates-strict-worktree.md](./dispatch-creates-strict-worktree.md) | provisions a strict worktree and writes workspace metadata into the attempt and payload |
| `dispatch-rejects-dirty-repo-without-base-ref` | [dispatch-rejects-dirty-repo-without-base-ref.md](./dispatch-rejects-dirty-repo-without-base-ref.md) | blocks strict worktree dispatch from a dirty repository without an explicit base ref |
| `dispatch-creates-strict-worktree` | [dispatch-creates-strict-worktree.md](./dispatch-creates-strict-worktree.md) | provisions a code-mode worktree and writes workspace metadata into the attempt and payload |
| `dispatch-rejects-dirty-repo-without-base-ref` | [dispatch-rejects-dirty-repo-without-base-ref.md](./dispatch-rejects-dirty-repo-without-base-ref.md) | blocks code-mode worktree dispatch from a dirty repository without an explicit base ref |
| `dispatch-allows-explicit-base-ref-on-dirty-repo` | [dispatch-allows-explicit-base-ref-on-dirty-repo.md](./dispatch-allows-explicit-base-ref-on-dirty-repo.md) | accepts dirty repository state when `--base-ref` resolves to a concrete commit |
| `dispatch-auto-enables-worktree-for-code-like-task` | [dispatch-auto-enables-worktree-for-code-like-task.md](./dispatch-auto-enables-worktree-for-code-like-task.md) | auto-enables worktree mode for code-like tasks when no explicit worktree flags are supplied |
| `dispatch-skips-auto-worktree-for-non-code-task` | [dispatch-skips-auto-worktree-for-non-code-task.md](./dispatch-skips-auto-worktree-for-non-code-task.md) | keeps clearly non-code tasks on the normal non-worktree dispatch path |
| `dispatch-requires-explicit-execution-mode` | [dispatch-requires-explicit-execution-mode.md](./dispatch-requires-explicit-execution-mode.md) | rejects dispatch when the caller does not declare `--execution-mode analysis|code` |
| `dispatch-analysis-mode-skips-worktree` | [dispatch-analysis-mode-skips-worktree.md](./dispatch-analysis-mode-skips-worktree.md) | keeps analysis-mode tasks on the normal non-worktree dispatch path |
@@ -16,7 +16,7 @@
```bash
orch --db TMPDIR/coord.db --json run init --run run_blog_worktree_003 --goal "Validate explicit base ref on dirty repo"
orch --db TMPDIR/coord.db --json task add --run run_blog_worktree_003 --task T1 --title "Implement backend" --default-to worker-a
orch --db TMPDIR/coord.db --json dispatch --run run_blog_worktree_003 --task T1 --repo-path TMPDIR/repo --workspace-root .orch/worktrees --strict-worktree --base-ref HEAD
orch --db TMPDIR/coord.db --json dispatch --run run_blog_worktree_003 --task T1 --execution-mode code --repo-path TMPDIR/repo --workspace-root .orch/worktrees --base-ref HEAD
```
## 预期输出
@@ -0,0 +1,31 @@
# Case: `dispatch-analysis-mode-skips-worktree`
## 用例意义
验证 `dispatch --execution-mode analysis` 会保持 thread-only,不会创建 worktree。
## 前置条件
- 已存在 run `run_blog_auto_worktree_002`
- 已存在任务 `T1`
## 输入
```bash
orch --db TMPDIR/coord.db --json run init --run run_blog_auto_worktree_002 --goal "Validate analysis-mode dispatch fallback"
orch --db TMPDIR/coord.db --json task add --run run_blog_auto_worktree_002 --task T1 --title "Review QA findings" --summary "Summarize test failures and next steps" --default-to qa-worker
orch --db TMPDIR/coord.db --json dispatch --run run_blog_auto_worktree_002 --task T1 --execution-mode analysis
```
## 预期输出
- `dispatch` 退出码为 `0`
- `data.attempt.worktree_path == ""`
- `data.attempt.workspace_status == ""`
- `data.message.payload_json.execution_mode == "analysis"`
- 仍会正常返回 `thread_id` 与首条任务消息
## 断言结论
- analysis mode 始终走标准 dispatch 路径,不会平白引入分支和工作目录
- worker brief 和桥接层可以从 payload 中读取显式的 `execution_mode`
@@ -1,34 +0,0 @@
# Case: `dispatch-auto-enables-worktree-for-code-like-task`
## 用例意义
验证 `dispatch` 在未显式传 worktree flags 时,会对 code-like 任务自动启用 worktree 流程。
## 前置条件
- `TMPDIR/repo` 是一个干净的 Git 仓库
- 已存在 code-like 任务 `T1`
## 输入
```bash
orch --db TMPDIR/coord.db --json run init --run run_blog_auto_worktree_001 --goal "Validate auto worktree detection"
orch --db TMPDIR/coord.db --json task add --run run_blog_auto_worktree_001 --task T1 --title "Implement backend API" --default-to backend-worker
orch --db TMPDIR/coord.db --json dispatch --run run_blog_auto_worktree_001 --task T1 --repo-path TMPDIR/repo
```
## 预期输出
- `dispatch` 退出码为 `0`
- `data.attempt.worktree_path` 为非空
- `data.attempt.workspace_status == "created"`
- 返回的 worktree 路径在磁盘上存在
## 断言结论
- `dispatch` 存在自动 worktree 推断逻辑,不要求 leader 每次显式写 `--strict-worktree`
## 补充约束
- 当前推断主要依赖任务角色与 acceptance JSON 的 code-like 标记
- 未指定 `--workspace-root` 时,自动 worktree 模式默认写到仓库下的 `.orch/worktrees`
@@ -14,7 +14,7 @@
```bash
orch --db TMPDIR/coord.db --json run init --run run_blog_001 --goal "Build blog MVP" --summary "Public blog plus admin CRUD"
orch --db TMPDIR/coord.db --json task add --run run_blog_001 --task T1 --title "Implement retry policy" --summary "Add retry policy to HTTP client" --default-to worker-a
orch --db TMPDIR/coord.db --json dispatch --run run_blog_001 --task T1 --body "Implement retry handling for the HTTP client."
orch --db TMPDIR/coord.db --json dispatch --run run_blog_001 --task T1 --execution-mode analysis --body "Implement retry handling for the HTTP client."
```
## 预期输出
@@ -26,6 +26,7 @@ orch --db TMPDIR/coord.db --json dispatch --run run_blog_001 --task T1 --body "I
- `data.attempt.assigned_to == "worker-a"`
- `data.thread.thread_id``data.attempt.thread_id` 一致
- `data.message.kind == "task"`
- `data.message.payload_json.execution_mode == "analysis"`
## 断言结论
@@ -2,7 +2,7 @@
## 用例意义
验证显式 `--strict-worktree` dispatch 会创建隔离 worktree,并把 workspace 元数据持久化到 attempt 与任务 payload 中。
验证显式 `--execution-mode code` dispatch 会创建隔离 worktree,并把 workspace 元数据持久化到 attempt 与任务 payload 中。
## 前置条件
@@ -15,7 +15,7 @@
```bash
orch --db TMPDIR/coord.db --json run init --run run_blog_worktree_001 --goal "Validate strict worktree dispatch"
orch --db TMPDIR/coord.db --json task add --run run_blog_worktree_001 --task T1 --title "Implement backend" --default-to worker-a
orch --db TMPDIR/coord.db --json dispatch --run run_blog_worktree_001 --task T1 --repo-path TMPDIR/repo --workspace-root .orch/worktrees --strict-worktree --body "Implement inside isolated worktree."
orch --db TMPDIR/coord.db --json dispatch --run run_blog_worktree_001 --task T1 --execution-mode code --repo-path TMPDIR/repo --workspace-root .orch/worktrees --body "Implement inside isolated worktree."
```
## 预期输出
@@ -26,11 +26,12 @@ orch --db TMPDIR/coord.db --json dispatch --run run_blog_worktree_001 --task T1
- `data.attempt.branch_name == "orch/run-blog-worktree-001/T1/attempt-1"`
- 返回非空 `data.attempt.worktree_path`
- `data.attempt.workspace_status == "created"`
- `data.message.payload_json.execution_mode == "code"`
- `data.message.payload_json.worktree_path` 与 attempt 中的路径一致
## 断言结论
- strict worktree dispatch 会创建真正的隔离工作目录,而不是只记录一组字符串元数据
- code-mode dispatch 会创建真正的隔离工作目录,而不是只记录一组字符串元数据
- worker 读取任务 payload 时可以拿到同一份 worktree 路径
## 补充约束
@@ -15,7 +15,7 @@
```bash
orch --db TMPDIR/coord.db --json run init --run run_blog_worktree_002 --goal "Validate dirty repo rejection"
orch --db TMPDIR/coord.db --json task add --run run_blog_worktree_002 --task T1 --title "Implement backend" --default-to worker-a
orch --db TMPDIR/coord.db --json dispatch --run run_blog_worktree_002 --task T1 --repo-path TMPDIR/repo --workspace-root .orch/worktrees --strict-worktree
orch --db TMPDIR/coord.db --json dispatch --run run_blog_worktree_002 --task T1 --execution-mode code --repo-path TMPDIR/repo --workspace-root .orch/worktrees
```
## 预期输出
@@ -17,7 +17,7 @@ orch --db TMPDIR/coord.db --json run init --run run_blog_003 --goal "Validate re
orch --db TMPDIR/coord.db --json task add --run run_blog_003 --task T1 --title "Backend"
orch --db TMPDIR/coord.db --json task add --run run_blog_003 --task T2 --title "Frontend"
orch --db TMPDIR/coord.db --json dep add --run run_blog_003 --task T2 --depends-on T1
orch --db TMPDIR/coord.db --json dispatch --run run_blog_003 --task T2
orch --db TMPDIR/coord.db --json dispatch --run run_blog_003 --task T2 --execution-mode analysis
```
## 预期输出
@@ -0,0 +1,29 @@
# Case: `dispatch-requires-explicit-execution-mode`
## 用例意义
验证 `dispatch` 不再做 worktree heuristics,而是要求 caller 显式声明 `--execution-mode analysis|code`
## 前置条件
- 已存在 run `run_blog_auto_worktree_001`
- 已存在任务 `T1`
## 输入
```bash
orch --db TMPDIR/coord.db --json run init --run run_blog_auto_worktree_001 --goal "Validate explicit execution mode"
orch --db TMPDIR/coord.db --json task add --run run_blog_auto_worktree_001 --task T1 --title "Implement backend API" --default-to worker-a
orch --db TMPDIR/coord.db --json dispatch --run run_blog_auto_worktree_001 --task T1
```
## 预期输出
- `dispatch` 退出码为 `30`
- JSON 错误码为 `invalid_input`
- 错误消息指出必须提供 `--execution-mode`
## 断言结论
- dispatch 的执行模式是显式契约,而不是由 runtime 根据任务元数据自行猜测
- leader 必须对 thread-only 与 worktree-backed 执行路径负责
@@ -1,35 +0,0 @@
# Case: `dispatch-skips-auto-worktree-for-non-code-task`
## 用例意义
验证 `dispatch` 在未显式传 worktree flags 时,不会把明显非代码任务错误地推进到 worktree 执行路径。
## 前置条件
- `TMPDIR/repo` 是一个干净的 Git 仓库
- 已存在 run `run_blog_auto_worktree_002`
- 已存在非 code-like 任务 `T1`
## 输入
```bash
orch --db TMPDIR/coord.db --json run init --run run_blog_auto_worktree_002 --goal "Validate non-code dispatch fallback"
orch --db TMPDIR/coord.db --json task add --run run_blog_auto_worktree_002 --task T1 --title "Review QA findings" --summary "Summarize test failures and next steps" --default-to qa-worker
orch --db TMPDIR/coord.db --json dispatch --run run_blog_auto_worktree_002 --task T1 --repo-path TMPDIR/repo
```
## 预期输出
- `dispatch` 退出码为 `0`
- `data.attempt.worktree_path == ""`
- `data.attempt.workspace_status == ""`
- 仍会正常返回 `thread_id` 与首条任务消息
## 断言结论
- 自动 worktree 推断不是“见仓库就建 worktree”
- 非代码任务仍走标准 dispatch 路径,不会平白引入分支和工作目录
## 补充约束
- 当前非代码判断通常来自任务标题、摘要、角色和 acceptance 信息都缺少 code-like 信号