--isolate creates .git/harness/worktrees/<session> on a session's first turn.
Nothing removes it afterwards.
profiles:delete cascades to workspaces and sessions in the projection, but a
worktree is on disk and outside the log, so deleting a profile leaves a full
checkout per session behind. On a large repository that adds up quickly.
packages/server/src/worktree.ts already has the pieces:
remove(workspacePath, path, force?)— refuses while the worktree holds uncommitted work, and keeps the branch either way, since the branch is the session's output and the directory is only scratch.prune(workspacePath)— clears registrations whose directories are gone, which is what a crash leaves behind.
What is missing is when to call them. Worth deciding deliberately rather than wiring to the first plausible hook:
- On session stop — too eager. A stopped session is one you may still want to read the diff of, and the diff reads the worktree.
- On profile delete — right, but only for worktrees whose work is committed or whose branch is merged. Silently deleting uncommitted agent output because someone tidied a profile would be the worst version of this.
- A
harness:worktreescommand — list, prune, remove. Explicit, and the honest first step: it makes the state visible before anything automatic starts removing things.
The branch should always survive. It is the deliverable; the directory is not.