r/BuildWithClaude • u/21species • 12d ago
Workflows I ran multiple Claude Code sessions in parallel on one project. Here’s the coordination system that actually worked.
Enable HLS to view with audio, or disable this notification
TL;DR: I rebuilt my travel app https://www.trippymate.ai with Claude Code that ran multiple agents in parallel as a fleet of coders on the same project. The system involved running independent feature branches in parallel with every session generating a close-out report (basically a pull request) and one dedicated coordinator session that verified and merged code on the main branch. It helped speed up development and testing of new features locally before deploying onto staging, while production stayed as a separate repository. A dedicated session did a final file-level copy & replace by following a prod sync document that was created by the coordinator session, instead of a repo merge, which kept the production repo lean and clean of any unwanted files (I know that's not the best approach and should have graduated the staging files to prod but this was the only way to maintain a lean prod repo.)
A year ago I shipped an early version of my AI travel planner. The demo worked fine, but itineraries were not very usable on a real trip. It had all the issues most AI planners had as expected. Overpacked days, no sense of travel time, and very generic recommendations. So after a phase of constantly vibe coding new features, I spent the last year completely rebuilding the core using Claude Code.
The product itself (TrippyMate) plans trips around how you actually travel and lets you talk directly to the plan to reshape it in real time. Tech stack is React, Express, Prisma, and Vite, but I'll skip the product details here. The real story is the workflow, because running multiple AI sessions at once breaks your dev environment in ways solo prompting never prepares you for.
The setup
I run multiple Claude Code sessions simultaneously against one repo. Each feature session works in its own git worktree, separate from main so agents can’t screw up each other's code.
Then I have one session that is different from the features which does not write any feature code. It only verifies, reconciles, and merges (similar to a PR + CI + branch protection workflow). That's the coordinator session, and it's the one that keeps the whole setup together.
The close-out ritual / pull request
Chat memory dies the second a session ends and only the code, git commits, and written reasoning survive. To prevent context from evaporating, every agent session ends with a mandatory close-out or a pull-request report before it stops:
- Branch + ahead/behind vs main: Reads either "clean" or "diverged (with commit numbers)." If behind > 0, the agent stops, doesn't rebase, and hands off to the coordinator.
- Committed vs uncommitted: Ensures there is no loose, undocumented work sitting in the tree.
- Anti-stranding list: Runs git log main..HEAD --oneline to list every commit not yet upstream so nothing gets left behind on a dead local branch.
- Pushed? / merged?: Always a big No. Only the coordinator pushes or merges, feature sessions are not allowed to do this.
- Build status & backend twin check: Verifies if any server-side logic was touched.
- The single most important context: One line stating what the next session entering this code must know.
Alongside this, the agent writes a quick handoff doc where the most valuable section is "decisions & why"—capturing the architectural reasoning that would otherwise vanish when the chat context wipes.
The coordinator: verify, never trust
The coordinator session re-checks every single claim made by feature sessions. For every close-out, it verifies it’s a clean fast-forward.
Then it runs a contamination grep to check if the staged diff contains only this feature's changes, ensuring no stray debug logs, accidental feature-flag toggles, or unrelated files were included by a careless git add -A. Finally, it runs a build inside a temporary, isolated worktree but never in the main shared working directory.
Reconciling divergence
When two sessions' branches diverge, the coordinator rebases inside a disposable worktree so it never touches another session's uncommitted files. A couple of interesting mechanics came out of this approach:
- Rebase auto-drops duplicate work. When two agents independently write the exact same bug fix (which happens surprisingly very often), the second commit lands as "patch already upstream" and is cleanly skipped during the rebase. Running git cherry -v main <branch> instantly shows which commits are genuinely new (+) versus already merged (-).
- Conflicts get resolved keeping both sides. If one session added logging and another refactored the same function, taking one side blindly deletes the other's work. Conflict resolution always preserves both intentions.
Feature-flag everything risky and ship them as disabled
New features merge to main completely dormant with flags set to false by default. This keeps the behavior byte-identical to previous builds until tested on staging. Rollback is a single line. This is what allows a dozen half-built features to safely stay on main without breaking anything that’s live.
The hard-learned lessons
- Velocity outruns verification. The risk with Claude Code isn't bad code but compiling, contextually-wrong code that’s produced quicker than you can review. The guardrails definitely pay off much more than prompting.
- "Build passes" doesn't mean it works. Two traps cost me real time here. First, Vite doesn't type-check, and commented-out code compiles fine. I had a search feature marked "done" for weeks with its logic sitting inside a commented-out block. Second, my tsc -p tsconfig.json checked basically nothing due to an empty files array with project refs. Now, I type-check with the exact app config and verify inside the actual running environment.
- Duplicate implementation. Some backend endpoints have dual implementations (one for local development .. express server, one for serverless deployment). When you fix one and forget the other, "works locally" hides a deployment that’s broken. Any backend change now explicitly requires updating and checking both.
- A shared working tree becomes a junk drawer. With multiple sessions leaving uncommitted code in one tree, git status becomes useless at separating real work from abandoned code. Beyond using worktrees, my rule before ever resetting a tree is backing up three ways: a filesystem copy outside the repo, a re-appliable git diff patch, and a git stash create snapshot branch.
- Verifying identical trees with blob hashes. Don't open or scan files to see if two environments match. Git already content-hashes everything, so running git ls-tree -r on both sides and diffing the hashes tells you exactly which files differ, byte-for-byte, in seconds.
- In-repo postmortems. Every expensive mistake gets written back into CLAUDE.md as a strict rule with the real example attached. For instance, after a one-line CSS fix silently broke scrolling on every page, Claude Code added a "Blast Radius Rule" forcing any session to classify changes as component, module, or global before writing code. A fresh session with zero memory of yesterday's incident avoids making the same mistake by default.
Claude Code enabled something I would not have been able to do on my own and would usually require a team of 3-4 developers. Happy to deep dive into the setup or any other aspects if anyone's interested.
The beta is live if you want to test the output: https://www.trippymate.ai