PRACTICE · 3 hours
How Brandon's production multi-agent SDLC harness turns Claude Code into a structured, scalable workflow engine — from scoped sessions to parallel worktrees.
When I started using Claude Code on real projects, my first instinct was the same as most engineers': open a terminal, describe what I want, and let it run. That works fine for a one-off script or a quick bug fix. It breaks down the moment the task spans more than one file, more than one decision point, or more than one hour.
The failure mode is always the same. The context grows until Claude's suggestions stop being grounded in your actual codebase. You accept a change in one area without realizing it breaks a contract in another. The session drifts, and by the end you are not sure what you actually built.
I hit this wall early in my Python orchestration framework work. I was building a multi-agent SDLC harness — a system that takes a feature spec and drives it through implement → test → review → document phases, in parallel, across git worktrees, on a Mac Mini behind a Cloudflare Tunnel. Trying to build that entire harness in one long Claude Code session was like trying to pour the foundation, frame the walls, and wire the electrical at the same time.
The core insight: Claude Code becomes a scalable workflow tool when you treat each session as a bounded unit of work — with a clear input, a clear output, and an explicit exit criterion.
Three primitives make that possible:
Analogy: Think of a CLAUDE.md file the way you think of a good engineer's onboarding doc. A new hire ramps up by reading it; a new Claude session picks up project context the same way. The difference is that the "new hire" resets completely between every conversation — the doc is their only memory.
The rest of this module builds from the simplest useful case up to the production wave-orchestration pattern that drives my SDLC harness.
Before reaching for parallel worktrees or orchestration scripts, start with what works for 80% of real tasks: a single session with a scoped CLAUDE.md and a clear task spec.
A CLAUDE.md at the root of your project (or a worktree) is read automatically at the start of every Claude Code session in that directory. It is the most underused lever for keeping sessions focused.
The most useful CLAUDE.md for a feature branch has three parts:
<CodeExample title="CLAUDE.md — Feature Branch Context" language="markdown" code={`# Context
This branch adds rate limiting to the task submission API. See: planning/tasks/rate-limiting/tasks.md
Once the single-session pattern is solid, the next level is running multiple sessions in parallel across isolated git worktrees. This is the core pattern of my production SDLC harness.
A git worktree creates a separate working directory for a branch without stashing or branch-switching. Two Claude Code sessions in two worktrees work in parallel with no shared file state, no lock contention, no interference.
Each worktree directory is a full checkout of the repo on its own branch. The only difference from the main working directory is which branch it is on. Claude Code sessions started in these directories are completely independent.
With worktrees set up, each session runs in its own terminal:
The key is telling each session to stop at a specific, verifiable condition. "Stop when npm test passes" is a real exit criterion. "Do the feature" is not.
Pitfall: Two Claude Code sessions modifying the same file in the same directory create race conditions. Always give each parallel session its own worktree. The two-command setup cost is worth it every time.
When both sessions finish, I merge in the order dependencies require. If the webhook endpoint depends on the delivery library, the library lands on main first:
This sequence is exactly what the SDLC harness automates: dependency-ordered waves, with each wave merging before the next wave begins. The manual version makes the logic explicit before you automate it.
Once the manual pattern is routine, extracting it into a script is straightforward. The following is a simplified version of how the SDLC harness drives a wave of parallel tasks:
The production SDLC harness reads a dependency graph from the task spec and groups tasks into waves automatically. But the core loop above is the skeleton every layer of the full system builds on.
CLAUDE.md files are hierarchical. A file at the root of a worktree applies to the whole session; a file in a subdirectory narrows the context for that scope. I use this in the SDLC harness to give task-specific constraints without bloating the project-level file:
The innermost CLAUDE.md wins for its directory — the same principle as directory-scoped config in most toolchains. Broader rules set defaults; task-specific rules consciously override them.
Before the quiz, work through these checks in your head:
Check 1: You have a feature that changes a shared database schema and adds an API route that reads from it. Can these be two parallel worktree sessions, or must they be sequential? Why?
Check 2: What happens to Session 2 after Session 1 merges to main and Session 2 is still running? What do you need to do before merging Session 2?
Check 3: In the wave orchestration script, npm test runs after each merge, not once at the end. Why does the order matter?
Take a minute to work through each before the quiz. The questions below test the same reasoning from different angles.
The shortest path to reliable Claude Code sessions: Write a CLAUDE.md with explicit file boundaries and a verifiable exit criterion. Those two additions eliminate the majority of scope creep and context drift.
1. An hour into a Claude Code session to add a new API route, Claude begins suggesting changes to the authentication layer. What is the most likely root cause?
Correct Answer: B
Without explicit file boundaries in CLAUDE.md, Claude follows the code's logical connections — the route references auth, so it explores auth. A 'Touch ONLY these files' boundary in CLAUDE.md prevents scope creep at the source, before the session starts.
2. Feature A adds a new database table. Feature B adds an API route that queries that table. How should you structure these as worktree sessions?
Correct Answer: C
B depends on A's output. Parallel is only safe for independent tasks. Running A first, verifying it merges cleanly, then starting B on updated main guarantees B has the real schema to work against — not a guess about what A will produce.
3. Session 1 finishes and you merge it to main. Session 2 is still running in its worktree. What must you do before merging Session 2?
Correct Answer: C
Session 2 branched from main before Session 1 landed. A rebase onto updated main ensures Session 2's output is compatible with Session 1's changes. Always re-run the validation gate after a rebase — the rebase may surface incompatibilities that only tests will catch.
4. In the wave orchestration script, why does npm test run after each merge rather than once at the very end?
Correct Answer: C
A gate after each merge acts as a checkpoint. If the second merge fails the tests, you know exactly which feature introduced the regression and main is only one merge ahead of where it was. Catching it at the end leaves you debugging a combined diff that could be much larger.
5. What is the minimum a bounded session spec needs to be reliable?
Correct Answer: C
Scope without exit criterion causes drift. Exit criterion without scope causes scope creep. Constraints without scope let Claude modify any file that satisfies the constraint. All three together make a session self-contained and self-terminating.
6. A project-root CLAUDE.md says 'Never modify auth/'. A task-level CLAUDE.md in a worktree says 'Update auth/middleware.ts to add rate-limit headers.' Which takes precedence, and why?
Correct Answer: B
More-specific CLAUDE.md files narrow or override broader ones — the same principle as directory-scoped config in most toolchains. The task-level file reflects a deliberate, scoped override. The root file sets project-wide defaults; task files consciously extend them for a particular bounded context.