How do AI agents fit a feature-branch workflow?
.kanbots/worktrees/issue-N-runId/, branched from the repo default as kanbots/issue-N-runId. A pre-push hook installed at run creation prevents the agent from publishing anything; the human promotes work as a commit or a draft PR explicitly.The model in one sentence
One agent, one branch, one PR — isolated by a real git worktree, published only when the human says so. KanBots' branch and worktree handling is intentionally identical to how a careful human developer works on a feature, because the goal is to make the agent's output reviewable with the tools you already trust.
What happens on dispatch
When you click Dispatch on a card, the dispatcher (packages/dispatcher/src/worker.ts and worktree.ts) does five things in order, before the CLI ever spawns:
- Reserves a unique
runIdfrom theagent_runstable. Worktrees and branches are named off this id so two runs on the same issue never collide. - Creates the worktree at
.kanbots/worktrees/issue-N-runId/. This is a realgit worktree add, not a copy — your working tree and index in the main checkout are untouched. - Branches from the repository's default branch as
kanbots/issue-N-runId. Ifmainis the default, the agent starts on a branch off main. If you are working on a long-lived feature branch, the agent still branches from default — there is no contamination across in-flight human work. - Drops
.kanbots-identity.jsonat the worktree root. This is how the desktop recovers orphaned runs after a crash — on startup it scans worktrees and reattaches threads to cards. - Installs the
pre-pushhook that exits non-zero on every push. The agent process can callgit pushbut the push will fail with a clear error. The hook is part of the containment guarantee; nothing the agent does inside the worktree leaves your machine until you promote it.
The CLI then spawns with --permission-mode bypassPermissions (Claude) or the Codex equivalent, working out of that worktree. Containment watches every tool_use against paths outside the worktree root and either logs, pauses, or allows depending on containmentMode in .kanbots/config.json.
Branch naming, in detail
The exact format is kanbots/issue-<n>-<runId>where n is the issue number (GitHub issue number in GitHub mode, local SQLite id in local mode) and runIdis the database row id of the run. So issue #42's third dispatched run becomes a branch like kanbots/issue-42-194. The fact that runIdis included is what lets you have many parked worktrees per issue — re-dispatching the same issue does not clobber the previous run's worktree, it spawns a new one.
The branch prefix kanbots/ is deliberate. It makes agent branches visible at a glance in git branch -aand easy to clean up with git branch -D $(git branch --list 'kanbots/*') if you need to. It also means your branch protection rules can target the prefix — if you have a "no force push to main" rule, you can add a "only allow merge from kanbots/* via PR" rule.
Why pre-push, not just trust
bypassPermissions is what makes the agent hands-off — no "may I use Bash?" prompts every two seconds. But that same flag gives the CLI the ability to run any shell command including git push origin --force. The pre-push hook is a belt-and-suspenders: even if the agent confidently runs a push command, the hook exits non-zero and the push aborts before the network call. The agent sees the error and continues — the human is still the only path through which commits reach the remote.
This is a meaningful difference from agent-IDE workflows where the agent can in principle push to your live branches. KanBots' answer is structural, not advisory: the agent's process cannot publish.
Promote-to-PR
When a run finishes you have four actions on its worktree:
- Promote commit — squashes or cherry-picks the branch tip onto the active branch in your main checkout. The worktree is removed; the branch sticks around. Use when the change is small enough that a PR review is overkill.
- Open draft PR — GitHub mode only. Pushes the branch to
originwith the pre-push hook temporarily bypassed by the desktop's explicit promote flow (not by the agent), then opens a draft PR via the Octokit client. The worktree stays on disk so you can iterate while the PR is open. - Reveal worktree — opens the worktree path in your file manager. Use to hand-edit before promoting (rename a file, drop a stray debug log).
- Discard — stops the run if it is still running, removes the worktree, deletes the branch. Use when the run went sideways and you do not want to keep the artifacts.
Promote-to-PR is the path that mirrors human feature-branch hygiene exactly: branch off default, work isolated, open a draft PR with the diff so reviewers can comment line-by-line, merge when ready. The agent's commits show up in the PR with their original timestamps and authorship; if you have configured a commit-message convention, the agent's runs respected it.
A worked promotion
- Dispatch on issue #87 ("Add password reset endpoint"). The desktop creates worktree
.kanbots/worktrees/issue-87-501/, branchkanbots/issue-87-501. - The agent runs for 8 minutes, makes four commits, and finishes successfully. Total cost $1.40. The card moves to Review.
- You read the live thread, scan the diff in the worktree (Reveal worktree → your editor of choice), notice an unused import.
- Open the issue detail and pick Open draft PR. KanBots pushes
kanbots/issue-87-501to origin, opens a draft PR titled "Add password reset endpoint (#87)", and links it to the card. - You comment on the unused-import line in the PR. Drop a Reply on the card: "/spec remove the unused import in routes/auth.ts". The agent runs once more, commits, pushes via the desktop's promote flow. PR has a new commit.
- You mark the PR ready for review, your teammates approve, you merge. The branch is now in your main history with the agent's original authorship.
Three failure modes
Worktree directory drift across machines. Worktrees live under .kanbots/worktrees/ which is local to the repo on disk. If two developers dispatch on the same card from different machines they have two separate worktrees with two separate branches. Fix: in team workflows use KanBots Cloud so dispatch is the team's single source; on the local desktop, only one human should dispatch a given card at a time.
Pre-push hook bypass via global git config. A user with core.hooksPath set globally can route around the hook. Fix: keep core.hooksPath unset; KanBots installs the hook at .git/hooks/pre-push inside the worktree's gitdir which is where git looks by default. If you must use a global hooks path, copy the hook into it.
The default branch moved during the run. A long-running autopilot session has child runs all branched from the default branch as it was at session start. If teammates merge into default mid-session, child branches are stale. Fix: when promoting, rebase the branch onto the new default — KanBots offers this from the run actions menu, or you can do it from the terminal in the worktree.
When the feature-branch model is wrong
It is wrong for trivial fixes you would normally just commit directly to main as a human — a typo, a dependency bump, a comment change. The overhead of worktree creation and promote-to-PR is larger than the work itself. Use the desktop's Promote commit path (no PR) or just skip the agent and edit in your editor.
For the autopilot loop that drives many parallel branches at once, see autopilot mode; for cost tracking across those branches see cost and budget control.
Try it on your own folder
Drop a folder, get a board, dispatch parallel agents. The desktop runs locally on macOS, Linux, and Windows.
Related questions
- What is autopilot mode for Claude Code?Autopilot picks personas, parallelism, and budget. It loops until the work converges or the cost cap hits. The mental model and when to use it.
- How does multi-persona AI agent orchestration work?Product author → engineer → reviewer → tester. How round-robin persona cycles produce better output than single-persona loops, and how to configure them.
- How do you put a budget cap on AI coding agents?Per-run cost tracking, per-card rollups, per-autopilot-session caps. Stop runaway spend before it stops you.
- Can an AI agent backlog evolve itself?When personas split a parent issue into subtasks, the backlog grows. How to keep that growth productive instead of runaway.