Four Coding Agents Need Four Workspaces, Not Four Chat Windows A developer argues that running multiple coding agents on a shared machine requires dedicated workspaces rather than multiple chat windows, citing collisions in ports, caches, and shared state. The post recommends using Git worktrees, defining ownership boundaries for resources, and limiting each agent's authority to reduce failures. Opening four coding-agent sessions feels like scaling. On a shared machine, it is closer to giving four fast contributors the same repository, shell, credentials, ports, caches, and merge queue without deciding who owns any of them. The first failure probably will not come from model quality. One task will restart a dev server while another is testing it. Two workers will touch the same lockfile. A branch will pass its own checks and still conflict with a migration waiting in the merge queue. Four chat windows create concurrency. Four owned workspaces plus one deliberate merge queue create a system. Tasks that sound independent in a prompt can overlap in the environment. A frontend change and an API change may both edit generated types. Two test runs may expect the same database or browser profile. Separate worktrees can still launch services on the same port, read the same environment variables, and write to shared caches. The agents do not collide in the prompt. They collide in everything the prompt lets them touch. This is why adding a second agent changes the job. With one worker, the operator can keep a surprising amount of state in their head. With four, every unstated assumption becomes a race condition or a review problem. The fix is to make ownership visible before execution starts. Git worktrees are a sensible first step. Each task gets its own branch and working files, so one agent is less likely to overwrite another agent's edits by accident. That is useful isolation, but it is narrow isolation. A worktree does not reserve a port. It does not separate process trees, temporary directories, credentials, network access, browser state, or external services. Treating it as a sandbox gives the workflow more confidence than the boundary deserves. Proliferate is an instructive project example because its documented design pairs isolated task worktrees with visible review state. The important idea is the pairing. Filesystem separation tells you where a patch was produced; task state tells you what should happen to that patch next. The project description is not independent proof that every boundary is solved, and it does not need to be. The pattern is useful on its own. For each concurrent task, define at least these ownership boundaries: Assign one repository scope, branch, and worktree. State which generated files or shared configuration the task may change. If two tasks own the same file, they are coupled work and should be queued accordingly. Reserve ports, dev servers, test databases, caches, temporary paths, and browser profiles. A process should have a named task owner and a cleanup rule instead of becoming shared background state. Name the output before the run begins: a patch, a report, a screenshot set, a migration plan, or some other reviewable object. "Improve the app" is not an artifact contract. The easiest setup is to launch every worker from the operator's normal shell. It is also the setup with the least useful separation. A task that edits a local component rarely needs every token, deployment command, network destination, and destructive tool available to the human running it. Grant the repository, commands, credentials, and network surface required for that task. Leave the rest out. Current agent harnesses do not all enforce these boundaries in the same way. If a tool cannot restrict a credential or network path, write that limitation into the run record and reduce the task's authority. Do not silently treat the operator's full shell as a reasonable default. This also makes failures easier to understand. When a task has a small authority budget, the failure surface is smaller: you can see which files, processes, and external systems were in play without reconstructing the whole machine after the fact. Implementation can run in parallel. Integration should have one owner and an explicit order. Two patches can both be locally correct and still disagree about an API shape, migration sequence, dependency version, generated file, or user-visible behavior. Git may merge the text cleanly while the combined system is wrong. That is an integration conflict even when there are no conflict markers. Give one person, or one tightly bounded integration role, responsibility for: The merge queue is where parallel work becomes one product. Making it serial is coordination, not wasted parallelism. An agent saying "done" proves that it generated a completion message. It does not prove the patch works. Every task should return an evidence bundle with: Repository-native agent systems are starting to expose this control layer directly. GitHub Agentic Workflows defines bounded jobs and safe-output handling. Its August 24 update describes safe-output validation, run steering, inspectable model and catalog state, and clearer startup diagnostics. GitHub Copilot's August releases describe task management, queued prompts, plan/autopilot behavior, and rewind. These are product descriptions, not reliability benchmarks, but the direction is useful: long-running work needs intervention, recovery, and inspectable output. The evidence rule also applies to non-code artifacts. If a frontend task produces launch or social graphics, a narrow browser-local step such as Resize Image For https://resizeimagefor.com can handle resizing, fitting, cropping or padding, previews, and export while keeping source-image processing in the browser. That is easier to review than handing the source files to another remote worker with a broad instruction to "prepare the assets." A small task record is enough. The exact schema matters less than forcing the decisions into the open. task: fix-mobile-navigation owner: agent-2 stop when: mobile navigation passes the named browser checks workspace: repository scope: apps/web worktree: ../worktrees/fix-mobile-navigation shared files: pnpm-lock.yaml process: ports: 3102 services: web-dev-server browser profile: agent-2-mobile authority: credentials: network: localhost destructive tools: false expected artifacts: - code-diff - test-results - mobile-screenshots - known-issues integration: merge owner: human-reviewer review after: shared-design-token-change rollback: discard-worktree-and-branch This is an operating record, not a universal security configuration. The point is to make shared state, authority, evidence, and merge order reviewable before they become an incident report. If the task cannot fill in these fields, it is probably too vague or too coupled to run concurrently. Parallelize tasks with separate state and separate validation paths. A documentation change in one package and an isolated test addition in another may fit well. Shared-schema changes, coupled migrations, global dependency upgrades, and work that relies on one fragile validation environment usually deserve a queue. There is no prize for keeping every agent busy. If coordination and verification cost more than the execution time you saved, reduce the agent count. Before opening another session, provision its workspace, authority, integration path, and evidence contract. If that is too expensive for the task, keep the work serial. Source notes