How it works
Branch and worktree creation
When a task enters thein-progress state, dotbot automatically creates a dedicated git branch and worktree for it before the provider session starts:
-
Derives a branch name from the task’s short ID and a URL-safe slug of the task name:
For example:
task/a1b2c3d4-add-user-authentication -
Creates a worktree path under a
worktrees/directory next to the repo root:For example:../worktrees/my-app/task-a1b2c3d4-add-user-authentication/ -
Runs
git worktree add -b <branch> <path> <base-branch>to create the branch and check it out in the new worktree directory. -
Links the central task queue and control directory into the worktree via directory junctions or symlinks, so the task process reads and writes the same live queue and runtime state as every other task. The framework itself — the MCP server, runtime, prompts, and hooks — is resolved separately from the active install through
$env:DOTBOT_HOMEand is not copied into the worktree.
Task execution in isolation
The AI agent runs entirely within the worktree directory. It reads project files, edits code, and stages commits — all within that isolated tree. It cannot accidentally modify another task’s files because those files are in a different worktree on a different branch. The linked task queue and control directory let the agent communicate with the rest of the system, updating task state without copying data between worktrees. Product artifacts are branch-local: each worktree has its own copy that is committed on the task branch and merged when the task completes.Completion and cleanup
When a task reachesdone, dotbot automatically cleans up the worktree:
- Removes the directory junctions so git sees only the task’s own tracked files
- Rebases the task branch onto the current base branch (brings it up to date)
- Squash-merges the task branch into main — producing a single, clean commit
- Tags the merge commit with the task short ID:
feat: <task name> [task:XXXXXXXX] - Deletes the task branch with
git branch -D - Removes the worktree with
git worktree remove - Removes the entry from the worktree map in
.bot/.control/
dotbot uses squash merges so every completed task produces exactly one commit on main, regardless of how many intermediate commits the AI made during implementation.
Example paths
Given a repository namedmy-app cloned at ~/projects/my-app, a task with short ID a1b2c3d4 and name “Add user authentication” produces:
A second concurrent task with short ID
e5f6a7b8 and name “Fix login bug” runs simultaneously at:
Both tasks work in complete isolation with no risk of conflicting edits.
Benefits
Concurrent tasks without conflicts
Because each task has its own working tree, multiple tasks can edit different parts of the codebase at the same time. dotbot’s multi-slot execution model takes full advantage of this — you can run several task-runners in parallel, shortening wall-clock time for large task queues.Clean git history
Squash merges produce one logical commit per task on the main branch. The commit message includes the task name and short ID, so the history is readable and every change is traceable back to the task that produced it. To find all commits from a specific task, search git history for its ID tag:Easy rollback
The task branch exists on disk from the moment the task goesin-progress until the squash merge completes. If something goes wrong during implementation, you can inspect the branch, cherry-pick commits, or simply delete the branch and reset the task to todo to try again.
Shared state and framework resolution
A task worktree does not carry a full copy of the framework. dotbot keeps three things separate: the live runtime state that every task shares, the branch-local artifacts each task owns, and the framework that is resolved from the active install.
Because the control directory and task queue are linked rather than copied, the MCP tools in every worktree process read from and write to the same live state. Task state transitions, question routing, and session tracking stay consistent even when many tasks run concurrently. The framework is shared a different way: each process resolves it from
$env:DOTBOT_HOME, so updating the install updates every project at once.