Skip to content

Worktree Configuration

Configure managed placement, per-run branch names, bootstrap copying, setup, discovery freshness, and the default Task policy.

3 min read10 pages in Worktrees

On this page4

Worktree configuration belongs to the parent workspace. Put defaults in $COMPOZY_HOME/config.toml, then override individual fields in <workspace>/.compozy/config.toml when one repository needs a different bootstrap.

Annotated example

toml
[worktrees]
# Empty uses $COMPOZY_HOME/worktrees/<workspace>/<name>.
root = ""
# Lowercase, slash-terminated namespace for per-run branches.
run_branch_namespace = "run/"
# Relative Git pathspecs for ignored, untracked files copied after checkout.
copy_list = [".env", ".npmrc"]
# Runs inside the new checkout after copy. Empty skips setup.
setup_command = "bun install --frozen-lockfile"
setup_timeout = "10m"
teardown_command = ""
teardown_timeout = "10m"
# Deadline for `git worktree add`; raise it for very large repositories.
checkout_timeout = "15m"
# Git discovery and cached status freshness.
discovery_cache_ttl = "30s"

[task.orchestration.profile]
# inherit resolves to workspace-root semantics unless a higher task policy supplies a mode.
default_worktree_mode = "inherit"

Worktree fields

FieldDefaultValidation
root$COMPOZY_HOME/worktreesEmpty or absolute path.
run_branch_namespacerun/Lowercase namespace ending in /.
copy_listemptyNon-empty relative Git pathspecs.
setup_commandemptyShell command; empty skips setup.
teardown_commandemptyShell command; empty skips teardown.
setup_timeout10mPositive Go duration.
teardown_timeout10mPositive Go duration.
checkout_timeout15mPositive Go duration.
discovery_cache_ttl30sPositive Go duration.

Changing root affects new managed Worktrees only; it does not move existing checkouts. The copy list and setup command apply only during managed creation, not adoption. Only ignored, untracked files matching copy_list are candidates, so keep secret-bearing pathspecs narrow and never copy a file that the new checkout should not receive.

default_worktree_mode accepts inherit, none, or per_run. Task profiles additionally accept ref because they can carry a specific worktree_ref; the global default cannot name one Worktree.

Apply and verify

Both key families have live lifecycle. Reload after a file change:

Terminal
compozy config reload -o json
compozy config apply-history --limit 5 -o json

Expected apply records report:

json
{
  "lifecycle": "live",
  "applied": true,
  "next_action": "none"
}

Later creates, removals and enqueues read the new values. Existing Worktree placement and already-enqueued run snapshots do not change.

Agents can read and mutate the worktree keys through compozy__config_get, compozy__config_set and compozy__config_unset, or compozy config get|set|unset. Use a workspace overlay for repository-specific setup and teardown. See the complete config.toml reference and lifecycle matrix.

Teardown on removal

Set worktrees.teardown_command to clean up resources started by setup, for example docker compose down. The default is empty (disabled); teardown_timeout defaults to 10m and must be positive. Both keys merge independently across user, profile, workspace and workspace-profile layers. Removal resolves these settings for the worktree owner profile. An explicit empty command disables an inherited command.

Teardown runs in the managed checkout after removal safety checks and worktree.pre_remove approval, before Git removes the directory. Hook denial skips teardown, including forced removal. It uses the same shell and allowlisted environment as setup: PATH, HOME, LANG, TMPDIR, LC_*, SHELL, COMPOZY_WORKSPACE_ROOT, COMPOZY_WORKTREE_PATH, COMPOZY_WORKTREE_ID, and COMPOZY_WORKTREE_BRANCH. Load any project-specific environment from the checkout explicitly.

Each stdout/stderr stream is captured up to 16 KiB and redacted as a whole, including multiline secrets. When the command finishes, the worktree event stream publishes the captured output as worktree.teardown_output with stream and chunk. A launch failure, nonzero exit or timeout emits worktree.teardown_failed with a bounded diagnostic and continues removal. A timeout terminates the command's process group. Removal rechecks checkout identity and unpushed-work risks after teardown; commands should be safe to retry. These events do not change the recorded setup result.

Dismiss remains metadata-only and never runs teardown, even if a checkout reappears. Missing paths, already removed records and discovered, unregistered worktrees also skip teardown. Adopted records use the configured teardown when removed. Unset teardown preserves existing removal behavior.