Run the server

Run items in your own checkout

Let a repo's work items run in the folder you connected, instead of in a git worktree each, and get one going again when Kraft stops it to keep your edits safe.

Added in 2.1

By default every work item gets its own worktree, so your checkout stays as you left it. An in-place item runs in the repo's own folder instead, on its own branch, beside whatever you are doing there. This page says when that is worth it, what Kraft checks so it never forces anything in your folder, and what to do when it stops.

Stopped already? Jump to Clear a checkout stop.

When to run in place

Run in place when a repo's environment is slow or awkward to set up again for every item, and you never run two of its items at once. An in-place item runs no setup_command and copies no local_files: your checkout is already set up.

Keep worktrees when you want items to run side by side, or a sandbox. In place, the trade-offs are:

  • One in-place item works in a checkout at a time. The others wait.
  • Your checkout moves onto the item's branch while it works, and stays there afterwards. Kraft never switches it back.
  • The agents run unsandboxed, as you, in the folder your shell and editor use. See No sandbox, and no Cursor.

Turn it on

For every new item of a repo, connect it with --in-place, which saves worktrees: false on its repos.yaml entry. On a repo already connected, the same command saves the setting and says so. In the web UI it is the repo's worktrees switch in Settings › Repos, under the Running group's defaults.

kraft repo connect --in-place

For one item, say so when you file it. --in-place runs it in the checkout, --worktree gives it a worktree even on a worktrees: false repo. Either one overrides the repo's setting:

kraft item create "tidy the parser" --in-place
kraft item create "try the big refactor" --worktree

The choice is frozen when the item is filed. Changing repos.yaml later moves no item already filed, and nothing changes an item's choice: file it again. The board and the item page mark an in-place item in your checkout, and the item page's Overview names the checkout's path.

Kraft refuses an in-place item that would also be sandboxed, naming the setting that turns the sandbox on. A workspace item never runs in place: one filed on a worktrees: false workspace root is refused until you file it with --worktree. A repos.yaml entry with both worktrees: false and a sandbox does not load.

One item at a time

An in-place item holds its checkout only while something works in it: while the item is active, or while an escalation, a reply to a review thread or an agent's gate review runs for it. At a gate, paused, waiting on CI or stopped, with no such agent running, it holds nothing, and you can use the folder freely, switching branches included.

