Level 3 · Loop Engineering

Run Parallel Agents Without Corrupting State

Parallel agents are only useful when every mutable surface is isolated, every handoff is explicit, and synthesis is treated as a first-class verification step.

Start With Containment

The core rule is simple: parallelism is a state-management problem before it is an agent problem. If two agents can edit the same checkout, mutate the same database, reuse the same browser session, or inherit the same bloated context, you are not running parallel workers. You are running a race condition with language models attached.

Use one git worktree per agent, one branch per task, and one durable job record per run. The job record should include the task spec, allowed files or subsystems, model and effort setting, budget ceiling, validation command, stop condition, retry count, and artifact locations. Do not rely on chat history as the source of truth. Long loops compact, drift, and forget. External state lets you resume, audit, cancel, and compare runs without asking the model what happened.

The same containment applies below the code layer. If an agent touches application data, give it a branched database, not shared staging. With Postgres or Neon-style branching, seed each job from the same baseline, run migrations and fixtures inside the branch, and destroy or archive the branch after synthesis. For browser work, isolate profiles and credentials by role. The mistake is assuming code conflicts are the main danger. In autonomous loops, data conflicts are usually quieter and more expensive.

Turn Work Into Queueable Units

Once state is contained, the next constraint is task shape. Parallel agents need queueable units with narrow inputs and objectively checkable outputs. A good unit is not "improve onboarding." It is "in worktree A, implement the empty-state variant for onboarding checklist, preserve existing tracking events, pass npm test and capture a screenshot at /onboarding/new." The narrower the unit, the less context the agent needs and the easier synthesis becomes.

A practical harness is a task queue plus a runner. The queue stores job specs and dependencies. The runner leases a job, creates a worktree, provisions environment variables, creates a database branch if needed, starts the agent with the spec, and streams logs, token use, tool calls, commits, screenshots, and test results back to the job record. Avoid letting agents invent their own process. Give them a loop: inspect, plan briefly, implement, verify, summarize artifacts, stop. If verification fails, allow bounded retries with a fresh hypothesis, not infinite self-talk.

This is where model routing pays for itself. Use cheaper models for classification, repo reconnaissance, fixture generation, and first-pass implementation on well-scoped changes. Reserve frontier models for architecture, ambiguous debugging, cross-agent synthesis, and changes with high blast radius. Fast mode is only rational when latency matters more than rework. High token spend is acceptable when it buys independent completed work; it is waste when the same agent spins on an underspecified task.

Fan Out, Then Synthesize

With isolated workers and queueable jobs, you can use fan-out patterns without corrupting state. For implementation, fan out variants: three agents solve the same bug from the same baseline in separate worktrees, each with the same verification command. For review, fan out specialties: one agent audits authorization paths, another searches performance traps, another reviews test coverage. For product work, fan out prototypes with screenshots or GIFs as first-class artifacts.

Do not merge agent output directly because it passed its own checks. Synthesis is a separate job with a fresh context. The synthesizer reads the task spec, diffs, test output, screenshots, logs, and job summaries. It selects one branch, combines compatible pieces, or rejects all variants. For high-risk work, add adversarial verification: a skeptic agent receives the proposed patch and a rubric, then tries to disprove correctness with exact file and line references. This counters the model's tendency to prefer its own solution and turns parallelism into evidence rather than noise.

Tournaments work better than list scoring when there are many options. Compare two candidate patches at a time in isolated contexts, promote the winner, then continue. The goal is not aesthetic ranking. It is reducing context pollution and forcing concrete tradeoff judgments: smaller diff versus stronger test coverage, simpler migration versus better rollback, faster patch versus lower operational risk. The synthesizer should produce one mergeable branch plus a rejection note for every discarded branch.

Verify Against Real Surfaces

Parallel agents fail when verification is treated as an afterthought. The harness should define success before execution and make the agent run against the same surfaces a reviewer would inspect. Unit tests are table stakes. Add migration checks, fixture replay, type checks, lint, smoke tests, browser automation, visual captures, API contract tests, benchmark thresholds, or log assertions depending on the task. A frontend worker that cannot attach a screenshot to its job record has not finished.

Use loop-until-done only around deterministic gates. "Keep improving until it feels right" creates runaway spend. "Reproduce the flaky test within 30 attempts, capture seed and logs, then patch and prove 100 clean runs" is a loop. "Reduce p95 under 50 ms on this benchmark without changing response shape" is a loop. Each loop needs retry limits, skip criteria, escalation conditions, and a stop reason. Overnight automation should be boring when read the next morning: finished, failed with evidence, or escalated with the smallest missing decision.

Safety hooks belong in the harness, not in a hopeful prompt. Block destructive filesystem commands against root, home, and shared project directories. Require approval or explicit allowlists for deploys, DNS, billing, production data, and broad deletes. Let agents run low-risk commands freely inside their worktree and branched database. The point is not to slow them down. It is to make autonomy local by default and global only by deliberate handoff.

Keep Context Short And Memory Durable

The last piece is context discipline. Long-lived manager agents are useful for coordination, but worker contexts should stay short. Research, plan, implement, and verify can be separate sessions when the task is large. The research agent returns a compact evidence pack. The planning agent turns that into queueable jobs. The implementation agent receives only the relevant spec, files, constraints, and validation commands. Carrying the entire conversation forward feels convenient until stale assumptions and obsolete rules become hidden dependencies.

Project rules and skills should be treated as executable policy, not a dumping ground. Keep style rules, test commands, deployment procedures, and recurring workflows there, but prune old instructions after major model or tool upgrades. Every extra rule taxes every context. If a workflow repeats, convert it into a skill or harness step with deterministic inputs and outputs: create worktree, run browser capture, branch database, execute benchmark, post PR summary.

The mature pattern is a manager with many disposable workers. The manager owns the queue, budgets, dependencies, and synthesis. Workers own isolated execution. Databases branch. Worktrees contain code. Fresh contexts contain reasoning. Verification produces artifacts. Cost controls route models by uncertainty and cap retries by expected value. When those boundaries are explicit, parallel agents stop being a swarm of editors and become a build system for autonomous work.

Key takeaways

  • Run every agent in its own worktree, branch, database branch, browser profile, and durable job record.
  • Make tasks queueable: narrow scope, explicit artifacts, validation commands, retry limits, and stop conditions.
  • Use fan-out for variants or specialist analysis, then synthesize in a fresh context instead of merging agent output directly.
  • Put verification in the harness: tests, migrations, browser captures, benchmarks, logs, and adversarial review where risk warrants it.
  • Route cheap models to bounded work and reserve frontier models for ambiguity, synthesis, architecture, and high-risk fixes.
  • Keep worker contexts short and externalize memory into job records, skills, rules, and observable artifacts.