aboutsummaryrefslogtreecommitdiff
path: root/claude-rules/subagents.md
diff options
context:
space:
mode:
Diffstat (limited to 'claude-rules/subagents.md')
-rw-r--r--claude-rules/subagents.md119
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.