name: legion-dispatcher description: Decide whether to run a single legion task as a local Claude Code subagent or as a cloud Modal worker. Used by the orchestrator skill per task. Inputs are the task spec + current swarm load + heuristics from legion.toml. Output is "local" or "cloud" with a one-line reason.
legion-dispatcher
Per-task router. Called once per task by the orchestrator's dispatch loop.
Inputs
- task:
{id, title, spec, deps, estimated_minutes, files_touched} - load:
{in_flight_local, in_flight_cloud, max_workers, throttle_active} - heuristics from
legion.toml [dispatch]:local_file_threshold(default 5)cloud_minutes_threshold(default 5)always_cloud_patterns(regex list)
Decision rules
Apply in order. First match wins.
always_cloud_patternsmatches the title →cloud. Reason: "matched pattern". - Throttle active AND task is read-only / quick →
local. Reason: "throttle backoff". estimated_minutes≤ 2 ANDlen(files_touched)≤ 2 →local. Reason: "trivial task".- Task spec mentions "browser", "scrape", "playwright" →
cloud. Reason: "browser work; cloud has dedicated chromium". - Task spec mentions "benchmark", "measure", "profile", "long-running" →
cloud. Reason: "throughput-bound". len(files_touched)<local_file_thresholdANDestimated_minutes<cloud_minutes_threshold→local. Reason: "small enough for local".- Default →
cloud. Reason: "default route".
Output
Return JSON: {"target": "local" | "cloud", "reason": "..."}.
If cloud:
- The orchestrator will shell out to
modal run ~/holyclaude-cloud/modal/worker.py::run_taskwith the task fields.
If local:
- The orchestrator will spawn a Claude Code Agent subagent (
general-purpose) with the framed task prompt and the same constraints (work on a worktree branch, push when done).
Why an LLM call is overkill here
These rules are the prior. For Phase 1, don't call Opus — just apply the rules. Adding an LLM tiebreaker is a Phase 2 polish that will marginally improve routing at meaningful cost (one Opus call per task, on top of the per-worker cost). The rules cover ~95% of cases.
If you want to eyeball the routing before dispatch, the orchestrator already shows the task graph with assignments at the human checkpoint.