Four Coding Agents Need Four Workspaces, Not Four Chat Windows
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. Parallelism multiplies shared state 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. A worktree is the start, not the boundary 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: Workspace ownership 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. Process ownership 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. Artifact ownership 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. Treat authority as a task budget 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. Keep integration serial on purpose 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: - choosing the review order - resolving overlapping decisions - rerunning checks against the combined state - deciding what lands and what returns for another pass The merge queue is where parallel work becomes one product. Making it serial is coordination, not wasted parallelism. Completion needs evidence, not a status message 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: - the changed files and the intent of the diff - the exact checks run and their real results - screenshots or browser evidence when behavior is visual - known failures, skipped checks, and unresolved assumptions - merge-order or conflict notes for the integration owner 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 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." Write the contract before launching the second agent 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. Know when serial work wins 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 Top comments (0)
Comments
No comments yet. Start the discussion.