# Subagents — When, How, and When Not To Applies to: `**/*` Subagents exist to protect the main thread's context and parallelize independent work. They are not free — every spawn pays a prompt-construction cost and breaks the chain of context from the current conversation. Use them deliberately, not reflexively. ## Pre-Dispatch Checks Run these two checks before any spawn. Both can send the work back to the main thread without the spawn ever happening. ### Availability The dispatch path assumes a subagent/Agent capability exists in the environment. If it doesn't — no Agent tool, no spawn mechanism — don't block. Do the work in the main thread, but preserve the same scope boundaries the subagent contract would have enforced: bounded scope, the explicit "do NOT" constraints, and the named output shape. The discipline is in the contract, not the tool. Hold the task to it even when you're the one executing, so the work doesn't sprawl. ### Cost Dispatching isn't free — it pays the prompt-construction cost and breaks context continuity (see the opening paragraph). For a small task, writing the full contract (scope, context, constraints, output format) can cost more than just doing the task inline. When that's the case, do it inline. The subagent earns its place by absorbing context pollution and running work in parallel, not on tasks where the handoff exceeds the work itself. This is the same boundary the "Don't Subagent At All" section and the "Subagenting trivial work" anti-pattern draw; treat it as an explicit gate at dispatch time. Every size-based rule in this file — the cost gate here, "Don't Subagent At All", the trivial-work anti-pattern — is subject to the isolation override below. ## Isolation Override — When Size Doesn't Gate Every size heuristic in this file rests on one assumption: that the main thread could do the task itself just as well, so the only question is whether delegating is worth the overhead. When that assumption fails, the heuristics don't apply, and a five-line task can require a subagent that a five-hundred-line one wouldn't. The assumption fails whenever **the main thread is structurally disqualified from the task** — not slower at it, disqualified. The test: would the main thread's own context make its answer *less* trustworthy? If holding the context is what corrupts the judgment, then doing it inline doesn't save the overhead, it destroys the result. The isolation *is* the deliverable, and "it's only a small diff" is not an argument against it. **The standing instance is the pre-commit code review** (`publish` skill, Step 1). The author cannot review their own change, because a self-review checks the diff against the author's own model of it and cannot check the model. Errors that survive a self-review are the ones that were never in the diff — an inherited scope, an estimated blast radius, a fix correct for the case in mind and wrong for the one never considered. So that review is dispatched on *every* commit including a one-line one, and the ~10-tool-call floor, the single-function rule, and the trivial-work anti-pattern are all overridden there by design. Other cases with the same shape: verifying a claim the main thread already committed to in conversation, and any second opinion where the first opinion is already in context. If you find yourself reasoning "I already know the answer, so a subagent is wasteful," check whether already knowing it is the problem. This override widens *what* gets dispatched. Scope, constraints, and output format are still required, and arguably matter more here, since an isolated agent can't fall back on shared context to fill a gap. **Field 2 of the Prompt Contract inverts under this override, and the inversion is the whole point.** Normally field 2 says to paste the relevant output verbatim and include what you learned in earlier turns. Do that for an isolation dispatch and you hand over the very model you spawned the agent to escape — a reviewer given your findings reviews your findings. So for an isolation dispatch, field 2 is *the artifact under test and the independent record of what was asked, and nothing else*: the diff, a one-line claim of what it does, and the ticket or plan where one exists. The conversation, the rationale, and the dead ends are withheld on purpose. Keep the requirement source in. A ticket is not your model of the change; it was written before the work, usually by someone else, and it is the only thing that can contradict your claim about your own diff. **The output is a judgment, so the review gate resolves differently.** The Review-Gate Cadence below says subagent output is a claim to be verified before moving on, which is right when the deliverable is *work*. When the deliverable is *a judgment about your work*, verifying it against your own reading reinstates exactly the bias the dispatch removed. Disagreement goes to the user to adjudicate, not back to the author's own judgment. ## When to Spawn a Subagent ### Parallel-safe (spawn multiple in parallel) - **Read-only investigation across independent domains** — "what uses function X?", "what are the three logging libraries in this repo?", etc. spread across different subsystems. - **N independent test-file failures** where each is its own diagnosis. - **Library/API research across unrelated topics** — doc fan-out. - **Analysis scans over different parts of a codebase** — e.g. C4 diagram generation scanning distinct services. ### Sequential-with-review (one at a time, review between) - **Plan-task execution** where each task may depend on the last. - **Coupled edits** — related files that must stay in sync (schema + migration + seed script). - **Anything where mid-course correction is likely** — the review gate is where course correction happens. ### Never Parallel - **Concurrent writes to the same files or directories** — race conditions, conflicting edits, lost work. - **Ordered edits where sequence matters** — e.g. add a config flag, then read it in code; don't fan these out. ### Don't Subagent At All Unless the Isolation Override applies — these are efficiency rules, and they lapse when the main thread's own context is what makes its answer untrustworthy. - **The target is already known** and the work fits in under ~10 tool calls. - **Single-function logic** — one Read + one Edit is faster than briefing an agent. - **You can see the answer from context** — don't spawn a researcher for something already on screen. (The inverse of this one is the override's clearest case: when *having* seen it is the disqualification, dispatch.) ## Prompt Contract Every Agent spawn must include four fields. Missing any one produces shallow, generic work: 1. **Scope** — one bounded task, named file or domain. Not "fix the bugs" but "find the root cause of the NPE in `order_service.py:process_refund`." 2. **Context** — paste the relevant output, error, or prior finding. The subagent cannot see this conversation. If you learned something from an earlier turn, include it verbatim; don't paraphrase. 3. **Constraints** — explicit "do NOT" list. "Do not refactor surrounding code." "Do not add tests." "Do not touch files outside `src/billing/`." 4. **Output format** — what to return and in what shape. "Report root cause + file:line + proposed fix in under 200 words" beats "investigate this." If you can't fill all four fields, you don't yet understand the task well enough to delegate it. Do it yourself, or think more before dispatching. ## Context-Pollution Rule Subagents exist to absorb noise the main thread shouldn't carry. When one fails or produces unexpected results: - **Do not retry the task manually in the orchestrator context.** That re-imports the exact noise the subagent was meant to contain — failed approaches, dead ends, irrelevant exploration. - **Dispatch a fix subagent** with the failure report as its context (paste the subagent's output verbatim). New scope, fresh context. - **If two fix attempts fail**, stop and surface the problem to the user. Don't keep spawning. The corollary: if you're tempted to "just quickly fix it myself after the agent failed," you are about to pollute your context. Dispatch. ## Review-Gate Cadence Subagent output is not verified work — it's a claim about what was done. Review before moving on: - **Sequential execution** — review after each task completes. Read the diff, run the relevant tests, confirm the claim matches reality (see `verification.md`). Then spawn the next task. - **Parallel execution** — review after every batch of ~3 tasks. Larger batches compound bugs; smaller batches make review overhead dominate. - **Never chain subagents past a failed review.** If the review finds a problem, dispatch a fix subagent before continuing the plan. ## Delegation vs Understanding Subagents execute; they do not understand *for you*. Never write prompts like: - "Based on your findings, fix the bug" — synthesis pushed onto the agent - "Investigate and implement" — scope too broad, no contract Do the understanding step yourself (read the agent's report, decide the fix), then dispatch the fix with a specific contract. ## Anti-Patterns - **Parallel implementation agents on overlapping files** — they will conflict. Fan-out is for investigation, not concurrent writes. - **Broad prompts** — "fix the failing tests" sends the agent exploring; "fix the assertion at `test_cart.py:142`" gets a diff. - **Timeout-tuning to quiet flaky tests** — the flake is usually a race condition. Diagnose, don't mask. - **Retrying a failed subagent task in the orchestrator** — pollutes context. Dispatch a fix agent instead. - **Subagenting trivial work** — one Read + one Edit doesn't need an agent; spawn overhead exceeds benefit. Except under the Isolation Override, where a one-line diff still gets its own reviewer. - **Reviewing your own change inline** — the mirror-image failure, and the more expensive one. Skipping a dispatch to save overhead on a small diff costs a review that could only have come from outside your context. - **Skipping review between tasks** — compounding bugs are much harder to unwind than any single bug. - **Letting the agent decide scope** — "figure out what needs changing" produces sprawling, unfocused work. You decide scope; the agent executes it. ## Cross-References - Completion claims must be verified regardless of who produced them — see `verification.md`. - Testing discipline applies to subagent-produced tests too — see `testing.md`.