v2.0.0next
Sandboxed workers

Git in a sandbox

How a sandboxed worker's repository refs, workspace members and worktree are handled, and what Kraft's own git does and does not do there.

This page tells how a sandboxed item's git state is kept: the copy of the repository's refs, the members of a workspace, and what Kraft's own git does in the worktree.

Repository refs

The worker sees every branch and tag as of its session's start, and may create, move or delete refs, but only in that copy.

When a session ends, Kraft moves the item's branch in your repository to where the worker left it, and only if nothing else moved it since. Any other ref the worker changed is dropped. What Kraft relies on to decide that lives outside the copy, where the worker cannot write.

A branch Kraft could not move is recorded as a sandbox_branch_not_synced event, and its commit is kept at refs/kraft/unsynced/<branch>. A setup command sees the copy but never moves a branch.

A HEAD the worker points at another branch, or a rebase, merge or other git operation it leaves in progress, is never acted on: Kraft stops the item and waits for you instead (see Troubleshooting).

Workspace members

A workspace with members can be sandboxed like a single repository. A sandbox on the root or on any member (sandbox or policy.sandbox), or one that comes from a chain, node or task, wraps the item's whole checkout.

The container sees each member as it sees the root: the member's refs go through a ref store of its own (see Repository refs), and the files git trusts for it are read-only.

  • The member's .git file, and the commondir, gitdir and config.worktree of its git directory, are read-only, as the root's are. Every directory from the worktree down to the member is a mount point, which the worker cannot rename or remove.
  • Kraft takes every path it mounts from the connected repository, never from the member's .git.
  • A member that is not the checkout Kraft made, or that is reached through a symlink, is not mounted, and the launch does not start.
  • A task fanned out to one member still mounts the whole worktree, and starts in the member.
  • A member branch Kraft could not move is its own sandbox_branch_not_synced event, naming the repository. Abandoning or archiving the item removes the members' copies too.

Before Kraft runs git in a member, it checks that the member is still the checkout Kraft made from its connected repository. If it is not, the item stops and waits for you, naming the member. A member whose repository is not connected stops a sandboxed item too: connect it, then retry.

Git in a sandboxed worktree

What Kraft's own git does, and does not do, in a sandboxed item's worktree.

Nested repositories

A sandboxed worker can create a git repository of its own inside its worktree, even on a plain repository, and commit a gitlink to it. A gitlink is the entry a commit holds for a nested repository: it records one commit of that repository, not its files.

The nested repository's config belongs to the worker, so Kraft's own git never works inside it:

  • Its status and diff calls compare only the commit a gitlink records.
  • Its automatic commit of leftover work skips nested repositories.
  • Kraft pins submodule.recurse, fetch.recurseSubmodules, push.recurseSubmodules, diff.submodule, status.submoduleSummary and diff.ignoreSubmodules, whatever your own git config says.

When a nested repository stops the item

If a sandboxed item's worktree holds a nested repository Kraft did not create, the item stops and waits for you, and the stop names the paths. That includes:

  • an untracked nested repository
  • a populated gitlink
  • a gitlink the branch added or moved

To go on, remove them, or run git rm --cached on the gitlinks, and retry. A submodule your repository already had, left unpopulated, does not stop anything.

Git while a session runs

While one of a sandboxed item's sessions is still running, Kraft runs no git in its worktree at all.

  • When one of those sessions ends, Kraft may move the item's branch in your repository to the commit the worker left, through the ref store, without reading the worktree.
  • While a sandboxed session runs, the diff view says the diff will be available when the session ends.
  • A task that needs the review package (the commit list and diff a review task reads) stops and waits for you.
  • Kraft's automatic commit of leftover work waits for the last task of the step.

The clean check under a sandbox

Under a sandbox, the clean check before a merge request does not look for uncommitted edits inside a submodule. It still catches a submodule whose commit moved, and each declared workspace member is checked on its own.

Leftover work is committed into a submodule's pointer only when that submodule is one of the item's declared members.

Copyright © 2026