Expedition 01 · Shape of the Team
The plan
Written down and published before the first run, so you can check the results against what I said I'd do.
Written October 29, 2026, 7:45 PM CDT, commit d455c08 in the expeditions repo. Anything changed after that is listed under Changes at the bottom, with its date and reason; this copy matches commit 3cc84ec. File paths below point into that repo, which is private. The results post will link the rest of the evidence here.
Question
Sojourner tells the supervisor to hand work to cheaper workers rather than do it inline: “inline work on the strongest model costs more.” Is that true in Claude Code, and what does it do to quality?
Why this one
Whether multi-agent setups beat a single agent is already widely argued, mostly on research tasks and raw API calls. Nobody has measured this specific rule, inside Claude Code, in plan usage.
Who it helps
Anyone running agent teams in Claude Code on a usage-limited plan. It tells them whether to delegate to subagents or let the main session do the work.
Setup
- Variable: who does the implementation work. One comparison:
- Inline (baseline): the supervisor does every step itself. The subagent tool is disallowed for the run.
- Delegate: the supervisor hands steps to Sojourner’s
workeragent, as the rules say, using the brief format fromengine/docs/agents/delegation.md.workeris the only subagent available: scouts and reviewers belong to experiments 02 and 03.
- Models: supervisor
claude-opus-5-5, workerclaude-sonnet-5-5(seeharness/README.md, Model overrides). Overrides are passed on the command line, not by editingengine/; the pilot confirms the worker actually runs on the pinned model. - Held constant: models, engine commit, Claude Code version, rules files, task prompt, tools other than the subagent tool, and the checks the agents are told to run.
- Tasks: 6 coding tasks in small fixture repos, 5 to 10 steps that depend on each other. Each task plants 2 facts in early steps that later steps need. Hidden tests check both the work and the planted facts; agents never see them.
- Order: runs go in pairs, one per config, with the order inside each pair alternating (inline-delegate, delegate-inline, …). A re-run takes the next free slot.
- Run limits: every run has a turn limit and a wall-clock timeout, both set to 3× the longest pilot run and fixed before the first scored run. Hitting either is a
fail.
Pre-registration
Written before the pilot and committed; the post cites that commit. Changes after the first scored run go under Changes, with date and reason.
- Hypothesis: delegating lowers API-equivalent dollars per passed task, and lowers the pass rate by no more than 10 points.
- Pass: every hidden test for the task passes.
- Cost of a run: for each model, input, output, cache-write and cache-read tokens from the run’s stream-json result, each priced at its own rate from the cited price table, summed. Claude Code’s own cost figure is recorded as a cross-check only.
- Primary metric: dollars per passed task, for each config: total cost of its scored runs divided by its passed runs. Compared as the ratio delegate ÷ inline.
- Run count: 5 scored runs per config per task, so 30 per config and 60 in all.
errorandabortedruns don’t count and are re-run (ground rule 3). - Protocol breaches: an inline run that starts another Claude Code process (for example
claudethrough Bash) is anerrorand is re-run. Denied subagent calls are logged per run. - Intent to treat: delegate runs count whatever the supervisor actually did. How much it delegated (worker dispatches, share of file edits by role) is reported as a secondary.
- Analysis: 95% percentile bootstrap, resampling runs within each task, 10,000 resamples. Resamples with zero passes in either config are dropped and their share reported; if it exceeds 5%, the ratio is called inconclusive and cost per run is reported instead. Pass rates also get a 95% interval for their difference. Tasks are fixed: results apply to these 6 tasks, not to coding tasks in general.
- Delegation is cheaper: the ratio’s whole interval lies below 1.
- No effect: the ratio’s interval includes 1.
- Quality: delegation “costs no more than 10 points” only if the whole pass-rate interval lies above −10 points. Otherwise the quality result is reported as inconclusive, not as harm.
- Secondary measures: pass rate, plan usage percent per passed task, tokens per role, context loss (share of planted-fact tests failed), and delegation share. Reported, but no conclusions rest on them.
- Sensitivity check: the primary metric is recomputed with the tokens of turns spent on denied subagent calls removed from inline runs.
Pilot
One task, one run per config, before any scored run. Pilot runs don’t count. It checks:
- Tokens, including cache tokens, can be split per model from
claude -p --output-format stream-json. Since each role uses its own model, per model means per role. - How much plan usage one run takes, to schedule the 60 runs. One run per config gives only a rough figure.
- The inline config works with the subagent tool disallowed: it doesn’t stall on the rule telling it to delegate, and doesn’t start
claudesome other way. - The delegate config can only start
worker, and the worker runs onclaude-sonnet-5-5. - The hidden tests can’t be reached during a run.
- The longest run, to set the run limits.
If the inline config stalls, the fix gets the same tuning effort as the delegate config and is logged under Changes. The baseline’s prompts, as run, are published with the results (ground rule 10).
Known limits
- With 30 runs per config, the pass-rate interval is likely around ±20 points, so the 10-point quality bound will probably come out inconclusive. Cost is the question this experiment can answer.
- Delegating changes two things at once: a fresh context per step and a cheaper model. This experiment can’t tell them apart; an Opus-worker config could, later.
- 60 runs likely won’t fit in one week’s budget. Runs spread over weeks must keep the same Claude Code version, engine commit and models (ground rule 4).
- The person running this built Sojourner and wrote the tasks and tests (ground rule 10).
Changes
- 2026-10-29, before any scored run: engine pin moved from
2d74cd7tof51ca59(134 Sojourner commits). New hooks now apply in both configs: a brief check on worker and architect briefs (delegate only, since inline can’t brief), a Stop hook that blocks hand-back endings, and a hook-denial log, which the run record now captures ashook_denials. The Stop hook doesn’t log its own blocks, so the harness wraps it to log them, without changing its output. Briefs the check rejects are counted asbrief_rejectionsand left out ofagent_dispatches_started.
Walk along
New writing, sent to your inbox when there's something worth sharing.

