Workspaces
Where sat runner puts repositories, per-run git worktrees and agent scratch folders, and how to clean them up.
Every run executes in a directory on the runner's machine, its workspace. If the task belongs to a project with a repository, the agent works in a fresh git worktree on its own branch, so concurrent runs never share a checkout. Otherwise it works in a persistent scratch folder of its own. Workspaces stay on disk after the run so you can review the work. The runner never pushes anything.
Layout
The root is the runner's workdir. Under it, one folder per company, named after the company's task prefix in lower case:
| Path | What it is |
|---|---|
.bin/sat | The sat shim put first on the agent's PATH. See Adapters |
.sat-agent-config/ | The empty configuration directory given to agents as SAT_CONFIG_DIR (mode 0700) |
nf/ | The company with task prefix NF |
nf/web-app/repo/ | The project's clone, made once and shared by all its runs |
nf/web-app/runs/3f2a6c1e/ | A git worktree for one run, named after the first 8 characters of the run id |
nf/agents/maya/ | Maya's scratch folder, for runs without a project repository |
Folder names are slugs: lower case, runs of other characters replaced by -, at most 40 characters. The project "Web app" becomes web-app; the agent "Maya" becomes maya.
Where the workdir is
The first one set wins:
--workdir <dir>onsat runner startSAT_WORKDIR$XDG_DATA_HOME/sat/workspaces~/.local/share/sat/workspaces
Two runners on one machine can share a workdir. The API runs one run per agent at a time, and each project run gets its own worktree.
Runs in a project with a repository
When the run's task has a project and the project's repository is set:
Clone once
If <workdir>/<prefix>/<project>/repo has no .git, the runner clones the repository there with git clone --quiet. If it already exists, the runner runs git fetch --quiet --all --prune in it, and ignores fetch errors.
Add a worktree for the run
The runner creates a worktree at runs/<run8> on a new branch, starting from the clone's origin/HEAD (usually origin/main), or from the clone's HEAD if origin/HEAD is not set:
# run inside repo/
git worktree add --quiet -b sat/nf-12-3f2a6c1e ../runs/3f2a6c1e origin/mainThe branch is sat/<task key>-<run8>, with the task key slugged (NF-12 becomes nf-12). If the worktree folder already exists, it is reused.
Run the agent there
The agent's working directory is the worktree. The first transcript entry the runner writes says where, for example Runner grace-laptop:4242 · worktree /home/grace/.local/share/sat/workspaces/nf/web-app/runs/3f2a6c1e on branch sat/nf-12-3f2a6c1e.
Clone URL rules
The runner passes the project's repository value to git clone with one rewrite:
repository | Cloned from |
|---|---|
github.com/noteflow/web (exactly host/owner/name) | https://github.com/noteflow/web |
https://github.com/noteflow/web.git | Used as given |
git@github.com:noteflow/web.git | Used as given |
/srv/git/web | Used as given (a local path) |
The clone runs as the runner's user, with that user's git configuration, SSH agent and credential helpers. For a private repository, give the runner's account read access. If the clone fails, the run fails with the git error, for example git clone --quiet https://github.com/noteflow/web /home/... failed: Repository not found.
Runs without a repository
A run uses the agent's scratch folder, <workdir>/<prefix>/agents/<agent>, when:
- the run has no task (a heartbeat), or
- the task has no project, or
- the project has no
repository.
The folder persists between runs, so the agent can keep notes and files there. The first transcript entry the runner writes is Runner <id> · scratch folder <path>.
Nothing is pushed
The runner never commits, pushes or opens pull requests. The agent's changes stay in the worktree and its local branch, where you review them:
cd ~/.local/share/sat/workspaces/nf/web-app/repo
git log --oneline main..sat/nf-12-3f2a6c1e
git diff main...sat/nf-12-3f2a6c1eThe agent itself can run git commands, including git push, if its permission mode lets it run commands and the runner's git credentials allow it. If you do not want agents to push, run the runner as an account without push rights. See Runner security.
Clean up
The runner does not delete workspaces. Worktrees and sat/... branches accumulate, one per project run. Clean them up yourself, for example from a weekly cron job.
Advice
These commands are suggestions, not something SAT runs. Check that you have kept the work you want before you remove a worktree.
REPO=~/.local/share/sat/workspaces/nf/web-app/repo
git -C "$REPO" worktree list # what exists
git -C "$REPO" worktree remove ../runs/3f2a6c1e # remove one worktree
git -C "$REPO" worktree prune # forget worktrees whose folders you deleted
git -C "$REPO" branch --list 'sat/*' --merged origin/main \
| xargs -r git -C "$REPO" branch -d # delete merged sat/ branchesDo not remove the worktree of a run that is still running; sat runner status lists them with their run ids. Scratch folders under agents/ hold an agent's notes between runs, so remove them only when you mean to reset the agent.