One History, Many Agents: Using jj workspaces for parallel coding agents Jujutsu (jj) 0.46 workspaces let a developer run five Claude Code agents on one repository, with each agent's edits recorded as a commit in a single shared history, according to a first-person account tested against git 2.56. The author reports that `jj diff -r fix-retry@` shows an agent's in-progress changes without interrupting it, a single `jj rebase` moves all agents onto the latest main, `jj evolog` and `jj restore` recover edits an agent discarded, and `jj workspace add -r fix-retry@` hands a finished change to a second agent with every recorded edit. In a colocated repo, jj registers each workspace as a git worktree, so git status, IDEs, gh and pre-commit hooks behave as before. One History, Many Agents With five coding agents, jj workspaces let me check on each one, rebase them all onto main and recover what one destroyed, without stopping any of them. This is jj log in the main checkout of a service while three coding agents work on it, each in its own directory: fix-retry@ is one agent’s working copy. It has no description because the agent has not committed anything, and it is still a commit in my history. From my own directory, without interrupting the agent, I can see what it has changed so far: I run several Claude Code agents on one repo at once, each in its own terminal split. They need separate directories, or two of them edit the same file, and git has handed out directories since 2015 with git worktree add . With one agent, a worktree is all I need. With five, most of my time goes into four things that a worktree does not help with: checking on agents while they work, keeping them on the latest main as their work lands, recovering what an agent broke, and handing one agent’s work to the next. Every one of them goes through the agent’s commits and its branch, and agents commit when their instructions say so, not when I need them to. jj https://docs.jj-vcs.dev/latest/ workspaces https://docs.jj-vcs.dev/latest/working-copy/ workspaces turn each agent’s files into a commit in one shared history, and all four become commands I run from my own checkout while the agents keep working. Every command and output here was run on jj 0.46 and git 2.56. Four moments in a day with parallel agents four-moments-in-a-day-with-parallel-agents | Moment | With git worktrees | With jj workspaces | |---|---|---| | I want to see how an agent is doing | cd into its worktree, or ask it to commit | jj diff -r fix-retry@ from my checkout | | One agent’s change lands, the rest fall behind | git rebase inside each worktree, stopping at the first conflict | one jj rebase for all of them, conflicts left to each agent | | An agent throws away its own edits | uncommitted files are gone | every snapshot is in jj evolog , jj restore brings it back | | A second agent picks up a finished change | git worktree add --detach gets the last commit only | jj workspace add -r fix-retry@ includes every recorded edit | A workspace is still a worktree a-workspace-is-still-a-worktree jj in a colocated repo https://docs.jj-vcs.dev/latest/git-compatibility/ colocated-jujutsugit-workspaces , one where .jj/ sits next to .git/ , registers each new workspace as a git worktree: Inside it, git status , the IDE, gh and pre-commit hooks behave as in any worktree, so moving to workspaces costs no git tooling. What changes is where the agents’ work lives. Checking on an agent without stopping it checking-on-an-agent-without-stopping-it An agent that took a wrong turn ten minutes in is cheap to correct. One that took it an hour ago has built on it. So I look at each agent’s work while it runs, not only when it says it is done. The jj diff at the top of this post is that look. With worktrees, an agent’s edits do not exist outside its directory until it commits. git log in my checkout shows nothing, git diff main fix-retry shows only what was committed, and the rest I can only read by going into the agent’s worktree and running git status there. Asking the agent to commit interrupts its task and leaves a half-done commit on its branch. jj has no staging area and no commit step between a file and the history. Before any jj command runs in a workspace, jj records the directory’s files https://docs.jj-vcs.dev/latest/working-copy/ into its working-copy change, @ . An agent runs jj st or jj diff every few steps, so its edits are in the commit within seconds, and the log at the top of this post is current without the agent committing anything. An edit made after the agent’s last jj command is not there yet, and jj st in its directory closes that gap. When one agent lands, the others fall behind when-one-agent-lands-the-others-fall-behind Every change that reaches main leaves every other agent working on an old base, and the longer one goes without a rebase, the bigger its conflicts get. With worktrees, the rebase cannot happen from my checkout, because a branch can be checked out in one worktree only: So it happens inside each worktree, one at a time. A conflict stops the rebase halfway, and the worktree sits in the middle of it, with the agent’s task on hold, until someone resolves it. With workspaces, the whole round runs from my checkout. fix-retry is done, so I move main to its change and push it: The other two agents are now one change behind, and one command moves both: The rebase finished even though add-metrics changed the same line of the README as fix-retry . jj stores the conflict in the commit https://docs.jj-vcs.dev/latest/conflicts/ instead of stopping, so add-tracing is on the new main with nothing to do, and add-metrics is on it too, with the conflict recorded in its two commits for its agent to resolve. Each workspace whose change I rewrote from outside is now stale, and the next jj command in it says so: jj workspace update-stale in that directory checks out the rebased change, conflict markers included. I do the whole round while the agents wait for input: jj st in each workspace first, so recent edits move with the commit, then the rebase, then update-stale in each, so no agent sees the error. An agent’s mistake stays its own an-agents-mistake-stays-its-own I do not watch every command an agent runs. Sooner or later one runs git reset --hard or git checkout . to get out of a mess. With worktrees, git’s reflog covers commits, and git fsck --lost-found finds files that were once git add ed. Files the agent never added are gone. With jj, every snapshot of the agent’s working copy is still in the repo, and jj evolog https://docs.jj-vcs.dev/latest/cli-reference/ jj-evolog lists them: The 10:22 snapshot has the work, and restoring from it brings the files back: Recovery covers what jj recorded, so edits made after the agent’s last jj command are lost the same way as in git. Undo stays inside one workspace too. Every jj command is an operation in the operation log https://docs.jj-vcs.dev/latest/operation-log/ , and jj undo reverts the last one. With several agents writing to one repo, the last operation is usually some other agent’s, and jj refuses that case: An agent’s jj undo reverts its own mistake or does nothing. To take back one specific thing an agent did, jj op revert