-
Notifications
You must be signed in to change notification settings - Fork 1
Description
Part of #974
Background
Claude Code supports isolation: worktree in agent definitions. When set, the agent runs inside a temporary git worktree created from the current HEAD. If the agent makes no changes, the worktree is automatically cleaned up. This prevents unintended modifications to the working tree during exploratory or experimental tasks.
Current state in Zeph
All sub-agents share the same working directory as the parent process. There is no isolation mechanism. SubAgentPermissions has a background: bool flag but no worktree concept.
Implementation
-
Add
isolation: IsolationModetoAgentFileSpecandSubAgentDef:pub enum IsolationMode { None, Worktree, }
-
Implement
WorktreeManagerinzeph-core/src/subagent/worktree.rs:create(base_path: &Path, agent_id: &AgentId) -> Result<WorktreeHandle>- Creates worktree via
git worktree add --detach /tmp/zeph-agent-{id} HEAD WorktreeHandlecontains path and implementsDropfor cleanupcleanup(): runsgit worktree remove --force {path}thenstd::fs::remove_dir_all
-
On agent spawn with
IsolationMode::Worktree:- Create worktree before first tool call
- Set agent's working directory to the worktree path
- On completion: if
git status --porcelainin worktree is empty, auto-remove; otherwise log path and leave for user inspection
-
Expose worktree path in
AgentHandlefor status reporting. -
Config key:
agent.worktree_base_dir(default:std::env::temp_dir()).
Acceptance criteria
-
isolation: worktreecreates a git worktree before agent execution. - Worktree is placed under a configurable base directory.
- Clean worktree (no changes) is automatically removed after agent completion.
- Dirty worktree is left on disk and its path is logged at
infolevel. - Agent's shell tool calls execute in the worktree path.
-
WorktreeHandle::dropis idempotent (no panic if already removed). - Unit test: mock git commands, verify worktree create/remove sequence.
-
cargo nextest run -p zeph-corepasses.
Technical notes
- Use
tokio::process::Commandto invoke git — keep it async. - Guard
WorktreeManager::createbehind a check that the base path is inside a git repo (git rev-parse --git-dir). - If git is not available, log a warning and fall back to
IsolationMode::None. WorktreeHandleusesstd::sync::Arc<WorktreeDrop>whereWorktreeDropimplementsDropfor the sync cleanup path (std::process::Command).