Converging three parallel agent builds into one main — what actually made the merge survivable
Three Claude sessions built three subsystems in parallel — a cloud web seam, a memory/connector engine, and an in-app architecture map — on separate worktrees. Merging them into one main was the hard part. Here is the methodology that made it work, written from the pain, not from theory.
The setup
Three things got built at the same time, by separate sessions, each on its own git worktree:
- Cloud web seam — Supabase-direct data, multi-tenant RBAC, two-way sync, real-time coordination.
- Memory engine — operating-memory RAG, a Gmail IMAP/SMTP connector, a secret vault, plus a merged-in WorkItem action spine.
- In-app architecture map — a ⌘⇧A panel that scans the repo and draws a live component map.
Parallelism made the building fast. It also made the merge the whole ballgame.
What actually hurt
- Divergence. Branches sat 88–130 commits apart before anyone merged. The cost of a merge scales with how long branches drift; we let them drift a long way.
- Shared-file contention. Every real conflict was in a handful of files three sessions all touched: the desktop App.tsx, the Rust lib.rs, a widget package, the shared docs. The disjoint 95% auto-merged for free; the overlapping 5% was all the work.
- A refactor nobody downstream knew about. Main had moved the widgets into a shared package; a branch built before that move kept importing the old path. Its own handoff doc's conflict estimate was stale because it predated the refactor — so the real conflict count was double the documented one.
- Branch topology traps. Two branches looked like the same WorkItem work; one strictly contained the other. Merging the wrong one would have silently dropped an entire memory/connector layer.
- Cross-domain conflicts. The hardest conflicts sat exactly on the seam between two agents' code — neither fully understood the other's half.
- Late gates. Formatting (rustfmt, biome) was never run before commit, so the canonical verify script failed on committed code after the merge.
The methodology that made it survivable
- One integrator drives the merge; domain owners review their own half. No single agent understood both the cloud and the engine. So the cloud agent drove the git merge and owned the web/widget conflicts; the engine agent reviewed that its memory/connector/spine survived. Each owns the conflicts in code it actually wrote.
- Union, never replace. Every conflict was resolved by keeping both sides' features. The rule was literally: drop nothing. A merge that picks "ours" over "theirs" on a feature file is a silent deletion.
- Dual-verify — because no one can verify both halves. The engine's cargo tests do not test cloud RLS; the cloud's tests do not test the Rust engine. "My checks are green" is a false green for the other half. Both suites must run on the merged tree before anything is called done.
- Adversarial audit before the merge lands. A panel of skeptic agents read the merged result for dropped features and regressions. It caught a real cross-tenant privacy leak and the stale conflict count that the handoffs missed.
- Merge on an isolated branch, then fast-forward. Never resolve a big merge directly on the live main. Do it on an integration branch, run every build/test/audit there, and only fast-forward main when it is provably clean. Main stays pristine until the last second.
- Re-verify handoffs against current main. A handoff written yesterday describes yesterday's main. Recompute the actual conflict set against today's HEAD before trusting any "only ~6 conflicts" claim.
- Map topology before touching anything. A quick survey — which branch subsumes which, what is abandoned, what is a byte-identical duplicate — prevents merging the wrong branch or re-resolving the same conflict twice.
The one lesson under all of it
The cost of concurrent agents is not the building — it is the merge, and the merge cost is shared-file contention × divergence time. Both are controllable, and we controlled neither well this round:
- Partition by subsystem so sessions own disjoint files. Contention you don't create has no conflict.
- Merge often. Short-lived branches keep divergence small; a 130-commit gap is a self-inflicted wound.
Parallel agents are worth it. But the discipline that makes them worth it lives entirely in how you converge them — isolate, drive-with-one-integrator, union, dual-verify, audit, fast-forward. Speed is in the fan-out; safety is in the merge.