The problem
Running two AI coding agents in parallel sounds efficient. In practice, both agents will reach for the same files — a large admin page, a shared utility, a central data layer — and produce changes that cannot be cleanly merged.
The deeper problem is that agents don't negotiate. Neither agent knows what the other is doing unless you explicitly tell it. Asking both agents to "be careful" is not a coordination strategy.
The pattern: protected lanes
Divide the work into two lanes before either agent starts:
Protected lane — one agent works here, no exceptions. The other agent is explicitly told not to touch these files or contracts.
Parallel lane — work that can proceed independently: tests, documentation, UI copy, audit tasks, and anything that reads but does not restructure shared state.
## Protected Lane (Codex)
Active work:
- app/admin/page.tsx — workflow rendering rewires
- lib/content-db.ts — distributionState persistence changes
- lib/distribution-state.ts — shared contract
## Parallel Lane (Claude)
Safe to work on:
1. Unit test coverage for buildDistributionState
2. Documentation hygiene in docs/
3. UI copy and status label polish
4. Settings consistency audit (read-only)
Claude must not touch:
- app/admin/page.tsx workflow rendering
- Provider orchestration core logic
- Shared distributionState contract
How to define the boundary
The boundary should be defined by data contract ownership, not by feature or component.
Ask: which agent is changing the shape of shared state (types, KV schemas, API contracts)? That agent owns the protected lane. The other agent works only with what already exists.
A common mistake is to split by "frontend vs backend" or "this feature vs that feature." These splits sound clean but tend to break down because both sides need to modify the same shared types or the same large component file.
Communicating the boundary to agents
Put the lane split in the working-memory file. State it explicitly in the prompt:
"Read docs/working-memory.md first. Your lane is the parallel lane. Do not touch any files listed under 'Claude must not touch.' If you find you need to modify a protected file to complete your task, stop and report back instead of proceeding."
The instruction to stop-and-report is important. An agent that silently modifies a protected file is worse than one that says "I need to touch lib/content-db.ts — is that allowed?"
What belongs in the parallel lane
Good candidates for parallel-lane work:
- Tests — unit tests for pure functions can be written independently of the functions being called
- Documentation — updating working-memory, decision logs, plan files
- Audits — reading and reporting on code quality, consistency, edge cases without modifying
- Copy and labels — UI strings, status messages, error copy that does not require restructuring rendering logic
- New isolated files — a shared constants file, a helper with no current callers
Bad candidates (keep in the protected lane):
- Anything that modifies a shared type definition
- Anything that changes how state is persisted or read
- Anything that restructures a file the other agent is actively editing
After the parallel work merges
When the parallel lane work is committed, update the working-memory file:
- Mark parallel tasks done
- Note any findings that the protected-lane agent should know about before proceeding
- Identify new wiring points the next protected-lane pass should handle
This keeps the two agents loosely coupled — they share a memory file, not a real-time channel.