When a second in-place item of the same folder would start, resume, retry or continue past a gate while the first holds the checkout, it is queued instead. The board shows waiting for the checkout: “<title>” is using it, and the item's Queued card links to that item. It starts by itself, in the order it queued, when that item lets go. Nothing you asked for is lost meanwhile: an approval stands and a steer is kept.

  • Two repos.yaml entries pointing at the same folder share it, through a link or, on a case-insensitive disk such as macOS's, a name in another case.
  • Worktree items of the same repo never wait for it, and run beside it as before.
  • It is not a slot. max_concurrent counts as it always has.
  • An escalation, a reply or a gate review takes the checkout with the same checks as a task. An agent Kraft starts on its own (the reply at a gate it opens, the gate's review, an automatic escalation) waits for a checkout in use, queued like a start, and runs when it frees. To decide the gate or retry the item yourself meanwhile, pause it first; that drops the waiting agent.
  • kraft item skip cannot queue: it answers that the checkout is in use by the other item. Try again when that one stops.

What Kraft checks

Before a task

Kraft takes the checkout right before each agent or command task, never earlier:

  1. It refuses a checkout with a rebase, merge, cherry-pick, revert or bisect under way, or with unmerged paths. Your uncommitted edits are not a reason to stop.
  2. If the checkout is not on the item's branch, it runs a plain git checkout <item branch>, never -f. Git carries your uncommitted edits across, and refuses only when the switch would overwrite one. The switch is on the item's history as checkout_switched, naming the branch it left.
  3. On the item's first task, its spec and plan are copied in and committed on its branch, by path.

The item's branch starts from its base branch, never from whatever you had checked out: your uncommitted edits ride across onto it, untouched and uncommitted.

Kraft never writes your git config: its identity reaches git and the agents through the environment. Before an agent or command task it records the branch's tip and which paths you already had changed (task_marked).

After an agent task

The agent is told it is in your checkout: commit only its own files, by path, and never git add -A, stash, checkout or reset. The agent resolving a rebase conflict may rebase with --autostash (see Rebases). After it exits, Kraft checks, and never repairs:

  • The branch. The checkout must still be on the item's branch, and every commit made during the task must be on it. A rebase, merge, cherry-pick or revert you began on the item's branch and left under way is named as that, not as a switch. Files a git operation of yours left mid-way are never taken for the task's.
  • Your files. The agent's commits must not touch a path you had already changed before it started. Kraft compares every path the branch gained during the task, a branch the agent merged in included, and every path of a commit made in your checkout during it, even one a later commit or a reset undid. A commit you make on the item's branch while a task runs counts as the task's.
  • The base branch's commits. Commits a merge or rebase brings from the base branch do not count, unless your edit to a path was stashed for that merge or rebase (--autostash) and the base branch changed that path too. Then the path counts, and the item stops for you to check it.
  • Tasks side by side. When tasks of one step run at once, a path changed after one of them started counts as that task's work, not yours.
  • Leftovers. Paths changed during the task and left uncommitted are recorded on the item's history as left_uncommitted. Kraft never commits them. Kraft cannot tell a file you edit while the task runs from one the agent left behind, so your edit lands in that list too: check it.

A command task, such as the test suite, gets the branch check too. If the checkout moved while it ran, its result was about other code: the item stops as checkout and retrying it runs the command again.

A later task that commits a file an earlier task left behind, unchanged since, is the item's own work and does not count as yours. The item's diff and review show its branch's commits only, never your uncommitted files.

Rebases

When the item's branch moves onto a newer base and the checkout is on that branch, Kraft runs git rebase --autostash there: your edits are stashed for the seconds the rebase takes, then put back. They come back unstaged, with their content kept: stage again whatever you had staged, partial hunks included. When the checkout is elsewhere, Kraft rebases in a throwaway worktree under run/scratch/ and removes it, so your checkout never moves.

A rebase that conflicts is aborted, and the agent that resolves it takes the checkout like any task. That agent runs the rebase again with git rebase --autostash, the one stash it is allowed, so your edits are set aside and put back the same way. When they do not fit, the item stops as it does for Kraft's own rebase: see Recover your stashed edits.

Unlike Kraft's own rebase, the agent's keeps your edits out of the checkout for as long as it takes to resolve. They come back when the rebase finishes or is aborted.

A rebase that would overwrite a file ignored in your checkout but tracked on the newer base is refused, and in that case no agent is sent to resolve a conflict either. Before that agent, Kraft switches your checkout to the item's branch first, so the files ignored are the ones that branch ignores.

Git is never stopped part way through your checkout: a server told to stop waits for the rebase to finish, and kraft admin stop waits for it, up to about 80 seconds in all.

Clear a checkout stop

The item stops as Needs you, with the stop kind checkout, when Kraft could not take the checkout without forcing it, or a task left it in a state Kraft will not repair. The reason names the files or branches. Nothing is undone and nothing is forced. Fix what it names, then run kraft item retry ID. A checkout stop is never escalated to an agent on its own.

Every reason and its fix are in Git state of the worktree. Two need more than a line, below.

After the checkout moved

Kraft did not switch your checkout back when it stopped. When you retry, the item's next task takes the checkout as any task does: a plain git checkout <item branch> that keeps your uncommitted edits. If an edit would clash with the item's branch, commit or stash it first, or the retry stops again, naming the files. When the stop also lists commits made off the item's branch, the retry runs the task again.

Recover your stashed edits

When your stashed edits do not fit the newer base, git puts them back with conflict markers in the named files and keeps the originals in a stash entry named autostash. Kraft records that entry's commit on the stop. Use the sha, not stash@{n}: the stash list is shared by every checkout of the repo, and its numbers move.

  1. In the checkout, list the conflicted files with git status. Your edits to the other files came back too, but staged (M in git status): git reset -q -- <file> unstages one.
  2. Resolve each one, keeping your edits and the newer base's, then mark it resolved with git reset -q -- <file>, which leaves your edits in the file, unstaged.
  3. Once your edits are back, drop the entry yourself. Find its current number with git stash list, then git stash drop 'stash@{n}'. Kraft never drops it.
  4. Retry the item.

The sha is for reading your originals while you resolve, not for applying them again: on the rebased branch, git stash apply <sha> makes the same conflict. It applies cleanly only on a checkout of the old base.

git stash show -p <sha>
git show <sha>:<file>

The first prints your original changes as a diff, the second one original file whole.

Abandon or archive an in-place item

Abandoning or archiving an in-place item never deletes the folder and never stops a process running in it. The item's branch is deleted unless the checkout is on it, another use of the checkout holds it, or (on archive) it holds commits nowhere else. Then the branch stays, and the answer and the event say why in branch_kept. Storage limits never measure, hold or archive an in-place item.

No sandbox, and no Cursor

An in-place item is never sandboxed: its agents' files land in the folder you work in, which is what a sandbox exists to prevent. Kraft refuses the combination when the item is filed, and stops a task as config if the repo gained a sandbox since. Security has what that means for you.

The Cursor harness writes its permission hook into the folder it runs in, so an in-place item that needs that hook stops before the agent starts, asking for another harness. See Switch harness.

Copyright © 2026