diff options
Diffstat (limited to 'claude-rules/subagents.md')
| -rw-r--r-- | claude-rules/subagents.md | 119 |
1 files changed, 116 insertions, 3 deletions
diff --git a/claude-rules/subagents.md b/claude-rules/subagents.md index 8578dea..b36abba 100644 --- a/claude-rules/subagents.md +++ b/claude-rules/subagents.md @@ -10,7 +10,10 @@ 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. +main thread without the spawn ever happening. The two overrides below +(Isolation, Output Destination) point the other way, at dispatch, and each +lifts the Cost gate. Neither touches Availability: no override can conjure a +spawn mechanism that isn't there. ### Availability @@ -34,6 +37,98 @@ 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 +and the output-destination gate below. + +## Output-Destination Override: When the Terminal Is the Cost + +The cost gate above weighs the handoff against the work. The isolation +override below fires when the main thread is disqualified from judging. This +third justification is neither. The work is trivial, the main thread is +perfectly capable of it, and dispatching is still correct, because a background +subagent's output goes to a file while the main thread's goes to Craig's +terminal. Background is the operative word. A foreground dispatch puts the +output right back where it started. + +It fires for a **repeated multi-step pass on a schedule**: a recurring battery +of checks, a monitor loop's per-cycle body, any prompt that walks the same list +every N minutes. Ten Bash calls once is fine inline. Ten Bash calls every hour +for eleven hours is a hundred and ten blocks of output in the buffer he's +working in, which is what happened on 2026-08-05. + +Dispatch those, and let the quiet-output rule in `interaction.md` govern what +the main thread then says about the result: deviations, plus one line per cycle. +The justification is where the output lands, not how hard the work is. So the +size gates in this file don't apply, the same way they don't apply under the +isolation override. In particular, "the target is already known and the work +fits in under ~10 tool calls" is exactly the shape of a recurring check battery, +so that gate would otherwise refuse every case this one exists to catch. + +The inverse keeps this from becoming a licence to dispatch everything. Work that +produces little output, or output Craig actually wants to watch, gains nothing +from the handoff and still pays the contract cost. A one-off check stays inline +and prints quietly. + +Craig's directive, 2026-08-05: quiet form always, and hand a repeated pass to a +subagent. + +## 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) @@ -63,11 +158,20 @@ at dispatch time. ### Don't Subagent At All +Unless one of the two overrides applies. These are efficiency rules, and they +lapse under the Isolation Override (the main thread's own context is what makes +its answer untrustworthy) and under the Output-Destination Override (the pass +repeats on a schedule, so its output floods Craig's terminal). The first bullet +below is the one the second override most often lifts. A recurring check battery +is always a known target in under ~10 calls, and that's not a reason to run it +inline. + - **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. + 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 @@ -138,7 +242,13 @@ fix), then dispatch the fix with a specific contract. - **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. + agent; spawn overhead exceeds benefit. Except under either override: the + Isolation Override, where a one-line diff still gets its own reviewer, and + the Output-Destination Override, where a trivial pass that repeats hourly + gets dispatched for where its output lands. +- **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" @@ -151,3 +261,6 @@ fix), then dispatch the fix with a specific contract. see `verification.md`. - Testing discipline applies to subagent-produced tests too — see `testing.md`. +- What the main thread prints once a pass is dispatched: see the + quiet-output rule in `interaction.md`. It's the other half of the + Output-Destination Override above. |
