farm-out
SkillSearchRun ALL delegated agent work through the CLIProxyAPI wrappers. Use INSTEAD OF the Agent tool, subagents, the Workflow tool, and in-session agent teams, for any \"delegate this\", \"run these in parallel\", \"fan out\", \"have an agent review/investigate/search\", \"use a subagent\", \"spawn a team\", \"get a second opinion\", \"run this workflow script\", or any task you were about to hand to a background agent. Also use for explicit mentions of cliproxy, codex-code, gemini-code, claude-code, farm out, or delegating work to another model. NEGATIVE ROUTING: anything phrased as a new, background, separate or companion SESSION, 'spawn an agent', 'spawn a background claude', 'kick off claude in <dir>', belongs to agent-spawn, which fires first and carries this work inside its prompt; messaging a session that already exists is agent-msg; designing, repairing or auditing a workflow is workflow-creator; and a craft, dev or ds dispatch goes through work-dispatch.sh, never a hand-written farm.sh --workflow line.
Available today. Use it from your connected AI after setup.
No other account needed.
Connect ahel once, and every AI you use reads what you have installed.
Then ask your AI: use the farm-out skill
What this skill tells your AI
The instructions your AI receives, as published by edwinhu/workflows in skills/farm-out/SKILL.md and read by ahel’s review.
What this skill carries — grep references/ for any subject the names below miss:
!d=${CLAUDE_SKILL_DIR}; command -v skill-toc >/dev/null 2>&1 && exec skill-toc "$d"; s=$HOME/.claude/skills/plugin-utils/bin/skill-toc; [ -x "$s" ] && exec "$s" "$d"; echo "(skill-toc unavailable: references and scripts are NOT listed here — install the plugin-utils plugin, or start a new session so its bin/ reaches PATH)"
Delegation runs in a separate process on a CLIProxyAPI wrapper, not in this session. This session keeps its own auth, Remote Control, and connectors; the work runs on proxy models.
Default runner is claude-code (Claude models via the proxy). Use
codex-code or gemini-code only when the task calls for a different model
family, or when cross-checking one family against another.
Supersedes the built-in tools
| Instead of | Use |
|---|---|
Agent tool / subagents | scripts/farm.sh (single or fan-out) |
Workflow tool | scripts/farm.sh --workflow <abs script> --args <file> --out <file> |
| in-session agent team | scripts/farm-team.sh |
| persistent / remote agents | the agent-spawn skill (it reaches other machines; this skill does not) |
A description cannot carry this on its own — three rewrites all plateaued near
40% recall, so the routing is enforced by ~/.claude/hooks/main-thread-guard.sh
(PreToolUse on Agent|Task|Workflow|Edit|Write|NotebookEdit). It denies with a
reason that names the runner, which a bare permissions.deny rule cannot do. The
hook exempts FARM_OUT_CHILD=1 (our own runners' children, else farm-team.sh
blocks itself) and named agent types like Explore/Plan/librarian. Add to its
case to exempt another one.
Delegating is a choice the hook cannot make for you — the Agent|Workflow
branch only redirects delegation you already chose. To make a project refuse
main-thread implementation outright, set "farmOutOnly": true in its committed
.claude-workflows.json; every Edit/Write there is then denied unless it
targets that file, .claude/plans/, or .craft/. Without it the Edit branch
allows unconditionally whenever no craft dispatch is owed — measured 2026-08-20:
313 main-thread writes in mail-bridge over 28 hours with the hook enabled, the
user objecting three times.
Two rules that are not optional
1. A returned result is not evidence. A delegated run reports
is_error: false and a confident summary whether or not it did the work.
Observed twice: two runs quoted invented teammate output, with zero tool calls
and zero filesystem trace. Always give the task a checkable artifact and pass
--expect <path>; the runners exit non-zero when an expected artifact is
missing. Never relay a delegated summary you did not verify.
2. Every delegated prompt carries the anti-simulation clause. The runners append it automatically. Do not hand-roll a delegation that skips it.
A dispatch you will not wait on arms a Monitor
Before the turn ends, arm a Monitor on that row's --expect path (persistent: true,
command test -s <expect>). Every row already carries --expect, so the command is derived, not
invented. Nothing else can arm it — a script makes no tool calls, a hook only returns text, and the
sealed personas hold no Monitor — so an unarmed background row finishes silently and whatever you
chained after it never happens. Measured 2026-09-10: nine backgrounded dispatches in one session,
four unmonitored, and all four surfaced only because the user asked.
The Monitor wakes YOU, not the user. A row is a STEP, usually a small one. Do not send a notification when one finishes.
Pick the shape first: sealed worker, or orchestrator
--agent <name> runs the delegation AS one of your agents — its real system prompt,
its preloaded skills, its declared toolset. That last part is the whole decision,
because every persona agent is sealed against DELEGATION: ds is
Read/Grep/Glob/Edit/Write/Bash/Skill with no Agent and no Workflow, so it can
do the work and load a domain skill, but it cannot fan out or dispatch a run.
Skill is deliberately NOT withheld. Withholding Agent/Workflow prevents recursive
fan-out; withholding Skill only blinded the persona to its own domain library — ds
gets the constraint aggregates it is graded against as task refs, while wrds,
crsp-v2, dewey, bmll, marimo and ten more sat unreachable. teaching always
carried Skill; the others not carrying it was drift, not policy.
| Job | Shape |
|---|---|
| one well-scoped piece of work | a one-row --tasks file with "agent": "ds" — the persona's prompt and its narrow toolset are the point |
| needs to plan, fan out, dispatch subagents, or run a craft workflow end-to-end | same, but omit "agent" — a persona has Skill but no Agent/Workflow, so it cannot fan out or dispatch |
| several independent jobs at once | more rows; each carries its own "agent" |
Row count is orthogonal to the persona question: a fan-out of five can be five ds
workers. "More than one job" does not mean "generic".
An orchestrating child is a full Claude Code session, so it has Agent and Workflow
and can dispatch the persona itself — Agent(subagent_type: "ds") gives the subagent
the same real persona plus the same deliberate restriction. That layering is the design
the craft skills already use (skills/ds/SKILL.md sets implementerAgentType: "ds"),
not a workaround.
Agents live in ~/.claude/agents/: ds, writing, writing-econ, writing-legal,
workshop, teaching (workers); ds-reviewer, workshop-reviewer, writing-reviewer
(read-only).
A --workflow run takes no --agent — it picks agents PER LEG, which is the point:
agent(prompt, {agentType: "ds"}) inside the script, or implementerAgentType /
verifierAgentType / reviewLenses[].agentType in a craft args file. One top-level
persona could only apply to every leg, when what you want is ds implementing and
ds-reviewer or Explore judging. Note workflow.js strips the Agent tool from every
leg regardless of agentType, so legs cannot nest further delegation; fan-out is the
workflow's own parallel() / pipeline().
Use
There is one task mode, --tasks, and it always takes a JSON array — one row or
fifty. There is no inline --task: the only caller is a model reading this file, so
an inline prompt saved nobody anything, and a machine-written prompt passed as a shell
argument has to survive quoting (backticks, nested quotes, $) that a JSON file
sidesteps.
S=~/.claude/skills/workflows/skills/farm-out/scripts
# Build the task file with jq, never by hand-quoting a heredoc.
jq -n '[{prompt:"…", expect:"/repo/out.md", label:"count", agent:"ds"}]' > /tmp/t.json
bash $S/farm.sh --tasks /tmp/t.json --cwd /repo
# Rows run in PARALLEL. Per row: prompt (required), expect (string or array),
# label, agent, model. Omit "agent" when the row must orchestrate.
# workflow script — --out is REQUIRED (the structured return is the result, not the
# summary), and paths resolve against OUR cwd, not --cwd, so pass them absolute.
bash $S/farm.sh --workflow /abs/wf.js --args /abs/args.json --out /abs/result.json --cwd /repo
# Long runs: never foreground (a Bash-tool call caps out and kills the run mid-flight).
# Detach, then wait on the artifact:
setsid nohup bash $S/farm.sh --workflow /abs/wf.js --out /abs/result.json --cwd /repo \
> /abs/run.log 2>&1 < /dev/null &
# team: named teammates that message each other, one result back
$S/farm-team.sh --prompt-file t.txt --cwd /repo --expect /repo/a.txt --expect /repo/b.txt
--provider claude|codex|gemini (default claude) on both runners.
Read reference.md before changing a runner, debugging a 429, or hand-writing
a proxy call — it holds the verified model-routing and failure-mode details.
Signals
- GitHub stars
- 21
- Forks
- 4
- Last commit
- Sep 2026
Advanced
- Catalog kind
- skill
- Gateway key
farm-out- Source
- github.com/edwinhu/workflows