Isolated branches
Give a conversation its own branch and its own checkout of the repository, so several agents can work at once without overwriting each other. Opt-in per conversation, with the full Pathrule context following the checkout, and a landing step that merges or opens a pull request instead of stopping at commit.
Two agents on one repository used to overwrite each other. Turn isolation on for a conversation and it gets its own branch and its own checkout of the repo: the agent edits, installs and tests in there, and your working copy is never checked out, never stashed and never touched. Several agents can run on the same project, each on its own branch.
Isolation is opt-in per conversation. The default stays the main checkout, so if you never reach for it, nothing about a normal session changes.
Arming it in the composer
The control is a chip in the composer, next to the engine and mode pickers, because "should this run on its own branch" is the same kind of decision as "which model". There is no launcher to walk through and no extra step in starting a chat.
Two things follow from where the chip sits:
- Arming cuts the checkout immediately, while you are still typing, and dependency preparation starts there too. Cutting a checkout and preparing a monorepo takes real seconds, and the worst possible place to spend them is between pressing enter and the agent starting. By the time you send, the branch exists.
- The chip locks after your first message and becomes the branch badge. An engine's working directory is fixed when its conversation is created, so a control that still looked editable would be lying to you.
Branch names are always English, even when you write your request in another language, and they follow the convention your repository already uses rather than imposing one, with a namespace per engine so it is obvious where a branch came from. The name is derived from your first message in the background, while the agent is already working, so naming never delays anything. If no model is reachable the branch keeps a neutral English name instead of the session failing.
A parallel agent is not a context-blind one
An isolated checkout lives outside the folder your workspace is bound to. Taken naively, that means an agent working in it resolves to no workspace at all: no memories, no rules, no skills, and every working-directory-bound tool call failing. Isolation would have made Pathrule blind inside its own feature.
So Pathrule resolves an isolated checkout back to the workspace it was cut from. A parallel agent receives exactly the same path-scoped context as an agent in the main checkout, delivered the same way, before its first tool call. Extra checkouts you cut by hand before any of this existed can be adopted, so they stop running without context too.
This is the part that does not come for free with a git command. Isolation is a checkout; keeping the knowledge layer attached to it is the product.
A checkout the agent can actually build in
A fresh checkout carries no installed dependencies and none of your ignored files, so on most real projects an agent would land somewhere it cannot install, build or test. Studio closes that gap, and asks first:
- It reads your lockfile, names the exact command it would run (
pnpm install --frozen-lockfile,npm ci,yarn install --immutable,bun install --frozen-lockfile), and lists the ignored files it would copy across, typically.envand.env.local. - You answer once per project: Skip, Run once, or Always. On Always, later sessions in that project prepare silently. No command is ever run in your repository before one of those two answers.
- Preparation state is visible on the conversation while it happens: preparing, ready, failed, or skipped. A failed preparation keeps the checkout and its output, because that output is the only diagnosis you have.
When the lockfile in the new checkout is byte identical to the one in your main checkout, Studio borrows the prepared dependency tree instead of installing a second one. It prefers to clone it, so the tree belongs to that checkout: an install you run there does not reach your other sessions. On a filesystem that cannot share blocks it falls back to a symlink, and then the consent line says "shared" out loud, because an install run inside one session is visible to the others. If borrowing is not safe at all, a dependency bump or a different base branch, it installs properly instead.
What a checkout actually costs
A prepared isolated checkout costs about what your tracked sources weigh, and almost nothing for dependencies. Measured on two projects on the same machine (macOS, APFS, August 24 2026):
| Project | Tracked sources | Dependencies | Prepared checkout |
|---|---|---|---|
| This monorepo (pnpm, 5147 files tracked) | 83 MB | 9 MB | 92 MB |
| A Next.js app (npm, 45824-entry tree) | 11 MB | 17 MB | 28 MB |
Ten parallel isolated sessions on this monorepo therefore cost roughly 0.9 GB. Your git history is not part of that: a worktree shares the main repository's object store, so this repository's 361 MB of history is not copied even once.
Three things make those numbers what they are.
Copy-on-write. A directory walk reports 1392 MB for the same monorepo checkout. It is not lying about the files; it is counting shared blocks at full size. Where the package manager imports from a global store, those bytes exist on disk once. Studio measures the free-space delta around each create and each removal instead of walking the tree, and records "not measured" rather than a zero when a reading cannot be separated from other disk activity on your machine, so a walked figure is never treated as the space a cleanup would return.
Cloning the prepared tree. Not every package manager shares blocks on its own: on the same volume, an npm project's tree cost 684 MB to install where the pnpm one cost 9 MB. So Studio clones the prepared tree into the new checkout, which measured 17 MB for that 45824-entry tree. The clone is checked rather than trusted: every entry present, relative .bin symlinks intact, binaries running from it, and a write inside it leaving the original file untouched.
Measuring, not guessing, whether the disk can do it. A clone-preferring copy onto a filesystem that cannot clone quietly performs a full copy and still reports success, so Studio writes a small probe and reads the volume. An answer it cannot trust counts as unknown, which falls back to the shared symlink rather than committing you to a full copy.
One thing worth knowing, because it tells you where to look if a checkout ever does get large: the dependency tree is not what grows. Divergence is. Once an agent builds, shared blocks are rewritten into real bytes, and build outputs in this repository's main checkout measure about 343 MB against a 9 MB dependency install. So clearing build output reclaims space and clearing dependencies does not, which is the opposite of what the folder sizes suggest.
Skipping is a legitimate answer. The agent can still read and edit; it just cannot install or test, and the conversation says so rather than letting you find out from a confusing failure.
Seeing what the isolated agent did
Isolation without visibility reads as "the agent did nothing". Source Control gains a checkout switcher: pick a checkout and the file status, the per-file diff, staging, commit, the branch menu and push all operate on that one. There is a single changes view rather than a second surface to keep in sync with the first. You can also open a terminal in a checkout or reveal it in Finder.
Watching several at once
Tabs stop working as the only view when several agents are running, so the chat splits into panes and each pane carries its own identity: the branch, the engine, and what that session is doing right now. A session waiting on a human gets an accent ring, an icon and a "needs you" label, because the bottleneck is often the one blocked on an answer. Colour alone would not carry that.
Panes are deliberately not reordered when a session starts waiting. You built that layout by dragging; moving panes under you is a worse problem than the one it would solve.
Landing the work
This is where isolation stops being a parking space. A landing bar sits under the changes list, and one explicit action takes the branch home.
- Merge into the base, as a squash, a fast-forward, or a merge commit. Squash is offered first: agents produce a lot of small commits, and your history probably does not want all of them.
- Pull request, pushed and opened for you. The agent may draft the title and body from its own work; you edit them and press the button. Draft PRs are one toggle.
Everything here is executed by the desktop, never by the model: Studio runs git and gh, and an engine is never asked to do it instead. That has consequences worth stating.
- A checkout with uncommitted changes is refused with the reason, not merged half way.
- A conflict stops and leaves your working copy untouched, naming the files that conflicted. Pathrule reports a conflict; it does not resolve one for you.
- If
ghis missing or not authenticated, the error names the missing tool. There is no silent fallback. - After a successful merge, Studio asks whether to remove the checkout and reclaim its disk. It never deletes silently.
Nothing lands automatically. There is no flow in Pathrule that merges an agent's branch without you pressing something.
Lifecycle, disk and privacy
A conversation and a checkout are separate things. Closing a conversation leaves its checkout and its branch alone, because the work in there may still be the thing you care about. Removing a checkout warns you about uncommitted changes with the count, and asks separately whether the branch should go too; by default the branch is kept.
Checkouts live in one predictable place, ~/Pathrule/worktrees by default and configurable, outside your repository. That is deliberate: nested copies of a project would be walked by every file watcher, project scan and index you have, and one folder is what you can exclude from a backup or clear out in a single action.
Housekeeping stays conservative, and it now covers the one checkout that actually accumulates: the one whose branch already landed.
A landed checkout keeps its owner, so it used to sit there until you answered the offer above. But once a branch is in your base, everything left in its checkout is either tracked, and so already in the base, or ignored, and so reproducible. Studio reclaims it, and only when all of these hold:
- The work landed. Two separate ways of knowing, because neither covers the other. Studio's own record covers a landing it performed, including a squash merge, which rewrites your commits so they stop being ancestors of anything. Asking git covers a landing Studio never saw: a merge you did in the terminal, a pull request merged in a browser, a teammate's push. The question is not "did Studio merge this" but "is there anything here your base branch does not already have". If git cannot answer, the checkout stays.
- Nothing is using it. An engine's working directory is fixed for its conversation's life, so a merge does not end the isolation. A landed checkout can still be where a live conversation is running, and that one is never touched. This covers Tasks too: a card's run creates a conversation, so the same question answers both.
- A grace period has passed, because landing is not the same moment as being done looking at the work. A day by default.
git statusis clean. An ignored build artefact is reproducible; a tracked change is your work. This is why a checkout holding gigabytes of dependencies still counts as clean, and why one holding an uncommitted edit never gets swept.- Studio created it. A checkout you added by hand is adopted, and adopted checkouts are never removed automatically.
The branch itself is left alone. Reclaiming a folder Studio created is housekeeping; deleting a branch is a decision about your history, and nothing automatic makes that decision for you.
The older rules still apply too: a clean checkout that was armed and never claimed goes after an age guard, and records whose folder is gone are pruned. And the safety net underneath all of it is unchanged: if a checkout disappears from under a conversation, that conversation reopens on the main checkout and tells you so rather than silently relocating the agent.
Housekeeping is meant to be something you never think about, so it runs in the background rather than as a screen you tend. What it does is still recorded rather than assumed: the measured bytes it reclaimed, and separately the removals it could not measure, because "reclaimed nothing" and "could not tell" are different facts and only one of them is a number.
Checkout records stay on your machine and are never synced to your teammates. Paths are machine specific, and a preparation command is a shell command: a synced record would let one person's setting run on another person's laptop.
Tasks cards can be isolated too
On the Tasks board, "run in an isolated branch" is a per-run action on a card rather than a board setting, so the default stays the main checkout there as well. A card that ran isolated carries the branch and the base it ran on, and shows them on its face. If cutting the checkout fails, the run continues on the main checkout with the reason reported instead of dying over bookkeeping. Parallel board runs appear in the same checkout list as chat sessions, so there is one place where every extra checkout on the machine is visible.
What to read next
- The Tasks board for running a card on its own branch.
- Pathrule Studio for the surfaces around the chat.
- How hooks work for what reaches an agent before its first action, isolated or not.