Plan first, then fan out

Every run starts with the Coordinator. The LLM decomposes the query into sub-tasks, and those sub-tasks are persisted to the database before anything spawns — so a run can be inspected, resumed, and audited. Only then does the fan-out begin: each sub-task gets its own AgentRuntime, either as a tokio task inside a JoinSet (the default — one process, lightweight) or, with use_multiprocess = true, as a separate OS process managed by the ProcessManager and talking over Unix domain sockets.

The fleet is not homogeneous on purpose. Researchers drive web_search, web_fetch and extract_contacts; analysts get file_read and python_exec; personas (hunter, analyst, validator or your own TOML profile) pre-wire prompts, models and depth limits. Each depth-0 agent also receives a memory digest in its prompt, so the fleet starts with everything previous runs already learned.

Collect with budgets, not transcripts

A fan-out is only as useful as its collection step. Sub-agents do not hand their full context back up — their results pass through a budget capper that trims them to summaries. That keeps the coordinator's own context small enough to reason over the whole fleet, while raw findings stay persisted in SQLite for verification. Ordering and attribution survive the trip: every summary is traceable to the sub-task and agent that produced it.

Reflection and the LLM judge

Collection is followed by reflection. For lead generation it is count-based: if the contact quota is missed, the coordinator runs gap rounds until the target is met or attempts run out. Then, if Goal Mode is on, an LLM judge compares the collected result against the original goal — not against the plan. Where it names concrete gaps, new gap-filling sub-tasks are spawned; the loop runs for up to replan_rounds rounds. The judge is what stops a run from "completing the plan" while missing the point.

Synthesize, export, notify

Finally the coordinator synthesizes: the LLM merges findings into a single report, written as index.md, summary.md and a findings/ directory. The session summary and discovered contacts are absorbed into long-term memory — the next fan-out starts smarter. Then export (PDF, HTML, JSON, DOCX) and notification (webhook, email, Telegram), plus optional CRM sync. One query in; a deliverable out.

Failure is part of the design

Fleets fail in ways single agents do not, so the control plane assumes it. The DoomLoopDetector watches for three identical tool calls in a row and stops the loop before it burns the budget. Cancellation tokens propagate through the entire agent tree, so cancelling a run cancels every child; a shell failure cascades to sibling tool calls instead of leaving half-executed batches. In multiprocess mode each worker is an isolated OS process with kill_on_drop semantics — one crash never takes down the fleet — and the coordinator watches stall timeouts: warn at 450 seconds, kill at 1200.

The coordinator's job is not to run agents. It is to keep a budget, hold the goal, and know when to stop — everything else is mechanics.— Parallel Research, architecture notes

The same loop, one level down

Each sub-agent is itself the standard agent loop: build the prompt in three cache tiers, check the doom loop, estimate tokens and compact if needed, stream the LLM, pass tool calls through deny/approval/hook gates, execute the batch (reads in parallel, writes serialized), and loop until done. The fan-out is just that loop, multiplied — with a coordinator on top that keeps the multipliers honest.