--- name: claude-subagents description: Spin up a short-lived headless `claude` sub-instance to grind through a well-scoped, mechanical batch (bulk relabeling, a repetitive find/replace, a mechanical migration) instead of burning your own context on it inline. Use this when a task has a clear, describable recipe and is either big enough to eat your context or long enough that you'd rather not babysit it. Not for judgement-heavy work, anything needing operator back-and-forth, or a task whose blast radius you can't bound up front. --- # Ephemeral Sub-Agents via the Claude CLI `claude` is on `PATH` in your container, and a sub-instance you spawn inherits the same filesystem and credentials you have. This is a first-class tool for offloading a bounded, mechanical batch - not a hack. ## When to use it - **Yes:** mechanical batches with a clear recipe (relabel N issues, rewrite a call-site pattern, migrate a config field), especially when the batch would eat your context or take long enough that you'd rather not babysit it turn-by-turn. - **No:** judgement-heavy work, anything needing back-and-forth with a human, or a task whose blast radius you can't bound up front. ## The spawn command Put the task recipe in a file and pass it as a path, with a short `-p` trigger: ```bash claude --name --model --dangerously-skip-permissions \ --append-system-prompt-file task-prompt.md \ -p "Carry out the task described in your instructions." ``` - **`--name `** - names the session so you can `--resume` it by name for follow-ups. - **`--model `** - think about which model the task actually needs; don't spend a bigger model's tokens than your own on mechanical work a cheaper one handles fine. Never use a *bigger* model than yourself for a sub-agent - if the task needs that much capability, it's not the "mechanical batch" case this skill is for. - **`--dangerously-skip-permissions`** - required in headless (`-p`) mode. Without it, tool calls that would normally prompt for approval are auto-**denied** non-interactively, so the sub-agent silently does nothing. Acceptable here because the sub-instance runs inside your already-sandboxed environment, with your already-scoped credentials, on a bounded task - don't reach for it when the task could touch things outside its intended blast radius. - **`--append-system-prompt-file `** - read the recipe from a file rather than inlining it in `-p` (which is bounded by `ARG_MAX` - a long recipe passed as `-p "$(cat …)"` can blow past it and the exec fails). Keeps Claude Code's default scaffolding and adds your recipe on top. - **`-p ""`** - headless print mode. Keep this short: just tell the sub-agent to act on its file-supplied instructions. ## Run it in the background, don't babysit Wrap the launch in a background bash task and end your turn - your bash-task runner already captures stdout/stderr and hands you a completion pointer, and ending the turn keeps you reachable for other work while the sub-agent grinds. ## Prompt hygiene - this is where batches succeed or fail - **Concrete constants, not "figure it out":** exact ids, field names, option values, endpoints. - **Critical ordering rules, spelled out** - the sub-agent won't infer invariants you don't state. - **Explicit scope + exemptions**, plus a fallback rule for ambiguous cases: "leave it as-is where genuinely unclear; do not guess." - **Ask for a report file** - per-item results + anything skipped and why, so you can verify without re-deriving. - **Tune on ONE item first**, eyeball the result, fix the prompt, *then* turn it loose on the full batch. A prompt bug replicated across 100 items is 100 cleanups. ## Split a big independent batch across parallel subagents One subagent is a sequential worker — a 50-item batch takes roughly 50 items' worth of wall-clock even though nothing about the recipe forces serialization. If the items are independent (each one touches its own file/issue/row, nothing depends on another item's result) and the batch is big enough that wall-clock matters, chunk it across N subagents running at once instead of handing the whole thing to one. - **Split by natural boundaries**, not an arbitrary item count — one subagent per file, per directory, per module, per label, whatever grouping keeps each worker's slice self-contained. A worker that has to coordinate with another worker mid-task isn't actually independent work; re-scope the split until it is. - **Isolate each worker's writes.** For a git-based batch, give each worker its own `git worktree` (own working directory, own branch, same underlying repo — cheap, no full reclone) so N workers editing different files never race on the same working tree or index. For a non-git batch (issue relabeling, API calls), independent items don't need filesystem isolation at all — just launch N in parallel. - **Launch all N in the background and don't babysit any single one** — same as the one-subagent case, just N background bash tasks instead of one. Check on them as a batch, not by polling each individually in a loop. - **Mind the container's memory cap before picking N.** Your whole container shares one `MemoryMax` (a few GB by default) with every subagent you spawn *and* your own process. A `claude` process plus its MCP servers can hold several hundred MB to ~1GB depending on the task; spawning a dozen at once on a small container doesn't just slow things down, it can OOM the whole container — taking your own in-flight turn down with it, not just the subagents. Rule of thumb: **2-4 concurrent workers** on a default-sized container; check `free -h` (or ask whoever owns the container's config for its `MemoryMax`) before going higher, and chunk a bigger batch into successive waves of that size rather than firing everything at once. - **You own the merge.** Once all N report done, review + verify each worker's slice (same "don't trust the self-report blind" rule as below), then combine — for a git-based split, that's you merging N branches (or cherry-picking) into one, not each worker pushing/PRing its own slice. Skip this for a batch small enough to finish in a couple minutes single- threaded — the coordination overhead isn't worth it below that size. ## Resume for follow-ups `claude --resume -p "Now run the same procedure over the second batch."` reuses the same session, so the sub-agent keeps every constant and gotcha it already discovered instead of re-learning the surface from a cold prompt. Spawn a new `--name` only for a genuinely unrelated task. ## Verify, then report On completion: read the report file, spot-check a handful of results yourself (don't trust the self-report blind), then summarize. Surface anything the sub-agent left ambiguous or exempted for a human call. ## Pitfalls (all observed in practice) - No `--dangerously-skip-permissions` → headless tool calls denied, the sub-agent burns a run doing nothing. - Using a model bigger than yourself → paying premium cost for mechanical work that didn't need it. - Skipping the one-item tuning pass → a systematic mistake smeared across the whole batch. - Spawning fresh instead of `--resume` for a follow-up → throws away all the context the first pass earned. - Baking an unverified assumption into the recipe - if a quick check suggests something "isn't possible" or "doesn't exist," confirm it before writing that conclusion into the prompt; a wrong assumption gets replicated across the whole batch. - Handing a big independent batch to one subagent instead of splitting it across several in parallel - a 50-item sequential run burns wall- clock the split-by-worktree approach above would've avoided for free.