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
+8 -8
View File
@@ -40,9 +40,9 @@ Use the bundled `./assets/orch` CLI to control leader-side orchestration through
- Prefer `orch` over hand-written `inbox send` for normal leader operations.
- Treat `dispatch` as handoff, not execution. After dispatch, arrange a separate worker runtime or worker agent to claim the mapped inbox thread.
- For analysis, review, or other read-only tasks, omit worktree flags so dispatch stays thread-only and light.
- For analysis, review, or other read-only tasks, dispatch with `--execution-mode analysis`.
- If nothing is actionable, use `wait` instead of manual sleep loops.
- For code tasks, dispatch from a committed base and allocate a fresh worktree per attempt.
- For code tasks, dispatch with `--execution-mode code` from a committed base and allocate a fresh worktree per attempt.
- Use `blocked` and `answer` to resolve worker questions through the active attempt thread.
- Use `retry` or `reassign` only after checking the latest task and attempt state.
- Use `inbox` directly only for inspection or manual repair, not routine scheduling.
@@ -64,7 +64,7 @@ Use this when the leader wants durable `orch` state plus a worker sub-agent laun
1. save the dispatch output:
```bash
./assets/orch --db ./coord.db --json dispatch --run RUN_ID --task TASK_ID > TMPDIR/dispatch.json
./assets/orch --db ./coord.db --json dispatch --run RUN_ID --task TASK_ID --execution-mode analysis > TMPDIR/dispatch.json
```
2. render a standardized worker brief:
@@ -92,7 +92,7 @@ See:
- The worker side should use `skills/inbox/`, not this skill.
- The leader should pass or preserve the `dispatch` result, especially `attempt.thread_id`, `attempt.assigned_to`, and worktree metadata when present.
- Code-writing workers should execute inside the assigned worktree path from the task payload or attempt metadata.
- Read-only or analysis workers can stay on the normal thread-only path with no worktree.
- Read-only or analysis workers should be dispatched with `--execution-mode analysis` and stay on the normal thread-only path with no worktree.
## Typical Commands
@@ -103,9 +103,9 @@ See:
./assets/orch --db ./coord.db --json task add --run blog_mvp_001 --task T2 --title "Summarize flaky tests" --summary "Read logs and report next steps" --default-to qa-worker --acceptance-json '{"kind":"analysis"}'
./assets/orch --db ./coord.db --json dep add --run blog_mvp_001 --task T2 --depends-on T1
./assets/orch --db ./coord.db --json ready --run blog_mvp_001
./assets/orch --db ./coord.db --json dispatch --run blog_mvp_001 --task T1 --to foundation-worker --base-ref main --workspace-root .orch/worktrees --strict-worktree --body-file tasks/t1.md > /tmp/t1-dispatch.json
./assets/orch --db ./coord.db --json dispatch --run blog_mvp_001 --task T1 --execution-mode code --to foundation-worker --base-ref main --workspace-root .orch/worktrees --body-file tasks/t1.md > /tmp/t1-dispatch.json
./assets/orch-worker-brief --dispatch-json /tmp/t1-dispatch.json --db ./coord.db > /tmp/t1-worker-brief.txt
./assets/orch --db ./coord.db --json dispatch --run blog_mvp_001 --task T2 --to qa-worker --body "Read the failing test logs and summarize the root cause." > /tmp/t2-dispatch.json
./assets/orch --db ./coord.db --json dispatch --run blog_mvp_001 --task T2 --execution-mode analysis --to qa-worker --body "Read the failing test logs and summarize the root cause." > /tmp/t2-dispatch.json
./assets/orch-worker-brief --dispatch-json /tmp/t2-dispatch.json --db ./coord.db > /tmp/t2-worker-brief.txt
./assets/orch --db ./coord.db --json status --run blog_mvp_001
./assets/orch --db ./coord.db --json wait --run blog_mvp_001 --for task_blocked,task_done,task_failed --after-event 0 --timeout-seconds 900
@@ -135,8 +135,8 @@ See:
## Notes
- `dispatch` supports `--repo-path`, `--workspace-root`, `--strict-worktree`, and `--base-ref` for worktree-backed code execution.
- When worktree flags are omitted, code-like task metadata can still auto-enable strict worktree mode. Non-code tasks stay on the normal thread-only path.
- `dispatch` requires `--execution-mode analysis|code`.
- `dispatch` supports `--repo-path`, `--workspace-root`, and `--base-ref` for `--execution-mode code`.
- `./assets/orch-worker-brief` is the supported way to turn a saved dispatch JSON response into a stable worker prompt for a spawned sub-agent.
- `answer` supports `--payload-json` for structured decisions, not just freeform text.
- `status` is the full run view; `run show` is the lighter aggregate view.
Binary file not shown.
+13 -4
View File
@@ -90,6 +90,7 @@ attempt_no="$(jq -r '.data.attempt.attempt_no // empty' "${dispatch_json}")"
assigned_to="$(jq -r '.data.attempt.assigned_to // .data.task.default_to // empty' "${dispatch_json}")"
thread_id="$(jq -r '.data.attempt.thread_id // .data.thread.thread_id // empty' "${dispatch_json}")"
worktree_path="$(jq -r '.data.attempt.worktree_path // empty' "${dispatch_json}")"
execution_mode="$(jq -r '.data.message.payload_json.execution_mode // empty' "${dispatch_json}")"
base_ref="$(jq -r '.data.attempt.base_ref // empty' "${dispatch_json}")"
task_title="$(jq -r '.data.task.title // empty' "${dispatch_json}")"
task_summary="$(jq -r '.data.task.summary // empty' "${dispatch_json}")"
@@ -100,9 +101,17 @@ if [ -z "${run_id}" ] || [ -z "${task_id}" ] || [ -z "${assigned_to}" ] || [ -z
exit 1
fi
mode="analysis"
if [ -n "${worktree_path}" ]; then
mode="code"
if [ "${execution_mode}" != "analysis" ] && [ "${execution_mode}" != "code" ]; then
printf 'dispatch json is missing a supported execution_mode in message.payload_json\n' >&2
exit 1
fi
if [ "${execution_mode}" = "code" ] && [ -z "${worktree_path}" ]; then
printf 'dispatch json is inconsistent: execution_mode=code requires a worktree_path\n' >&2
exit 1
fi
if [ "${execution_mode}" = "analysis" ] && [ -n "${worktree_path}" ]; then
printf 'dispatch json is inconsistent: execution_mode=analysis must not include a worktree_path\n' >&2
exit 1
fi
cat <<EOF
@@ -114,7 +123,7 @@ You are assigned one existing attempt:
- attempt_no: ${attempt_no}
- assigned_to: ${assigned_to}
- thread_id: ${thread_id}
- execution_mode: ${mode}
- execution_mode: ${execution_mode}
EOF
if [ -n "${task_title}" ]; then
@@ -14,7 +14,7 @@ Keep `orch` as the control plane and use a leader-side bridge to launch a worker
4. save the dispatch response:
```bash
./assets/orch --db ./coord.db --json dispatch --run RUN_ID --task TASK_ID > TMPDIR/dispatch.json
./assets/orch --db ./coord.db --json dispatch --run RUN_ID --task TASK_ID --execution-mode analysis > TMPDIR/dispatch.json
```
5. render a standardized worker brief:
@@ -39,3 +39,4 @@ Rules:
- The template is intentionally worker-only. Leader control stays with `orch`.
- The generated brief should be passed into a spawned worker sub-agent together with `skills/inbox/`.
- Keep the main-thread launch parameters in the leader workflow, not in the worker brief.
- `execution_mode` is part of the explicit dispatch contract and should come from the saved dispatch payload, not from local heuristics.